mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-06-26 18:18:24 +00:00
Move toolkit config file update to separate file
This change moves the generating of a toolkit config to a separate file. Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
parent
82a69ee21b
commit
23bd41163c
146
cmd/nvidia-ctk-installer/toolkit/configure.go
Normal file
146
cmd/nvidia-ctk-installer/toolkit/configure.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
package toolkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
configFilename = "config.toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
// installToolkitConfig installs the config file for the NVIDIA container toolkit ensuring
|
||||||
|
// that the settings are updated to match the desired install and nvidia driver directories.
|
||||||
|
func (t *Installer) installToolkitConfig(c *cli.Context, opts *Options) error {
|
||||||
|
toolkitConfigDir := filepath.Join(t.toolkitRoot, ".config", "nvidia-container-runtime")
|
||||||
|
toolkitConfigPath := filepath.Join(toolkitConfigDir, configFilename)
|
||||||
|
|
||||||
|
t.logger.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
|
||||||
|
|
||||||
|
err := t.createDirectories(toolkitConfigDir)
|
||||||
|
if err != nil && !opts.ignoreErrors {
|
||||||
|
return fmt.Errorf("could not create required directories: %v", err)
|
||||||
|
} else if err != nil {
|
||||||
|
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not create required directories: %v", err))
|
||||||
|
}
|
||||||
|
nvidiaContainerCliExecutablePath := filepath.Join(t.toolkitRoot, "nvidia-container-cli")
|
||||||
|
nvidiaCTKPath := filepath.Join(t.toolkitRoot, "nvidia-ctk")
|
||||||
|
nvidiaContainerRuntimeHookPath := filepath.Join(t.toolkitRoot, "nvidia-container-runtime-hook")
|
||||||
|
|
||||||
|
cfg, err := config.New()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open source config file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
targetConfig, err := os.Create(toolkitConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not create target config file: %v", err)
|
||||||
|
}
|
||||||
|
defer targetConfig.Close()
|
||||||
|
|
||||||
|
// Read the ldconfig path from the config as this may differ per platform
|
||||||
|
// On ubuntu-based systems this ends in `.real`
|
||||||
|
ldconfigPath := fmt.Sprintf("%s", cfg.GetDefault("nvidia-container-cli.ldconfig", "/sbin/ldconfig"))
|
||||||
|
// Use the driver run root as the root:
|
||||||
|
driverLdconfigPath := config.NormalizeLDConfigPath("@" + filepath.Join(opts.DriverRoot, strings.TrimPrefix(ldconfigPath, "@/")))
|
||||||
|
|
||||||
|
configValues := map[string]interface{}{
|
||||||
|
// Set the options in the root toml table
|
||||||
|
"accept-nvidia-visible-devices-envvar-when-unprivileged": opts.acceptNVIDIAVisibleDevicesWhenUnprivileged,
|
||||||
|
"accept-nvidia-visible-devices-as-volume-mounts": opts.acceptNVIDIAVisibleDevicesAsVolumeMounts,
|
||||||
|
// Set the nvidia-container-cli options
|
||||||
|
"nvidia-container-cli.root": opts.DriverRoot,
|
||||||
|
"nvidia-container-cli.path": nvidiaContainerCliExecutablePath,
|
||||||
|
"nvidia-container-cli.ldconfig": driverLdconfigPath,
|
||||||
|
// Set nvidia-ctk options
|
||||||
|
"nvidia-ctk.path": nvidiaCTKPath,
|
||||||
|
// Set the nvidia-container-runtime-hook options
|
||||||
|
"nvidia-container-runtime-hook.path": nvidiaContainerRuntimeHookPath,
|
||||||
|
"nvidia-container-runtime-hook.skip-mode-detection": opts.ContainerRuntimeHookSkipModeDetection,
|
||||||
|
}
|
||||||
|
|
||||||
|
toolkitRuntimeList := opts.ContainerRuntimeRuntimes.Value()
|
||||||
|
if len(toolkitRuntimeList) > 0 {
|
||||||
|
configValues["nvidia-container-runtime.runtimes"] = toolkitRuntimeList
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, optInFeature := range opts.optInFeatures.Value() {
|
||||||
|
configValues["features."+optInFeature] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range configValues {
|
||||||
|
cfg.Set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the optional config options
|
||||||
|
optionalConfigValues := map[string]interface{}{
|
||||||
|
"nvidia-container-runtime.debug": opts.ContainerRuntimeDebug,
|
||||||
|
"nvidia-container-runtime.log-level": opts.ContainerRuntimeLogLevel,
|
||||||
|
"nvidia-container-runtime.mode": opts.ContainerRuntimeMode,
|
||||||
|
"nvidia-container-runtime.modes.cdi.annotation-prefixes": opts.ContainerRuntimeModesCDIAnnotationPrefixes,
|
||||||
|
"nvidia-container-runtime.modes.cdi.default-kind": opts.ContainerRuntimeModesCdiDefaultKind,
|
||||||
|
"nvidia-container-runtime.runtimes": opts.ContainerRuntimeRuntimes,
|
||||||
|
"nvidia-container-cli.debug": opts.ContainerCLIDebug,
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range optionalConfigValues {
|
||||||
|
if !c.IsSet(key) {
|
||||||
|
t.logger.Infof("Skipping unset option: %v", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if value == nil {
|
||||||
|
t.logger.Infof("Skipping option with nil value: %v", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
if v == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case cli.StringSlice:
|
||||||
|
if len(v.Value()) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
value = v.Value()
|
||||||
|
default:
|
||||||
|
t.logger.Warningf("Unexpected type for option %v=%v: %T", key, value, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.Set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := cfg.WriteTo(targetConfig); err != nil {
|
||||||
|
return fmt.Errorf("error writing config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Stdout.WriteString("Using config:\n")
|
||||||
|
if _, err = cfg.WriteTo(os.Stdout); err != nil {
|
||||||
|
t.logger.Warningf("Failed to output config to STDOUT: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -20,14 +20,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"tags.cncf.io/container-device-interface/pkg/cdi"
|
"tags.cncf.io/container-device-interface/pkg/cdi"
|
||||||
"tags.cncf.io/container-device-interface/pkg/parser"
|
"tags.cncf.io/container-device-interface/pkg/parser"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk-installer/toolkit/installer"
|
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk-installer/toolkit/installer"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/system/nvdevices"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/system/nvdevices"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
|
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
|
||||||
@ -37,11 +35,6 @@ import (
|
|||||||
const (
|
const (
|
||||||
// DefaultNvidiaDriverRoot specifies the default NVIDIA driver run directory
|
// DefaultNvidiaDriverRoot specifies the default NVIDIA driver run directory
|
||||||
DefaultNvidiaDriverRoot = "/run/nvidia/driver"
|
DefaultNvidiaDriverRoot = "/run/nvidia/driver"
|
||||||
|
|
||||||
nvidiaContainerCliSource = "/usr/bin/nvidia-container-cli"
|
|
||||||
nvidiaContainerRuntimeHookSource = "/usr/bin/nvidia-container-runtime-hook"
|
|
||||||
|
|
||||||
configFilename = "config.toml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type cdiOptions struct {
|
type cdiOptions struct {
|
||||||
@ -318,20 +311,7 @@ func (t *Installer) Install(cli *cli.Context, opts *Options) error {
|
|||||||
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not install toolkit components: %w", err))
|
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not install toolkit components: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
toolkitConfigDir := filepath.Join(t.toolkitRoot, ".config", "nvidia-container-runtime")
|
err = t.installToolkitConfig(cli, opts)
|
||||||
toolkitConfigPath := filepath.Join(toolkitConfigDir, configFilename)
|
|
||||||
|
|
||||||
err = t.createDirectories(toolkitConfigDir)
|
|
||||||
if err != nil && !opts.ignoreErrors {
|
|
||||||
return fmt.Errorf("could not create required directories: %v", err)
|
|
||||||
} else if err != nil {
|
|
||||||
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("could not create required directories: %v", err))
|
|
||||||
}
|
|
||||||
nvidiaContainerCliExecutable := filepath.Join(t.toolkitRoot, "nvidia-container-cli")
|
|
||||||
nvidiaCTKPath := filepath.Join(t.toolkitRoot, "nvidia-ctk")
|
|
||||||
nvidiaCDIHookPath := filepath.Join(t.toolkitRoot, "nvidia-cdi-hook")
|
|
||||||
nvidiaContainerRuntimeHookPath := filepath.Join(t.toolkitRoot, "nvidia-container-runtime-hook")
|
|
||||||
err = t.installToolkitConfig(cli, toolkitConfigPath, nvidiaContainerCliExecutable, nvidiaCTKPath, nvidiaContainerRuntimeHookPath, opts)
|
|
||||||
if err != nil && !opts.ignoreErrors {
|
if err != nil && !opts.ignoreErrors {
|
||||||
return fmt.Errorf("error installing NVIDIA container toolkit config: %v", err)
|
return fmt.Errorf("error installing NVIDIA container toolkit config: %v", err)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -345,6 +325,7 @@ func (t *Installer) Install(cli *cli.Context, opts *Options) error {
|
|||||||
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("error creating device nodes: %v", err))
|
t.logger.Errorf("Ignoring error: %v", fmt.Errorf("error creating device nodes: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvidiaCDIHookPath := filepath.Join(t.toolkitRoot, "nvidia-cdi-hook")
|
||||||
err = t.generateCDISpec(opts, nvidiaCDIHookPath)
|
err = t.generateCDISpec(opts, nvidiaCDIHookPath)
|
||||||
if err != nil && !opts.ignoreErrors {
|
if err != nil && !opts.ignoreErrors {
|
||||||
return fmt.Errorf("error generating CDI specification: %v", err)
|
return fmt.Errorf("error generating CDI specification: %v", err)
|
||||||
@ -355,106 +336,6 @@ func (t *Installer) Install(cli *cli.Context, opts *Options) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// installToolkitConfig installs the config file for the NVIDIA container toolkit ensuring
|
|
||||||
// that the settings are updated to match the desired install and nvidia driver directories.
|
|
||||||
func (t *Installer) installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContainerCliExecutablePath string, nvidiaCTKPath string, nvidaContainerRuntimeHookPath string, opts *Options) error {
|
|
||||||
t.logger.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
|
|
||||||
|
|
||||||
cfg, err := config.New()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not open source config file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
targetConfig, err := os.Create(toolkitConfigPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not create target config file: %v", err)
|
|
||||||
}
|
|
||||||
defer targetConfig.Close()
|
|
||||||
|
|
||||||
// Read the ldconfig path from the config as this may differ per platform
|
|
||||||
// On ubuntu-based systems this ends in `.real`
|
|
||||||
ldconfigPath := fmt.Sprintf("%s", cfg.GetDefault("nvidia-container-cli.ldconfig", "/sbin/ldconfig"))
|
|
||||||
// Use the driver run root as the root:
|
|
||||||
driverLdconfigPath := config.NormalizeLDConfigPath("@" + filepath.Join(opts.DriverRoot, strings.TrimPrefix(ldconfigPath, "@/")))
|
|
||||||
|
|
||||||
configValues := map[string]interface{}{
|
|
||||||
// Set the options in the root toml table
|
|
||||||
"accept-nvidia-visible-devices-envvar-when-unprivileged": opts.acceptNVIDIAVisibleDevicesWhenUnprivileged,
|
|
||||||
"accept-nvidia-visible-devices-as-volume-mounts": opts.acceptNVIDIAVisibleDevicesAsVolumeMounts,
|
|
||||||
// Set the nvidia-container-cli options
|
|
||||||
"nvidia-container-cli.root": opts.DriverRoot,
|
|
||||||
"nvidia-container-cli.path": nvidiaContainerCliExecutablePath,
|
|
||||||
"nvidia-container-cli.ldconfig": driverLdconfigPath,
|
|
||||||
// Set nvidia-ctk options
|
|
||||||
"nvidia-ctk.path": nvidiaCTKPath,
|
|
||||||
// Set the nvidia-container-runtime-hook options
|
|
||||||
"nvidia-container-runtime-hook.path": nvidaContainerRuntimeHookPath,
|
|
||||||
"nvidia-container-runtime-hook.skip-mode-detection": opts.ContainerRuntimeHookSkipModeDetection,
|
|
||||||
}
|
|
||||||
|
|
||||||
toolkitRuntimeList := opts.ContainerRuntimeRuntimes.Value()
|
|
||||||
if len(toolkitRuntimeList) > 0 {
|
|
||||||
configValues["nvidia-container-runtime.runtimes"] = toolkitRuntimeList
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, optInFeature := range opts.optInFeatures.Value() {
|
|
||||||
configValues["features."+optInFeature] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, value := range configValues {
|
|
||||||
cfg.Set(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the optional config options
|
|
||||||
optionalConfigValues := map[string]interface{}{
|
|
||||||
"nvidia-container-runtime.debug": opts.ContainerRuntimeDebug,
|
|
||||||
"nvidia-container-runtime.log-level": opts.ContainerRuntimeLogLevel,
|
|
||||||
"nvidia-container-runtime.mode": opts.ContainerRuntimeMode,
|
|
||||||
"nvidia-container-runtime.modes.cdi.annotation-prefixes": opts.ContainerRuntimeModesCDIAnnotationPrefixes,
|
|
||||||
"nvidia-container-runtime.modes.cdi.default-kind": opts.ContainerRuntimeModesCdiDefaultKind,
|
|
||||||
"nvidia-container-runtime.runtimes": opts.ContainerRuntimeRuntimes,
|
|
||||||
"nvidia-container-cli.debug": opts.ContainerCLIDebug,
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, value := range optionalConfigValues {
|
|
||||||
if !c.IsSet(key) {
|
|
||||||
t.logger.Infof("Skipping unset option: %v", key)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if value == nil {
|
|
||||||
t.logger.Infof("Skipping option with nil value: %v", key)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v := value.(type) {
|
|
||||||
case string:
|
|
||||||
if v == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case cli.StringSlice:
|
|
||||||
if len(v.Value()) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
value = v.Value()
|
|
||||||
default:
|
|
||||||
t.logger.Warningf("Unexpected type for option %v=%v: %T", key, value, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.Set(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := cfg.WriteTo(targetConfig); err != nil {
|
|
||||||
return fmt.Errorf("error writing config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Stdout.WriteString("Using config:\n")
|
|
||||||
if _, err = cfg.WriteTo(os.Stdout); err != nil {
|
|
||||||
t.logger.Warningf("Failed to output config to STDOUT: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Installer) createDirectories(dir ...string) error {
|
func (t *Installer) createDirectories(dir ...string) error {
|
||||||
for _, d := range dir {
|
for _, d := range dir {
|
||||||
t.logger.Infof("Creating directory '%v'", d)
|
t.logger.Infof("Creating directory '%v'", d)
|
||||||
|
Loading…
Reference in New Issue
Block a user