Skip to content

Commit d32d3f9

Browse files
committed
[nvidia-ctk-installer] remove default_runtime from cri-o config on cleanup
Signed-off-by: Christopher Desiniotis <[email protected]>
1 parent c9c7aa7 commit d32d3f9

File tree

11 files changed

+236
-15
lines changed

11 files changed

+236
-15
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (o Options) Configure(cfg engine.Interface) error {
6565
if err != nil {
6666
return fmt.Errorf("unable to update config: %v", err)
6767
}
68-
return o.flush(cfg)
68+
return o.Flush(cfg)
6969
}
7070

7171
// Unconfigure removes the options from the specified config
@@ -75,7 +75,7 @@ func (o Options) Unconfigure(cfg engine.Interface) error {
7575
return fmt.Errorf("unable to update config: %v", err)
7676
}
7777

78-
if err := o.flush(cfg); err != nil {
78+
if err := o.Flush(cfg); err != nil {
7979
return err
8080
}
8181

@@ -93,8 +93,8 @@ func (o Options) Unconfigure(cfg engine.Interface) error {
9393
return nil
9494
}
9595

96-
// flush flushes the specified config to disk
97-
func (o Options) flush(cfg engine.Interface) error {
96+
// Flush flushes the specified config to disk
97+
func (o Options) Flush(cfg engine.Interface) error {
9898
filepath := o.DropInConfig
9999
if filepath == "" {
100100
filepath = o.TopLevelConfigPath

cmd/nvidia-ctk-installer/container/runtime/crio/config_test.go

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,30 @@ func TestCrioConfigLifecycle(t *testing.T) {
8888
},
8989
assertCleanupPostConditions: func(t *testing.T, co *container.Options, _ *Options) error {
9090
require.NoFileExists(t, co.TopLevelConfigPath)
91+
// drop-in file not removed on cleanup
92+
actual, err := os.ReadFile(co.DropInConfig)
93+
require.NoError(t, err)
94+
95+
expected := `
96+
[crio]
97+
98+
[crio.runtime]
99+
100+
[crio.runtime.runtimes]
101+
102+
[crio.runtime.runtimes.nvidia]
103+
runtime_path = "/usr/bin/nvidia-container-runtime"
104+
runtime_type = "oci"
105+
106+
[crio.runtime.runtimes.nvidia-cdi]
107+
runtime_path = "/usr/bin/nvidia-container-runtime.cdi"
108+
runtime_type = "oci"
109+
110+
[crio.runtime.runtimes.nvidia-legacy]
111+
runtime_path = "/usr/bin/nvidia-container-runtime.legacy"
112+
runtime_type = "oci"
113+
`
114+
require.Equal(t, expected, string(actual))
91115
return nil
92116
},
93117
},
@@ -200,6 +224,37 @@ signature_policy = "/etc/crio/policy.json"
200224
`
201225
require.Equal(t, expectedTopLevel, string(actualTopLevel))
202226

227+
// drop-in file not removed on cleanup
228+
require.FileExists(t, co.DropInConfig)
229+
actual, err := os.ReadFile(co.DropInConfig)
230+
require.NoError(t, err)
231+
232+
expected := `
233+
[crio]
234+
235+
[crio.runtime]
236+
237+
[crio.runtime.runtimes]
238+
239+
[crio.runtime.runtimes.nvidia]
240+
monitor_path = "/usr/libexec/crio/conmon"
241+
runtime_path = "/usr/bin/nvidia-container-runtime"
242+
runtime_root = "/run/crun"
243+
runtime_type = "oci"
244+
245+
[crio.runtime.runtimes.nvidia-cdi]
246+
monitor_path = "/usr/libexec/crio/conmon"
247+
runtime_path = "/usr/bin/nvidia-container-runtime.cdi"
248+
runtime_root = "/run/crun"
249+
runtime_type = "oci"
250+
251+
[crio.runtime.runtimes.nvidia-legacy]
252+
monitor_path = "/usr/libexec/crio/conmon"
253+
runtime_path = "/usr/bin/nvidia-container-runtime.legacy"
254+
runtime_root = "/run/crun"
255+
runtime_type = "oci"
256+
`
257+
require.Equal(t, expected, string(actual))
203258
return nil
204259
},
205260
},
@@ -309,8 +364,33 @@ runtime_type = "oci"
309364

310365
require.Equal(t, expectedTopLevel, string(actualTopLevel))
311366

312-
require.NoFileExists(t, co.DropInConfig)
367+
// drop-in file not removed on cleanup
368+
// default_runtime setting removed from drop-in
369+
require.FileExists(t, co.DropInConfig)
370+
actual, err := os.ReadFile(co.DropInConfig)
371+
require.NoError(t, err)
372+
373+
expected := `
374+
[crio]
375+
376+
[crio.runtime]
377+
378+
[crio.runtime.runtimes]
313379
380+
[crio.runtime.runtimes.nvidia]
381+
runtime_path = "/usr/bin/nvidia-container-runtime"
382+
runtime_type = "oci"
383+
384+
[crio.runtime.runtimes.nvidia-cdi]
385+
runtime_path = "/usr/bin/nvidia-container-runtime.cdi"
386+
runtime_type = "oci"
387+
388+
[crio.runtime.runtimes.nvidia-legacy]
389+
runtime_path = "/usr/bin/nvidia-container-runtime.legacy"
390+
runtime_type = "oci"
391+
`
392+
393+
require.Equal(t, expected, string(actual))
314394
return nil
315395
},
316396
},
@@ -477,6 +557,38 @@ plugin_dirs = [
477557
`
478558
require.Equal(t, expected, string(actual))
479559

560+
// drop-in file not removed on cleanup
561+
require.FileExists(t, co.DropInConfig)
562+
actualDropIn, err := os.ReadFile(co.DropInConfig)
563+
require.NoError(t, err)
564+
565+
expectedDropIn := `
566+
[crio]
567+
568+
[crio.runtime]
569+
570+
[crio.runtime.runtimes]
571+
572+
[crio.runtime.runtimes.nvidia]
573+
monitor_path = "/usr/libexec/crio/conmon"
574+
runtime_path = "/usr/bin/nvidia-container-runtime"
575+
runtime_root = "/run/crun"
576+
runtime_type = "oci"
577+
578+
[crio.runtime.runtimes.nvidia-cdi]
579+
monitor_path = "/usr/libexec/crio/conmon"
580+
runtime_path = "/usr/bin/nvidia-container-runtime.cdi"
581+
runtime_root = "/run/crun"
582+
runtime_type = "oci"
583+
584+
[crio.runtime.runtimes.nvidia-legacy]
585+
monitor_path = "/usr/libexec/crio/conmon"
586+
runtime_path = "/usr/bin/nvidia-container-runtime.legacy"
587+
runtime_root = "/run/crun"
588+
runtime_type = "oci"
589+
`
590+
require.Equal(t, expectedDropIn, string(actualDropIn))
591+
480592
return nil
481593
},
482594
},

cmd/nvidia-ctk-installer/container/runtime/crio/crio.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func setupHook(o *container.Options, co *Options) error {
133133
func setupConfig(o *container.Options) error {
134134
log.Infof("Updating config file")
135135

136-
cfg, err := getRuntimeConfig(o)
136+
cfg, err := getRuntimeConfig(o, false)
137137
if err != nil {
138138
return fmt.Errorf("unable to load config: %v", err)
139139
}
@@ -186,14 +186,15 @@ func cleanupConfig(o *container.Options) error {
186186

187187
log.Infof("Reverting config file modifications")
188188

189-
cfg, err := getRuntimeConfig(o)
189+
cfg, err := getRuntimeConfig(o, true)
190190
if err != nil {
191191
return fmt.Errorf("unable to load config: %v", err)
192192
}
193193

194-
err = o.Unconfigure(cfg)
195-
if err != nil {
196-
return fmt.Errorf("unable to unconfigure cri-o: %v", err)
194+
cfg.UnsetDefaultRuntime(o.RuntimeName)
195+
196+
if err := o.Flush(cfg); err != nil {
197+
return err
197198
}
198199

199200
err = RestartCrio(o)
@@ -210,24 +211,35 @@ func RestartCrio(o *container.Options) error {
210211
}
211212

212213
func GetLowlevelRuntimePaths(o *container.Options) ([]string, error) {
213-
cfg, err := getRuntimeConfig(o)
214+
cfg, err := getRuntimeConfig(o, false)
214215
if err != nil {
215216
return nil, fmt.Errorf("unable to load crio config: %w", err)
216217
}
217218
return engine.GetBinaryPathsForRuntimes(cfg), nil
218219
}
219220

220-
func getRuntimeConfig(o *container.Options) (engine.Interface, error) {
221+
func getRuntimeConfig(o *container.Options, loadDestinationConfig bool) (engine.Interface, error) {
221222
loaders, err := o.GetConfigLoaders(crio.CommandLineSource)
222223
if err != nil {
223224
return nil, err
224225
}
225-
return crio.New(
226+
227+
options := []crio.Option{
226228
crio.WithTopLevelConfigPath(o.TopLevelConfigPath),
227229
crio.WithConfigSource(
228230
toml.LoadFirst(
229231
loaders...,
230232
),
231233
),
232-
)
234+
}
235+
236+
if loadDestinationConfig {
237+
destinationConfigPath := o.TopLevelConfigPath
238+
if o.DropInConfig != "" {
239+
destinationConfigPath = o.DropInConfig
240+
}
241+
options = append(options, crio.WithConfigDestination(toml.FromFile(destinationConfigPath)))
242+
}
243+
244+
return crio.New(options...)
233245
}

pkg/config/engine/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type Interface interface {
2929
EnableCDI()
3030
GetRuntimeConfig(string) (RuntimeConfig, error)
3131
RemoveRuntime(string) error
32+
UnsetDefaultRuntime(string)
3233
Save(string) (int64, error)
3334
String() string
3435
}

pkg/config/engine/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type RuntimeConfigDestination interface {
4343
AddRuntimeWithOptions(string, string, bool, interface{}) error
4444
EnableCDI()
4545
RemoveRuntime(string) error
46+
UnsetDefaultRuntime(string)
4647
Save(string) (int64, error)
4748
String() string
4849
}
@@ -60,6 +61,11 @@ func (c *Config) RemoveRuntime(runtime string) error {
6061
return c.Destination.RemoveRuntime(runtime)
6162
}
6263

64+
// UnsetDefaultRuntime removes the default runtime setting from the destination config.
65+
func (c *Config) UnsetDefaultRuntime(runtime string) {
66+
c.Destination.UnsetDefaultRuntime(runtime)
67+
}
68+
6369
// EnableCDI enables CDI in the destination config.
6470
func (c *Config) EnableCDI() {
6571
c.Destination.EnableCDI()

pkg/config/engine/containerd/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,17 @@ func (c *Config) RemoveRuntime(name string) error {
154154
*c.Tree = config
155155
return nil
156156
}
157+
158+
func (c *Config) UnsetDefaultRuntime(name string) {
159+
if c == nil || c.Tree == nil {
160+
return
161+
}
162+
163+
config := *c.Tree
164+
if runtime, ok := config.GetPath([]string{"plugins", c.CRIRuntimePluginName, "containerd", "default_runtime_name"}).(string); ok {
165+
if runtime == name {
166+
config.DeletePath([]string{"plugins", c.CRIRuntimePluginName, "containerd", "default_runtime_name"})
167+
}
168+
}
169+
*c.Tree = config
170+
}

pkg/config/engine/containerd/config_drop_in.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ func (c *ConfigWithDropIn) RemoveRuntime(name string) error {
9696
return c.Interface.RemoveRuntime(name)
9797
}
9898

99+
func (c *ConfigWithDropIn) UnsetDefaultRuntime(name string) {
100+
c.Interface.UnsetDefaultRuntime(name)
101+
}
102+
99103
// flush saves the top-level config to its path.
100104
// If the config is empty, the file will be deleted.
101105
func (c *topLevelConfig) Save(dropInPath string) (int64, error) {

pkg/config/engine/containerd/config_v1.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,28 @@ func (c *ConfigV1) RemoveRuntime(name string) error {
120120
return nil
121121
}
122122

123+
func (c *ConfigV1) UnsetDefaultRuntime(name string) {
124+
if c == nil || c.Tree == nil {
125+
return
126+
}
127+
128+
config := *c.Tree
129+
130+
runtimePath, ok := config.GetPath([]string{"plugins", "cri", "containerd", "runtimes", name, "options", "BinaryName"}).(string)
131+
if !ok || runtimePath == "" {
132+
runtimePath, _ = config.GetPath([]string{"plugins", "cri", "containerd", "runtimes", name, "options", "Runtime"}).(string)
133+
}
134+
defaultRuntimePath, ok := config.GetPath([]string{"plugins", "cri", "containerd", "default_runtime", "options", "BinaryName"}).(string)
135+
if !ok || defaultRuntimePath == "" {
136+
defaultRuntimePath, _ = config.GetPath([]string{"plugins", "cri", "containerd", "default_runtime", "options", "Runtime"}).(string)
137+
}
138+
if runtimePath != "" && defaultRuntimePath != "" && runtimePath == defaultRuntimePath {
139+
config.DeletePath([]string{"plugins", "cri", "containerd", "default_runtime"})
140+
}
141+
142+
*c.Tree = config
143+
}
144+
123145
// Save writes the config to a file
124146
func (c ConfigV1) Save(path string) (int64, error) {
125147
return (Config)(c).Save(path)

pkg/config/engine/crio/crio.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,23 @@ func New(opts ...Option) (engine.Interface, error) {
6767
return nil, err
6868
}
6969

70+
var destinationConfig *toml.Tree
71+
if b.configDestination != nil {
72+
destinationConfig, err = b.configDestination.Load()
73+
if err != nil {
74+
return nil, err
75+
}
76+
} else {
77+
destinationConfig = toml.NewEmpty()
78+
}
79+
7080
cfg := &engine.Config{
7181
Source: &Config{
7282
Tree: sourceConfig,
7383
Logger: b.logger,
7484
},
7585
Destination: &Config{
76-
Tree: toml.NewEmpty(),
86+
Tree: destinationConfig,
7787
Logger: b.logger,
7888
},
7989
}
@@ -167,6 +177,22 @@ func (c *Config) RemoveRuntime(name string) error {
167177
return nil
168178
}
169179

180+
// UnsetDefaultRuntime ensures that the provided runtime name is not
181+
// configured as the default runtime in the config
182+
func (c *Config) UnsetDefaultRuntime(name string) {
183+
if c == nil || c.Tree == nil {
184+
return
185+
}
186+
187+
config := *c.Tree
188+
if runtime, ok := config.GetPath([]string{"crio", "runtime", "default_runtime"}).(string); ok {
189+
if runtime == name {
190+
config.DeletePath([]string{"crio", "runtime", "default_runtime"})
191+
}
192+
}
193+
*c.Tree = config
194+
}
195+
170196
func (c *Config) GetRuntimeConfig(name string) (engine.RuntimeConfig, error) {
171197
if c == nil || c.Tree == nil {
172198
return nil, fmt.Errorf("config is nil")

pkg/config/engine/crio/option.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
type builder struct {
2525
logger logger.Interface
2626
configSource toml.Loader
27+
configDestination toml.Loader
2728
topLevelConfigPath string
2829
}
2930

@@ -50,3 +51,10 @@ func WithConfigSource(configSource toml.Loader) Option {
5051
b.configSource = configSource
5152
}
5253
}
54+
55+
// WithConfigDestination sets the TOML destination for the config.
56+
func WithConfigDestination(configDestination toml.Loader) Option {
57+
return func(b *builder) {
58+
b.configDestination = configDestination
59+
}
60+
}

0 commit comments

Comments
 (0)