Skip to content

Commit c11d433

Browse files
alam0rtelezar
authored andcommitted
Add support for containerd version 3 config
This change adds support for containerd configs with version=3. From the perspective of the runtime configuration the contents of the config are the same. This means that we just have to load the new version and ensure that this is propagated to the generated config. Note that we still use a default config of version=2 since we need to ensure compatibility with older containerd versions (1.6.x and 1.7.x). Signed-off-by: Sam Lockart <[email protected]> Signed-off-by: Evan Lezar <[email protected]>
1 parent 1417c51 commit c11d433

File tree

4 files changed

+93
-25
lines changed

4 files changed

+93
-25
lines changed

pkg/config/engine/containerd/config_v2.go renamed to pkg/config/engine/containerd/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (c *Config) AddRuntime(name string, path string, setAsDefault bool) error {
3030
}
3131
config := *c.Tree
3232

33-
config.Set("version", int64(2))
33+
config.Set("version", c.Version)
3434

3535
runtimeNamesForConfig := engine.GetLowLevelRuntimes(c)
3636
for _, r := range runtimeNamesForConfig {

pkg/config/engine/containerd/config_v2_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,68 @@ func TestAddRuntime(t *testing.T) {
195195
SystemdCgroup = false
196196
`,
197197
},
198+
{
199+
description: "empty v3 spec is supported",
200+
config: `
201+
version = 3
202+
`,
203+
expectedConfig: `
204+
version = 3
205+
[plugins]
206+
[plugins."io.containerd.grpc.v1.cri"]
207+
[plugins."io.containerd.grpc.v1.cri".containerd]
208+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
209+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test]
210+
privileged_without_host_devices = false
211+
runtime_engine = ""
212+
runtime_root = ""
213+
runtime_type = "io.containerd.runc.v2"
214+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test.options]
215+
BinaryName = "/usr/bin/test"
216+
`,
217+
expectedError: nil,
218+
},
219+
{
220+
description: "v3 spec is supported",
221+
config: `
222+
version = 3
223+
[plugins]
224+
[plugins."io.containerd.grpc.v1.cri"]
225+
[plugins."io.containerd.grpc.v1.cri".containerd]
226+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
227+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
228+
privileged_without_host_devices = true
229+
runtime_engine = "engine"
230+
runtime_root = "root"
231+
runtime_type = "type"
232+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
233+
BinaryName = "/usr/bin/runc"
234+
SystemdCgroup = true
235+
`,
236+
expectedConfig: `
237+
version = 3
238+
[plugins]
239+
[plugins."io.containerd.grpc.v1.cri"]
240+
[plugins."io.containerd.grpc.v1.cri".containerd]
241+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
242+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
243+
privileged_without_host_devices = true
244+
runtime_engine = "engine"
245+
runtime_root = "root"
246+
runtime_type = "type"
247+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
248+
BinaryName = "/usr/bin/runc"
249+
SystemdCgroup = true
250+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test]
251+
privileged_without_host_devices = true
252+
runtime_engine = "engine"
253+
runtime_root = "root"
254+
runtime_type = "type"
255+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test.options]
256+
BinaryName = "/usr/bin/test"
257+
SystemdCgroup = true
258+
`,
259+
},
198260
}
199261

200262
for _, tc := range testCases {

pkg/config/engine/containerd/containerd.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ import (
2424
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/toml"
2525
)
2626

27+
const (
28+
defaultConfigVersion = 2
29+
defaultRuntimeType = "io.containerd.runc.v2"
30+
)
31+
2732
// Config represents the containerd config
2833
type Config struct {
2934
*toml.Tree
35+
Version int64
3036
Logger logger.Interface
3137
RuntimeType string
3238
UseDefaultRuntimeName bool
@@ -55,7 +61,8 @@ func (c *containerdCfgRuntime) GetBinaryPath() string {
5561
// New creates a containerd config with the specified options
5662
func New(opts ...Option) (engine.Interface, error) {
5763
b := &builder{
58-
runtimeType: defaultRuntimeType,
64+
configVersion: defaultConfigVersion,
65+
runtimeType: defaultRuntimeType,
5966
}
6067
for _, opt := range opts {
6168
opt(b)
@@ -72,45 +79,41 @@ func New(opts ...Option) (engine.Interface, error) {
7279
return nil, fmt.Errorf("failed to load config: %v", err)
7380
}
7481

82+
configVersion, err := b.parseVersion(tomlConfig)
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to parse config version: %w", err)
85+
}
86+
7587
cfg := &Config{
7688
Tree: tomlConfig,
89+
Version: configVersion,
7790
Logger: b.logger,
7891
RuntimeType: b.runtimeType,
79-
UseDefaultRuntimeName: b.useLegacyConfig,
92+
UseDefaultRuntimeName: configVersion == 1,
8093
ContainerAnnotations: b.containerAnnotations,
8194
}
8295

83-
version, err := cfg.parseVersion(b.useLegacyConfig)
84-
if err != nil {
85-
return nil, fmt.Errorf("failed to parse config version: %v", err)
86-
}
87-
switch version {
96+
switch configVersion {
8897
case 1:
8998
return (*ConfigV1)(cfg), nil
90-
case 2:
99+
case 2, 3:
91100
return cfg, nil
92101
}
93-
94-
return nil, fmt.Errorf("unsupported config version: %v", version)
102+
return nil, fmt.Errorf("unsupported config version: %v", configVersion)
95103
}
96104

97105
// parseVersion returns the version of the config
98-
func (c *Config) parseVersion(useLegacyConfig bool) (int, error) {
99-
defaultVersion := 2
100-
if useLegacyConfig {
101-
defaultVersion = 1
102-
}
103-
106+
func (b *builder) parseVersion(c *toml.Tree) (int64, error) {
104107
switch v := c.Get("version").(type) {
105108
case nil:
106109
switch len(c.Keys()) {
107110
case 0: // No config exists, or the config file is empty, use version inferred from containerd
108-
return defaultVersion, nil
111+
return int64(b.configVersion), nil
109112
default: // A config file exists, has content, and no version is set
110113
return 1, nil
111114
}
112115
case int64:
113-
return int(v), nil
116+
return v, nil
114117
default:
115118
return -1, fmt.Errorf("unsupported type for version field: %v", v)
116119
}

pkg/config/engine/containerd/option.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,12 @@ import (
2121
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/toml"
2222
)
2323

24-
const (
25-
defaultRuntimeType = "io.containerd.runc.v2"
26-
)
27-
2824
type builder struct {
2925
logger logger.Interface
3026
configSource toml.Loader
27+
configVersion int
3128
path string
3229
runtimeType string
33-
useLegacyConfig bool
3430
containerAnnotations []string
3531
}
3632

@@ -68,7 +64,14 @@ func WithRuntimeType(runtimeType string) Option {
6864
// WithUseLegacyConfig sets the useLegacyConfig flag for the config builder
6965
func WithUseLegacyConfig(useLegacyConfig bool) Option {
7066
return func(b *builder) {
71-
b.useLegacyConfig = useLegacyConfig
67+
b.configVersion = 1
68+
}
69+
}
70+
71+
// WithConfigVersion sets the config version for the config builder
72+
func WithConfigVersion(configVersion int) Option {
73+
return func(b *builder) {
74+
b.configVersion = configVersion
7275
}
7376
}
7477

0 commit comments

Comments
 (0)