Skip to content

Commit 0de9b10

Browse files
committed
add limited support for containerd config patch version-awareness
1 parent 09df23d commit 0de9b10

File tree

5 files changed

+88
-15
lines changed

5 files changed

+88
-15
lines changed

pkg/apis/config/v1alpha4/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,14 @@ type Cluster struct {
7575
// ContainerdConfigPatches are applied to every node's containerd config
7676
// in the order listed.
7777
// These should be toml stringsto be applied as merge patches
78+
// If the version field in these patches doesn't match containerd config, it will not be a applied
79+
// This way you can write configurations that work for both by supplying two patches
7880
ContainerdConfigPatches []string `yaml:"containerdConfigPatches,omitempty" json:"containerdConfigPatches,omitempty"`
7981

8082
// ContainerdConfigPatchesJSON6902 are applied to every node's containerd config
8183
// in the order listed.
8284
// These should be YAML or JSON formatting RFC 6902 JSON patches
85+
// NOTE: These are not currently version-aware.
8386
ContainerdConfigPatchesJSON6902 []string `yaml:"containerdConfigPatchesJSON6902,omitempty" json:"containerdConfigPatchesJSON6902,omitempty"`
8487
}
8588

pkg/build/nodeimage/containerd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const containerdConfigPatchSystemdCgroupFalse = `
3636
`
3737

3838
func configureContainerdSystemdCgroupFalse(containerCmdr exec.Cmder, config string) error {
39-
patched, err := patch.TOML(config, []string{containerdConfigPatchSystemdCgroupFalse}, []string{})
39+
patched, err := patch.ContainerdTOML(config, []string{containerdConfigPatchSystemdCgroupFalse}, []string{})
4040
if err != nil {
4141
return errors.Wrap(err, "failed to configure containerd SystemdCgroup=false")
4242
}

pkg/cluster/internal/create/actions/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (a *Action) Execute(ctx *actions.ActionContext) error {
127127
if err := node.Command("cat", containerdConfigPath).SetStdout(&buff).Run(); err != nil {
128128
return errors.Wrap(err, "failed to read containerd config from node")
129129
}
130-
patched, err := patch.TOML(buff.String(), ctx.Config.ContainerdConfigPatches, ctx.Config.ContainerdConfigPatchesJSON6902)
130+
patched, err := patch.ContainerdTOML(buff.String(), ctx.Config.ContainerdConfigPatches, ctx.Config.ContainerdConfigPatchesJSON6902)
131131
if err != nil {
132132
return errors.Wrap(err, "failed to patch containerd config")
133133
}

pkg/internal/patch/toml.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,33 @@ import (
2929
"sigs.k8s.io/kind/pkg/errors"
3030
)
3131

32-
// TOML patches toPatch with the patches (should be TOML merge patches) and patches6902 (should be JSON 6902 patches)
33-
func TOML(toPatch string, patches []string, patches6902 []string) (string, error) {
32+
// ContainerdTOML patches toPatch with the patches (should be TOML merge patches) and patches6902 (should be JSON 6902 patches)
33+
func ContainerdTOML(toPatch string, patches []string, patches6902 []string) (string, error) {
3434
// convert to JSON for patching
3535
j, err := tomlToJSON([]byte(toPatch))
3636
if err != nil {
3737
return "", err
3838
}
39+
version, err := containerdConfigVersion(toPatch)
40+
if err != nil {
41+
return "", errors.WithStack(err)
42+
}
43+
if version == 0 {
44+
return "", errors.New("failed to detect containerd config version")
45+
}
3946
// apply merge patches
4047
for _, patch := range patches {
4148
pj, err := tomlToJSON([]byte(patch))
4249
if err != nil {
43-
return "", err
50+
return "", errors.WithStack(err)
51+
}
52+
patchVersion, err := containerdConfigVersion(patch)
53+
if err != nil {
54+
return "", errors.WithStack(err)
55+
}
56+
// skip if patch sets version and version does not match
57+
if patchVersion != 0 && patchVersion != version {
58+
continue
4459
}
4560
patched, err := jsonpatch.MergePatch(j, pj)
4661
if err != nil {
@@ -64,6 +79,17 @@ func TOML(toPatch string, patches []string, patches6902 []string) (string, error
6479
return jsonToTOMLString(j)
6580
}
6681

82+
func containerdConfigVersion(configTOML string) (int, error) {
83+
type version struct {
84+
Version int `toml:"version,omitempty"`
85+
}
86+
v := version{}
87+
if err := toml.Unmarshal([]byte(configTOML), &v); err != nil {
88+
return 0, errors.WithStack(err)
89+
}
90+
return v.Version, nil
91+
}
92+
6793
// tomlToJSON converts arbitrary TOML to JSON
6894
func tomlToJSON(t []byte) ([]byte, error) {
6995
// we use github.com.pelletier/go-toml here to unmarshal arbitrary TOML to JSON

pkg/internal/patch/toml_test.go

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"sigs.k8s.io/kind/pkg/internal/assert"
2323
)
2424

25-
func TestTOML(t *testing.T) {
25+
func TestContainerdTOML(t *testing.T) {
2626
t.Parallel()
2727
type testCase struct {
2828
Name string
@@ -39,15 +39,48 @@ func TestTOML(t *testing.T) {
3939
ExpectError: true,
4040
ExpectOutput: "",
4141
},
42+
{
43+
Name: "invalid containerd versioning",
44+
ToPatch: `version = "five"`,
45+
ExpectError: true,
46+
ExpectOutput: "",
47+
},
4248
{
4349
Name: "no patches",
44-
ToPatch: `disabled_plugins = ["restart"]
50+
ToPatch: `version = 2
51+
disabled_plugins = ["restart"]
4552
[plugins.linux]
4653
shim_debug = true
4754
[plugins.cri.containerd.runtimes.runsc]
4855
runtime_type = "io.containerd.runsc.v1"`,
4956
ExpectError: false,
5057
ExpectOutput: `disabled_plugins = ["restart"]
58+
version = 2
59+
60+
[plugins]
61+
[plugins.cri]
62+
[plugins.cri.containerd]
63+
[plugins.cri.containerd.runtimes]
64+
[plugins.cri.containerd.runtimes.runsc]
65+
runtime_type = "io.containerd.runsc.v1"
66+
[plugins.linux]
67+
shim_debug = true
68+
`,
69+
},
70+
{
71+
Name: "Only matching patches",
72+
ToPatch: `version = 2
73+
74+
disabled_plugins = ["restart"]
75+
76+
[plugins.linux]
77+
shim_debug = true
78+
[plugins.cri.containerd.runtimes.runsc]
79+
runtime_type = "io.containerd.runsc.v1"`,
80+
Patches: []string{"version = 3\ndisabled_plugins=[\"bar\"]", "version = 2\n disabled_plugins=[\"baz\"]"},
81+
ExpectError: false,
82+
ExpectOutput: `disabled_plugins = ["baz"]
83+
version = 2
5184
5285
[plugins]
5386
[plugins.cri]
@@ -61,7 +94,8 @@ func TestTOML(t *testing.T) {
6194
},
6295
{
6396
Name: "invalid patch TOML",
64-
ToPatch: `disabled_plugins = ["restart"]
97+
ToPatch: `version = 2
98+
disabled_plugins = ["restart"]
6599
[plugins.linux]
66100
shim_debug = true
67101
[plugins.cri.containerd.runtimes.runsc]
@@ -81,14 +115,16 @@ func TestTOML(t *testing.T) {
81115
},
82116
{
83117
Name: "trivial patch",
84-
ToPatch: `disabled_plugins = ["restart"]
118+
ToPatch: `version = 2
119+
disabled_plugins = ["restart"]
85120
[plugins.linux]
86121
shim_debug = true
87122
[plugins.cri.containerd.runtimes.runsc]
88123
runtime_type = "io.containerd.runsc.v1"`,
89124
Patches: []string{`disabled_plugins=[]`},
90125
ExpectError: false,
91126
ExpectOutput: `disabled_plugins = []
127+
version = 2
92128
93129
[plugins]
94130
[plugins.cri]
@@ -102,14 +138,17 @@ func TestTOML(t *testing.T) {
102138
},
103139
{
104140
Name: "trivial 6902 patch",
105-
ToPatch: `disabled_plugins = ["restart"]
141+
ToPatch: `version = 2
142+
disabled_plugins = ["restart"]
106143
[plugins.linux]
107144
shim_debug = true
108145
[plugins.cri.containerd.runtimes.runsc]
109146
runtime_type = "io.containerd.runsc.v1"`,
110147
PatchesJSON6902: []string{`[{"op": "remove", "path": "/disabled_plugins"}]`},
111148
ExpectError: false,
112-
ExpectOutput: `[plugins]
149+
ExpectOutput: `version = 2
150+
151+
[plugins]
113152
[plugins.cri]
114153
[plugins.cri.containerd]
115154
[plugins.cri.containerd.runtimes]
@@ -121,15 +160,18 @@ func TestTOML(t *testing.T) {
121160
},
122161
{
123162
Name: "trivial patch and trivial 6902 patch",
124-
ToPatch: `disabled_plugins = ["restart"]
163+
ToPatch: `version = 2
164+
disabled_plugins = ["restart"]
125165
[plugins.linux]
126166
shim_debug = true
127167
[plugins.cri.containerd.runtimes.runsc]
128168
runtime_type = "io.containerd.runsc.v1"`,
129169
Patches: []string{`disabled_plugins=["foo"]`},
130170
PatchesJSON6902: []string{`[{"op": "remove", "path": "/disabled_plugins"}]`},
131171
ExpectError: false,
132-
ExpectOutput: `[plugins]
172+
ExpectOutput: `version = 2
173+
174+
[plugins]
133175
[plugins.cri]
134176
[plugins.cri.containerd]
135177
[plugins.cri.containerd.runtimes]
@@ -160,7 +202,8 @@ func TestTOML(t *testing.T) {
160202
},
161203
{
162204
Name: "patch registry",
163-
ToPatch: `disabled_plugins = ["restart"]
205+
ToPatch: `version = 2
206+
disabled_plugins = ["restart"]
164207
[plugins.linux]
165208
shim_debug = true
166209
[plugins.cri.containerd.runtimes.runsc]
@@ -170,6 +213,7 @@ func TestTOML(t *testing.T) {
170213
endpoint = ["http://registry:5000"]`},
171214
ExpectError: false,
172215
ExpectOutput: `disabled_plugins = ["restart"]
216+
version = 2
173217
174218
[plugins]
175219
[plugins.cri]
@@ -190,7 +234,7 @@ func TestTOML(t *testing.T) {
190234
tc := tc // capture test case
191235
t.Run(tc.Name, func(t *testing.T) {
192236
t.Parallel()
193-
out, err := TOML(tc.ToPatch, tc.Patches, tc.PatchesJSON6902)
237+
out, err := ContainerdTOML(tc.ToPatch, tc.Patches, tc.PatchesJSON6902)
194238
assert.ExpectError(t, tc.ExpectError, err)
195239
if err == nil {
196240
assert.StringEqual(t, tc.ExpectOutput, out)

0 commit comments

Comments
 (0)