From 7084de351638b42fddd0633a4669f435e9c9ec68 Mon Sep 17 00:00:00 2001 From: Stefan Bueringer Date: Wed, 15 Sep 2021 09:32:59 +0200 Subject: [PATCH] Add backported rolloutStrategy to KCP v1alpha3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Büringer buringerst@vmware.com --- .../kubeadm/api/v1alpha3/conversion.go | 1 - .../v1alpha3/kubeadm_control_plane_types.go | 42 ++++++++++++ .../api/v1alpha3/zz_generated.conversion.go | 66 ++++++++++++++++++- .../api/v1alpha3/zz_generated.deepcopy.go | 46 +++++++++++++ ...cluster.x-k8s.io_kubeadmcontrolplanes.yaml | 24 +++++++ test/e2e/clusterctl_upgrade.go | 2 +- 6 files changed, 178 insertions(+), 3 deletions(-) diff --git a/controlplane/kubeadm/api/v1alpha3/conversion.go b/controlplane/kubeadm/api/v1alpha3/conversion.go index fb5c8c3f2242..8244b44436b0 100644 --- a/controlplane/kubeadm/api/v1alpha3/conversion.go +++ b/controlplane/kubeadm/api/v1alpha3/conversion.go @@ -37,7 +37,6 @@ func (src *KubeadmControlPlane) ConvertTo(destRaw conversion.Hub) error { return err } - dest.Spec.RolloutStrategy = restored.Spec.RolloutStrategy dest.Spec.MachineTemplate.ObjectMeta = restored.Spec.MachineTemplate.ObjectMeta dest.Status.Version = restored.Status.Version diff --git a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_types.go b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_types.go index f21ebac2a8b0..5f20da42355f 100644 --- a/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_types.go +++ b/controlplane/kubeadm/api/v1alpha3/kubeadm_control_plane_types.go @@ -19,12 +19,22 @@ package v1alpha3 import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" cabpkv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" "sigs.k8s.io/cluster-api/errors" ) +// RolloutStrategyType defines the rollout strategies for a KubeadmControlPlane. +type RolloutStrategyType string + +const ( + // RollingUpdateStrategyType replaces the old control planes by new one using rolling update + // i.e. gradually scale up or down the old control planes and scale up or down the new one. + RollingUpdateStrategyType RolloutStrategyType = "RollingUpdate" +) + const ( // KubeadmControlPlaneFinalizer is the finalizer applied to KubeadmControlPlane resources // by its managing controller. @@ -77,6 +87,38 @@ type KubeadmControlPlaneSpec struct { // NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` // +optional NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"` + + // The RolloutStrategy to use to replace control plane machines with + // new ones. + // +optional + RolloutStrategy *RolloutStrategy `json:"rolloutStrategy,omitempty"` +} + +// RolloutStrategy describes how to replace existing machines +// with new ones. +type RolloutStrategy struct { + // Type of rollout. Currently the only supported strategy is + // "RollingUpdate". + // Default is RollingUpdate. + // +optional + Type RolloutStrategyType `json:"type,omitempty"` + + // Rolling update config params. Present only if + // RolloutStrategyType = RollingUpdate. + // +optional + RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty"` +} + +// RollingUpdate is used to control the desired behavior of rolling update. +type RollingUpdate struct { + // The maximum number of control planes that can be scheduled above or under the + // desired number of control planes. + // Value can be an absolute number 1 or 0. + // Defaults to 1. + // Example: when this is set to 1, the control plane can be scaled + // up immediately when the rolling update starts. + // +optional + MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"` } // KubeadmControlPlaneStatus defines the observed state of KubeadmControlPlane. diff --git a/controlplane/kubeadm/api/v1alpha3/zz_generated.conversion.go b/controlplane/kubeadm/api/v1alpha3/zz_generated.conversion.go index 10103dd3431e..844fb88c34c6 100644 --- a/controlplane/kubeadm/api/v1alpha3/zz_generated.conversion.go +++ b/controlplane/kubeadm/api/v1alpha3/zz_generated.conversion.go @@ -25,6 +25,7 @@ import ( conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" + intstr "k8s.io/apimachinery/pkg/util/intstr" clusterapiapiv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3" apiv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4" apiv1alpha3 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" @@ -64,6 +65,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*RollingUpdate)(nil), (*v1alpha4.RollingUpdate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_RollingUpdate_To_v1alpha4_RollingUpdate(a.(*RollingUpdate), b.(*v1alpha4.RollingUpdate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha4.RollingUpdate)(nil), (*RollingUpdate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_RollingUpdate_To_v1alpha3_RollingUpdate(a.(*v1alpha4.RollingUpdate), b.(*RollingUpdate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*RolloutStrategy)(nil), (*v1alpha4.RolloutStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_RolloutStrategy_To_v1alpha4_RolloutStrategy(a.(*RolloutStrategy), b.(*v1alpha4.RolloutStrategy), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha4.RolloutStrategy)(nil), (*RolloutStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_RolloutStrategy_To_v1alpha3_RolloutStrategy(a.(*v1alpha4.RolloutStrategy), b.(*RolloutStrategy), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*KubeadmControlPlaneSpec)(nil), (*v1alpha4.KubeadmControlPlaneSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_KubeadmControlPlaneSpec_To_v1alpha4_KubeadmControlPlaneSpec(a.(*KubeadmControlPlaneSpec), b.(*v1alpha4.KubeadmControlPlaneSpec), scope) }); err != nil { @@ -165,6 +186,7 @@ func autoConvert_v1alpha3_KubeadmControlPlaneSpec_To_v1alpha4_KubeadmControlPlan } // WARNING: in.UpgradeAfter requires manual conversion: does not exist in peer-type // WARNING: in.NodeDrainTimeout requires manual conversion: does not exist in peer-type + out.RolloutStrategy = (*v1alpha4.RolloutStrategy)(unsafe.Pointer(in.RolloutStrategy)) return nil } @@ -176,7 +198,7 @@ func autoConvert_v1alpha4_KubeadmControlPlaneSpec_To_v1alpha3_KubeadmControlPlan return err } // WARNING: in.RolloutAfter requires manual conversion: does not exist in peer-type - // WARNING: in.RolloutStrategy requires manual conversion: does not exist in peer-type + out.RolloutStrategy = (*RolloutStrategy)(unsafe.Pointer(in.RolloutStrategy)) return nil } @@ -235,3 +257,45 @@ func autoConvert_v1alpha4_KubeadmControlPlaneStatus_To_v1alpha3_KubeadmControlPl } return nil } + +func autoConvert_v1alpha3_RollingUpdate_To_v1alpha4_RollingUpdate(in *RollingUpdate, out *v1alpha4.RollingUpdate, s conversion.Scope) error { + out.MaxSurge = (*intstr.IntOrString)(unsafe.Pointer(in.MaxSurge)) + return nil +} + +// Convert_v1alpha3_RollingUpdate_To_v1alpha4_RollingUpdate is an autogenerated conversion function. +func Convert_v1alpha3_RollingUpdate_To_v1alpha4_RollingUpdate(in *RollingUpdate, out *v1alpha4.RollingUpdate, s conversion.Scope) error { + return autoConvert_v1alpha3_RollingUpdate_To_v1alpha4_RollingUpdate(in, out, s) +} + +func autoConvert_v1alpha4_RollingUpdate_To_v1alpha3_RollingUpdate(in *v1alpha4.RollingUpdate, out *RollingUpdate, s conversion.Scope) error { + out.MaxSurge = (*intstr.IntOrString)(unsafe.Pointer(in.MaxSurge)) + return nil +} + +// Convert_v1alpha4_RollingUpdate_To_v1alpha3_RollingUpdate is an autogenerated conversion function. +func Convert_v1alpha4_RollingUpdate_To_v1alpha3_RollingUpdate(in *v1alpha4.RollingUpdate, out *RollingUpdate, s conversion.Scope) error { + return autoConvert_v1alpha4_RollingUpdate_To_v1alpha3_RollingUpdate(in, out, s) +} + +func autoConvert_v1alpha3_RolloutStrategy_To_v1alpha4_RolloutStrategy(in *RolloutStrategy, out *v1alpha4.RolloutStrategy, s conversion.Scope) error { + out.Type = v1alpha4.RolloutStrategyType(in.Type) + out.RollingUpdate = (*v1alpha4.RollingUpdate)(unsafe.Pointer(in.RollingUpdate)) + return nil +} + +// Convert_v1alpha3_RolloutStrategy_To_v1alpha4_RolloutStrategy is an autogenerated conversion function. +func Convert_v1alpha3_RolloutStrategy_To_v1alpha4_RolloutStrategy(in *RolloutStrategy, out *v1alpha4.RolloutStrategy, s conversion.Scope) error { + return autoConvert_v1alpha3_RolloutStrategy_To_v1alpha4_RolloutStrategy(in, out, s) +} + +func autoConvert_v1alpha4_RolloutStrategy_To_v1alpha3_RolloutStrategy(in *v1alpha4.RolloutStrategy, out *RolloutStrategy, s conversion.Scope) error { + out.Type = RolloutStrategyType(in.Type) + out.RollingUpdate = (*RollingUpdate)(unsafe.Pointer(in.RollingUpdate)) + return nil +} + +// Convert_v1alpha4_RolloutStrategy_To_v1alpha3_RolloutStrategy is an autogenerated conversion function. +func Convert_v1alpha4_RolloutStrategy_To_v1alpha3_RolloutStrategy(in *v1alpha4.RolloutStrategy, out *RolloutStrategy, s conversion.Scope) error { + return autoConvert_v1alpha4_RolloutStrategy_To_v1alpha3_RolloutStrategy(in, out, s) +} diff --git a/controlplane/kubeadm/api/v1alpha3/zz_generated.deepcopy.go b/controlplane/kubeadm/api/v1alpha3/zz_generated.deepcopy.go index be97eb20a684..7c33554eede0 100644 --- a/controlplane/kubeadm/api/v1alpha3/zz_generated.deepcopy.go +++ b/controlplane/kubeadm/api/v1alpha3/zz_generated.deepcopy.go @@ -23,6 +23,7 @@ package v1alpha3 import ( "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" apiv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3" ) @@ -104,6 +105,11 @@ func (in *KubeadmControlPlaneSpec) DeepCopyInto(out *KubeadmControlPlaneSpec) { *out = new(v1.Duration) **out = **in } + if in.RolloutStrategy != nil { + in, out := &in.RolloutStrategy, &out.RolloutStrategy + *out = new(RolloutStrategy) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmControlPlaneSpec. @@ -142,3 +148,43 @@ func (in *KubeadmControlPlaneStatus) DeepCopy() *KubeadmControlPlaneStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollingUpdate) DeepCopyInto(out *RollingUpdate) { + *out = *in + if in.MaxSurge != nil { + in, out := &in.MaxSurge, &out.MaxSurge + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdate. +func (in *RollingUpdate) DeepCopy() *RollingUpdate { + if in == nil { + return nil + } + out := new(RollingUpdate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RolloutStrategy) DeepCopyInto(out *RolloutStrategy) { + *out = *in + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(RollingUpdate) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutStrategy. +func (in *RolloutStrategy) DeepCopy() *RolloutStrategy { + if in == nil { + return nil + } + out := new(RolloutStrategy) + in.DeepCopyInto(out) + return out +} diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml index a2b59e1df22d..8abb3ecd9cfd 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml @@ -1045,6 +1045,30 @@ spec: This is a pointer to distinguish between explicit zero and not specified. format: int32 type: integer + rolloutStrategy: + description: The RolloutStrategy to use to replace control plane machines + with new ones. + properties: + rollingUpdate: + description: Rolling update config params. Present only if RolloutStrategyType + = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: 'The maximum number of control planes that can + be scheduled above or under the desired number of control + planes. Value can be an absolute number 1 or 0. Defaults + to 1. Example: when this is set to 1, the control plane + can be scaled up immediately when the rolling update starts.' + x-kubernetes-int-or-string: true + type: object + type: + description: Type of rollout. Currently the only supported strategy + is "RollingUpdate". Default is RollingUpdate. + type: string + type: object upgradeAfter: description: UpgradeAfter is a field to indicate an upgrade should be performed after the specified time even if no changes have been diff --git a/test/e2e/clusterctl_upgrade.go b/test/e2e/clusterctl_upgrade.go index 209383c07518..90140dbbf7e2 100644 --- a/test/e2e/clusterctl_upgrade.go +++ b/test/e2e/clusterctl_upgrade.go @@ -278,7 +278,7 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg framework.DumpAllResources(ctx, framework.DumpAllResourcesInput{ Lister: managementClusterProxy.GetClient(), - Namespace: managementClusterNamespace.Name, + Namespace: testNamespace.Name, LogPath: filepath.Join(input.ArtifactFolder, "clusters", managementClusterResources.Cluster.Name, "resources"), })