mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-05-15 00:56:41 +00:00
Merge branch 'fix-relative-files' into 'main'
Fix adjusting relative paths for containerised devices and mounts. See merge request nvidia/container-toolkit/container-toolkit!193
This commit is contained in:
commit
629a68937e
internal
@ -30,16 +30,14 @@ var _ Discover = (*charDevices)(nil)
|
|||||||
func NewCharDeviceDiscoverer(logger *logrus.Logger, devices []string, root string) Discover {
|
func NewCharDeviceDiscoverer(logger *logrus.Logger, devices []string, root string) Discover {
|
||||||
locator := lookup.NewCharDeviceLocator(logger, root)
|
locator := lookup.NewCharDeviceLocator(logger, root)
|
||||||
|
|
||||||
return NewDeviceDiscoverer(logger, locator, devices)
|
return NewDeviceDiscoverer(logger, locator, root, devices)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDeviceDiscoverer creates a discoverer which locates the specified set of device nodes using the specified locator.
|
// NewDeviceDiscoverer creates a discoverer which locates the specified set of device nodes using the specified locator.
|
||||||
func NewDeviceDiscoverer(logger *logrus.Logger, locator lookup.Locator, devices []string) Discover {
|
func NewDeviceDiscoverer(logger *logrus.Logger, locator lookup.Locator, root string, devices []string) Discover {
|
||||||
return &charDevices{
|
m := NewMounts(logger, locator, root, devices).(*mounts)
|
||||||
logger: logger,
|
|
||||||
lookup: locator,
|
return (*charDevices)(m)
|
||||||
required: devices,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mounts returns the discovered mounts for the charDevices.
|
// Mounts returns the discovered mounts for the charDevices.
|
||||||
|
@ -52,7 +52,7 @@ func NewFromCSVFiles(logger *logrus.Logger, files []string, root string) (Discov
|
|||||||
mountSpecs = append(mountSpecs, targets...)
|
mountSpecs = append(mountSpecs, targets...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFromMountSpecs(logger, locators, mountSpecs)
|
return newFromMountSpecs(logger, locators, root, mountSpecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadCSVFile loads the specified CSV file and returns the list of mount specs
|
// loadCSVFile loads the specified CSV file and returns the list of mount specs
|
||||||
@ -71,7 +71,7 @@ func loadCSVFile(logger *logrus.Logger, filename string) ([]*csv.MountSpec, erro
|
|||||||
|
|
||||||
// newFromMountSpecs creates a discoverer for the CSV file. A logger is also supplied.
|
// newFromMountSpecs creates a discoverer for the CSV file. A logger is also supplied.
|
||||||
// A list of csvDiscoverers is returned, with each being associated with a single MountSpecType.
|
// A list of csvDiscoverers is returned, with each being associated with a single MountSpecType.
|
||||||
func newFromMountSpecs(logger *logrus.Logger, locators map[csv.MountSpecType]lookup.Locator, targets []*csv.MountSpec) (Discover, error) {
|
func newFromMountSpecs(logger *logrus.Logger, locators map[csv.MountSpecType]lookup.Locator, root string, targets []*csv.MountSpec) (Discover, error) {
|
||||||
if len(targets) == 0 {
|
if len(targets) == 0 {
|
||||||
return &None{}, nil
|
return &None{}, nil
|
||||||
}
|
}
|
||||||
@ -95,13 +95,9 @@ func newFromMountSpecs(logger *logrus.Logger, locators map[csv.MountSpecType]loo
|
|||||||
var m Discover
|
var m Discover
|
||||||
switch t {
|
switch t {
|
||||||
case csv.MountSpecDev:
|
case csv.MountSpecDev:
|
||||||
m = NewDeviceDiscoverer(logger, locator, candidatesByType[t])
|
m = NewDeviceDiscoverer(logger, locator, root, candidatesByType[t])
|
||||||
default:
|
default:
|
||||||
m = &mounts{
|
m = NewMounts(logger, locator, root, candidatesByType[t])
|
||||||
logger: logger,
|
|
||||||
lookup: locator,
|
|
||||||
required: candidatesByType[t],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
discoverers = append(discoverers, m)
|
discoverers = append(discoverers, m)
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ func TestNewFromMountSpec(t *testing.T) {
|
|||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
description string
|
description string
|
||||||
|
root string
|
||||||
targets []*csv.MountSpec
|
targets []*csv.MountSpec
|
||||||
expectedError error
|
expectedError error
|
||||||
expectedDiscoverer Discover
|
expectedDiscoverer Discover
|
||||||
@ -76,12 +77,50 @@ func TestNewFromMountSpec(t *testing.T) {
|
|||||||
&mounts{
|
&mounts{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
lookup: locators["dev"],
|
lookup: locators["dev"],
|
||||||
|
root: "/",
|
||||||
required: []string{"dev0", "dev1"},
|
required: []string{"dev0", "dev1"},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
&mounts{
|
&mounts{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
lookup: locators["lib"],
|
lookup: locators["lib"],
|
||||||
|
root: "/",
|
||||||
|
required: []string{"lib0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "sets root",
|
||||||
|
targets: []*csv.MountSpec{
|
||||||
|
{
|
||||||
|
Type: "dev",
|
||||||
|
Path: "dev0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "lib",
|
||||||
|
Path: "lib0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "dev",
|
||||||
|
Path: "dev1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
root: "/some/root",
|
||||||
|
expectedDiscoverer: &list{
|
||||||
|
discoverers: []Discover{
|
||||||
|
(*charDevices)(
|
||||||
|
&mounts{
|
||||||
|
logger: logger,
|
||||||
|
lookup: locators["dev"],
|
||||||
|
root: "/some/root",
|
||||||
|
required: []string{"dev0", "dev1"},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
&mounts{
|
||||||
|
logger: logger,
|
||||||
|
lookup: locators["lib"],
|
||||||
|
root: "/some/root",
|
||||||
required: []string{"lib0"},
|
required: []string{"lib0"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -91,7 +130,7 @@ func TestNewFromMountSpec(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
discoverer, err := newFromMountSpecs(logger, locators, tc.targets)
|
discoverer, err := newFromMountSpecs(logger, locators, tc.root, tc.targets)
|
||||||
if tc.expectedError != nil {
|
if tc.expectedError != nil {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
return
|
return
|
||||||
|
@ -36,17 +36,19 @@ func NewGDSDiscoverer(logger *logrus.Logger, root string) (Discover, error) {
|
|||||||
root,
|
root,
|
||||||
)
|
)
|
||||||
|
|
||||||
udev := &mounts{
|
udev := NewMounts(
|
||||||
logger: logger,
|
logger,
|
||||||
lookup: lookup.NewDirectoryLocator(logger, root),
|
lookup.NewDirectoryLocator(logger, root),
|
||||||
required: []string{"/run/udev"},
|
root,
|
||||||
}
|
[]string{"/run/udev"},
|
||||||
|
)
|
||||||
|
|
||||||
cufile := &mounts{
|
cufile := NewMounts(
|
||||||
logger: logger,
|
logger,
|
||||||
lookup: lookup.NewFileLocator(logger, root),
|
lookup.NewFileLocator(logger, root),
|
||||||
required: []string{"/etc/cufile.json"},
|
root,
|
||||||
}
|
[]string{"/etc/cufile.json"},
|
||||||
|
)
|
||||||
|
|
||||||
d := gdsDeviceDiscoverer{
|
d := gdsDeviceDiscoverer{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
@ -18,6 +18,8 @@ package discover
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
||||||
@ -31,6 +33,7 @@ type mounts struct {
|
|||||||
None
|
None
|
||||||
logger *logrus.Logger
|
logger *logrus.Logger
|
||||||
lookup lookup.Locator
|
lookup lookup.Locator
|
||||||
|
root string
|
||||||
required []string
|
required []string
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
cache []Mount
|
cache []Mount
|
||||||
@ -38,6 +41,16 @@ type mounts struct {
|
|||||||
|
|
||||||
var _ Discover = (*mounts)(nil)
|
var _ Discover = (*mounts)(nil)
|
||||||
|
|
||||||
|
// NewMounts creates a discoverer for the required mounts using the specified locator.
|
||||||
|
func NewMounts(logger *logrus.Logger, lookup lookup.Locator, root string, required []string) Discover {
|
||||||
|
return &mounts{
|
||||||
|
logger: logger,
|
||||||
|
lookup: lookup,
|
||||||
|
root: filepath.Join("/", root),
|
||||||
|
required: required,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (d *mounts) Mounts() ([]Mount, error) {
|
func (d *mounts) Mounts() ([]Mount, error) {
|
||||||
if d.lookup == nil {
|
if d.lookup == nil {
|
||||||
return nil, fmt.Errorf("no lookup defined")
|
return nil, fmt.Errorf("no lookup defined")
|
||||||
@ -71,11 +84,7 @@ func (d *mounts) Mounts() ([]Mount, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := d.lookup.Relative(p)
|
r := d.relativeTo(p)
|
||||||
if err != nil {
|
|
||||||
d.logger.Warnf("Failed to get relative path of %v: %v", p, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if r == "" {
|
if r == "" {
|
||||||
r = p
|
r = p
|
||||||
}
|
}
|
||||||
@ -97,3 +106,12 @@ func (d *mounts) Mounts() ([]Mount, error) {
|
|||||||
|
|
||||||
return d.cache, nil
|
return d.cache, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// relativeTo returns the path relative to the root for the file locator
|
||||||
|
func (d *mounts) relativeTo(path string) string {
|
||||||
|
if d.root == "/" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimPrefix(path, d.root)
|
||||||
|
}
|
||||||
|
@ -140,37 +140,14 @@ func TestMounts(t *testing.T) {
|
|||||||
input: &mounts{
|
input: &mounts{
|
||||||
lookup: &lookup.LocatorMock{
|
lookup: &lookup.LocatorMock{
|
||||||
LocateFunc: func(s string) ([]string, error) {
|
LocateFunc: func(s string) ([]string, error) {
|
||||||
return []string{"located"}, nil
|
return []string{"/some/root/located"}, nil
|
||||||
},
|
|
||||||
RelativeFunc: func(s string) (string, error) {
|
|
||||||
return "relative", nil
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
root: "/some/root",
|
||||||
required: []string{"required0", "multiple", "required1"},
|
required: []string{"required0", "multiple", "required1"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{
|
expectedMounts: []Mount{
|
||||||
{Path: "relative", HostPath: "located"},
|
{Path: "/located", HostPath: "/some/root/located"},
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "mounts skips relative error",
|
|
||||||
input: &mounts{
|
|
||||||
lookup: &lookup.LocatorMock{
|
|
||||||
LocateFunc: func(s string) ([]string, error) {
|
|
||||||
return []string{s}, nil
|
|
||||||
},
|
|
||||||
RelativeFunc: func(s string) (string, error) {
|
|
||||||
if s == "error" {
|
|
||||||
return "", fmt.Errorf("no relative path")
|
|
||||||
}
|
|
||||||
return "relative" + s, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
required: []string{"required0", "error", "required1"},
|
|
||||||
},
|
|
||||||
expectedMounts: []Mount{
|
|
||||||
{Path: "relativerequired0", HostPath: "required0"},
|
|
||||||
{Path: "relativerequired1", HostPath: "required1"},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
// prefixes. The validity of a file is determined by a filter function.
|
// prefixes. The validity of a file is determined by a filter function.
|
||||||
type file struct {
|
type file struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
root string
|
|
||||||
prefixes []string
|
prefixes []string
|
||||||
filter func(string) error
|
filter func(string) error
|
||||||
}
|
}
|
||||||
@ -78,15 +77,6 @@ func (p file) Locate(pattern string) ([]string, error) {
|
|||||||
return filenames, nil
|
return filenames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relative returns the path relative to the root for the file locator
|
|
||||||
func (p file) Relative(path string) (string, error) {
|
|
||||||
if p.root == "" || p.root == "/" {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Rel(p.root, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertFile checks whether the specified path is a regular file
|
// assertFile checks whether the specified path is a regular file
|
||||||
func assertFile(filename string) error {
|
func assertFile(filename string) error {
|
||||||
info, err := os.Stat(filename)
|
info, err := os.Stat(filename)
|
||||||
|
@ -21,5 +21,4 @@ package lookup
|
|||||||
// Locator defines the interface for locating files on a system.
|
// Locator defines the interface for locating files on a system.
|
||||||
type Locator interface {
|
type Locator interface {
|
||||||
Locate(string) ([]string, error)
|
Locate(string) ([]string, error)
|
||||||
Relative(string) (string, error)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user