@@ -32,6 +32,9 @@ import (
3232
3333 "github.com/NVIDIA/nvidia-container-toolkit/internal/config"
3434 "github.com/NVIDIA/nvidia-container-toolkit/internal/system/nvdevices"
35+ pkgconfig "github.com/NVIDIA/nvidia-container-toolkit/pkg/config"
36+ "github.com/NVIDIA/nvidia-container-toolkit/pkg/config/engine/containerd"
37+ "github.com/NVIDIA/nvidia-container-toolkit/pkg/config/engine/crio"
3538 "github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
3639 transformroot "github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform/root"
3740)
@@ -40,6 +43,8 @@ const (
4043 // DefaultNvidiaDriverRoot specifies the default NVIDIA driver run directory
4144 DefaultNvidiaDriverRoot = "/run/nvidia/driver"
4245
46+ DefaultHostRootMount = "/host"
47+
4348 nvidiaContainerCliSource = "/usr/bin/nvidia-container-cli"
4449 nvidiaContainerRuntimeHookSource = "/usr/bin/nvidia-container-runtime-hook"
4550
@@ -54,6 +59,7 @@ type Options struct {
5459 DevRoot string
5560 DriverRootCtrPath string
5661 DevRootCtrPath string
62+ HostRootMount string
5763
5864 ContainerRuntimeMode string
5965 ContainerRuntimeDebug string
@@ -109,6 +115,13 @@ func Flags(opts *Options) []cli.Flag {
109115 Destination : & opts .DevRootCtrPath ,
110116 EnvVars : []string {"DEV_ROOT_CTR_PATH" },
111117 },
118+ & cli.StringFlag {
119+ Name : "host-root" ,
120+ Usage : "Specify the path to the host root to be used when executing shell commands." ,
121+ Value : DefaultHostRootMount ,
122+ Destination : & opts .HostRootMount ,
123+ EnvVars : []string {"HOST_ROOT_MOUNT" },
124+ },
112125 & cli.StringFlag {
113126 Name : "nvidia-container-runtime.debug" ,
114127 Aliases : []string {"nvidia-container-runtime-debug" },
@@ -342,7 +355,14 @@ func Install(cli *cli.Context, opts *Options, toolkitRoot string) error {
342355 log .Errorf ("Ignoring error: %v" , fmt .Errorf ("error installing NVIDIA Container CDI Hook CLI: %v" , err ))
343356 }
344357
345- err = installToolkitConfig (cli , toolkitConfigPath , nvidiaContainerCliExecutable , nvidiaCTKPath , nvidiaContainerRuntimeHookPath , opts )
358+ var runtimeBinPaths []string
359+ runtimeBinPaths , err = getRuntimeBinaryPaths (opts .HostRootMount )
360+ if err != nil {
361+ log .Warningf ("Error retrieving runtime binary paths: %v" , err )
362+ }
363+
364+ err = installToolkitConfig (cli , toolkitConfigPath , nvidiaContainerCliExecutable , nvidiaCTKPath ,
365+ nvidiaContainerRuntimeHookPath , runtimeBinPaths , opts )
346366 if err != nil && ! opts .ignoreErrors {
347367 return fmt .Errorf ("error installing NVIDIA container toolkit config: %v" , err )
348368 } else if err != nil {
@@ -419,11 +439,15 @@ func installLibrary(libName string, toolkitRoot string) error {
419439func installToolkitConfig (c * cli.Context , toolkitConfigPath string , nvidiaContainerCliExecutablePath string , nvidiaCTKPath string , nvidaContainerRuntimeHookPath string , opts * Options ) error {
420440 log .Infof ("Installing NVIDIA container toolkit config '%v'" , toolkitConfigPath )
421441
422- cfg , err := loadConfig (nvidiaContainerToolkitConfigSource )
442+ cfg , err := config .New (
443+ config .WithConfigFile (opts .toolkitConfigSource ),
444+ )
423445 if err != nil {
424446 return fmt .Errorf ("could not open source config file: %v" , err )
425447 }
426448
449+ log .Infof ("Printing Default toolkit toml config: %v" , cfg )
450+
427451 targetConfig , err := os .Create (toolkitConfigPath )
428452 if err != nil {
429453 return fmt .Errorf ("could not create target config file: %v" , err )
@@ -436,6 +460,18 @@ func installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContai
436460 // Use the driver run root as the root:
437461 driverLdconfigPath := config .NormalizeLDConfigPath ("@" + filepath .Join (opts .DriverRoot , strings .TrimPrefix (ldconfigPath , "@/" )))
438462
463+ var ctkRuntimes []string
464+ defaultCfg , err := cfg .Config ()
465+ if err == nil {
466+ defaultCfgRuntimes := defaultCfg .NVIDIAContainerRuntimeConfig .Runtimes
467+ if len (runtimeBinaryPaths ) > 0 {
468+ ctkRuntimes = append (ctkRuntimes , runtimeBinaryPaths ... )
469+ }
470+ ctkRuntimes = append (ctkRuntimes , defaultCfgRuntimes ... )
471+ } else {
472+ log .Warningf ("could not get default toolkit config: %v" , err )
473+ }
474+
439475 configValues := map [string ]interface {}{
440476 // Set the options in the root toml table
441477 "accept-nvidia-visible-devices-envvar-when-unprivileged" : opts .acceptNVIDIAVisibleDevicesWhenUnprivileged ,
@@ -450,6 +486,11 @@ func installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContai
450486 "nvidia-container-runtime-hook.path" : nvidaContainerRuntimeHookPath ,
451487 "nvidia-container-runtime-hook.skip-mode-detection" : opts .ContainerRuntimeHookSkipModeDetection ,
452488 }
489+
490+ if len (ctkRuntimes ) > 0 {
491+ configValues ["nvidia-container-runtime.runtimes" ] = ctkRuntimes
492+ }
493+
453494 for key , value := range configValues {
454495 cfg .Set (key , value )
455496 }
@@ -503,16 +544,6 @@ func installToolkitConfig(c *cli.Context, toolkitConfigPath string, nvidiaContai
503544 return nil
504545}
505546
506- func loadConfig (path string ) (* toml.Tree , error ) {
507- _ , err := os .Stat (path )
508- if err == nil {
509- return toml .LoadFile (path )
510- } else if os .IsNotExist (err ) {
511- return toml .TreeFromMap (nil )
512- }
513- return nil , err
514- }
515-
516547// installContainerToolkitCLI installs the nvidia-ctk CLI executable and wrapper.
517548func installContainerToolkitCLI (toolkitDir string ) (string , error ) {
518549 e := executable {
@@ -793,3 +824,64 @@ func generateCDISpec(opts *Options, nvidiaCDIHookPath string) error {
793824
794825 return nil
795826}
827+
828+ // getRuntimeBinaryPaths extracts the full paths of the low-level runtime binaries specified in the container runtime config
829+ func getRuntimeBinaryPaths (hostRoot string ) ([]string , error ) {
830+ var runtimeBinaryPaths []string
831+
832+ if r , ok := os .LookupEnv ("RUNTIME" ); ok {
833+
834+ switch r {
835+ case "containerd" :
836+ var cliArgs []string
837+ if hostRoot != "" {
838+ cliArgs = append (cliArgs , "chroot" , hostRoot )
839+ }
840+ cliArgs = append (cliArgs , "containerd" , "config" , "dump" )
841+
842+ cfg , err := containerd .New (
843+ containerd .WithReference (pkgconfig .FromCLI (cliArgs )),
844+ )
845+ if err != nil {
846+ return nil , fmt .Errorf ("unable to load containerd config: %w" , err )
847+ }
848+
849+ containerdDefaultRuntime := cfg .DefaultRuntime ()
850+ if containerdDefaultRuntime != "" {
851+ runtimeData , err := cfg .GetRuntime (containerdDefaultRuntime )
852+ if err == nil {
853+ runtimeTOML := runtimeData .(* toml.Tree )
854+ if binaryPath , ok := runtimeTOML .GetPath ([]string {"options" , "BinaryName" }).(string ); ok && binaryPath != "" {
855+ runtimeBinaryPaths = append (runtimeBinaryPaths , binaryPath )
856+ }
857+ }
858+ }
859+
860+ case "crio" :
861+ var cliArgs []string
862+ if hostRoot != "" {
863+ cliArgs = append (cliArgs , "chroot" , hostRoot )
864+ }
865+ cliArgs = append (cliArgs , "crio" , "status" , "config" )
866+
867+ cfg , err := crio .New (
868+ crio .WithReference (pkgconfig .FromCLI (cliArgs )),
869+ )
870+ if err != nil {
871+ return nil , fmt .Errorf ("unable to load crio config: %w" , err )
872+ }
873+
874+ crioDefaultRuntime := cfg .DefaultRuntime ()
875+ if crioDefaultRuntime != "" {
876+ runtimeData , err := cfg .GetRuntime (crioDefaultRuntime )
877+ if err == nil {
878+ runtimeTOML := runtimeData .(* toml.Tree )
879+ if binaryPath , ok := runtimeTOML .GetPath ([]string {"runtime_path" }).(string ); ok && binaryPath != "" {
880+ runtimeBinaryPaths = append (runtimeBinaryPaths , binaryPath )
881+ }
882+ }
883+ }
884+ }
885+ }
886+ return runtimeBinaryPaths , nil
887+ }
0 commit comments