Skip to content

Commit 4997729

Browse files
authored
Merge pull request #1251 from elezar/allow-config-source-to-be-overridden
Allow config sources to be specified for containerd and cri-o
2 parents 7b30453 + c789a8d commit 4997729

File tree

6 files changed

+81
-9
lines changed

6 files changed

+81
-9
lines changed

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ import (
2121
"fmt"
2222
"os"
2323
"os/exec"
24+
"strings"
2425

2526
"github.com/sirupsen/logrus"
2627

2728
"github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk-installer/container/operator"
2829
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/engine"
30+
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/toml"
2931
)
3032

3133
const (
@@ -53,6 +55,8 @@ type Options struct {
5355
SetAsDefault bool
5456
RestartMode string
5557
HostRootMount string
58+
59+
ConfigSources []string
5660
}
5761

5862
// Configure applies the options to the specified config
@@ -182,3 +186,38 @@ func (o Options) SystemdRestart(service string) error {
182186

183187
return nil
184188
}
189+
190+
// GetConfigLoaders returns the loaders for the requested config sources.
191+
// Supported config sources can be specified as:
192+
//
193+
// * 'file[=path/to/file]': The specified file or the top-level config path is used.
194+
// * command: The runtime-specific function supplied as an argument is used.
195+
func (o Options) GetConfigLoaders(commandSourceFunc func(string, string) toml.Loader) ([]toml.Loader, error) {
196+
if len(o.ConfigSources) == 0 {
197+
return []toml.Loader{toml.Empty}, nil
198+
}
199+
var loaders []toml.Loader
200+
for _, configSource := range o.ConfigSources {
201+
parts := strings.SplitN(configSource, "=", 2)
202+
source := parts[0]
203+
switch source {
204+
case "file":
205+
fileSourcePath := o.TopLevelConfigPath
206+
if len(parts) > 1 {
207+
fileSourcePath = parts[1]
208+
}
209+
loaders = append(loaders, toml.FromFile(fileSourcePath))
210+
case "command":
211+
if commandSourceFunc == nil {
212+
logrus.Warnf("Ignoring command config source")
213+
}
214+
if len(parts) > 1 {
215+
logrus.Warnf("Ignoring additional command argument %q", parts[1])
216+
}
217+
loaders = append(loaders, commandSourceFunc(o.HostRootMount, o.ExecutablePath))
218+
default:
219+
return nil, fmt.Errorf("unsupported config source %q", configSource)
220+
}
221+
}
222+
return loaders, nil
223+
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,10 @@ version = 3
17831783
}
17841784

17851785
for _, tc := range testCases {
1786+
// Set default options that would normally be set by the CLI.
1787+
if tc.containerOptions.ConfigSources == nil {
1788+
tc.containerOptions.ConfigSources = []string{"command", "file"}
1789+
}
17861790
t.Run(tc.description, func(t *testing.T) {
17871791
// Create a temporary directory for the test
17881792
testRoot := t.TempDir()
@@ -1791,6 +1795,11 @@ version = 3
17911795
tc.containerOptions.TopLevelConfigPath = strings.ReplaceAll(tc.containerOptions.TopLevelConfigPath, "{{ .testRoot }}", testRoot)
17921796
tc.containerOptions.DropInConfig = strings.ReplaceAll(tc.containerOptions.DropInConfig, "{{ .testRoot }}", testRoot)
17931797
tc.containerOptions.RuntimeDir = strings.ReplaceAll(tc.containerOptions.RuntimeDir, "{{ .testRoot }}", testRoot)
1798+
var testConfigSources []string
1799+
for _, configSource := range tc.containerOptions.ConfigSources {
1800+
testConfigSources = append(testConfigSources, strings.ReplaceAll(configSource, "{{ .testRoot }}", testRoot))
1801+
}
1802+
tc.containerOptions.ConfigSources = testConfigSources
17941803

17951804
// Prepare the environment
17961805
if tc.prepareEnvironment != nil {

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,15 @@ func GetLowlevelRuntimePaths(o *container.Options, co *Options) ([]string, error
172172
}
173173

174174
func getRuntimeConfig(o *container.Options, co *Options) (engine.Interface, error) {
175+
loaders, err := o.GetConfigLoaders(containerd.CommandLineSource)
176+
if err != nil {
177+
return nil, err
178+
}
175179
options := []containerd.Option{
176180
containerd.WithTopLevelConfigPath(o.TopLevelConfigPath),
177181
containerd.WithConfigSource(
178182
toml.LoadFirst(
179-
containerd.CommandLineSource(o.HostRootMount, o.ExecutablePath),
180-
toml.FromFile(o.TopLevelConfigPath),
183+
loaders...,
181184
),
182185
),
183186
containerd.WithRuntimeType(co.runtimeType),

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,17 +621,24 @@ plugin_dirs = [
621621
},
622622
}
623623

624-
for i, tc := range testCases {
625-
if i > 3 {
626-
t.SkipNow()
624+
for _, tc := range testCases {
625+
// Set default options that would normally be set by the CLI.
626+
if tc.containerOptions.ConfigSources == nil {
627+
tc.containerOptions.ConfigSources = []string{"command", "file"}
627628
}
629+
tc.options.hookFilename = "99-nvidia.json"
630+
628631
t.Run(tc.description, func(t *testing.T) {
629632
// Update any paths as required
630633
testRoot := t.TempDir()
631634
tc.containerOptions.TopLevelConfigPath = strings.ReplaceAll(tc.containerOptions.TopLevelConfigPath, "{{ .testRoot }}", testRoot)
632635
tc.containerOptions.DropInConfig = strings.ReplaceAll(tc.containerOptions.DropInConfig, "{{ .testRoot }}", testRoot)
633636
tc.options.hooksDir = strings.ReplaceAll(tc.options.hooksDir, "{{ .testRoot }}", testRoot)
634-
tc.options.hookFilename = "99-nvidia.json"
637+
var testConfigSources []string
638+
for _, configSource := range tc.containerOptions.ConfigSources {
639+
testConfigSources = append(testConfigSources, strings.ReplaceAll(configSource, "{{ .testRoot }}", testRoot))
640+
}
641+
tc.containerOptions.ConfigSources = testConfigSources
635642

636643
// Prepare the test environment
637644
if tc.prepareEnvironment != nil {

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,15 @@ func GetLowlevelRuntimePaths(o *container.Options) ([]string, error) {
214214
}
215215

216216
func getRuntimeConfig(o *container.Options) (engine.Interface, error) {
217+
loaders, err := o.GetConfigLoaders(crio.CommandLineSource)
218+
if err != nil {
219+
return nil, err
220+
}
217221
return crio.New(
218222
crio.WithTopLevelConfigPath(o.TopLevelConfigPath),
219223
crio.WithConfigSource(
220224
toml.LoadFirst(
221-
crio.CommandLineSource(o.HostRootMount, o.ExecutablePath),
222-
toml.FromFile(o.TopLevelConfigPath),
225+
loaders...,
223226
),
224227
),
225228
)

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ func Flags(opts *Options) []cli.Flag {
117117
Sources: cli.EnvVars("NVIDIA_RUNTIME_SET_AS_DEFAULT", "CONTAINERD_SET_AS_DEFAULT", "DOCKER_SET_AS_DEFAULT"),
118118
Hidden: true,
119119
},
120+
&cli.StringSliceFlag{
121+
Name: "config-source",
122+
Aliases: []string{"config-sources"},
123+
Usage: "Specify the config sources for the container runtime. Any combination of " +
124+
"[command | file]. " +
125+
"When `file` is specified, the absolute path to the file to be used as a config source can " +
126+
"be specified as `file=/path/to/source/config.toml",
127+
Value: []string{"command", "file"},
128+
Destination: &opts.ConfigSources,
129+
Sources: cli.EnvVars("RUNTIME_CONFIG_SOURCES", "RUNTIME_CONFIG_SOURCE"),
130+
},
120131
}
121132

122133
flags = append(flags, containerd.Flags(&opts.containerdOptions)...)
@@ -144,6 +155,7 @@ func (opts *Options) Validate(logger logger.Interface, c *cli.Command, runtime s
144155
logger.Warningf("Ignoring drop-in-config=%q flag for %v", opts.DropInConfig, opts.RuntimeName)
145156
opts.DropInConfig = ""
146157
}
158+
opts.ConfigSources = []string{"file"}
147159
case containerd.Name:
148160
case crio.Name:
149161
if err := opts.crioOptions.Validate(logger, c); err != nil {
@@ -152,7 +164,6 @@ func (opts *Options) Validate(logger logger.Interface, c *cli.Command, runtime s
152164
}
153165

154166
// Apply the runtime-specific config changes.
155-
// TODO: Add the runtime-specific DropInConfigs here.
156167
switch runtime {
157168
case containerd.Name:
158169
if opts.TopLevelConfigPath == runtimeSpecificDefault {

0 commit comments

Comments
 (0)