From 7a1af6615283b3d46c0e1ebd2679069417ddea30 Mon Sep 17 00:00:00 2001 From: Ciprian Hacman Date: Fri, 27 Oct 2023 07:28:04 +0300 Subject: [PATCH] Add option to provide additional config entries for containerd --- k8s/crds/kops.k8s.io_clusters.yaml | 9 + k8s/crds/kops.k8s.io_instancegroups.yaml | 9 + nodeup/pkg/model/containerd.go | 25 +- nodeup/pkg/model/containerd_test.go | 4 + .../containerdbuilder/complex/cluster.yaml | 43 ++ .../containerdbuilder/complex/tasks.yaml | 374 ++++++++++++++++++ pkg/apis/kops/containerdconfig.go | 3 + pkg/apis/kops/v1alpha2/containerdconfig.go | 7 +- .../kops/v1alpha2/zz_generated.conversion.go | 2 + .../kops/v1alpha2/zz_generated.deepcopy.go | 7 + pkg/apis/kops/v1alpha3/containerdconfig.go | 7 +- .../kops/v1alpha3/zz_generated.conversion.go | 2 + .../kops/v1alpha3/zz_generated.deepcopy.go | 7 + pkg/apis/kops/zz_generated.deepcopy.go | 7 + util/pkg/reflectutils/access.go | 4 + 15 files changed, 507 insertions(+), 3 deletions(-) create mode 100644 nodeup/pkg/model/tests/containerdbuilder/complex/cluster.yaml create mode 100644 nodeup/pkg/model/tests/containerdbuilder/complex/tasks.yaml diff --git a/k8s/crds/kops.k8s.io_clusters.yaml b/k8s/crds/kops.k8s.io_clusters.yaml index 30484ac614..b3a6fa6826 100644 --- a/k8s/crds/kops.k8s.io_clusters.yaml +++ b/k8s/crds/kops.k8s.io_clusters.yaml @@ -816,6 +816,15 @@ spec: address: description: Address of containerd's GRPC server (default "/run/containerd/containerd.sock"). type: string + configAdditions: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + description: ConfigAdditions adds additional config entries to + the generated config file. + type: object configOverride: description: ConfigOverride is the complete containerd config file provided by the user. diff --git a/k8s/crds/kops.k8s.io_instancegroups.yaml b/k8s/crds/kops.k8s.io_instancegroups.yaml index 6d664edc2c..ffca491ab2 100644 --- a/k8s/crds/kops.k8s.io_instancegroups.yaml +++ b/k8s/crds/kops.k8s.io_instancegroups.yaml @@ -115,6 +115,15 @@ spec: address: description: Address of containerd's GRPC server (default "/run/containerd/containerd.sock"). type: string + configAdditions: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + description: ConfigAdditions adds additional config entries to + the generated config file. + type: object configOverride: description: ConfigOverride is the complete containerd config file provided by the user. diff --git a/nodeup/pkg/model/containerd.go b/nodeup/pkg/model/containerd.go index 88f496587e..19e2de63af 100644 --- a/nodeup/pkg/model/containerd.go +++ b/nodeup/pkg/model/containerd.go @@ -17,6 +17,7 @@ limitations under the License. package model import ( + "encoding/csv" "encoding/json" "fmt" "path/filepath" @@ -25,8 +26,8 @@ import ( "github.com/blang/semver/v4" "github.com/pelletier/go-toml" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/klog/v2" - "k8s.io/kops/nodeup/pkg/model/resources" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/flagbuilder" @@ -513,6 +514,28 @@ func (b *ContainerdBuilder) buildContainerdConfig() (string, error) { return "", err } } + + for k, v := range containerd.ConfigAdditions { + r := csv.NewReader(strings.NewReader(k)) + r.Comma = '.' + path, err := r.Read() + if err != nil { + return "", fmt.Errorf("parsing additional containerd config entry: %w", err) + } + + if v.Type == intstr.Int { + config.SetPath(path, int64(v.IntValue())) + } else { + if v.String() == "true" { + config.SetPath(path, true) + } else if v.String() == "false" { + config.SetPath(path, false) + } else { + config.SetPath(path, v.String()) + } + } + } + return config.String(), nil } diff --git a/nodeup/pkg/model/containerd_test.go b/nodeup/pkg/model/containerd_test.go index 42d98fdddb..486c2ef358 100644 --- a/nodeup/pkg/model/containerd_test.go +++ b/nodeup/pkg/model/containerd_test.go @@ -44,6 +44,10 @@ func TestContainerdBuilder_SkipInstall(t *testing.T) { runContainerdBuilderTest(t, "skipinstall", distributions.DistributionUbuntu2004) } +func TestContainerdBuilder_Complex(t *testing.T) { + runContainerdBuilderTest(t, "complex", distributions.DistributionUbuntu2004) +} + func TestContainerdBuilder_BuildFlags(t *testing.T) { grid := []struct { config kops.ContainerdConfig diff --git a/nodeup/pkg/model/tests/containerdbuilder/complex/cluster.yaml b/nodeup/pkg/model/tests/containerdbuilder/complex/cluster.yaml new file mode 100644 index 0000000000..2cd53827df --- /dev/null +++ b/nodeup/pkg/model/tests/containerdbuilder/complex/cluster.yaml @@ -0,0 +1,43 @@ +apiVersion: kops.k8s.io/v1alpha2 +kind: Cluster +metadata: + name: minimal.example.com +spec: + kubernetesApiAccess: + - 0.0.0.0/0 + channel: stable + cloudProvider: aws + configBase: memfs://clusters.example.com/minimal.example.com + containerRuntime: containerd + containerd: + version: 1.4.4 + configAdditions: + plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler.test_bool_false: "false" + plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler.test_bool_true: "true" + plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler.test_int: 1 + plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler.test_intstr: "1" + plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler.test_str: test + etcdClusters: + - etcdMembers: + - instanceGroup: master-us-test-1a + name: master-us-test-1a + name: main + - etcdMembers: + - instanceGroup: master-us-test-1a + name: master-us-test-1a + name: events + iam: + legacy: false + kubernetesVersion: v1.21.0 + masterPublicName: api.minimal.example.com + networkCIDR: 172.20.0.0/16 + networking: + kubenet: {} + nonMasqueradeCIDR: 100.64.0.0/10 + sshAccess: + - 0.0.0.0/0 + subnets: + - cidr: 172.20.32.0/19 + name: us-test-1a + type: Public + zone: us-test-1a diff --git a/nodeup/pkg/model/tests/containerdbuilder/complex/tasks.yaml b/nodeup/pkg/model/tests/containerdbuilder/complex/tasks.yaml new file mode 100644 index 0000000000..8da8abbc03 --- /dev/null +++ b/nodeup/pkg/model/tests/containerdbuilder/complex/tasks.yaml @@ -0,0 +1,374 @@ +contents: | + { + "cniVersion": "0.4.0", + "name": "k8s-pod-network", + "plugins": [ + { + "type": "ptp", + "ipam": { + "type": "host-local", + "ranges": [[{"subnet": "{{.PodCIDR}}"}]], + "routes": [{"dst":"0.0.0.0/0"}] + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + } + ] + } +path: /etc/containerd/config-cni.template +type: file +--- +contents: | + version = 2 + + [plugins] + + [plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "registry.k8s.io/pause:3.9" + + [plugins."io.containerd.grpc.v1.cri".cni] + conf_template = "/etc/containerd/config-cni.template" + + [plugins."io.containerd.grpc.v1.cri".containerd] + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + runtime_type = "io.containerd.runc.v2" + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] + SystemdCgroup = true + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler] + test_bool_false = false + test_bool_true = true + test_int = 1 + test_intstr = "1" + test_str = "test" +path: /etc/containerd/config.toml +type: file +--- +contents: |2 + + runtime-endpoint: unix:///run/containerd/containerd.sock +path: /etc/crictl.yaml +type: file +--- +contents: CONTAINERD_OPTS=--log-level=info +path: /etc/sysconfig/containerd +type: file +--- +contents: | + #!/bin/bash + # Built by kOps - do not edit + + iptables -w -t nat -N IP-MASQ + iptables -w -t nat -A POSTROUTING -m comment --comment "ip-masq: ensure nat POSTROUTING directs all non-LOCAL destination traffic to our custom IP-MASQ chain" -m addrtype ! --dst-type LOCAL -j IP-MASQ + iptables -w -t nat -A IP-MASQ -d 100.64.0.0/10 -m comment --comment "ip-masq: pod cidr is not subject to MASQUERADE" -j RETURN + iptables -w -t nat -A IP-MASQ -m comment --comment "ip-masq: outbound traffic is subject to MASQUERADE (must be last in chain)" -j MASQUERADE +mode: "0755" +path: /opt/kops/bin/cni-iptables-setup +type: file +--- +contents: + Asset: + AssetPath: bin/containerd + Key: containerd +mode: "0755" +path: /usr/bin/containerd +type: file +--- +contents: + Asset: + AssetPath: bin/containerd-shim + Key: containerd-shim +mode: "0755" +path: /usr/bin/containerd-shim +type: file +--- +contents: + Asset: + AssetPath: bin/containerd-shim-runc-v1 + Key: containerd-shim-runc-v1 +mode: "0755" +path: /usr/bin/containerd-shim-runc-v1 +type: file +--- +contents: + Asset: + AssetPath: bin/containerd-shim-runc-v2 + Key: containerd-shim-runc-v2 +mode: "0755" +path: /usr/bin/containerd-shim-runc-v2 +type: file +--- +contents: + Asset: + AssetPath: bin/containerd-stress + Key: containerd-stress +mode: "0755" +path: /usr/bin/containerd-stress +type: file +--- +contents: + Asset: + AssetPath: bin/ctr + Key: ctr +mode: "0755" +path: /usr/bin/ctr +type: file +--- +contents: + Asset: + AssetPath: https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64 + Key: runc.amd64 +mode: "0755" +path: /usr/sbin/runc +type: file +--- +contents: |2 + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright The containerd Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +path: /usr/share/doc/containerd/apache.txt +type: file +--- +Name: cni-iptables-setup.service +definition: | + [Unit] + Description=Configure iptables for kubernetes CNI + Documentation=https://github.com/kubernetes/kops + Before=network.target + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=/opt/kops/bin/cni-iptables-setup + + [Install] + WantedBy=basic.target +enabled: true +manageState: true +running: true +smartRestart: true +--- +Name: containerd.service +definition: | + [Unit] + Description=containerd container runtime + Documentation=https://containerd.io + After=network.target local-fs.target + + [Service] + EnvironmentFile=/etc/sysconfig/containerd + EnvironmentFile=/etc/environment + ExecStartPre=-/sbin/modprobe overlay + ExecStart=/usr/bin/containerd -c /etc/containerd/config.toml "$CONTAINERD_OPTS" + Type=notify + Delegate=yes + KillMode=process + Restart=always + RestartSec=5 + LimitNPROC=infinity + LimitCORE=infinity + LimitNOFILE=infinity + TasksMax=infinity + OOMScoreAdjust=-999 + + [Install] + WantedBy=multi-user.target +enabled: true +manageState: true +running: true +smartRestart: true diff --git a/pkg/apis/kops/containerdconfig.go b/pkg/apis/kops/containerdconfig.go index 3084321d13..95ed7aa702 100644 --- a/pkg/apis/kops/containerdconfig.go +++ b/pkg/apis/kops/containerdconfig.go @@ -18,6 +18,7 @@ package kops import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) // NvidiaDefaultDriverPackage is the nvidia driver default version @@ -27,6 +28,8 @@ const NvidiaDefaultDriverPackage = "nvidia-headless-515-server" type ContainerdConfig struct { // Address of containerd's GRPC server (default "/run/containerd/containerd.sock"). Address *string `json:"address,omitempty" flag:"address"` + // ConfigAdditions adds additional config entries to the generated config file. + ConfigAdditions map[string]intstr.IntOrString `json:"configAdditions,omitempty"` // ConfigOverride is the complete containerd config file provided by the user. ConfigOverride *string `json:"configOverride,omitempty"` // LogLevel controls the logging details [trace, debug, info, warn, error, fatal, panic] (default "info"). diff --git a/pkg/apis/kops/v1alpha2/containerdconfig.go b/pkg/apis/kops/v1alpha2/containerdconfig.go index 884c154bfd..e4430b7908 100644 --- a/pkg/apis/kops/v1alpha2/containerdconfig.go +++ b/pkg/apis/kops/v1alpha2/containerdconfig.go @@ -16,12 +16,17 @@ limitations under the License. package v1alpha2 -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) // ContainerdConfig is the configuration for containerd type ContainerdConfig struct { // Address of containerd's GRPC server (default "/run/containerd/containerd.sock"). Address *string `json:"address,omitempty" flag:"address"` + // ConfigAdditions adds additional config entries to the generated config file. + ConfigAdditions map[string]intstr.IntOrString `json:"configAdditions,omitempty"` // ConfigOverride is the complete containerd config file provided by the user. ConfigOverride *string `json:"configOverride,omitempty"` // LogLevel controls the logging details [trace, debug, info, warn, error, fatal, panic] (default "info"). diff --git a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go index afe0773329..52cad77670 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go @@ -3156,6 +3156,7 @@ func Convert_kops_ClusterSubnetSpec_To_v1alpha2_ClusterSubnetSpec(in *kops.Clust func autoConvert_v1alpha2_ContainerdConfig_To_kops_ContainerdConfig(in *ContainerdConfig, out *kops.ContainerdConfig, s conversion.Scope) error { out.Address = in.Address + out.ConfigAdditions = in.ConfigAdditions out.ConfigOverride = in.ConfigOverride out.LogLevel = in.LogLevel if in.Packages != nil { @@ -3210,6 +3211,7 @@ func Convert_v1alpha2_ContainerdConfig_To_kops_ContainerdConfig(in *ContainerdCo func autoConvert_kops_ContainerdConfig_To_v1alpha2_ContainerdConfig(in *kops.ContainerdConfig, out *ContainerdConfig, s conversion.Scope) error { out.Address = in.Address + out.ConfigAdditions = in.ConfigAdditions out.ConfigOverride = in.ConfigOverride out.LogLevel = in.LogLevel if in.Packages != nil { diff --git a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go index d19872f5a2..267fa6ef4b 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go @@ -1427,6 +1427,13 @@ func (in *ContainerdConfig) DeepCopyInto(out *ContainerdConfig) { *out = new(string) **out = **in } + if in.ConfigAdditions != nil { + in, out := &in.ConfigAdditions, &out.ConfigAdditions + *out = make(map[string]intstr.IntOrString, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.ConfigOverride != nil { in, out := &in.ConfigOverride, &out.ConfigOverride *out = new(string) diff --git a/pkg/apis/kops/v1alpha3/containerdconfig.go b/pkg/apis/kops/v1alpha3/containerdconfig.go index 32a370e465..be69f3e9a7 100644 --- a/pkg/apis/kops/v1alpha3/containerdconfig.go +++ b/pkg/apis/kops/v1alpha3/containerdconfig.go @@ -16,12 +16,17 @@ limitations under the License. package v1alpha3 -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) // ContainerdConfig is the configuration for containerd type ContainerdConfig struct { // Address of containerd's GRPC server (default "/run/containerd/containerd.sock"). Address *string `json:"address,omitempty" flag:"address"` + // ConfigAdditions adds additional config entries to the generated config file. + ConfigAdditions map[string]intstr.IntOrString `json:"configAdditions,omitempty"` // ConfigOverride is the complete containerd config file provided by the user. ConfigOverride *string `json:"configOverride,omitempty"` // LogLevel controls the logging details [trace, debug, info, warn, error, fatal, panic] (default "info"). diff --git a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go index 1455573643..0953d065b0 100644 --- a/pkg/apis/kops/v1alpha3/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha3/zz_generated.conversion.go @@ -3401,6 +3401,7 @@ func Convert_kops_ConfigStoreSpec_To_v1alpha3_ConfigStoreSpec(in *kops.ConfigSto func autoConvert_v1alpha3_ContainerdConfig_To_kops_ContainerdConfig(in *ContainerdConfig, out *kops.ContainerdConfig, s conversion.Scope) error { out.Address = in.Address + out.ConfigAdditions = in.ConfigAdditions out.ConfigOverride = in.ConfigOverride out.LogLevel = in.LogLevel if in.Packages != nil { @@ -3455,6 +3456,7 @@ func Convert_v1alpha3_ContainerdConfig_To_kops_ContainerdConfig(in *ContainerdCo func autoConvert_kops_ContainerdConfig_To_v1alpha3_ContainerdConfig(in *kops.ContainerdConfig, out *ContainerdConfig, s conversion.Scope) error { out.Address = in.Address + out.ConfigAdditions = in.ConfigAdditions out.ConfigOverride = in.ConfigOverride out.LogLevel = in.LogLevel if in.Packages != nil { diff --git a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go index d7721968ef..89a2f9df5b 100644 --- a/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha3/zz_generated.deepcopy.go @@ -1333,6 +1333,13 @@ func (in *ContainerdConfig) DeepCopyInto(out *ContainerdConfig) { *out = new(string) **out = **in } + if in.ConfigAdditions != nil { + in, out := &in.ConfigAdditions, &out.ConfigAdditions + *out = make(map[string]intstr.IntOrString, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.ConfigOverride != nil { in, out := &in.ConfigOverride, &out.ConfigOverride *out = new(string) diff --git a/pkg/apis/kops/zz_generated.deepcopy.go b/pkg/apis/kops/zz_generated.deepcopy.go index e4a8be6726..785cca01db 100644 --- a/pkg/apis/kops/zz_generated.deepcopy.go +++ b/pkg/apis/kops/zz_generated.deepcopy.go @@ -1453,6 +1453,13 @@ func (in *ContainerdConfig) DeepCopyInto(out *ContainerdConfig) { *out = new(string) **out = **in } + if in.ConfigAdditions != nil { + in, out := &in.ConfigAdditions, &out.ConfigAdditions + *out = make(map[string]intstr.IntOrString, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.ConfigOverride != nil { in, out := &in.ConfigOverride, &out.ConfigOverride *out = new(string) diff --git a/util/pkg/reflectutils/access.go b/util/pkg/reflectutils/access.go index 6c741128e0..d4f193dc22 100644 --- a/util/pkg/reflectutils/access.go +++ b/util/pkg/reflectutils/access.go @@ -144,6 +144,10 @@ func setType(v reflect.Value, newValue string) error { name, value, _ := strings.Cut(newValue, "=") v.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(value)) + case "map[string]intstr.IntOrString": + name, value, _ := strings.Cut(newValue, "=") + v.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(intstr.Parse(value))) + default: return fmt.Errorf("unhandled type %q", t) }