From 820683bba0e9ea3d0ad2ed01e3b9ee19e9052154 Mon Sep 17 00:00:00 2001 From: Ole Markus With Date: Mon, 9 Aug 2021 16:02:41 +0200 Subject: [PATCH 1/2] Test if update_service behaves as intended --- nodeup/pkg/model/BUILD.bazel | 1 + nodeup/pkg/model/kubelet_test.go | 8 +++ .../automatic/cluster.yaml | 64 +++++++++++++++++++ .../automatic/tasks-updateservice.yaml | 1 + .../external/cluster.yaml | 64 +++++++++++++++++++ .../external/tasks-updateservice.yaml | 9 +++ nodeup/pkg/model/update_service_test.go | 38 +++++++++++ 7 files changed, 185 insertions(+) create mode 100644 nodeup/pkg/model/tests/updateservicebuilder/automatic/cluster.yaml create mode 100644 nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml create mode 100644 nodeup/pkg/model/tests/updateservicebuilder/external/cluster.yaml create mode 100644 nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml create mode 100644 nodeup/pkg/model/update_service_test.go diff --git a/nodeup/pkg/model/BUILD.bazel b/nodeup/pkg/model/BUILD.bazel index 24fb2a4fb7c77..93cbf874efd5b 100644 --- a/nodeup/pkg/model/BUILD.bazel +++ b/nodeup/pkg/model/BUILD.bazel @@ -99,6 +99,7 @@ go_test( "kubelet_test.go", "protokube_test.go", "secrets_test.go", + "update_service_test.go", ], data = glob(["tests/**"]), #keep embed = [":go_default_library"], diff --git a/nodeup/pkg/model/kubelet_test.go b/nodeup/pkg/model/kubelet_test.go index d5a8fa4b72c11..5bc79eeca7e5f 100644 --- a/nodeup/pkg/model/kubelet_test.go +++ b/nodeup/pkg/model/kubelet_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/kops/pkg/testutils" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup" + "k8s.io/kops/util/pkg/distributions" "k8s.io/kops/util/pkg/vfs" ) @@ -298,6 +299,11 @@ func BuildNodeupModelContext(model *testutils.Model) (*NodeupModelContext, error } nodeupModelContext.NodeupConfig.ContainerdConfig = nodeupModelContext.Cluster.Spec.Containerd + updatePolicy := nodeupModelContext.Cluster.Spec.UpdatePolicy + if updatePolicy == nil { + updatePolicy = fi.String(kops.UpdatePolicyAutomatic) + } + nodeupModelContext.NodeupConfig.UpdatePolicy = *updatePolicy return nodeupModelContext, nil } @@ -397,6 +403,8 @@ func RunGoldenTest(t *testing.T, basedir string, key string, builder func(*Nodeu nodeupModelContext.KeyStore = keystore + nodeupModelContext.Distribution = distributions.DistributionUbuntu2004 + if err := nodeupModelContext.Init(); err != nil { t.Fatalf("error from nodeupModelContext.Init(): %v", err) } diff --git a/nodeup/pkg/model/tests/updateservicebuilder/automatic/cluster.yaml b/nodeup/pkg/model/tests/updateservicebuilder/automatic/cluster.yaml new file mode 100644 index 0000000000000..644196b987cd7 --- /dev/null +++ b/nodeup/pkg/model/tests/updateservicebuilder/automatic/cluster.yaml @@ -0,0 +1,64 @@ +apiVersion: kops.k8s.io/v1alpha2 +kind: Cluster +metadata: + creationTimestamp: "2016-12-10T22:42:27Z" + name: minimal.example.com +spec: + kubernetesApiAccess: + - 0.0.0.0/0 + channel: stable + cloudProvider: aws + configBase: memfs://clusters.example.com/minimal.example.com + containerd: + version: 1.3.4 + containerRuntime: containerd + etcdClusters: + - etcdMembers: + - instanceGroup: master-us-test-1a + name: master-us-test-1a + name: main + provider: Manager + - etcdMembers: + - instanceGroup: master-us-test-1a + name: master-us-test-1a + name: events + provider: Manager + iam: {} + kubelet: + hostnameOverride: master.hostname.invalid + kubernetesVersion: v1.17.0 + masterInternalName: api.internal.minimal.example.com + masterPublicName: api.minimal.example.com + networkCIDR: 172.20.0.0/16 + networking: + calico: {} + nonMasqueradeCIDR: 100.64.0.0/10 + sshAccess: + - 0.0.0.0/0 + topology: + masters: public + nodes: public + subnets: + - cidr: 172.20.32.0/19 + name: us-test-1a + type: Public + zone: us-test-1a + +--- + +apiVersion: kops.k8s.io/v1alpha2 +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + name: master-1a + labels: + kops.k8s.io/cluster: minimal.example.com +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: t2.medium + maxSize: 2 + minSize: 2 + role: Master + subnets: + - us-test-1a diff --git a/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml b/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml @@ -0,0 +1 @@ + diff --git a/nodeup/pkg/model/tests/updateservicebuilder/external/cluster.yaml b/nodeup/pkg/model/tests/updateservicebuilder/external/cluster.yaml new file mode 100644 index 0000000000000..a3cd870c334ff --- /dev/null +++ b/nodeup/pkg/model/tests/updateservicebuilder/external/cluster.yaml @@ -0,0 +1,64 @@ +apiVersion: kops.k8s.io/v1alpha2 +kind: Cluster +metadata: + creationTimestamp: "2016-12-10T22:42:27Z" + name: minimal.example.com +spec: + kubernetesApiAccess: + - 0.0.0.0/0 + channel: stable + cloudProvider: aws + configBase: memfs://clusters.example.com/minimal.example.com + containerd: + version: 1.3.4 + containerRuntime: containerd + etcdClusters: + - etcdMembers: + - instanceGroup: master-us-test-1a + name: master-us-test-1a + name: main + provider: Manager + - etcdMembers: + - instanceGroup: master-us-test-1a + name: master-us-test-1a + name: events + provider: Manager + iam: {} + kubelet: + hostnameOverride: master.hostname.invalid + kubernetesVersion: v1.17.0 + masterInternalName: api.internal.minimal.example.com + masterPublicName: api.minimal.example.com + networkCIDR: 172.20.0.0/16 + networking: + calico: {} + nonMasqueradeCIDR: 100.64.0.0/10 + sshAccess: + - 0.0.0.0/0 + topology: + masters: public + nodes: public + subnets: + - cidr: 172.20.32.0/19 + name: us-test-1a + type: Public + zone: us-test-1a + updatePolicy: external +--- + +apiVersion: kops.k8s.io/v1alpha2 +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + name: master-1a + labels: + kops.k8s.io/cluster: minimal.example.com +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: t2.medium + maxSize: 2 + minSize: 2 + role: Master + subnets: + - us-test-1a diff --git a/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml b/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml new file mode 100644 index 0000000000000..7f3203ad4576e --- /dev/null +++ b/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml @@ -0,0 +1,9 @@ +contents: | + APT::Periodic::Update-Package-Lists "1"; + APT::Periodic::Unattended-Upgrade "1"; + + APT::Periodic::AutocleanInterval "7"; +path: /etc/apt/apt.conf.d/20auto-upgrades +type: file +--- +Name: unattended-upgrades diff --git a/nodeup/pkg/model/update_service_test.go b/nodeup/pkg/model/update_service_test.go new file mode 100644 index 0000000000000..cdddc3c5286ce --- /dev/null +++ b/nodeup/pkg/model/update_service_test.go @@ -0,0 +1,38 @@ +/* +Copyright 2021 The Kubernetes 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 + + http://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. +*/ + +package model + +import ( + "testing" + + "k8s.io/kops/upup/pkg/fi" +) + +func TestUpdateServiceBuilderAutomaticUpgrade(t *testing.T) { + RunGoldenTest(t, "tests/updateservicebuilder/automatic", "updateservice", func(nodeupModelContext *NodeupModelContext, target *fi.ModelBuilderContext) error { + builder := UpdateServiceBuilder{NodeupModelContext: nodeupModelContext} + return builder.Build(target) + }) +} + +func TestUpdateServiceBuilderExternal(t *testing.T) { + RunGoldenTest(t, "tests/updateservicebuilder/external", "updateservice", func(nodeupModelContext *NodeupModelContext, target *fi.ModelBuilderContext) error { + builder := UpdateServiceBuilder{NodeupModelContext: nodeupModelContext} + return builder.Build(target) + }) + +} From f1a856502409e4c120b13d27aab25f886a642ffd Mon Sep 17 00:00:00 2001 From: Ole Markus With Date: Mon, 9 Aug 2021 14:23:49 +0200 Subject: [PATCH 2/2] Fix disabling unattended upgrades Current default AMIs pre-install and pre-configure unattended upgrades. We therefor need to explicitly disable it if the update policy requires it. --- .../automatic/tasks-updateservice.yaml | 8 ++++++++ .../external/tasks-updateservice.yaml | 7 +------ nodeup/pkg/model/update_service.go | 16 ++++++++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml b/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml index 8b137891791fe..7f3203ad4576e 100644 --- a/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml +++ b/nodeup/pkg/model/tests/updateservicebuilder/automatic/tasks-updateservice.yaml @@ -1 +1,9 @@ +contents: | + APT::Periodic::Update-Package-Lists "1"; + APT::Periodic::Unattended-Upgrade "1"; + APT::Periodic::AutocleanInterval "7"; +path: /etc/apt/apt.conf.d/20auto-upgrades +type: file +--- +Name: unattended-upgrades diff --git a/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml b/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml index 7f3203ad4576e..34d7216455fee 100644 --- a/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml +++ b/nodeup/pkg/model/tests/updateservicebuilder/external/tasks-updateservice.yaml @@ -1,9 +1,4 @@ contents: | - APT::Periodic::Update-Package-Lists "1"; - APT::Periodic::Unattended-Upgrade "1"; - - APT::Periodic::AutocleanInterval "7"; + APT::Periodic::Enable "0"; path: /etc/apt/apt.conf.d/20auto-upgrades type: file ---- -Name: unattended-upgrades diff --git a/nodeup/pkg/model/update_service.go b/nodeup/pkg/model/update_service.go index 33e4ff7ee5e6f..1a970fe7bb599 100644 --- a/nodeup/pkg/model/update_service.go +++ b/nodeup/pkg/model/update_service.go @@ -85,23 +85,27 @@ func (b *UpdateServiceBuilder) buildFlatcarSystemdService(c *fi.ModelBuilderCont } func (b *UpdateServiceBuilder) buildDebianPackage(c *fi.ModelBuilderContext) { - if b.NodeupConfig.UpdatePolicy != kops.UpdatePolicyExternal { + contents := "" + if b.NodeupConfig.UpdatePolicy == kops.UpdatePolicyExternal { klog.Infof("UpdatePolicy requests automatic updates; skipping installation of package %q", debianPackageName) - return - } + contents = `APT::Periodic::Enable "0"; +` + } else { - klog.Infof("Detected OS %s; installing %s package", b.Distribution, debianPackageName) + klog.Infof("Detected OS %s; installing %s package", b.Distribution, debianPackageName) + c.AddTask(&nodetasks.Package{Name: debianPackageName}) - contents := `APT::Periodic::Update-Package-Lists "1"; + contents = `APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; APT::Periodic::AutocleanInterval "7"; ` + } + c.AddTask(&nodetasks.File{ Path: "/etc/apt/apt.conf.d/20auto-upgrades", Contents: fi.NewStringResource(contents), Type: nodetasks.FileType_File, }) - c.AddTask(&nodetasks.Package{Name: debianPackageName}) }