@@ -44,6 +44,14 @@ const (
4444 defaultContainerdConfigFilePath = "/etc/containerd/config.toml"
4545 defaultCrioConfigFilePath = "/etc/crio/crio.conf"
4646 defaultDockerConfigFilePath = "/etc/docker/daemon.json"
47+
48+ defaultConfigSource = configSourceFile
49+ configSourceCommand = "command"
50+ configSourceFile = "file"
51+
52+ runtimeContainerd = "containerd"
53+ runtimeCrio = "crio"
54+ runtimeDocker = "docker"
4755)
4856
4957type command struct {
@@ -64,6 +72,7 @@ type config struct {
6472 dryRun bool
6573 runtime string
6674 configFilePath string
75+ configSource string
6776 mode string
6877 hookFilePath string
6978
@@ -120,6 +129,12 @@ func (m command) build() *cli.Command {
120129 Usage : "the config mode for runtimes that support multiple configuration mechanisms" ,
121130 Destination : & config .mode ,
122131 },
132+ & cli.StringFlag {
133+ Name : "config-source" ,
134+ Usage : "the source to retrieve the container runtime configuration; one of [command, file]\" " ,
135+ Destination : & config .configSource ,
136+ Value : defaultConfigSource ,
137+ },
123138 & cli.StringFlag {
124139 Name : "oci-hook-path" ,
125140 Usage : "the path to the OCI runtime hook to create if --config-mode=oci-hook is specified. If no path is specified, the generated hook is output to STDOUT.\n \t Note: The use of OCI hooks is deprecated." ,
@@ -174,14 +189,14 @@ func (m command) validateFlags(c *cli.Context, config *config) error {
174189 config .mode = "config-file"
175190
176191 switch config .runtime {
177- case "containerd" , "crio" , "docker" :
192+ case runtimeContainerd , runtimeCrio , runtimeDocker :
178193 break
179194 default :
180195 return fmt .Errorf ("unrecognized runtime '%v'" , config .runtime )
181196 }
182197
183198 switch config .runtime {
184- case "containerd" , "crio" :
199+ case runtimeContainerd , runtimeCrio :
185200 if config .nvidiaRuntime .path == defaultNVIDIARuntimeExecutable {
186201 config .nvidiaRuntime .path = defaultNVIDIARuntimeExpecutablePath
187202 }
@@ -190,7 +205,7 @@ func (m command) validateFlags(c *cli.Context, config *config) error {
190205 }
191206 }
192207
193- if config .runtime != "containerd" && config .runtime != "docker" {
208+ if config .runtime != runtimeContainerd && config .runtime != runtimeDocker {
194209 if config .cdi .enabled {
195210 m .logger .Warningf ("Ignoring cdi.enabled flag for %v" , config .runtime )
196211 }
@@ -220,22 +235,27 @@ func (m command) configureWrapper(c *cli.Context, config *config) error {
220235func (m command ) configureConfigFile (c * cli.Context , config * config ) error {
221236 configFilePath := config .resolveConfigFilePath ()
222237
223- var cfg engine.Interface
224238 var err error
239+ configSource , err := config .resolveConfigSource ()
240+ if err != nil {
241+ return err
242+ }
243+
244+ var cfg engine.Interface
225245 switch config .runtime {
226- case "containerd" :
246+ case runtimeContainerd :
227247 cfg , err = containerd .New (
228248 containerd .WithLogger (m .logger ),
229249 containerd .WithPath (configFilePath ),
230- containerd .WithConfigSource (toml . FromFile ( configFilePath ) ),
250+ containerd .WithConfigSource (configSource ),
231251 )
232- case "crio" :
252+ case runtimeCrio :
233253 cfg , err = crio .New (
234254 crio .WithLogger (m .logger ),
235255 crio .WithPath (configFilePath ),
236- crio .WithConfigSource (toml . FromFile ( configFilePath ) ),
256+ crio .WithConfigSource (configSource ),
237257 )
238- case "docker" :
258+ case runtimeDocker :
239259 cfg , err = docker .New (
240260 docker .WithLogger (m .logger ),
241261 docker .WithPath (configFilePath ),
@@ -285,16 +305,40 @@ func (c *config) resolveConfigFilePath() string {
285305 return c .configFilePath
286306 }
287307 switch c .runtime {
288- case "containerd" :
308+ case runtimeContainerd :
289309 return defaultContainerdConfigFilePath
290- case "crio" :
310+ case runtimeCrio :
291311 return defaultCrioConfigFilePath
292- case "docker" :
312+ case runtimeDocker :
293313 return defaultDockerConfigFilePath
294314 }
295315 return ""
296316}
297317
318+ // resolveConfigSource returns the default config source or the user provided config source
319+ func (c * config ) resolveConfigSource () (toml.Loader , error ) {
320+ switch c .configSource {
321+ case configSourceCommand :
322+ cmd , args := c .getConfigSourceCommand ()
323+ return toml .FromCommandLine (cmd , args ... ), nil
324+ case configSourceFile :
325+ return toml .FromFile (c .configFilePath ), nil
326+ default :
327+ return nil , fmt .Errorf ("unrecognized config source: %s" , c .configSource )
328+ }
329+ }
330+
331+ // getConfigSourceCommand returns the default cli command to fetch the current runtime config
332+ func (c * config ) getConfigSourceCommand () (string , []string ) {
333+ switch c .runtime {
334+ case runtimeContainerd :
335+ return "containerd" , []string {"config" , "dump" }
336+ case runtimeCrio :
337+ return "crio" , []string {"status" , "config" }
338+ }
339+ return "" , []string {}
340+ }
341+
298342// getOuputConfigPath returns the configured config path or "" if dry-run is enabled
299343func (c * config ) getOuputConfigPath () string {
300344 if c .dryRun {
@@ -318,9 +362,9 @@ func enableCDI(config *config, cfg engine.Interface) error {
318362 return nil
319363 }
320364 switch config .runtime {
321- case "containerd" :
365+ case runtimeContainerd :
322366 cfg .Set ("enable_cdi" , true )
323- case "docker" :
367+ case runtimeDocker :
324368 cfg .Set ("features" , map [string ]bool {"cdi" : true })
325369 default :
326370 return fmt .Errorf ("enabling CDI in %s is not supported" , config .runtime )
0 commit comments