Skip to content

Commit caf855b

Browse files
committed
Minor rework of disabled hooks
Signed-off-by: Evan Lezar <[email protected]>
1 parent f72732e commit caf855b

File tree

15 files changed

+164
-97
lines changed

15 files changed

+164
-97
lines changed

cmd/nvidia-ctk/cdi/generate/generate.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
270270
deviceNamers = append(deviceNamers, deviceNamer)
271271
}
272272

273-
initOpts := []nvcdi.Option{
273+
cdiOptions := []nvcdi.Option{
274274
nvcdi.WithLogger(m.logger),
275275
nvcdi.WithDriverRoot(opts.driverRoot),
276276
nvcdi.WithDevRoot(opts.devRoot),
@@ -287,10 +287,10 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
287287
}
288288

289289
for _, hook := range opts.disabledHooks.Value() {
290-
initOpts = append(initOpts, nvcdi.WithDisabledHook(hook))
290+
cdiOptions = append(cdiOptions, nvcdi.WithDisabledHook(hook))
291291
}
292292

293-
cdilib, err := nvcdi.New(initOpts...)
293+
cdilib, err := nvcdi.New(cdiOptions...)
294294
if err != nil {
295295
return nil, fmt.Errorf("failed to create CDI library: %v", err)
296296
}

cmd/nvidia-ctk/cdi/generate/generate_test.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ func TestGenerateSpec(t *testing.T) {
3737
require.NoError(t, err)
3838

3939
driverRoot := filepath.Join(moduleRoot, "testdata", "lookup", "rootfs-1")
40-
disableHook1 := cli.NewStringSlice("enable-cuda-compat")
41-
disableHook2 := cli.NewStringSlice("enable-cuda-compat", "update-ldcache")
42-
disableHook3 := cli.NewStringSlice("all")
4340

4441
logger, _ := testlog.NewNullLogger()
4542
testCases := []struct {
@@ -127,7 +124,7 @@ containerEdits:
127124
vendor: "example.com",
128125
class: "device",
129126
driverRoot: driverRoot,
130-
disabledHooks: *disableHook1,
127+
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat")),
131128
},
132129
expectedOptions: options{
133130
format: "yaml",
@@ -136,7 +133,7 @@ containerEdits:
136133
class: "device",
137134
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
138135
driverRoot: driverRoot,
139-
disabledHooks: *disableHook1,
136+
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat")),
140137
},
141138
expectedSpec: `---
142139
cdiVersion: 0.5.0
@@ -192,7 +189,7 @@ containerEdits:
192189
vendor: "example.com",
193190
class: "device",
194191
driverRoot: driverRoot,
195-
disabledHooks: *disableHook2,
192+
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat", "update-ldcache")),
196193
},
197194
expectedOptions: options{
198195
format: "yaml",
@@ -201,7 +198,7 @@ containerEdits:
201198
class: "device",
202199
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
203200
driverRoot: driverRoot,
204-
disabledHooks: *disableHook2,
201+
disabledHooks: valueOf(cli.NewStringSlice("enable-cuda-compat", "update-ldcache")),
205202
},
206203
expectedSpec: `---
207204
cdiVersion: 0.5.0
@@ -250,7 +247,7 @@ containerEdits:
250247
vendor: "example.com",
251248
class: "device",
252249
driverRoot: driverRoot,
253-
disabledHooks: *disableHook3,
250+
disabledHooks: valueOf(cli.NewStringSlice("all")),
254251
},
255252
expectedOptions: options{
256253
format: "yaml",
@@ -259,7 +256,7 @@ containerEdits:
259256
class: "device",
260257
nvidiaCDIHookPath: "/usr/bin/nvidia-cdi-hook",
261258
driverRoot: driverRoot,
262-
disabledHooks: *disableHook3,
259+
disabledHooks: valueOf(cli.NewStringSlice("all")),
263260
},
264261
expectedSpec: `---
265262
cdiVersion: 0.5.0
@@ -333,3 +330,9 @@ containerEdits:
333330
})
334331
}
335332
}
333+
334+
// valueOf returns the value of a pointer.
335+
// Note that this does not check for a nil pointer and is only used for testing.
336+
func valueOf[T any](v *T) T {
337+
return *v
338+
}

internal/discover/graphics_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525

2626
func TestGraphicsLibrariesDiscoverer(t *testing.T) {
2727
logger, _ := testlog.NewNullLogger()
28-
hookCreator := NewHookCreator("/usr/bin/nvidia-cdi-hook")
28+
hookCreator := NewHookCreator()
2929

3030
testCases := []struct {
3131
description string

internal/discover/hooks.go

Lines changed: 108 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,28 @@ import (
2222
"tags.cncf.io/container-device-interface/pkg/cdi"
2323
)
2424

25+
// A HookName represents a supported CDI hooks.
26+
type HookName string
27+
28+
const (
29+
// AllHooks is a special hook name that allows all hooks to be matched.
30+
AllHooks = HookName("all")
31+
32+
// A ChmodHook is used to set the file mode of the specified paths.
33+
// Deprecated: The chmod hook is deprecated and will be removed in a future release.
34+
ChmodHook = HookName("chmod")
35+
// A CreateSymlinksHook is used to create symlinks in the container.
36+
CreateSymlinksHook = HookName("create-symlinks")
37+
// An EnableCudaCompatHook is used to enabled CUDA Forward Compatibility.
38+
// Added in v1.17.5
39+
EnableCudaCompatHook = HookName("enable-cuda-compat")
40+
// An UpdateLDCacheHook is the hook used to update the ldcache in the
41+
// container. This allows injected libraries to be discoverable.
42+
UpdateLDCacheHook = HookName("update-ldcache")
43+
44+
defaultNvidiaCDIHookPath = "/usr/bin/nvidia-cdi-hook"
45+
)
46+
2547
var _ Discover = (*Hook)(nil)
2648

2749
// Devices returns an empty list of devices for a Hook discoverer.
@@ -44,89 +66,128 @@ func (h *Hook) Hooks() ([]Hook, error) {
4466
return []Hook{*h}, nil
4567
}
4668

47-
type HookName string
48-
49-
// disabledHooks allows individual hooks to be disabled.
50-
type disabledHooks map[HookName]bool
69+
type Option func(*cdiHookCreator)
5170

52-
const (
53-
// HookEnableCudaCompat refers to the hook used to enable CUDA Forward Compatibility.
54-
// This was added with v1.17.5 of the NVIDIA Container Toolkit.
55-
HookEnableCudaCompat = HookName("enable-cuda-compat")
56-
// directory path to be mounted into a container.
57-
HookCreateSymlinks = HookName("create-symlinks")
58-
// HookUpdateLDCache refers to the hook used to Update the dynamic linker
59-
// cache inside the directory path to be mounted into a container.
60-
HookUpdateLDCache = HookName("update-ldcache")
61-
)
71+
type cdiHookCreator struct {
72+
nvidiaCDIHookPath string
73+
disabledHooks map[HookName]bool
6274

63-
// AllHooks maintains a future-proof list of all defined hooks.
64-
var AllHooks = []HookName{
65-
HookEnableCudaCompat,
66-
HookCreateSymlinks,
67-
HookUpdateLDCache,
75+
fixedArgs []string
6876
}
6977

70-
type Option func(*CDIHook)
78+
// An allDisabledHookCreator is a HookCreator that does not create any hooks.
79+
type allDisabledHookCreator struct{}
7180

72-
type CDIHook struct {
73-
nvidiaCDIHookPath string
74-
disabledHooks disabledHooks
81+
// Create returns nil for all hooks for an allDisabledHookCreator.
82+
func (a *allDisabledHookCreator) Create(name HookName, args ...string) *Hook {
83+
return nil
7584
}
7685

86+
// A HookCreator defines an interface for creating discover hooks.
7787
type HookCreator interface {
7888
Create(HookName, ...string) *Hook
7989
}
8090

91+
// WithDisabledHooks sets the set of hooks that are disabled for the CDI hook creator.
92+
// This can be specified multiple times.
8193
func WithDisabledHooks(hooks ...HookName) Option {
82-
return func(c *CDIHook) {
94+
return func(c *cdiHookCreator) {
8395
for _, hook := range hooks {
8496
c.disabledHooks[hook] = true
8597
}
8698
}
8799
}
88100

89-
func NewHookCreator(nvidiaCDIHookPath string, opts ...Option) HookCreator {
90-
CDIHook := &CDIHook{
91-
nvidiaCDIHookPath: nvidiaCDIHookPath,
92-
disabledHooks: disabledHooks{},
101+
// WithNVIDIACDIHookPath sets the path to the nvidia-cdi-hook binary.
102+
func WithNVIDIACDIHookPath(nvidiaCDIHookPath string) Option {
103+
return func(c *cdiHookCreator) {
104+
c.nvidiaCDIHookPath = nvidiaCDIHookPath
93105
}
106+
}
94107

108+
func NewHookCreator(opts ...Option) HookCreator {
109+
cdiHookCreator := &cdiHookCreator{
110+
nvidiaCDIHookPath: defaultNvidiaCDIHookPath,
111+
disabledHooks: make(map[HookName]bool),
112+
}
95113
for _, opt := range opts {
96-
opt(CDIHook)
114+
opt(cdiHookCreator)
115+
}
116+
117+
if cdiHookCreator.disabledHooks[AllHooks] {
118+
return &allDisabledHookCreator{}
97119
}
98120

99-
return CDIHook
121+
cdiHookCreator.fixedArgs = getFixedArgsForCDIHookCLI(cdiHookCreator.nvidiaCDIHookPath)
122+
123+
return cdiHookCreator
100124
}
101125

102-
func (c CDIHook) Create(name HookName, args ...string) *Hook {
103-
if c.disabledHooks[name] {
126+
// Create creates a new hook with the given name and arguments.
127+
// If a hook is disabled, a nil hook is returned.
128+
func (c cdiHookCreator) Create(name HookName, args ...string) *Hook {
129+
if c.isDisabled(name, args...) {
104130
return nil
105131
}
106132

107-
if name == "create-symlinks" {
133+
return &Hook{
134+
Lifecycle: cdi.CreateContainerHook,
135+
Path: c.nvidiaCDIHookPath,
136+
Args: append(c.requiredArgs(name), c.transformArgs(name, args...)...),
137+
}
138+
}
139+
140+
// isDisabled checks if the specified hook name is disabled.
141+
func (c cdiHookCreator) isDisabled(name HookName, args ...string) bool {
142+
if c.disabledHooks[name] {
143+
return true
144+
}
145+
146+
switch name {
147+
case CreateSymlinksHook:
108148
if len(args) == 0 {
109-
return nil
149+
return true
110150
}
111-
112-
links := []string{}
113-
for _, arg := range args {
114-
links = append(links, "--link", arg)
151+
case ChmodHook:
152+
if len(args) == 0 {
153+
return true
115154
}
116-
args = links
117155
}
156+
return false
157+
}
118158

119-
return &Hook{
120-
Lifecycle: cdi.CreateContainerHook,
121-
Path: c.nvidiaCDIHookPath,
122-
Args: append(c.requiredArgs(string(name)), args...),
159+
func (c cdiHookCreator) requiredArgs(name HookName) []string {
160+
return append(c.fixedArgs, string(name))
161+
}
162+
163+
func (c cdiHookCreator) transformArgs(name HookName, args ...string) []string {
164+
switch name {
165+
case CreateSymlinksHook:
166+
var transformedArgs []string
167+
for _, arg := range args {
168+
transformedArgs = append(transformedArgs, "--link", arg)
169+
}
170+
return transformedArgs
171+
case ChmodHook:
172+
var transformedArgs = []string{"--mode", "755"}
173+
for _, arg := range args {
174+
transformedArgs = append(transformedArgs, "--path", arg)
175+
}
176+
return transformedArgs
177+
default:
178+
return args
123179
}
124180
}
125181

126-
func (c CDIHook) requiredArgs(name string) []string {
127-
base := filepath.Base(c.nvidiaCDIHookPath)
182+
// getFixedArgsForCDIHookCLI returns the fixed arguments for the hook CLI.
183+
// If the nvidia-ctk binary is used, hooks are implemented under the hook
184+
// subcommand.
185+
// For the nvidia-cdi-hook binary, the hooks are implemented as subcommands of
186+
// the top-level CLI.
187+
func getFixedArgsForCDIHookCLI(nvidiaCDIHookPath string) []string {
188+
base := filepath.Base(nvidiaCDIHookPath)
128189
if base == "nvidia-ctk" {
129-
return []string{base, "hook", name}
190+
return []string{base, "hook"}
130191
}
131-
return []string{base, name}
192+
return []string{base}
132193
}

internal/discover/ldconfig.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func createLDCacheUpdateHook(hookCreator HookCreator, ldconfig string, libraries
7272
args = append(args, "--folder", f)
7373
}
7474

75-
return hookCreator.Create(HookUpdateLDCache, args...)
75+
return hookCreator.Create(UpdateLDCacheHook, args...)
7676
}
7777

7878
// getLibraryPaths extracts the library dirs from the specified mounts

internal/discover/ldconfig_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const (
3131

3232
func TestLDCacheUpdateHook(t *testing.T) {
3333
logger, _ := testlog.NewNullLogger()
34-
hookCreator := NewHookCreator(testNvidiaCDIHookPath)
34+
hookCreator := NewHookCreator(WithNVIDIACDIHookPath(testNvidiaCDIHookPath))
3535

3636
testCases := []struct {
3737
description string

internal/discover/symlinks_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
113113
expectedHooks: []Hook{
114114
{
115115
Lifecycle: "createContainer",
116-
Path: "/path/to/nvidia-cdi-hook",
116+
Path: "/usr/bin/nvidia-cdi-hook",
117117
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
118118
},
119119
},
@@ -145,7 +145,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
145145
expectedHooks: []Hook{
146146
{
147147
Lifecycle: "createContainer",
148-
Path: "/path/to/nvidia-cdi-hook",
148+
Path: "/usr/bin/nvidia-cdi-hook",
149149
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
150150
},
151151
},
@@ -176,7 +176,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
176176
expectedHooks: []Hook{
177177
{
178178
Lifecycle: "createContainer",
179-
Path: "/path/to/nvidia-cdi-hook",
179+
Path: "/usr/bin/nvidia-cdi-hook",
180180
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
181181
},
182182
},
@@ -245,7 +245,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
245245
},
246246
{
247247
Lifecycle: "createContainer",
248-
Path: "/path/to/nvidia-cdi-hook",
248+
Path: "/usr/bin/nvidia-cdi-hook",
249249
Args: []string{"nvidia-cdi-hook", "create-symlinks", "--link", "libcuda.so.1::/usr/lib/libcuda.so"},
250250
},
251251
},
@@ -294,7 +294,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
294294
expectedHooks: []Hook{
295295
{
296296
Lifecycle: "createContainer",
297-
Path: "/path/to/nvidia-cdi-hook",
297+
Path: "/usr/bin/nvidia-cdi-hook",
298298
Args: []string{
299299
"nvidia-cdi-hook", "create-symlinks",
300300
"--link", "libcuda.so.1::/usr/lib/libcuda.so",
@@ -306,7 +306,7 @@ func TestWithWithDriverDotSoSymlinks(t *testing.T) {
306306
},
307307
}
308308

309-
hookCreator := NewHookCreator("/path/to/nvidia-cdi-hook")
309+
hookCreator := NewHookCreator()
310310
for _, tc := range testCases {
311311
t.Run(tc.description, func(t *testing.T) {
312312
d := WithDriverDotSoSymlinks(

internal/platform-support/tegra/csv_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ func TestDiscovererFromCSVFiles(t *testing.T) {
181181
},
182182
}
183183

184-
hookCreator := discover.NewHookCreator("/usr/bin/nvidia-cdi-hook")
184+
hookCreator := discover.NewHookCreator()
185185
for _, tc := range testCases {
186186
t.Run(tc.description, func(t *testing.T) {
187187
defer setGetTargetsFromCSVFiles(tc.moutSpecs)()

internal/runtime/runtime_factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func newSpecModifier(logger logger.Interface, cfg *config.Config, ociSpec oci.Sp
7575
return nil, err
7676
}
7777

78-
hookCreator := discover.NewHookCreator(cfg.NVIDIACTKConfig.Path)
78+
hookCreator := discover.NewHookCreator(discover.WithNVIDIACDIHookPath(cfg.NVIDIACTKConfig.Path))
7979

8080
mode := info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode, image)
8181
// We update the mode here so that we can continue passing just the config to other functions.

0 commit comments

Comments
 (0)