Skip to content

Commit 0c687be

Browse files
committed
[no-relnote] Also validate CDI management spec
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 8d869ac commit 0c687be

File tree

4 files changed

+90
-9
lines changed

4 files changed

+90
-9
lines changed

internal/lookup/device.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,15 @@ const (
2828
// NewCharDeviceLocator creates a Locator that can be used to find char devices at the specified root. A logger is
2929
// also specified.
3030
func NewCharDeviceLocator(opts ...Option) Locator {
31+
filter := assertCharDevice
32+
// TODO: We should have a better way to inject this logic than this envvar.
33+
if os.Getenv("__NVCT_TESTING_DEVICES_ARE_FILES") == "true" {
34+
filter = assertFile
35+
}
36+
3137
opts = append(opts,
3238
WithSearchPaths("", devRoot),
33-
WithFilter(assertCharDevice),
39+
WithFilter(filter),
3440
)
3541
return NewFileLocator(
3642
opts...,

testdata/lookup/rootfs-1/dev/nvidia0

Whitespace-only changes.

testdata/lookup/rootfs-1/dev/nvidiactl

Whitespace-only changes.

tools/container/toolkit/toolkit_test.go

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package toolkit
1818

1919
import (
20+
"fmt"
2021
"os"
2122
"path/filepath"
23+
"strings"
2224
"testing"
2325

2426
"github.com/stretchr/testify/require"
@@ -30,16 +32,20 @@ import (
3032
)
3133

3234
func TestInstall(t *testing.T) {
35+
t.Setenv("__NVCT_TESTING_DEVICES_ARE_FILES", "true")
36+
3337
moduleRoot, err := test.GetModuleRoot()
3438
require.NoError(t, err)
3539

3640
artifactRoot := filepath.Join(moduleRoot, "testdata", "installer", "artifacts")
3741

3842
testCases := []struct {
39-
description string
40-
hostRoot string
41-
packageType string
42-
expectedError error
43+
description string
44+
hostRoot string
45+
packageType string
46+
cdiEnabled bool
47+
expectedError error
48+
expectedCdiSpec string
4349
}{
4450
{
4551
hostRoot: "rootfs-empty",
@@ -49,22 +55,80 @@ func TestInstall(t *testing.T) {
4955
hostRoot: "rootfs-empty",
5056
packageType: "rpm",
5157
},
58+
{
59+
hostRoot: "rootfs-empty",
60+
packageType: "deb",
61+
cdiEnabled: true,
62+
expectedError: fmt.Errorf("no NVIDIA device nodes found"),
63+
},
64+
{
65+
hostRoot: "rootfs-1",
66+
packageType: "deb",
67+
cdiEnabled: true,
68+
expectedCdiSpec: `---
69+
cdiVersion: 0.5.0
70+
containerEdits:
71+
env:
72+
- NVIDIA_VISIBLE_DEVICES=void
73+
hooks:
74+
- args:
75+
- nvidia-cdi-hook
76+
- create-symlinks
77+
- --link
78+
- libcuda.so.1::/lib/x86_64-linux-gnu/libcuda.so
79+
hookName: createContainer
80+
path: {{ .toolkitRoot }}/nvidia-cdi-hook
81+
- args:
82+
- nvidia-cdi-hook
83+
- update-ldcache
84+
- --folder
85+
- /lib/x86_64-linux-gnu
86+
hookName: createContainer
87+
path: {{ .toolkitRoot }}/nvidia-cdi-hook
88+
mounts:
89+
- containerPath: /lib/x86_64-linux-gnu/libcuda.so.999.88.77
90+
hostPath: /host/driver/root/lib/x86_64-linux-gnu/libcuda.so.999.88.77
91+
options:
92+
- ro
93+
- nosuid
94+
- nodev
95+
- bind
96+
devices:
97+
- containerEdits:
98+
deviceNodes:
99+
- hostPath: /host/driver/root/dev/nvidia0
100+
path: /dev/nvidia0
101+
- hostPath: /host/driver/root/dev/nvidiactl
102+
path: /dev/nvidiactl
103+
name: all
104+
kind: example.com/class
105+
`,
106+
},
52107
}
53108

54109
for _, tc := range testCases {
55110
// hostRoot := filepath.Join(moduleRoot, "testdata", "lookup", tc.hostRoot)
56111
t.Run(tc.description, func(t *testing.T) {
57-
toolkitRoot := filepath.Join(t.TempDir(), "toolkit-test")
112+
testRoot := t.TempDir()
113+
toolkitRoot := filepath.Join(testRoot, "toolkit-test")
114+
cdiOutputDir := filepath.Join(moduleRoot, "toolkit-test", "/var/cdi")
58115
sourceRoot := filepath.Join(artifactRoot, tc.packageType)
59116
options := Options{
60-
DriverRoot: "/host/driver/root",
61-
cdiKind: "example.com/class",
117+
DriverRoot: "/host/driver/root",
118+
DriverRootCtrPath: filepath.Join(moduleRoot, "testdata", "lookup", tc.hostRoot),
119+
cdiEnabled: tc.cdiEnabled,
120+
cdiOutputDir: cdiOutputDir,
121+
cdiKind: "example.com/class",
62122
}
63123

64124
require.NoError(t, ValidateOptions(&options, toolkitRoot))
65125

66126
err := Install(&cli.Context{}, &options, sourceRoot, toolkitRoot)
67-
require.ErrorIs(t, err, tc.expectedError)
127+
if tc.expectedError == nil {
128+
require.NoError(t, err)
129+
} else {
130+
require.Contains(t, err.Error(), tc.expectedError.Error())
131+
}
68132

69133
require.DirExists(t, toolkitRoot)
70134
requireSymlink(t, toolkitRoot, "libnvidia-container.so.1", "libnvidia-container.so.99.88.77")
@@ -100,6 +164,17 @@ func TestInstall(t *testing.T) {
100164
require.Equal(t, "@/host/driver/root/sbin/ldconfig", cfg.NVIDIAContainerCLIConfig.Ldconfig)
101165
require.EqualValues(t, filepath.Join(toolkitRoot, "nvidia-container-cli"), cfg.NVIDIAContainerCLIConfig.Path)
102166
require.EqualValues(t, filepath.Join(toolkitRoot, "nvidia-ctk"), cfg.NVIDIACTKConfig.Path)
167+
168+
if len(tc.expectedCdiSpec) > 0 {
169+
cdiSpecFile := filepath.Join(cdiOutputDir, "example.com-class.yaml")
170+
require.FileExists(t, cdiSpecFile)
171+
info, err := os.Stat(cdiSpecFile)
172+
require.NoError(t, err)
173+
require.NotZero(t, info.Mode()&0004)
174+
contents, err := os.ReadFile(cdiSpecFile)
175+
require.NoError(t, err)
176+
require.Equal(t, strings.ReplaceAll(tc.expectedCdiSpec, "{{ .toolkitRoot }}", toolkitRoot), string(contents))
177+
}
103178
})
104179
}
105180
}

0 commit comments

Comments
 (0)