Skip to content

Commit e6d4b6e

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 e6d4b6e

File tree

11 files changed

+276
-14
lines changed

11 files changed

+276
-14
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: 23 additions & 8 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,18 @@ 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)
194+
err = cfg.UpdateDefaultRuntime(o.RuntimeName, "unset")
195195
if err != nil {
196-
return fmt.Errorf("unable to unconfigure cri-o: %v", err)
196+
return fmt.Errorf("failed to unset %q as the default runtime: %w", o.RuntimeName, err)
197+
}
198+
199+
if err := o.Flush(cfg); err != nil {
200+
return err
197201
}
198202

199203
err = RestartCrio(o)
@@ -210,24 +214,35 @@ func RestartCrio(o *container.Options) error {
210214
}
211215

212216
func GetLowlevelRuntimePaths(o *container.Options) ([]string, error) {
213-
cfg, err := getRuntimeConfig(o)
217+
cfg, err := getRuntimeConfig(o, false)
214218
if err != nil {
215219
return nil, fmt.Errorf("unable to load crio config: %w", err)
216220
}
217221
return engine.GetBinaryPathsForRuntimes(cfg), nil
218222
}
219223

220-
func getRuntimeConfig(o *container.Options) (engine.Interface, error) {
224+
func getRuntimeConfig(o *container.Options, loadDestinationConfig bool) (engine.Interface, error) {
221225
loaders, err := o.GetConfigLoaders(crio.CommandLineSource)
222226
if err != nil {
223227
return nil, err
224228
}
225-
return crio.New(
229+
230+
options := []crio.Option{
226231
crio.WithTopLevelConfigPath(o.TopLevelConfigPath),
227232
crio.WithConfigSource(
228233
toml.LoadFirst(
229234
loaders...,
230235
),
231236
),
232-
)
237+
}
238+
239+
if loadDestinationConfig {
240+
destinationConfigPath := o.TopLevelConfigPath
241+
if o.DropInConfig != "" {
242+
destinationConfigPath = o.DropInConfig
243+
}
244+
options = append(options, crio.WithConfigDestination(toml.FromFile(destinationConfigPath)))
245+
}
246+
247+
return crio.New(options...)
233248
}

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+
UpdateDefaultRuntime(string, string) error
3233
Save(string) (int64, error)
3334
String() string
3435
}

pkg/config/engine/config.go

Lines changed: 9 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+
UpdateDefaultRuntime(string, string) error
4647
Save(string) (int64, error)
4748
String() string
4849
}
@@ -60,6 +61,14 @@ func (c *Config) RemoveRuntime(runtime string) error {
6061
return c.Destination.RemoveRuntime(runtime)
6162
}
6263

64+
// UpdateDefaultRuntime updates the default runtime setting in the destination config.
65+
// When action is 'set' the provided runtime name is set as the default.
66+
// When action is 'unset' we make sure the provided runtime name is not
67+
// the default.
68+
func (c *Config) UpdateDefaultRuntime(runtime string, action string) error {
69+
return c.Destination.UpdateDefaultRuntime(runtime, action)
70+
}
71+
6372
// EnableCDI enables CDI in the destination config.
6473
func (c *Config) EnableCDI() {
6574
c.Destination.EnableCDI()

pkg/config/engine/containerd/config.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,33 @@ func (c *Config) RemoveRuntime(name string) error {
154154
*c.Tree = config
155155
return nil
156156
}
157+
158+
// UpdateDefaultRuntime updates the default runtime setting in the config.
159+
// When action is 'set' the provided runtime name is set as the default.
160+
// When action is 'unset' we make sure the provided runtime name is not
161+
// the default.
162+
func (c *Config) UpdateDefaultRuntime(name string, action string) error {
163+
if action != "set" && action != "unset" {
164+
return fmt.Errorf("invalid action %q, valid actions are 'set' and 'unset'", action)
165+
}
166+
167+
if c == nil || c.Tree == nil {
168+
if action == "set" {
169+
fmt.Errorf("config toml is nil")
170+
}
171+
return nil
172+
}
173+
174+
config := *c.Tree
175+
if action == "set" {
176+
config.SetPath([]string{"plugins", c.CRIRuntimePluginName, "containerd", "default_runtime_name"}, name)
177+
} else {
178+
defaultRuntime, ok := config.GetPath([]string{"plugins", c.CRIRuntimePluginName, "containerd", "default_runtime_name"}).(string)
179+
if ok && defaultRuntime == name {
180+
config.DeletePath([]string{"plugins", c.CRIRuntimePluginName, "containerd", "default_runtime_name"})
181+
}
182+
}
183+
184+
*c.Tree = config
185+
return nil
186+
}

pkg/config/engine/containerd/config_drop_in.go

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

99+
// UpdateDefaultRuntime updates the default runtime setting in the drop-in config.
100+
// When action is 'set' the provided runtime name is set as the default.
101+
// When action is 'unset' we make sure the provided runtime name is not
102+
// the default.
103+
func (c *ConfigWithDropIn) UpdateDefaultRuntime(name string, action string) error {
104+
return c.Interface.UpdateDefaultRuntime(name, action)
105+
}
106+
99107
// flush saves the top-level config to its path.
100108
// If the config is empty, the file will be deleted.
101109
func (c *topLevelConfig) Save(dropInPath string) (int64, error) {

pkg/config/engine/containerd/config_v1.go

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

123+
func (c *ConfigV1) UpdateDefaultRuntime(name string, action string) error {
124+
return fmt.Errorf("this method is not implemented")
125+
}
126+
123127
// Save writes the config to a file
124128
func (c ConfigV1) Save(path string) (int64, error) {
125129
return (Config)(c).Save(path)

pkg/config/engine/crio/crio.go

Lines changed: 43 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,38 @@ func (c *Config) RemoveRuntime(name string) error {
167177
return nil
168178
}
169179

180+
// UpdateDefaultRuntime updates the default runtime setting in the config.
181+
// When action is 'set' the provided runtime name is set as the default.
182+
// When action is 'unset' we make sure the provided runtime name is not
183+
// the default.
184+
func (c *Config) UpdateDefaultRuntime(name string, action string) error {
185+
if action != "set" && action != "unset" {
186+
return fmt.Errorf("invalid action %q, valid actions are 'set' and 'unset'", action)
187+
}
188+
189+
if c == nil || c.Tree == nil {
190+
if action == "set" {
191+
fmt.Errorf("config toml is nil")
192+
}
193+
return nil
194+
}
195+
196+
config := *c.Tree
197+
198+
if action == "set" {
199+
config.SetPath([]string{"crio", "runtime", "default_runtime"}, name)
200+
} else {
201+
if runtime, ok := config.GetPath([]string{"crio", "runtime", "default_runtime"}).(string); ok {
202+
if runtime == name {
203+
config.DeletePath([]string{"crio", "runtime", "default_runtime"})
204+
}
205+
}
206+
}
207+
208+
*c.Tree = config
209+
return nil
210+
}
211+
170212
func (c *Config) GetRuntimeConfig(name string) (engine.RuntimeConfig, error) {
171213
if c == nil || c.Tree == nil {
172214
return nil, fmt.Errorf("config is nil")

0 commit comments

Comments
 (0)