Skip to content

Commit 20a9788

Browse files
committed
Move config file update to separate file
Signed-off-by: Evan Lezar <[email protected]>
1 parent 1f722b2 commit 20a9788

File tree

2 files changed

+150
-122
lines changed

2 files changed

+150
-122
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
**/
17+
18+
package toolkit
19+
20+
import (
21+
"fmt"
22+
"os"
23+
"path/filepath"
24+
"strings"
25+
26+
"github.com/urfave/cli/v2"
27+
28+
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
29+
)
30+
31+
const (
32+
configFilename = "config.toml"
33+
)
34+
35+
// installToolkitConfig installs the config file for the NVIDIA container toolkit ensuring
36+
// that the settings are updated to match the desired install and nvidia driver directories.
37+
func (t *Installer) installToolkitConfig(c *cli.Context, opts *Options) error {
38+
toolkitConfigDir := filepath.Join(t.toolkitRoot, ".config", "nvidia-container-runtime")
39+
toolkitConfigPath := filepath.Join(toolkitConfigDir, configFilename)
40+
41+
t.logger.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
42+
43+
err := t.createDirectories(toolkitConfigDir)
44+
if err != nil && !opts.ignoreErrors {
45+
return fmt.Errorf("could not create required directories: %v", err)
46+
} else if err != nil {
47+
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not create required directories: %v", err))
48+
}
49+
nvidiaContainerCliExecutablePath := filepath.Join(t.toolkitRoot, "nvidia-container-cli")
50+
nvidiaCTKPath := filepath.Join(t.toolkitRoot, "nvidia-ctk")
51+
nvidiaContainerRuntimeHookPath := filepath.Join(t.toolkitRoot, "nvidia-container-runtime-hook")
52+
53+
cfg, err := config.New(
54+
config.WithConfigFile(nvidiaContainerToolkitConfigSource),
55+
)
56+
if err != nil {
57+
return fmt.Errorf("could not open source config file: %v", err)
58+
}
59+
60+
targetConfig, err := os.Create(toolkitConfigPath)
61+
if err != nil {
62+
return fmt.Errorf("could not create target config file: %v", err)
63+
}
64+
defer targetConfig.Close()
65+
66+
// Read the ldconfig path from the config as this may differ per platform
67+
// On ubuntu-based systems this ends in `.real`
68+
ldconfigPath := fmt.Sprintf("%s", cfg.GetDefault("nvidia-container-cli.ldconfig", "/sbin/ldconfig"))
69+
// Use the driver run root as the root:
70+
driverLdconfigPath := config.NormalizeLDConfigPath("@" + filepath.Join(opts.DriverRoot, strings.TrimPrefix(ldconfigPath, "@/")))
71+
72+
configValues := map[string]interface{}{
73+
// Set the options in the root toml table
74+
"accept-nvidia-visible-devices-envvar-when-unprivileged": opts.acceptNVIDIAVisibleDevicesWhenUnprivileged,
75+
"accept-nvidia-visible-devices-as-volume-mounts": opts.acceptNVIDIAVisibleDevicesAsVolumeMounts,
76+
// Set the nvidia-container-cli options
77+
"nvidia-container-cli.root": opts.DriverRoot,
78+
"nvidia-container-cli.path": nvidiaContainerCliExecutablePath,
79+
"nvidia-container-cli.ldconfig": driverLdconfigPath,
80+
// Set nvidia-ctk options
81+
"nvidia-ctk.path": nvidiaCTKPath,
82+
// Set the nvidia-container-runtime-hook options
83+
"nvidia-container-runtime-hook.path": nvidiaContainerRuntimeHookPath,
84+
"nvidia-container-runtime-hook.skip-mode-detection": opts.ContainerRuntimeHookSkipModeDetection,
85+
}
86+
87+
toolkitRuntimeList := opts.ContainerRuntimeRuntimes.Value()
88+
if len(toolkitRuntimeList) > 0 {
89+
configValues["nvidia-container-runtime.runtimes"] = toolkitRuntimeList
90+
}
91+
92+
for _, optInFeature := range opts.optInFeatures.Value() {
93+
configValues["features."+optInFeature] = true
94+
}
95+
96+
for key, value := range configValues {
97+
cfg.Set(key, value)
98+
}
99+
100+
// Set the optional config options
101+
optionalConfigValues := map[string]interface{}{
102+
"nvidia-container-runtime.debug": opts.ContainerRuntimeDebug,
103+
"nvidia-container-runtime.log-level": opts.ContainerRuntimeLogLevel,
104+
"nvidia-container-runtime.mode": opts.ContainerRuntimeMode,
105+
"nvidia-container-runtime.modes.cdi.annotation-prefixes": opts.ContainerRuntimeModesCDIAnnotationPrefixes,
106+
"nvidia-container-runtime.modes.cdi.default-kind": opts.ContainerRuntimeModesCdiDefaultKind,
107+
"nvidia-container-runtime.runtimes": opts.ContainerRuntimeRuntimes,
108+
"nvidia-container-cli.debug": opts.ContainerCLIDebug,
109+
}
110+
111+
for key, value := range optionalConfigValues {
112+
if !c.IsSet(key) {
113+
t.logger.Infof("Skipping unset option: %v", key)
114+
continue
115+
}
116+
if value == nil {
117+
t.logger.Infof("Skipping option with nil value: %v", key)
118+
continue
119+
}
120+
121+
switch v := value.(type) {
122+
case string:
123+
if v == "" {
124+
continue
125+
}
126+
case cli.StringSlice:
127+
if len(v.Value()) == 0 {
128+
continue
129+
}
130+
value = v.Value()
131+
default:
132+
t.logger.Warningf("Unexpected type for option %v=%v: %T", key, value, v)
133+
}
134+
135+
cfg.Set(key, value)
136+
}
137+
138+
if _, err := cfg.WriteTo(targetConfig); err != nil {
139+
return fmt.Errorf("error writing config: %v", err)
140+
}
141+
142+
os.Stdout.WriteString("Using config:\n")
143+
if _, err = cfg.WriteTo(os.Stdout); err != nil {
144+
t.logger.Warningf("Failed to output config to STDOUT: %v", err)
145+
}
146+
147+
return nil
148+
}

cmd/nvidia-ctk-installer/toolkit/toolkit.go

Lines changed: 2 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@ import (
2020
"fmt"
2121
"os"
2222
"path/filepath"
23-
"strings"
2423

2524
"github.com/urfave/cli/v2"
2625
"tags.cncf.io/container-device-interface/pkg/cdi"
2726
"tags.cncf.io/container-device-interface/pkg/parser"
2827

2928
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk-installer/toolkit/installer"
30-
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
3129
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
3230
"github.com/NVIDIA/nvidia-container-toolkit/internal/system/nvdevices"
3331
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
@@ -38,11 +36,7 @@ const (
3836
// DefaultNvidiaDriverRoot specifies the default NVIDIA driver run directory
3937
DefaultNvidiaDriverRoot = "/run/nvidia/driver"
4038

41-
nvidiaContainerCliSource = "/usr/bin/nvidia-container-cli"
42-
nvidiaContainerRuntimeHookSource = "/usr/bin/nvidia-container-runtime-hook"
43-
4439
nvidiaContainerToolkitConfigSource = "/etc/nvidia-container-runtime/config.toml"
45-
configFilename = "config.toml"
4640
)
4741

4842
type cdiOptions struct {
@@ -319,20 +313,7 @@ func (t *Installer) Install(cli *cli.Context, opts *Options) error {
319313
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not install toolkit components: %w", err))
320314
}
321315

322-
toolkitConfigDir := filepath.Join(t.toolkitRoot, ".config", "nvidia-container-runtime")
323-
toolkitConfigPath := filepath.Join(toolkitConfigDir, configFilename)
324-
325-
err = t.createDirectories(toolkitConfigDir)
326-
if err != nil && !opts.ignoreErrors {
327-
return fmt.Errorf("could not create required directories: %v", err)
328-
} else if err != nil {
329-
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not create required directories: %v", err))
330-
}
331-
nvidiaContainerCliExecutable := filepath.Join(t.toolkitRoot, "nvidia-container-cli")
332-
nvidiaCTKPath := filepath.Join(t.toolkitRoot, "nvidia-ctk")
333-
nvidiaCDIHookPath := filepath.Join(t.toolkitRoot, "nvidia-cdi-hook")
334-
nvidiaContainerRuntimeHookPath := filepath.Join(t.toolkitRoot, "nvidia-container-runtime-hook")
335-
err = t.installToolkitConfig(cli, toolkitConfigPath, nvidiaContainerCliExecutable, nvidiaCTKPath, nvidiaContainerRuntimeHookPath, opts)
316+
err = t.installToolkitConfig(cli, opts)
336317
if err != nil && !opts.ignoreErrors {
337318
return fmt.Errorf("error installing NVIDIA container toolkit config: %v", err)
338319
} else if err != nil {
@@ -346,6 +327,7 @@ func (t *Installer) Install(cli *cli.Context, opts *Options) error {
346327
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("error creating device nodes: %v", err))
347328
}
348329

330+
nvidiaCDIHookPath := filepath.Join(t.toolkitRoot, "nvidia-cdi-hook")
349331
err = t.generateCDISpec(opts, nvidiaCDIHookPath)
350332
if err != nil && !opts.ignoreErrors {
351333
return fmt.Errorf("error generating CDI specification: %v", err)
@@ -356,108 +338,6 @@ func (t *Installer) Install(cli *cli.Context, opts *Options) error {
356338
return nil
357339
}
358340

359-
// installToolkitConfig installs the config file for the NVIDIA container toolkit ensuring
360-
// that the settings are updated to match the desired install and nvidia driver directories.
361-
func (t *Installer) installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContainerCliExecutablePath string, nvidiaCTKPath string, nvidaContainerRuntimeHookPath string, opts *Options) error {
362-
t.logger.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
363-
364-
cfg, err := config.New(
365-
config.WithConfigFile(nvidiaContainerToolkitConfigSource),
366-
)
367-
if err != nil {
368-
return fmt.Errorf("could not open source config file: %v", err)
369-
}
370-
371-
targetConfig, err := os.Create(toolkitConfigPath)
372-
if err != nil {
373-
return fmt.Errorf("could not create target config file: %v", err)
374-
}
375-
defer targetConfig.Close()
376-
377-
// Read the ldconfig path from the config as this may differ per platform
378-
// On ubuntu-based systems this ends in `.real`
379-
ldconfigPath := fmt.Sprintf("%s", cfg.GetDefault("nvidia-container-cli.ldconfig", "/sbin/ldconfig"))
380-
// Use the driver run root as the root:
381-
driverLdconfigPath := config.NormalizeLDConfigPath("@" + filepath.Join(opts.DriverRoot, strings.TrimPrefix(ldconfigPath, "@/")))
382-
383-
configValues := map[string]interface{}{
384-
// Set the options in the root toml table
385-
"accept-nvidia-visible-devices-envvar-when-unprivileged": opts.acceptNVIDIAVisibleDevicesWhenUnprivileged,
386-
"accept-nvidia-visible-devices-as-volume-mounts": opts.acceptNVIDIAVisibleDevicesAsVolumeMounts,
387-
// Set the nvidia-container-cli options
388-
"nvidia-container-cli.root": opts.DriverRoot,
389-
"nvidia-container-cli.path": nvidiaContainerCliExecutablePath,
390-
"nvidia-container-cli.ldconfig": driverLdconfigPath,
391-
// Set nvidia-ctk options
392-
"nvidia-ctk.path": nvidiaCTKPath,
393-
// Set the nvidia-container-runtime-hook options
394-
"nvidia-container-runtime-hook.path": nvidaContainerRuntimeHookPath,
395-
"nvidia-container-runtime-hook.skip-mode-detection": opts.ContainerRuntimeHookSkipModeDetection,
396-
}
397-
398-
toolkitRuntimeList := opts.ContainerRuntimeRuntimes.Value()
399-
if len(toolkitRuntimeList) > 0 {
400-
configValues["nvidia-container-runtime.runtimes"] = toolkitRuntimeList
401-
}
402-
403-
for _, optInFeature := range opts.optInFeatures.Value() {
404-
configValues["features."+optInFeature] = true
405-
}
406-
407-
for key, value := range configValues {
408-
cfg.Set(key, value)
409-
}
410-
411-
// Set the optional config options
412-
optionalConfigValues := map[string]interface{}{
413-
"nvidia-container-runtime.debug": opts.ContainerRuntimeDebug,
414-
"nvidia-container-runtime.log-level": opts.ContainerRuntimeLogLevel,
415-
"nvidia-container-runtime.mode": opts.ContainerRuntimeMode,
416-
"nvidia-container-runtime.modes.cdi.annotation-prefixes": opts.ContainerRuntimeModesCDIAnnotationPrefixes,
417-
"nvidia-container-runtime.modes.cdi.default-kind": opts.ContainerRuntimeModesCdiDefaultKind,
418-
"nvidia-container-runtime.runtimes": opts.ContainerRuntimeRuntimes,
419-
"nvidia-container-cli.debug": opts.ContainerCLIDebug,
420-
}
421-
422-
for key, value := range optionalConfigValues {
423-
if !c.IsSet(key) {
424-
t.logger.Infof("Skipping unset option: %v", key)
425-
continue
426-
}
427-
if value == nil {
428-
t.logger.Infof("Skipping option with nil value: %v", key)
429-
continue
430-
}
431-
432-
switch v := value.(type) {
433-
case string:
434-
if v == "" {
435-
continue
436-
}
437-
case cli.StringSlice:
438-
if len(v.Value()) == 0 {
439-
continue
440-
}
441-
value = v.Value()
442-
default:
443-
t.logger.Warningf("Unexpected type for option %v=%v: %T", key, value, v)
444-
}
445-
446-
cfg.Set(key, value)
447-
}
448-
449-
if _, err := cfg.WriteTo(targetConfig); err != nil {
450-
return fmt.Errorf("error writing config: %v", err)
451-
}
452-
453-
os.Stdout.WriteString("Using config:\n")
454-
if _, err = cfg.WriteTo(os.Stdout); err != nil {
455-
t.logger.Warningf("Failed to output config to STDOUT: %v", err)
456-
}
457-
458-
return nil
459-
}
460-
461341
func (t *Installer) createDirectories(dir ...string) error {
462342
for _, d := range dir {
463343
t.logger.Infof("Creating directory '%v'", d)

0 commit comments

Comments
 (0)