From 9dc05066a91576d972e4f3f45b4ec2c3f0c3a4ac Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Wed, 14 Jan 2026 10:53:37 +0100 Subject: [PATCH 1/4] [no-relnote] Quick return from installer on noDaemon Signed-off-by: Evan Lezar --- cmd/nvidia-ctk-installer/main.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/cmd/nvidia-ctk-installer/main.go b/cmd/nvidia-ctk-installer/main.go index 8b4cd3629..26dca2622 100644 --- a/cmd/nvidia-ctk-installer/main.go +++ b/cmd/nvidia-ctk-installer/main.go @@ -260,25 +260,27 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { } } - if !o.noDaemon { - if o.enableNRIPlugin { - nriPlugin, err := a.startNRIPluginServer(ctx, o) - if err != nil { - a.logger.Errorf("unable to start NRI plugin server: %v", err) - } - defer nriPlugin.Stop() - } + if o.noDaemon { + return nil + } - err = a.waitForSignal() + if o.enableNRIPlugin { + nriPlugin, err := a.startNRIPluginServer(ctx, o) if err != nil { - return fmt.Errorf("unable to wait for signal: %v", err) + a.logger.Errorf("unable to start NRI plugin server: %v", err) } + defer nriPlugin.Stop() + } + + err = a.waitForSignal() + if err != nil { + return fmt.Errorf("unable to wait for signal: %v", err) + } - if !o.enableNRIPlugin { - err = runtime.Cleanup(c, &o.runtimeOptions, o.runtime) - if err != nil { - return fmt.Errorf("unable to cleanup runtime: %v", err) - } + if !o.enableNRIPlugin { + err = runtime.Cleanup(c, &o.runtimeOptions, o.runtime) + if err != nil { + return fmt.Errorf("unable to cleanup runtime: %v", err) } } From 0b0302e4068f4d010780ff3175448a5b808f0dfa Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Wed, 14 Jan 2026 10:58:11 +0100 Subject: [PATCH 2/4] [no-relnote] Move runtime name validation to runtime package Signed-off-by: Evan Lezar --- cmd/nvidia-ctk-installer/container/runtime/runtime.go | 9 +++++++++ cmd/nvidia-ctk-installer/main.go | 4 ---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cmd/nvidia-ctk-installer/container/runtime/runtime.go b/cmd/nvidia-ctk-installer/container/runtime/runtime.go index 950e1aeca..824ddd8bd 100644 --- a/cmd/nvidia-ctk-installer/container/runtime/runtime.go +++ b/cmd/nvidia-ctk-installer/container/runtime/runtime.go @@ -138,6 +138,15 @@ func Flags(opts *Options) []cli.Flag { // Validate checks whether the specified options are valid func (opts *Options) Validate(logger logger.Interface, c *cli.Command, runtime string, toolkitRoot string, to *toolkit.Options) error { + // Check that the specified runtime is supported. + switch runtime { + case containerd.Name: + case crio.Name: + case docker.Name: + default: + return fmt.Errorf("invalid runtime %q; expected one of [containerd | crio | docker]", runtime) + } + // We set this option here to ensure that it is available in future calls. opts.RuntimeDir = toolkitRoot diff --git a/cmd/nvidia-ctk-installer/main.go b/cmd/nvidia-ctk-installer/main.go index 26dca2622..32195ca5b 100644 --- a/cmd/nvidia-ctk-installer/main.go +++ b/cmd/nvidia-ctk-installer/main.go @@ -33,7 +33,6 @@ const ( defaultNRIPluginIdx uint = 10 ) -var availableRuntimes = map[string]struct{}{"docker": {}, "crio": {}, "containerd": {}} var defaultLowLevelRuntimes = []string{"runc", "crun"} var waitingForSignal = make(chan bool, 1) @@ -212,9 +211,6 @@ func (a *app) validateFlags(c *cli.Command, o *options) error { if o.toolkitInstallDir == "" { return fmt.Errorf("the install root must be specified") } - if _, exists := availableRuntimes[o.runtime]; !exists { - return fmt.Errorf("unknown runtime: %v", o.runtime) - } if filepath.Base(o.pidFile) != toolkitPidFilename { return fmt.Errorf("invalid toolkit.pid path %v", o.pidFile) } From 7c9a52267c03535e77a392435a76c82873fda9b5 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Wed, 14 Jan 2026 10:08:14 +0100 Subject: [PATCH 3/4] Add interface for runtime configuration to installer This change adds an interface (and a basic type) for configuring a target runtime from the nvidia-ctk-installer. Signed-off-by: Evan Lezar --- .../container/runtime/runtime.go | 31 +++++++++++++------ cmd/nvidia-ctk-installer/main.go | 8 +++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/cmd/nvidia-ctk-installer/container/runtime/runtime.go b/cmd/nvidia-ctk-installer/container/runtime/runtime.go index 824ddd8bd..5c8b48926 100644 --- a/cmd/nvidia-ctk-installer/container/runtime/runtime.go +++ b/cmd/nvidia-ctk-installer/container/runtime/runtime.go @@ -221,8 +221,21 @@ func (opts *Options) Validate(logger logger.Interface, c *cli.Command, runtime s return nil } -func Setup(c *cli.Command, opts *Options, runtime string) error { - switch runtime { +type Configurer interface { + Cleanup(*cli.Command, *Options) error + GetLowlevelRuntimePaths(*Options) ([]string, error) + Setup(*cli.Command, *Options) error +} + +type runtime string + +// NewConfigurer is a factory method for creating a runtime configurer. +func NewConfigurer(name string) Configurer { + return runtime(name) +} + +func (r runtime) Setup(c *cli.Command, opts *Options) error { + switch string(r) { case containerd.Name: return containerd.Setup(c, &opts.Options, &opts.containerdOptions) case crio.Name: @@ -230,12 +243,12 @@ func Setup(c *cli.Command, opts *Options, runtime string) error { case docker.Name: return docker.Setup(c, &opts.Options) default: - return fmt.Errorf("undefined runtime %v", runtime) + return fmt.Errorf("undefined runtime %v", r) } } -func Cleanup(c *cli.Command, opts *Options, runtime string) error { - switch runtime { +func (r runtime) Cleanup(c *cli.Command, opts *Options) error { + switch string(r) { case containerd.Name: return containerd.Cleanup(c, &opts.Options, &opts.containerdOptions) case crio.Name: @@ -243,12 +256,12 @@ func Cleanup(c *cli.Command, opts *Options, runtime string) error { case docker.Name: return docker.Cleanup(c, &opts.Options) default: - return fmt.Errorf("undefined runtime %v", runtime) + return fmt.Errorf("undefined runtime %v", r) } } -func GetLowlevelRuntimePaths(opts *Options, runtime string) ([]string, error) { - switch runtime { +func (r runtime) GetLowlevelRuntimePaths(opts *Options) ([]string, error) { + switch string(r) { case containerd.Name: return containerd.GetLowlevelRuntimePaths(&opts.Options, &opts.containerdOptions) case crio.Name: @@ -256,6 +269,6 @@ func GetLowlevelRuntimePaths(opts *Options, runtime string) ([]string, error) { case docker.Name: return docker.GetLowlevelRuntimePaths(&opts.Options) default: - return nil, fmt.Errorf("undefined runtime %v", runtime) + return nil, fmt.Errorf("undefined runtime %v", r) } } diff --git a/cmd/nvidia-ctk-installer/main.go b/cmd/nvidia-ctk-installer/main.go index 32195ca5b..83c14f186 100644 --- a/cmd/nvidia-ctk-installer/main.go +++ b/cmd/nvidia-ctk-installer/main.go @@ -234,8 +234,10 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { } defer a.shutdown(o.pidFile) + runtimeConfigurer := runtime.NewConfigurer(o.runtime) + if len(o.toolkitOptions.ContainerRuntimeRuntimes) == 0 { - lowlevelRuntimePaths, err := runtime.GetLowlevelRuntimePaths(&o.runtimeOptions, o.runtime) + lowlevelRuntimePaths, err := runtimeConfigurer.GetLowlevelRuntimePaths(&o.runtimeOptions) if err != nil { return fmt.Errorf("unable to determine runtime options: %w", err) } @@ -250,7 +252,7 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { } if !o.enableNRIPlugin { - err = runtime.Setup(c, &o.runtimeOptions, o.runtime) + err = runtimeConfigurer.Setup(c, &o.runtimeOptions) if err != nil { return fmt.Errorf("unable to setup runtime: %w", err) } @@ -274,7 +276,7 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { } if !o.enableNRIPlugin { - err = runtime.Cleanup(c, &o.runtimeOptions, o.runtime) + err = runtimeConfigurer.Cleanup(c, &o.runtimeOptions) if err != nil { return fmt.Errorf("unable to cleanup runtime: %v", err) } From 3791812c87525454544dc4eaa97b95b5be9d0743 Mon Sep 17 00:00:00 2001 From: Evan Lezar Date: Mon, 8 Dec 2025 17:12:07 +0100 Subject: [PATCH 4/4] Add --no-runtime-config option to toolkit installer This change adds a --no-runtime-config flag to the nvidia-ctk-installer. When specified, the configuration (and cleanup) of a supported runtime is skipped. This can be used in cases where a user has already configured the runtime for use with the NVIDIA Container Toolkit and no config modifications are required. Signed-off-by: Evan Lezar --- .../container/runtime/runtime.go | 18 +++++++- cmd/nvidia-ctk-installer/main.go | 41 +++++++++++-------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/cmd/nvidia-ctk-installer/container/runtime/runtime.go b/cmd/nvidia-ctk-installer/container/runtime/runtime.go index 5c8b48926..ed63d3c59 100644 --- a/cmd/nvidia-ctk-installer/container/runtime/runtime.go +++ b/cmd/nvidia-ctk-installer/container/runtime/runtime.go @@ -228,9 +228,13 @@ type Configurer interface { } type runtime string +type noopRuntimeConfigurer struct{} // NewConfigurer is a factory method for creating a runtime configurer. -func NewConfigurer(name string) Configurer { +func NewConfigurer(name string, noConfigureRuntime bool, nriEnabled bool) Configurer { + if noConfigureRuntime || nriEnabled { + return &noopRuntimeConfigurer{} + } return runtime(name) } @@ -272,3 +276,15 @@ func (r runtime) GetLowlevelRuntimePaths(opts *Options) ([]string, error) { return nil, fmt.Errorf("undefined runtime %v", r) } } + +func (r noopRuntimeConfigurer) Cleanup(_ *cli.Command, _ *Options) error { + return nil +} + +func (r noopRuntimeConfigurer) GetLowlevelRuntimePaths(_ *Options) ([]string, error) { + return nil, nil +} + +func (r noopRuntimeConfigurer) Setup(_ *cli.Command, _ *Options) error { + return nil +} diff --git a/cmd/nvidia-ctk-installer/main.go b/cmd/nvidia-ctk-installer/main.go index 83c14f186..ece435737 100644 --- a/cmd/nvidia-ctk-installer/main.go +++ b/cmd/nvidia-ctk-installer/main.go @@ -43,7 +43,6 @@ type options struct { toolkitInstallDir string noDaemon bool - runtime string pidFile string sourceRoot string packageType string @@ -53,7 +52,10 @@ type options struct { nriSocket string toolkitOptions toolkit.Options - runtimeOptions runtime.Options + + noRuntimeConfig bool + runtime string + runtimeOptions runtime.Options } func (o options) toolkitRoot() string { @@ -112,6 +114,14 @@ func (a app) build() *cli.Command { Destination: &options.noDaemon, Sources: cli.EnvVars("NO_DAEMON"), }, + &cli.BoolFlag{ + Name: "no-runtime-config", + Usage: "Disables the configuration of a container runtime. This is used in cases where the runtime has " + + "already been configured for use with the toolkit, and the installer is only used to deploy the " + + "components of the NVIDIA Container Toolkit.", + Destination: &options.noRuntimeConfig, + Sources: cli.EnvVars("NO_RUNTIME_CONFIG"), + }, &cli.BoolFlag{ Name: "enable-nri-plugin", Aliases: []string{"p"}, @@ -141,9 +151,10 @@ func (a app) build() *cli.Command { Sources: cli.EnvVars("NRI_SOCKET"), }, &cli.StringFlag{ - Name: "runtime", - Aliases: []string{"r"}, - Usage: "the runtime to setup on this node. One of {'docker', 'crio', 'containerd'}", + Name: "runtime", + Aliases: []string{"r"}, + Usage: "the runtime to setup on this node. One of {'docker', 'crio', 'containerd'}. " + + "This setting is ignored if --no-runtime-config is specified.", Value: defaultRuntime, Destination: &options.runtime, Sources: cli.EnvVars("RUNTIME"), @@ -218,9 +229,11 @@ func (a *app) validateFlags(c *cli.Command, o *options) error { if err := a.toolkit.ValidateOptions(&o.toolkitOptions); err != nil { return err } + if err := o.runtimeOptions.Validate(a.logger, c, o.runtime, o.toolkitRoot(), &o.toolkitOptions); err != nil { return err } + return nil } @@ -234,7 +247,7 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { } defer a.shutdown(o.pidFile) - runtimeConfigurer := runtime.NewConfigurer(o.runtime) + runtimeConfigurer := runtime.NewConfigurer(o.runtime, o.noRuntimeConfig, o.enableNRIPlugin) if len(o.toolkitOptions.ContainerRuntimeRuntimes) == 0 { lowlevelRuntimePaths, err := runtimeConfigurer.GetLowlevelRuntimePaths(&o.runtimeOptions) @@ -251,11 +264,9 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { return fmt.Errorf("unable to install toolkit: %v", err) } - if !o.enableNRIPlugin { - err = runtimeConfigurer.Setup(c, &o.runtimeOptions) - if err != nil { - return fmt.Errorf("unable to setup runtime: %w", err) - } + err = runtimeConfigurer.Setup(c, &o.runtimeOptions) + if err != nil { + return fmt.Errorf("unable to setup runtime: %w", err) } if o.noDaemon { @@ -275,11 +286,9 @@ func (a *app) Run(ctx context.Context, c *cli.Command, o *options) error { return fmt.Errorf("unable to wait for signal: %v", err) } - if !o.enableNRIPlugin { - err = runtimeConfigurer.Cleanup(c, &o.runtimeOptions) - if err != nil { - return fmt.Errorf("unable to cleanup runtime: %v", err) - } + err = runtimeConfigurer.Cleanup(c, &o.runtimeOptions) + if err != nil { + return fmt.Errorf("unable to cleanup runtime: %v", err) } return nil