mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2024-11-25 21:39:10 +00:00
Merge branch 'CNT-4285/add-runtime-hook-path' into 'main'
Add nvidia-contianer-runtime-hook.path config option See merge request nvidia/container-toolkit/container-toolkit!401
This commit is contained in:
parent
7386f86904
commit
2d7bb636b9
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## v1.13.2
|
## v1.13.2
|
||||||
|
|
||||||
|
* Add `nvidia-container-runtime-hook.path` config option to specify NVIDIA Container Runtime Hook path explicitly.
|
||||||
|
|
||||||
## v1.13.1
|
## v1.13.1
|
||||||
|
|
||||||
* Update `update-ldcache` hook to only update ldcache if it exists.
|
* Update `update-ldcache` hook to only update ldcache if it exists.
|
||||||
|
@ -172,7 +172,7 @@ func TestDuplicateHook(t *testing.T) {
|
|||||||
// addNVIDIAHook is a basic wrapper for an addHookModifier that is used for
|
// addNVIDIAHook is a basic wrapper for an addHookModifier that is used for
|
||||||
// testing.
|
// testing.
|
||||||
func addNVIDIAHook(spec *specs.Spec) error {
|
func addNVIDIAHook(spec *specs.Spec) error {
|
||||||
m := modifier.NewStableRuntimeModifier(logrus.StandardLogger())
|
m := modifier.NewStableRuntimeModifier(logrus.StandardLogger(), nvidiaHook)
|
||||||
return m.Modify(spec)
|
return m.Modify(spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,13 +21,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
||||||
"github.com/pelletier/go-toml"
|
"github.com/pelletier/go-toml"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
configOverride = "XDG_CONFIG_HOME"
|
configOverride = "XDG_CONFIG_HOME"
|
||||||
configFilePath = "nvidia-container-runtime/config.toml"
|
configFilePath = "nvidia-container-runtime/config.toml"
|
||||||
|
|
||||||
|
nvidiaContainerRuntimeHookExecutable = "nvidia-container-runtime-hook"
|
||||||
|
nvidiaContainerRuntimeHookDefaultPath = "/usr/bin/nvidia-container-runtime-hook"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -124,3 +130,41 @@ func getDefaultConfig() *Config {
|
|||||||
|
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolveNVIDIAContainerRuntimeHookPath resolves the path the nvidia-container-runtime-hook binary.
|
||||||
|
func ResolveNVIDIAContainerRuntimeHookPath(logger *logrus.Logger, nvidiaContainerRuntimeHookPath string) string {
|
||||||
|
return resolveWithDefault(
|
||||||
|
logger,
|
||||||
|
"NVIDIA Container Runtime Hook",
|
||||||
|
nvidiaContainerRuntimeHookPath,
|
||||||
|
nvidiaContainerRuntimeHookDefaultPath,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolveWithDefault resolves the path to the specified binary.
|
||||||
|
// If an absolute path is specified, it is used directly without searching for the binary.
|
||||||
|
// If the binary cannot be found in the path, the specified default is used instead.
|
||||||
|
func resolveWithDefault(logger *logrus.Logger, label string, path string, defaultPath string) string {
|
||||||
|
if filepath.IsAbs(path) {
|
||||||
|
logger.Debugf("Using specified %v path %v", label, path)
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
if path == "" {
|
||||||
|
path = filepath.Base(defaultPath)
|
||||||
|
}
|
||||||
|
logger.Debugf("Locating %v as %v", label, path)
|
||||||
|
lookup := lookup.NewExecutableLocator(logger, "")
|
||||||
|
|
||||||
|
resolvedPath := defaultPath
|
||||||
|
targets, err := lookup.Locate(path)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warnf("Failed to locate %v: %v", path, err)
|
||||||
|
} else {
|
||||||
|
logger.Debugf("Found %v candidates: %v", path, targets)
|
||||||
|
resolvedPath = targets[0]
|
||||||
|
}
|
||||||
|
logger.Debugf("Using %v path %v", label, path)
|
||||||
|
|
||||||
|
return resolvedPath
|
||||||
|
}
|
||||||
|
@ -76,6 +76,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
|
Path: "nvidia-container-runtime-hook",
|
||||||
|
},
|
||||||
NVIDIACTKConfig: CTKConfig{
|
NVIDIACTKConfig: CTKConfig{
|
||||||
Path: "nvidia-ctk",
|
Path: "nvidia-ctk",
|
||||||
},
|
},
|
||||||
@ -95,6 +98,7 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"nvidia-container-runtime.modes.cdi.default-kind = \"example.vendor.com/device\"",
|
"nvidia-container-runtime.modes.cdi.default-kind = \"example.vendor.com/device\"",
|
||||||
"nvidia-container-runtime.modes.cdi.annotation-prefixes = [\"cdi.k8s.io/\", \"example.vendor.com/\",]",
|
"nvidia-container-runtime.modes.cdi.annotation-prefixes = [\"cdi.k8s.io/\", \"example.vendor.com/\",]",
|
||||||
"nvidia-container-runtime.modes.csv.mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
"nvidia-container-runtime.modes.csv.mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
||||||
|
"nvidia-container-runtime-hook.path = \"/foo/bar/nvidia-container-runtime-hook\"",
|
||||||
"nvidia-ctk.path = \"/foo/bar/nvidia-ctk\"",
|
"nvidia-ctk.path = \"/foo/bar/nvidia-ctk\"",
|
||||||
},
|
},
|
||||||
expectedConfig: &Config{
|
expectedConfig: &Config{
|
||||||
@ -120,6 +124,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
|
Path: "/foo/bar/nvidia-container-runtime-hook",
|
||||||
|
},
|
||||||
NVIDIACTKConfig: CTKConfig{
|
NVIDIACTKConfig: CTKConfig{
|
||||||
Path: "/foo/bar/nvidia-ctk",
|
Path: "/foo/bar/nvidia-ctk",
|
||||||
},
|
},
|
||||||
@ -143,6 +150,8 @@ func TestGetConfig(t *testing.T) {
|
|||||||
"annotation-prefixes = [\"cdi.k8s.io/\", \"example.vendor.com/\",]",
|
"annotation-prefixes = [\"cdi.k8s.io/\", \"example.vendor.com/\",]",
|
||||||
"[nvidia-container-runtime.modes.csv]",
|
"[nvidia-container-runtime.modes.csv]",
|
||||||
"mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
"mount-spec-path = \"/not/etc/nvidia-container-runtime/host-files-for-container.d\"",
|
||||||
|
"[nvidia-container-runtime-hook]",
|
||||||
|
"path = \"/foo/bar/nvidia-container-runtime-hook\"",
|
||||||
"[nvidia-ctk]",
|
"[nvidia-ctk]",
|
||||||
"path = \"/foo/bar/nvidia-ctk\"",
|
"path = \"/foo/bar/nvidia-ctk\"",
|
||||||
},
|
},
|
||||||
@ -169,6 +178,9 @@ func TestGetConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NVIDIAContainerRuntimeHookConfig: RuntimeHookConfig{
|
||||||
|
Path: "/foo/bar/nvidia-container-runtime-hook",
|
||||||
|
},
|
||||||
NVIDIACTKConfig: CTKConfig{
|
NVIDIACTKConfig: CTKConfig{
|
||||||
Path: "/foo/bar/nvidia-ctk",
|
Path: "/foo/bar/nvidia-ctk",
|
||||||
},
|
},
|
||||||
|
@ -24,6 +24,9 @@ import (
|
|||||||
|
|
||||||
// RuntimeHookConfig stores the config options for the NVIDIA Container Runtime
|
// RuntimeHookConfig stores the config options for the NVIDIA Container Runtime
|
||||||
type RuntimeHookConfig struct {
|
type RuntimeHookConfig struct {
|
||||||
|
// Path specifies the path to the NVIDIA Container Runtime hook binary.
|
||||||
|
// If an executable name is specified, this will be resolved in the path.
|
||||||
|
Path string `toml:"path"`
|
||||||
// SkipModeDetection disables the mode check for the runtime hook.
|
// SkipModeDetection disables the mode check for the runtime hook.
|
||||||
SkipModeDetection bool `toml:"skip-mode-detection"`
|
SkipModeDetection bool `toml:"skip-mode-detection"`
|
||||||
}
|
}
|
||||||
@ -55,6 +58,7 @@ func getRuntimeHookConfigFrom(toml *toml.Tree) (*RuntimeHookConfig, error) {
|
|||||||
// GetDefaultRuntimeHookConfig defines the default values for the config
|
// GetDefaultRuntimeHookConfig defines the default values for the config
|
||||||
func GetDefaultRuntimeHookConfig() *RuntimeHookConfig {
|
func GetDefaultRuntimeHookConfig() *RuntimeHookConfig {
|
||||||
c := RuntimeHookConfig{
|
c := RuntimeHookConfig{
|
||||||
|
Path: NVIDIAContainerRuntimeHookExecutable,
|
||||||
SkipModeDetection: false,
|
SkipModeDetection: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,10 +17,8 @@
|
|||||||
package modifier
|
package modifier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -28,8 +26,11 @@ import (
|
|||||||
|
|
||||||
// NewStableRuntimeModifier creates an OCI spec modifier that inserts the NVIDIA Container Runtime Hook into an OCI
|
// NewStableRuntimeModifier creates an OCI spec modifier that inserts the NVIDIA Container Runtime Hook into an OCI
|
||||||
// spec. The specified logger is used to capture log output.
|
// spec. The specified logger is used to capture log output.
|
||||||
func NewStableRuntimeModifier(logger *logrus.Logger) oci.SpecModifier {
|
func NewStableRuntimeModifier(logger *logrus.Logger, nvidiaContainerRuntimeHookPath string) oci.SpecModifier {
|
||||||
m := stableRuntimeModifier{logger: logger}
|
m := stableRuntimeModifier{
|
||||||
|
logger: logger,
|
||||||
|
nvidiaContainerRuntimeHookPath: nvidiaContainerRuntimeHookPath,
|
||||||
|
}
|
||||||
|
|
||||||
return &m
|
return &m
|
||||||
}
|
}
|
||||||
@ -38,6 +39,7 @@ func NewStableRuntimeModifier(logger *logrus.Logger) oci.SpecModifier {
|
|||||||
// prestart hook. If the hook is already present, no modification is made.
|
// prestart hook. If the hook is already present, no modification is made.
|
||||||
type stableRuntimeModifier struct {
|
type stableRuntimeModifier struct {
|
||||||
logger *logrus.Logger
|
logger *logrus.Logger
|
||||||
|
nvidiaContainerRuntimeHookPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify applies the required modification to the incoming OCI spec, inserting the nvidia-container-runtime-hook
|
// Modify applies the required modification to the incoming OCI spec, inserting the nvidia-container-runtime-hook
|
||||||
@ -53,18 +55,9 @@ func (m stableRuntimeModifier) Modify(spec *specs.Spec) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We create a locator and look for the NVIDIA Container Runtime Hook in the path.
|
path := m.nvidiaContainerRuntimeHookPath
|
||||||
candidates, err := lookup.NewExecutableLocator(m.logger, "").Locate(config.NVIDIAContainerRuntimeHookExecutable)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to locate NVIDIA Container Runtime Hook: %v", err)
|
|
||||||
}
|
|
||||||
path := candidates[0]
|
|
||||||
if len(candidates) > 1 {
|
|
||||||
m.logger.Debugf("Using %v from multiple NVIDIA Container Runtime Hook candidates: %v", path, candidates)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.logger.Infof("Using prestart hook path: %v", path)
|
m.logger.Infof("Using prestart hook path: %v", path)
|
||||||
args := []string{path}
|
args := []string{filepath.Base(path)}
|
||||||
if spec.Hooks == nil {
|
if spec.Hooks == nil {
|
||||||
spec.Hooks = &specs.Hooks{}
|
spec.Hooks = &specs.Hooks{}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ func TestAddHookModifier(t *testing.T) {
|
|||||||
Prestart: []specs.Hook{
|
Prestart: []specs.Hook{
|
||||||
{
|
{
|
||||||
Path: testHookPath,
|
Path: testHookPath,
|
||||||
Args: []string{testHookPath, "prestart"},
|
Args: []string{"nvidia-container-runtime-hook", "prestart"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -95,7 +95,7 @@ func TestAddHookModifier(t *testing.T) {
|
|||||||
Prestart: []specs.Hook{
|
Prestart: []specs.Hook{
|
||||||
{
|
{
|
||||||
Path: testHookPath,
|
Path: testHookPath,
|
||||||
Args: []string{testHookPath, "prestart"},
|
Args: []string{"nvidia-container-runtime-hook", "prestart"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -141,7 +141,7 @@ func TestAddHookModifier(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Path: testHookPath,
|
Path: testHookPath,
|
||||||
Args: []string{testHookPath, "prestart"},
|
Args: []string{"nvidia-container-runtime-hook", "prestart"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -154,7 +154,7 @@ func TestAddHookModifier(t *testing.T) {
|
|||||||
|
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
|
||||||
m := NewStableRuntimeModifier(logger)
|
m := NewStableRuntimeModifier(logger, testHookPath)
|
||||||
|
|
||||||
err := m.Modify(&tc.spec)
|
err := m.Modify(&tc.spec)
|
||||||
if tc.expectedError != nil {
|
if tc.expectedError != nil {
|
||||||
|
@ -63,6 +63,10 @@ func (r rt) Run(argv []string) (rerr error) {
|
|||||||
r.logger.Reset()
|
r.logger.Reset()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// We apply some config updates here to ensure that the config is valid in
|
||||||
|
// all cases.
|
||||||
|
cfg.NVIDIAContainerRuntimeHookConfig.Path = config.ResolveNVIDIAContainerRuntimeHookPath(r.logger.Logger, cfg.NVIDIAContainerRuntimeHookConfig.Path)
|
||||||
|
|
||||||
// Print the config to the output.
|
// Print the config to the output.
|
||||||
configJSON, err := json.MarshalIndent(cfg, "", " ")
|
configJSON, err := json.MarshalIndent(cfg, "", " ")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -99,7 +99,7 @@ func newSpecModifier(logger *logrus.Logger, cfg *config.Config, ociSpec oci.Spec
|
|||||||
func newModeModifier(logger *logrus.Logger, cfg *config.Config, ociSpec oci.Spec, argv []string) (oci.SpecModifier, error) {
|
func newModeModifier(logger *logrus.Logger, cfg *config.Config, ociSpec oci.Spec, argv []string) (oci.SpecModifier, error) {
|
||||||
switch info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode) {
|
switch info.ResolveAutoMode(logger, cfg.NVIDIAContainerRuntimeConfig.Mode) {
|
||||||
case "legacy":
|
case "legacy":
|
||||||
return modifier.NewStableRuntimeModifier(logger), nil
|
return modifier.NewStableRuntimeModifier(logger, cfg.NVIDIAContainerRuntimeHookConfig.Path), nil
|
||||||
case "csv":
|
case "csv":
|
||||||
return modifier.NewCSVModifier(logger, cfg, ociSpec)
|
return modifier.NewCSVModifier(logger, cfg, ociSpec)
|
||||||
case "cdi":
|
case "cdi":
|
||||||
|
2
third_party/nvidia-container-runtime
vendored
2
third_party/nvidia-container-runtime
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 68b81a207bc936328955621708862ec72c6225d4
|
Subproject commit 6f328ae638853b5b295deabfa08becc74f7273ef
|
2
third_party/nvidia-docker
vendored
2
third_party/nvidia-docker
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 80902fe3afab0b08502a47b2f0e134869f813aa2
|
Subproject commit 8bef6b0a49951bfde3426ae80dba5e5810b15ee8
|
@ -305,7 +305,7 @@ func Install(cli *cli.Context, opts *options) error {
|
|||||||
log.Errorf("Ignoring error: %v", fmt.Errorf("error installing NVIDIA container CLI: %v", err))
|
log.Errorf("Ignoring error: %v", fmt.Errorf("error installing NVIDIA container CLI: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = installRuntimeHook(opts.toolkitRoot, toolkitConfigPath)
|
nvidiaContainerRuntimeHookPath, err := installRuntimeHook(opts.toolkitRoot, toolkitConfigPath)
|
||||||
if err != nil && !opts.ignoreErrors {
|
if err != nil && !opts.ignoreErrors {
|
||||||
return fmt.Errorf("error installing NVIDIA container runtime hook: %v", err)
|
return fmt.Errorf("error installing NVIDIA container runtime hook: %v", err)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -319,7 +319,7 @@ func Install(cli *cli.Context, opts *options) error {
|
|||||||
log.Errorf("Ignoring error: %v", fmt.Errorf("error installing NVIDIA Container Toolkit CLI: %v", err))
|
log.Errorf("Ignoring error: %v", fmt.Errorf("error installing NVIDIA Container Toolkit CLI: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = installToolkitConfig(cli, toolkitConfigPath, nvidiaContainerCliExecutable, nvidiaCTKPath, opts)
|
err = 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 {
|
||||||
@ -379,7 +379,7 @@ func installLibrary(libName string, toolkitRoot string) error {
|
|||||||
|
|
||||||
// installToolkitConfig installs the config file for the NVIDIA container toolkit ensuring
|
// 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.
|
// that the settings are updated to match the desired install and nvidia driver directories.
|
||||||
func installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContainerCliExecutablePath string, nvidiaCTKPath string, opts *options) error {
|
func installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContainerCliExecutablePath string, nvidiaCTKPath string, nvidaContainerRuntimeHookPath string, opts *options) error {
|
||||||
log.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
|
log.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
|
||||||
|
|
||||||
config, err := loadConfig(nvidiaContainerToolkitConfigSource)
|
config, err := loadConfig(nvidiaContainerToolkitConfigSource)
|
||||||
@ -410,6 +410,7 @@ func installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContai
|
|||||||
// Set nvidia-ctk options
|
// Set nvidia-ctk options
|
||||||
"nvidia-ctk.path": nvidiaCTKPath,
|
"nvidia-ctk.path": nvidiaCTKPath,
|
||||||
// Set the nvidia-container-runtime-hook options
|
// Set the nvidia-container-runtime-hook options
|
||||||
|
"nvidia-container-runtime-hook.path": nvidaContainerRuntimeHookPath,
|
||||||
"nvidia-container-runtime-hook.skip-mode-detection": opts.ContainerRuntimeHookSkipModeDetection,
|
"nvidia-container-runtime-hook.skip-mode-detection": opts.ContainerRuntimeHookSkipModeDetection,
|
||||||
}
|
}
|
||||||
for key, value := range configValues {
|
for key, value := range configValues {
|
||||||
|
Loading…
Reference in New Issue
Block a user