diff --git a/Makefile b/Makefile index 7096e4656301..6a56da4ae22e 100644 --- a/Makefile +++ b/Makefile @@ -921,6 +921,10 @@ test: $(SETUP_ENVTEST) ## Run unit and integration tests with race detector # To achieve that, all files with fuzz tests have the "!race" build tag, to still run fuzz tests # we have an additional `go test` run that focuses on "TestFuzzyConversion". KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test -race ./... $(TEST_ARGS) + $(MAKE) test-conversions TEST_ARGS="$(TEST_ARGS)" + +.PHONY: test-conversions +test-conversions: $(SETUP_ENVTEST) ## Run conversions test KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test -run "^TestFuzzyConversion$$" ./... $(TEST_ARGS) .PHONY: test-verbose diff --git a/api/v1beta1/conversion.go b/api/v1beta1/conversion.go index 406d368f3add..d9f4a3338d80 100644 --- a/api/v1beta1/conversion.go +++ b/api/v1beta1/conversion.go @@ -21,9 +21,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apimachineryconversion "k8s.io/apimachinery/pkg/conversion" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" ) func (src *Cluster) ConvertTo(dstRaw conversion.Hub) error { @@ -53,37 +55,80 @@ func (dst *ClusterClass) ConvertFrom(srcRaw conversion.Hub) error { func (src *Machine) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*clusterv1.Machine) - return Convert_v1beta1_Machine_To_v1beta2_Machine(src, dst, nil) + if err := Convert_v1beta1_Machine_To_v1beta2_Machine(src, dst, nil); err != nil { + return err + } + + restored := &clusterv1.Machine{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.MinReadySeconds = restored.Spec.MinReadySeconds + + return nil } func (dst *Machine) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*clusterv1.Machine) - return Convert_v1beta2_Machine_To_v1beta1_Machine(src, dst, nil) + if err := Convert_v1beta2_Machine_To_v1beta1_Machine(src, dst, nil); err != nil { + return err + } + + return utilconversion.MarshalData(src, dst) } func (src *MachineSet) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*clusterv1.MachineSet) - return Convert_v1beta1_MachineSet_To_v1beta2_MachineSet(src, dst, nil) + if err := Convert_v1beta1_MachineSet_To_v1beta2_MachineSet(src, dst, nil); err != nil { + return err + } + + if src.Spec.MinReadySeconds == 0 { + dst.Spec.Template.Spec.MinReadySeconds = nil + } else { + dst.Spec.Template.Spec.MinReadySeconds = &src.Spec.MinReadySeconds + } + + return nil } func (dst *MachineSet) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*clusterv1.MachineSet) - return Convert_v1beta2_MachineSet_To_v1beta1_MachineSet(src, dst, nil) + if err := Convert_v1beta2_MachineSet_To_v1beta1_MachineSet(src, dst, nil); err != nil { + return err + } + + dst.Spec.MinReadySeconds = ptr.Deref(src.Spec.Template.Spec.MinReadySeconds, 0) + + return nil } func (src *MachineDeployment) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*clusterv1.MachineDeployment) - return Convert_v1beta1_MachineDeployment_To_v1beta2_MachineDeployment(src, dst, nil) + if err := Convert_v1beta1_MachineDeployment_To_v1beta2_MachineDeployment(src, dst, nil); err != nil { + return err + } + + dst.Spec.Template.Spec.MinReadySeconds = src.Spec.MinReadySeconds + + return nil } func (dst *MachineDeployment) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*clusterv1.MachineDeployment) - return Convert_v1beta2_MachineDeployment_To_v1beta1_MachineDeployment(src, dst, nil) + if err := Convert_v1beta2_MachineDeployment_To_v1beta1_MachineDeployment(src, dst, nil); err != nil { + return err + } + + dst.Spec.MinReadySeconds = src.Spec.Template.Spec.MinReadySeconds + + return nil } func (src *MachineHealthCheck) ConvertTo(dstRaw conversion.Hub) error { @@ -710,3 +755,11 @@ func Convert_v1beta1_ClusterVariable_To_v1beta2_ClusterVariable(in *ClusterVaria // because it was already not possible to set it anymore with v1beta1. return autoConvert_v1beta1_ClusterVariable_To_v1beta2_ClusterVariable(in, out, s) } + +func Convert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *clusterv1.MachineSetSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(in, out, s) +} + +func Convert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(in *clusterv1.MachineSpec, out *MachineSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(in, out, s) +} diff --git a/api/v1beta1/machine_types.go b/api/v1beta1/machine_types.go index dfe13b126e94..d36848090d29 100644 --- a/api/v1beta1/machine_types.go +++ b/api/v1beta1/machine_types.go @@ -424,14 +424,6 @@ type MachineSpec struct { // +kubebuilder:validation:MaxLength=256 FailureDomain *string `json:"failureDomain,omitempty"` - // The minimum number of seconds for which a Machine should be ready before considering it available. - // Defaults to 0 (Machine will be considered available as soon as the Machine is ready) - // NOTE: this field will be considered only for computing v1beta2 conditions. - // +optional - // TODO: This field will be added in the v1beta2 API, and act as a replacement of existing MinReadySeconds in - // MachineDeployment, MachineSet and MachinePool - // MinReadySeconds int32 `json:"minReadySeconds,omitempty"` - // readinessGates specifies additional conditions to include when evaluating Machine Ready condition. // // This field can be used e.g. by Cluster API control plane providers to extend the semantic of the diff --git a/api/v1beta1/zz_generated.conversion.go b/api/v1beta1/zz_generated.conversion.go index dcc8501d0e63..b5cc216487e7 100644 --- a/api/v1beta1/zz_generated.conversion.go +++ b/api/v1beta1/zz_generated.conversion.go @@ -620,11 +620,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*MachineSetSpec)(nil), (*v1beta2.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta2.MachineSetSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1beta2.MachineSetSpec)(nil), (*MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_MachineSetSpec_To_v1beta1_MachineSetSpec(a.(*v1beta2.MachineSetSpec), b.(*MachineSetSpec), scope) }); err != nil { @@ -635,11 +630,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1beta2.MachineSpec)(nil), (*MachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(a.(*v1beta2.MachineSpec), b.(*MachineSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*MachineTemplateSpec)(nil), (*v1beta2.MachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_MachineTemplateSpec_To_v1beta2_MachineTemplateSpec(a.(*MachineTemplateSpec), b.(*v1beta2.MachineTemplateSpec), scope) }); err != nil { @@ -850,6 +840,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*MachineSetSpec)(nil), (*v1beta2.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta2.MachineSetSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*MachineSetStatus)(nil), (*v1beta2.MachineSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_MachineSetStatus_To_v1beta2_MachineSetStatus(a.(*MachineSetStatus), b.(*v1beta2.MachineSetStatus), scope) }); err != nil { @@ -910,6 +905,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta2.MachineSpec)(nil), (*MachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(a.(*v1beta2.MachineSpec), b.(*MachineSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta2.MachineStatus)(nil), (*MachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_MachineStatus_To_v1beta1_MachineStatus(a.(*v1beta2.MachineStatus), b.(*MachineStatus), scope) }); err != nil { @@ -2207,7 +2207,7 @@ func autoConvert_v1beta1_MachineDeploymentSpec_To_v1beta2_MachineDeploymentSpec( } out.Strategy = (*v1beta2.MachineDeploymentStrategy)(unsafe.Pointer(in.Strategy)) out.MachineNamingStrategy = (*v1beta2.MachineNamingStrategy)(unsafe.Pointer(in.MachineNamingStrategy)) - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused // WARNING: in.ProgressDeadlineSeconds requires manual conversion: does not exist in peer-type @@ -2224,7 +2224,6 @@ func autoConvert_v1beta2_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec( } out.Strategy = (*MachineDeploymentStrategy)(unsafe.Pointer(in.Strategy)) out.MachineNamingStrategy = (*MachineNamingStrategy)(unsafe.Pointer(in.MachineNamingStrategy)) - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused return nil @@ -3135,7 +3134,7 @@ func Convert_v1beta2_MachineSetList_To_v1beta1_MachineSetList(in *v1beta2.Machin func autoConvert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *v1beta2.MachineSetSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) - out.MinReadySeconds = in.MinReadySeconds + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.DeletePolicy = in.DeletePolicy out.Selector = in.Selector if err := Convert_v1beta1_MachineTemplateSpec_To_v1beta2_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { @@ -3145,15 +3144,9 @@ func autoConvert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSet return nil } -// Convert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec is an autogenerated conversion function. -func Convert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *v1beta2.MachineSetSpec, s conversion.Scope) error { - return autoConvert_v1beta1_MachineSetSpec_To_v1beta2_MachineSetSpec(in, out, s) -} - func autoConvert_v1beta2_MachineSetSpec_To_v1beta1_MachineSetSpec(in *v1beta2.MachineSetSpec, out *MachineSetSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) - out.MinReadySeconds = in.MinReadySeconds out.DeletePolicy = in.DeletePolicy out.Selector = in.Selector if err := Convert_v1beta2_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { @@ -3252,6 +3245,7 @@ func autoConvert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(in *v1beta2.MachineS out.Version = (*string)(unsafe.Pointer(in.Version)) out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) out.FailureDomain = (*string)(unsafe.Pointer(in.FailureDomain)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.ReadinessGates = *(*[]MachineReadinessGate)(unsafe.Pointer(&in.ReadinessGates)) out.NodeDrainTimeout = (*v1.Duration)(unsafe.Pointer(in.NodeDrainTimeout)) out.NodeVolumeDetachTimeout = (*v1.Duration)(unsafe.Pointer(in.NodeVolumeDetachTimeout)) @@ -3259,11 +3253,6 @@ func autoConvert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(in *v1beta2.MachineS return nil } -// Convert_v1beta2_MachineSpec_To_v1beta1_MachineSpec is an autogenerated conversion function. -func Convert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(in *v1beta2.MachineSpec, out *MachineSpec, s conversion.Scope) error { - return autoConvert_v1beta2_MachineSpec_To_v1beta1_MachineSpec(in, out, s) -} - func autoConvert_v1beta1_MachineStatus_To_v1beta2_MachineStatus(in *MachineStatus, out *v1beta2.MachineStatus, s conversion.Scope) error { out.NodeRef = (*corev1.ObjectReference)(unsafe.Pointer(in.NodeRef)) out.NodeInfo = (*corev1.NodeSystemInfo)(unsafe.Pointer(in.NodeInfo)) diff --git a/api/v1beta2/machine_types.go b/api/v1beta2/machine_types.go index cd721b3c7a92..d6830324ce5e 100644 --- a/api/v1beta2/machine_types.go +++ b/api/v1beta2/machine_types.go @@ -424,13 +424,10 @@ type MachineSpec struct { // +kubebuilder:validation:MaxLength=256 FailureDomain *string `json:"failureDomain,omitempty"` - // The minimum number of seconds for which a Machine should be ready before considering it available. + // minReadySeconds is the minimum number of seconds for which a Machine should be ready before considering it available. // Defaults to 0 (Machine will be considered available as soon as the Machine is ready) - // NOTE: this field will be considered only for computing v1beta2 conditions. // +optional - // TODO: This field will be added in the v1beta2 API, and act as a replacement of existing MinReadySeconds in - // MachineDeployment, MachineSet and MachinePool - // MinReadySeconds int32 `json:"minReadySeconds,omitempty"` + MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` // readinessGates specifies additional conditions to include when evaluating Machine Ready condition. // diff --git a/api/v1beta2/machinedeployment_types.go b/api/v1beta2/machinedeployment_types.go index 778f30d04d53..4c960feb544c 100644 --- a/api/v1beta2/machinedeployment_types.go +++ b/api/v1beta2/machinedeployment_types.go @@ -295,11 +295,6 @@ type MachineDeploymentSpec struct { // +optional MachineNamingStrategy *MachineNamingStrategy `json:"machineNamingStrategy,omitempty"` - // minReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. - // Defaults to 0 (machine will be considered available as soon as the Node is ready) - // +optional - MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` - // revisionHistoryLimit is the number of old MachineSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. // Defaults to 1. diff --git a/api/v1beta2/machineset_types.go b/api/v1beta2/machineset_types.go index 2d15a1d062e6..ce5d819239e6 100644 --- a/api/v1beta2/machineset_types.go +++ b/api/v1beta2/machineset_types.go @@ -65,11 +65,6 @@ type MachineSetSpec struct { // +optional Replicas *int32 `json:"replicas,omitempty"` - // minReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. - // Defaults to 0 (machine will be considered available as soon as the Node is ready) - // +optional - MinReadySeconds int32 `json:"minReadySeconds,omitempty"` - // deletePolicy defines the policy used to identify nodes to delete when downscaling. // Defaults to "Random". Valid values are "Random, "Newest", "Oldest" // +kubebuilder:validation:Enum=Random;Newest;Oldest diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 1d3c1568e0ee..8afc5a3dc85c 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -1479,11 +1479,6 @@ func (in *MachineDeploymentSpec) DeepCopyInto(out *MachineDeploymentSpec) { *out = new(MachineNamingStrategy) **out = **in } - if in.MinReadySeconds != nil { - in, out := &in.MinReadySeconds, &out.MinReadySeconds - *out = new(int32) - **out = **in - } if in.RevisionHistoryLimit != nil { in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit *out = new(int32) @@ -2555,6 +2550,11 @@ func (in *MachineSpec) DeepCopyInto(out *MachineSpec) { *out = new(string) **out = **in } + if in.MinReadySeconds != nil { + in, out := &in.MinReadySeconds, &out.MinReadySeconds + *out = new(int32) + **out = **in + } if in.ReadinessGates != nil { in, out := &in.ReadinessGates, &out.ReadinessGates *out = make([]MachineReadinessGate, len(*in)) diff --git a/api/v1beta2/zz_generated.openapi.go b/api/v1beta2/zz_generated.openapi.go index 1546f37088e3..ecdda325ade0 100644 --- a/api/v1beta2/zz_generated.openapi.go +++ b/api/v1beta2/zz_generated.openapi.go @@ -2502,13 +2502,6 @@ func schema_sigsk8sio_cluster_api_api_v1beta2_MachineDeploymentSpec(ref common.R Ref: ref("sigs.k8s.io/cluster-api/api/v1beta2.MachineNamingStrategy"), }, }, - "minReadySeconds": { - SchemaProps: spec.SchemaProps{ - Description: "minReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. Defaults to 0 (machine will be considered available as soon as the Node is ready)", - Type: []string{"integer"}, - Format: "int32", - }, - }, "revisionHistoryLimit": { SchemaProps: spec.SchemaProps{ Description: "revisionHistoryLimit is the number of old MachineSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.\n\nDeprecated: This field is deprecated and is going to be removed in the next apiVersion. Please see https://github.com/kubernetes-sigs/cluster-api/issues/10479 for more details.", @@ -4130,13 +4123,6 @@ func schema_sigsk8sio_cluster_api_api_v1beta2_MachineSetSpec(ref common.Referenc Format: "int32", }, }, - "minReadySeconds": { - SchemaProps: spec.SchemaProps{ - Description: "minReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. Defaults to 0 (machine will be considered available as soon as the Node is ready)", - Type: []string{"integer"}, - Format: "int32", - }, - }, "deletePolicy": { SchemaProps: spec.SchemaProps{ Description: "deletePolicy defines the policy used to identify nodes to delete when downscaling. Defaults to \"Random\". Valid values are \"Random, \"Newest\", \"Oldest\"", @@ -4376,6 +4362,13 @@ func schema_sigsk8sio_cluster_api_api_v1beta2_MachineSpec(ref common.ReferenceCa Format: "", }, }, + "minReadySeconds": { + SchemaProps: spec.SchemaProps{ + Description: "minReadySeconds is the minimum number of seconds for which a Machine should be ready before considering it available. Defaults to 0 (Machine will be considered available as soon as the Machine is ready)", + Type: []string{"integer"}, + Format: "int32", + }, + }, "readinessGates": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ diff --git a/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml b/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml index e40476836b36..8e880c0ccadd 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml @@ -1909,12 +1909,6 @@ spec: minLength: 1 type: string type: object - minReadySeconds: - description: |- - minReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. - Defaults to 0 (machine will be considered available as soon as the Node is ready) - format: int32 - type: integer paused: description: paused indicates that the deployment is paused. type: boolean @@ -2250,6 +2244,12 @@ spec: type: string type: object x-kubernetes-map-type: atomic + minReadySeconds: + description: |- + minReadySeconds is the minimum number of seconds for which a Machine should be ready before considering it available. + Defaults to 0 (Machine will be considered available as soon as the Machine is ready) + format: int32 + type: integer nodeDeletionTimeout: description: |- nodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine diff --git a/config/crd/bases/cluster.x-k8s.io_machinepools.yaml b/config/crd/bases/cluster.x-k8s.io_machinepools.yaml index 9b9a90eb3147..c92869554dc8 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinepools.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinepools.yaml @@ -1676,14 +1676,6 @@ spec: type: string maxItems: 100 type: array - minReadySeconds: - description: |- - minReadySeconds is the minimum number of seconds for which a newly created machine instances should - be ready. - Defaults to 0 (machine instance will be considered available as soon as it - is ready) - format: int32 - type: integer providerIDList: description: |- providerIDList are the identification IDs of machine instances provided by the provider. @@ -1850,6 +1842,12 @@ spec: type: string type: object x-kubernetes-map-type: atomic + minReadySeconds: + description: |- + minReadySeconds is the minimum number of seconds for which a Machine should be ready before considering it available. + Defaults to 0 (Machine will be considered available as soon as the Machine is ready) + format: int32 + type: integer nodeDeletionTimeout: description: |- nodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine diff --git a/config/crd/bases/cluster.x-k8s.io_machines.yaml b/config/crd/bases/cluster.x-k8s.io_machines.yaml index 27ff01da881a..ac8d20077afa 100644 --- a/config/crd/bases/cluster.x-k8s.io_machines.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machines.yaml @@ -1624,6 +1624,12 @@ spec: type: string type: object x-kubernetes-map-type: atomic + minReadySeconds: + description: |- + minReadySeconds is the minimum number of seconds for which a Machine should be ready before considering it available. + Defaults to 0 (Machine will be considered available as soon as the Machine is ready) + format: int32 + type: integer nodeDeletionTimeout: description: |- nodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine diff --git a/config/crd/bases/cluster.x-k8s.io_machinesets.yaml b/config/crd/bases/cluster.x-k8s.io_machinesets.yaml index 85e685fb60dd..9f1420d7d6d5 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinesets.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinesets.yaml @@ -1675,12 +1675,6 @@ spec: minLength: 1 type: string type: object - minReadySeconds: - description: |- - minReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. - Defaults to 0 (machine will be considered available as soon as the Node is ready) - format: int32 - type: integer replicas: description: |- replicas is the number of desired replicas. @@ -1905,6 +1899,12 @@ spec: type: string type: object x-kubernetes-map-type: atomic + minReadySeconds: + description: |- + minReadySeconds is the minimum number of seconds for which a Machine should be ready before considering it available. + Defaults to 0 (Machine will be considered available as soon as the Machine is ready) + format: int32 + type: integer nodeDeletionTimeout: description: |- nodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine diff --git a/controlplane/kubeadm/internal/controllers/controller.go b/controlplane/kubeadm/internal/controllers/controller.go index 9d888e878426..71682a7d3b93 100644 --- a/controlplane/kubeadm/internal/controllers/controller.go +++ b/controlplane/kubeadm/internal/controllers/controller.go @@ -792,6 +792,7 @@ func (r *KubeadmControlPlaneReconciler) syncMachines(ctx context.Context, contro m.Spec.NodeDeletionTimeout = controlPlane.KCP.Spec.MachineTemplate.NodeDeletionTimeout m.Spec.NodeVolumeDetachTimeout = controlPlane.KCP.Spec.MachineTemplate.NodeVolumeDetachTimeout + // Note: We intentionally don't set "minReadySeconds" on Machines because we consider it enough to have machine availability driven by readiness of control plane components. if err := patchHelper.Patch(ctx, m); err != nil { return err } diff --git a/controlplane/kubeadm/internal/controllers/helpers.go b/controlplane/kubeadm/internal/controllers/helpers.go index 2a7b055fc681..6937cd1952ae 100644 --- a/controlplane/kubeadm/internal/controllers/helpers.go +++ b/controlplane/kubeadm/internal/controllers/helpers.go @@ -466,6 +466,7 @@ func (r *KubeadmControlPlaneReconciler) computeDesiredMachine(kcp *controlplanev desiredMachine.Spec.NodeDeletionTimeout = kcp.Spec.MachineTemplate.NodeDeletionTimeout desiredMachine.Spec.NodeVolumeDetachTimeout = kcp.Spec.MachineTemplate.NodeVolumeDetachTimeout + // Note: We intentionally don't set "minReadySeconds" on Machines because we consider it enough to have machine availability driven by readiness of control plane components. if existingMachine != nil { desiredMachine.Spec.InfrastructureRef = existingMachine.Spec.InfrastructureRef desiredMachine.Spec.Bootstrap.ConfigRef = existingMachine.Spec.Bootstrap.ConfigRef diff --git a/exp/api/v1beta1/conversion.go b/exp/api/v1beta1/conversion.go index 6e2609d93abf..6e7c150bfcc9 100644 --- a/exp/api/v1beta1/conversion.go +++ b/exp/api/v1beta1/conversion.go @@ -29,13 +29,25 @@ import ( func (src *MachinePool) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*expv1.MachinePool) - return Convert_v1beta1_MachinePool_To_v1beta2_MachinePool(src, dst, nil) + if err := Convert_v1beta1_MachinePool_To_v1beta2_MachinePool(src, dst, nil); err != nil { + return err + } + + dst.Spec.Template.Spec.MinReadySeconds = src.Spec.MinReadySeconds + + return nil } func (dst *MachinePool) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*expv1.MachinePool) - return Convert_v1beta2_MachinePool_To_v1beta1_MachinePool(src, dst, nil) + if err := Convert_v1beta2_MachinePool_To_v1beta1_MachinePool(src, dst, nil); err != nil { + return err + } + + dst.Spec.MinReadySeconds = src.Spec.Template.Spec.MinReadySeconds + + return nil } func Convert_v1beta2_MachinePoolStatus_To_v1beta1_MachinePoolStatus(in *expv1.MachinePoolStatus, out *MachinePoolStatus, s apimachineryconversion.Scope) error { @@ -148,3 +160,7 @@ func Convert_v1_Condition_To_v1beta1_Condition(in *metav1.Condition, out *cluste func Convert_v1beta1_Condition_To_v1_Condition(in *clusterv1beta1.Condition, out *metav1.Condition, s apimachineryconversion.Scope) error { return clusterv1beta1.Convert_v1beta1_Condition_To_v1_Condition(in, out, s) } + +func Convert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *MachinePoolSpec, out *expv1.MachinePoolSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in, out, s) +} diff --git a/exp/api/v1beta1/zz_generated.conversion.go b/exp/api/v1beta1/zz_generated.conversion.go index 31ab13aa0076..b08653ca0ba2 100644 --- a/exp/api/v1beta1/zz_generated.conversion.go +++ b/exp/api/v1beta1/zz_generated.conversion.go @@ -60,11 +60,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*MachinePoolSpec)(nil), (*v1beta2.MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(a.(*MachinePoolSpec), b.(*v1beta2.MachinePoolSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1beta2.MachinePoolSpec)(nil), (*MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_MachinePoolSpec_To_v1beta1_MachinePoolSpec(a.(*v1beta2.MachinePoolSpec), b.(*MachinePoolSpec), scope) }); err != nil { @@ -80,6 +75,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*MachinePoolSpec)(nil), (*v1beta2.MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(a.(*MachinePoolSpec), b.(*v1beta2.MachinePoolSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*MachinePoolStatus)(nil), (*v1beta2.MachinePoolStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_MachinePoolStatus_To_v1beta2_MachinePoolStatus(a.(*MachinePoolStatus), b.(*v1beta2.MachinePoolStatus), scope) }); err != nil { @@ -183,24 +183,18 @@ func autoConvert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *MachineP if err := Convert_v1beta1_MachineTemplateSpec_To_v1beta2_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) return nil } -// Convert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec is an autogenerated conversion function. -func Convert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *MachinePoolSpec, out *v1beta2.MachinePoolSpec, s conversion.Scope) error { - return autoConvert_v1beta1_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in, out, s) -} - func autoConvert_v1beta2_MachinePoolSpec_To_v1beta1_MachinePoolSpec(in *v1beta2.MachinePoolSpec, out *MachinePoolSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) if err := Convert_v1beta2_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) return nil diff --git a/exp/api/v1beta2/machinepool_types.go b/exp/api/v1beta2/machinepool_types.go index 54906108d988..4c502ae49ee1 100644 --- a/exp/api/v1beta2/machinepool_types.go +++ b/exp/api/v1beta2/machinepool_types.go @@ -48,13 +48,6 @@ type MachinePoolSpec struct { // +required Template clusterv1.MachineTemplateSpec `json:"template"` - // minReadySeconds is the minimum number of seconds for which a newly created machine instances should - // be ready. - // Defaults to 0 (machine instance will be considered available as soon as it - // is ready) - // +optional - MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` - // providerIDList are the identification IDs of machine instances provided by the provider. // This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. // +optional diff --git a/exp/api/v1beta2/zz_generated.deepcopy.go b/exp/api/v1beta2/zz_generated.deepcopy.go index 8ac7af8383ce..3d6f19f82f3c 100644 --- a/exp/api/v1beta2/zz_generated.deepcopy.go +++ b/exp/api/v1beta2/zz_generated.deepcopy.go @@ -131,11 +131,6 @@ func (in *MachinePoolSpec) DeepCopyInto(out *MachinePoolSpec) { **out = **in } in.Template.DeepCopyInto(&out.Template) - if in.MinReadySeconds != nil { - in, out := &in.MinReadySeconds, &out.MinReadySeconds - *out = new(int32) - **out = **in - } if in.ProviderIDList != nil { in, out := &in.ProviderIDList, &out.ProviderIDList *out = make([]string, len(*in)) diff --git a/exp/internal/controllers/machinepool_controller_noderef.go b/exp/internal/controllers/machinepool_controller_noderef.go index 364206e10625..fed15776f8b4 100644 --- a/exp/internal/controllers/machinepool_controller_noderef.go +++ b/exp/internal/controllers/machinepool_controller_noderef.go @@ -26,6 +26,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog/v2" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -94,8 +95,7 @@ func (r *MachinePoolReconciler) reconcileNodeRefs(ctx context.Context, s *scope) return ctrl.Result{}, errors.New("failed to get Node references") } - // Get the Node references. - nodeRefsResult, err := r.getNodeReferences(ctx, mp.Spec.ProviderIDList, mp.Spec.MinReadySeconds, s.nodeRefMap) + nodeRefsResult, err := r.getNodeReferences(ctx, mp.Spec.ProviderIDList, ptr.Deref(mp.Spec.Template.Spec.MinReadySeconds, 0), s.nodeRefMap) if err != nil { if err == errNoAvailableNodes { log.Info("Cannot assign NodeRefs to MachinePool, no matching Nodes") @@ -172,7 +172,7 @@ func (r *MachinePoolReconciler) deleteRetiredNodes(ctx context.Context, c client return nil } -func (r *MachinePoolReconciler) getNodeReferences(ctx context.Context, providerIDList []string, minReadySeconds *int32, nodeRefsMap map[string]*corev1.Node) (getNodeReferencesResult, error) { +func (r *MachinePoolReconciler) getNodeReferences(ctx context.Context, providerIDList []string, minReadySeconds int32, nodeRefsMap map[string]*corev1.Node) (getNodeReferencesResult, error) { log := ctrl.LoggerFrom(ctx, "providerIDList", len(providerIDList)) var ready, available int @@ -186,7 +186,7 @@ func (r *MachinePoolReconciler) getNodeReferences(ctx context.Context, providerI if node, ok := nodeRefsMap[providerID]; ok { if noderefutil.IsNodeReady(node) { ready++ - if noderefutil.IsNodeAvailable(node, *minReadySeconds, metav1.Now()) { + if noderefutil.IsNodeAvailable(node, minReadySeconds, metav1.Now()) { available++ } } diff --git a/exp/internal/controllers/machinepool_controller_noderef_test.go b/exp/internal/controllers/machinepool_controller_noderef_test.go index 7ff826abab21..9452d1344aa5 100644 --- a/exp/internal/controllers/machinepool_controller_noderef_test.go +++ b/exp/internal/controllers/machinepool_controller_noderef_test.go @@ -23,7 +23,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" - "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -281,7 +280,7 @@ func TestMachinePoolGetNodeReference(t *testing.T) { t.Run(test.name, func(t *testing.T) { g := NewWithT(t) - result, err := r.getNodeReferences(ctx, test.providerIDList, ptr.To(test.minReadySeconds), nodeRefsMap) + result, err := r.getNodeReferences(ctx, test.providerIDList, test.minReadySeconds, nodeRefsMap) if test.err == nil { g.Expect(err).ToNot(HaveOccurred()) } else { diff --git a/exp/internal/controllers/machinepool_controller_phases_test.go b/exp/internal/controllers/machinepool_controller_phases_test.go index 077c6ab108a6..63f1dab8bb66 100644 --- a/exp/internal/controllers/machinepool_controller_phases_test.go +++ b/exp/internal/controllers/machinepool_controller_phases_test.go @@ -1761,7 +1761,6 @@ func TestReconcileMachinePoolScaleToFromZero(t *testing.T) { }, }, }, - MinReadySeconds: ptr.To[int32](0), }, Status: expv1.MachinePoolStatus{}, } diff --git a/exp/internal/webhooks/machinepool.go b/exp/internal/webhooks/machinepool.go index bed24303fbb2..ff097ea83236 100644 --- a/exp/internal/webhooks/machinepool.go +++ b/exp/internal/webhooks/machinepool.go @@ -100,10 +100,6 @@ func (webhook *MachinePool) Default(ctx context.Context, obj runtime.Object) err m.Spec.Replicas = ptr.To[int32](replicas) - if m.Spec.MinReadySeconds == nil { - m.Spec.MinReadySeconds = ptr.To[int32](0) - } - if m.Spec.Template.Spec.Bootstrap.ConfigRef != nil && m.Spec.Template.Spec.Bootstrap.ConfigRef.Namespace == "" { m.Spec.Template.Spec.Bootstrap.ConfigRef.Namespace = m.Namespace } @@ -122,6 +118,7 @@ func (webhook *MachinePool) Default(ctx context.Context, obj runtime.Object) err normalizedVersion := "v" + *m.Spec.Template.Spec.Version m.Spec.Template.Spec.Version = &normalizedVersion } + return nil } diff --git a/exp/internal/webhooks/machinepool_test.go b/exp/internal/webhooks/machinepool_test.go index 4e6791fceb38..f46f959a8e6a 100644 --- a/exp/internal/webhooks/machinepool_test.go +++ b/exp/internal/webhooks/machinepool_test.go @@ -58,7 +58,6 @@ func TestMachinePoolDefault(t *testing.T) { g.Expect(mp.Labels[clusterv1.ClusterNameLabel]).To(Equal(mp.Spec.ClusterName)) g.Expect(mp.Spec.Replicas).To(Equal(ptr.To[int32](1))) - g.Expect(mp.Spec.MinReadySeconds).To(Equal(ptr.To[int32](0))) g.Expect(mp.Spec.Template.Spec.Bootstrap.ConfigRef.Namespace).To(Equal(mp.Namespace)) g.Expect(mp.Spec.Template.Spec.InfrastructureRef.Namespace).To(Equal(mp.Namespace)) g.Expect(mp.Spec.Template.Spec.Version).To(Equal(ptr.To("v1.20.0"))) diff --git a/exp/topology/desiredstate/desired_state.go b/exp/topology/desiredstate/desired_state.go index 8d505447c81c..3f2308a37e1c 100644 --- a/exp/topology/desiredstate/desired_state.go +++ b/exp/topology/desiredstate/desired_state.go @@ -814,9 +814,8 @@ func (g *generator) computeMachineDeployment(ctx context.Context, s *scope.Scope Namespace: s.Current.Cluster.Namespace, }, Spec: clusterv1.MachineDeploymentSpec{ - ClusterName: s.Current.Cluster.Name, - MinReadySeconds: minReadySeconds, - Strategy: strategy, + ClusterName: s.Current.Cluster.Name, + Strategy: strategy, Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ ClusterName: s.Current.Cluster.Name, @@ -828,6 +827,7 @@ func (g *generator) computeMachineDeployment(ctx context.Context, s *scope.Scope NodeVolumeDetachTimeout: nodeVolumeDetachTimeout, NodeDeletionTimeout: nodeDeletionTimeout, ReadinessGates: readinessGates, + MinReadySeconds: minReadySeconds, }, }, }, @@ -1135,9 +1135,8 @@ func (g *generator) computeMachinePool(_ context.Context, s *scope.Scope, machin Namespace: s.Current.Cluster.Namespace, }, Spec: expv1.MachinePoolSpec{ - ClusterName: s.Current.Cluster.Name, - MinReadySeconds: minReadySeconds, - FailureDomains: failureDomains, + ClusterName: s.Current.Cluster.Name, + FailureDomains: failureDomains, Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ ClusterName: s.Current.Cluster.Name, @@ -1147,6 +1146,7 @@ func (g *generator) computeMachinePool(_ context.Context, s *scope.Scope, machin NodeDrainTimeout: nodeDrainTimeout, NodeVolumeDetachTimeout: nodeVolumeDetachTimeout, NodeDeletionTimeout: nodeDeletionTimeout, + MinReadySeconds: minReadySeconds, }, }, }, diff --git a/exp/topology/desiredstate/desired_state_test.go b/exp/topology/desiredstate/desired_state_test.go index 48f09cba408d..179d04e998ba 100644 --- a/exp/topology/desiredstate/desired_state_test.go +++ b/exp/topology/desiredstate/desired_state_test.go @@ -1568,8 +1568,8 @@ func TestComputeMachineDeployment(t *testing.T) { actualMd := actual.Object g.Expect(*actualMd.Spec.Replicas).To(Equal(replicas)) - g.Expect(*actualMd.Spec.MinReadySeconds).To(Equal(topologyMinReadySeconds)) g.Expect(*actualMd.Spec.Strategy).To(BeComparableTo(topologyStrategy)) + g.Expect(actualMd.Spec.Template.Spec.MinReadySeconds).To(HaveValue(Equal(topologyMinReadySeconds))) g.Expect(*actualMd.Spec.Template.Spec.FailureDomain).To(Equal(topologyFailureDomain)) g.Expect(*actualMd.Spec.Template.Spec.NodeDrainTimeout).To(Equal(topologyDuration)) g.Expect(*actualMd.Spec.Template.Spec.NodeVolumeDetachTimeout).To(Equal(topologyDuration)) @@ -1626,8 +1626,8 @@ func TestComputeMachineDeployment(t *testing.T) { // checking only values from CC defaults actualMd := actual.Object - g.Expect(*actualMd.Spec.MinReadySeconds).To(Equal(clusterClassMinReadySeconds)) g.Expect(*actualMd.Spec.Strategy).To(BeComparableTo(clusterClassStrategy)) + g.Expect(actualMd.Spec.Template.Spec.MinReadySeconds).To(HaveValue(Equal(clusterClassMinReadySeconds))) g.Expect(*actualMd.Spec.Template.Spec.FailureDomain).To(Equal(clusterClassFailureDomain)) g.Expect(actualMd.Spec.Template.Spec.ReadinessGates).To(Equal(clusterClassReadinessGates)) g.Expect(*actualMd.Spec.Template.Spec.NodeDrainTimeout).To(Equal(clusterClassDuration)) @@ -2031,8 +2031,8 @@ func TestComputeMachinePool(t *testing.T) { actualMp := actual.Object g.Expect(*actualMp.Spec.Replicas).To(Equal(replicas)) - g.Expect(*actualMp.Spec.MinReadySeconds).To(Equal(topologyMinReadySeconds)) g.Expect(actualMp.Spec.FailureDomains).To(Equal(topologyFailureDomains)) + g.Expect(actualMp.Spec.Template.Spec.MinReadySeconds).To(HaveValue(Equal(topologyMinReadySeconds))) g.Expect(*actualMp.Spec.Template.Spec.NodeDrainTimeout).To(Equal(topologyDuration)) g.Expect(*actualMp.Spec.Template.Spec.NodeVolumeDetachTimeout).To(Equal(topologyDuration)) g.Expect(*actualMp.Spec.Template.Spec.NodeDeletionTimeout).To(Equal(topologyDuration)) @@ -2082,8 +2082,8 @@ func TestComputeMachinePool(t *testing.T) { // checking only values from CC defaults actualMp := actual.Object - g.Expect(*actualMp.Spec.MinReadySeconds).To(Equal(clusterClassMinReadySeconds)) g.Expect(actualMp.Spec.FailureDomains).To(Equal(clusterClassFailureDomains)) + g.Expect(actualMp.Spec.Template.Spec.MinReadySeconds).To(HaveValue(Equal(clusterClassMinReadySeconds))) g.Expect(*actualMp.Spec.Template.Spec.NodeDrainTimeout).To(Equal(clusterClassDuration)) g.Expect(*actualMp.Spec.Template.Spec.NodeVolumeDetachTimeout).To(Equal(clusterClassDuration)) g.Expect(*actualMp.Spec.Template.Spec.NodeDeletionTimeout).To(Equal(clusterClassDuration)) diff --git a/internal/apis/core/exp/v1alpha3/conversion.go b/internal/apis/core/exp/v1alpha3/conversion.go index 0896318c12c8..b61331a6f4f3 100644 --- a/internal/apis/core/exp/v1alpha3/conversion.go +++ b/internal/apis/core/exp/v1alpha3/conversion.go @@ -93,11 +93,14 @@ func (src *MachinePool) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Initialization.InfrastructureProvisioned = src.Status.InfrastructureReady } + dst.Spec.Template.Spec.MinReadySeconds = src.Spec.MinReadySeconds + // Manually restore data. restored := &expv1.MachinePool{} if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { return err } + dst.Spec.Template.Spec.ReadinessGates = restored.Spec.Template.Spec.ReadinessGates dst.Spec.Template.Spec.NodeDeletionTimeout = restored.Spec.Template.Spec.NodeDeletionTimeout dst.Spec.Template.Spec.NodeVolumeDetachTimeout = restored.Spec.Template.Spec.NodeVolumeDetachTimeout @@ -145,6 +148,8 @@ func (dst *MachinePool) ConvertFrom(srcRaw conversion.Hub) error { dst.Status.InfrastructureReady = src.Status.Initialization.InfrastructureProvisioned } + dst.Spec.MinReadySeconds = src.Spec.Template.Spec.MinReadySeconds + return utilconversion.MarshalData(src, dst) } diff --git a/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go b/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go index c9f4bf10f863..569b0e84551f 100644 --- a/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go +++ b/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go @@ -174,7 +174,7 @@ func autoConvert_v1alpha3_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *Machine return err } // WARNING: in.Strategy requires manual conversion: does not exist in peer-type - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) return nil @@ -186,7 +186,6 @@ func autoConvert_v1beta2_MachinePoolSpec_To_v1alpha3_MachinePoolSpec(in *v1beta2 if err := Convert_v1beta2_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) return nil diff --git a/internal/apis/core/exp/v1alpha4/conversion.go b/internal/apis/core/exp/v1alpha4/conversion.go index cf80399f863b..96f87f5cde5e 100644 --- a/internal/apis/core/exp/v1alpha4/conversion.go +++ b/internal/apis/core/exp/v1alpha4/conversion.go @@ -58,6 +58,7 @@ func (src *MachinePool) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Initialization.BootstrapDataSecretCreated = src.Status.BootstrapReady dst.Status.Initialization.InfrastructureProvisioned = src.Status.InfrastructureReady } + dst.Spec.Template.Spec.MinReadySeconds = src.Spec.MinReadySeconds // Manually restore data. restored := &expv1.MachinePool{} @@ -111,6 +112,8 @@ func (dst *MachinePool) ConvertFrom(srcRaw conversion.Hub) error { dst.Status.InfrastructureReady = src.Status.Initialization.InfrastructureProvisioned } + dst.Spec.MinReadySeconds = src.Spec.Template.Spec.MinReadySeconds + // Preserve Hub data on down-conversion except for metadata return utilconversion.MarshalData(src, dst) } @@ -141,3 +144,7 @@ func Convert_v1_Condition_To_v1alpha4_Condition(in *metav1.Condition, out *clust func Convert_v1alpha4_Condition_To_v1_Condition(in *clusterv1alpha4.Condition, out *metav1.Condition, s apimachineryconversion.Scope) error { return clusterv1alpha4.Convert_v1alpha4_Condition_To_v1_Condition(in, out, s) } + +func Convert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *MachinePoolSpec, out *expv1.MachinePoolSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in, out, s) +} diff --git a/internal/apis/core/exp/v1alpha4/zz_generated.conversion.go b/internal/apis/core/exp/v1alpha4/zz_generated.conversion.go index d8ae37421c6d..177a2c16d5ee 100644 --- a/internal/apis/core/exp/v1alpha4/zz_generated.conversion.go +++ b/internal/apis/core/exp/v1alpha4/zz_generated.conversion.go @@ -60,11 +60,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*MachinePoolSpec)(nil), (*v1beta2.MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(a.(*MachinePoolSpec), b.(*v1beta2.MachinePoolSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*v1beta2.MachinePoolSpec)(nil), (*MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_MachinePoolSpec_To_v1alpha4_MachinePoolSpec(a.(*v1beta2.MachinePoolSpec), b.(*MachinePoolSpec), scope) }); err != nil { @@ -80,6 +75,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*MachinePoolSpec)(nil), (*v1beta2.MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(a.(*MachinePoolSpec), b.(*v1beta2.MachinePoolSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*MachinePoolStatus)(nil), (*v1beta2.MachinePoolStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_MachinePoolStatus_To_v1beta2_MachinePoolStatus(a.(*MachinePoolStatus), b.(*v1beta2.MachinePoolStatus), scope) }); err != nil { @@ -183,24 +183,18 @@ func autoConvert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *Machine if err := Convert_v1alpha4_MachineTemplateSpec_To_v1beta2_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) return nil } -// Convert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec is an autogenerated conversion function. -func Convert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in *MachinePoolSpec, out *v1beta2.MachinePoolSpec, s conversion.Scope) error { - return autoConvert_v1alpha4_MachinePoolSpec_To_v1beta2_MachinePoolSpec(in, out, s) -} - func autoConvert_v1beta2_MachinePoolSpec_To_v1alpha4_MachinePoolSpec(in *v1beta2.MachinePoolSpec, out *MachinePoolSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) if err := Convert_v1beta2_MachineTemplateSpec_To_v1alpha4_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) return nil diff --git a/internal/apis/core/v1alpha3/conversion.go b/internal/apis/core/v1alpha3/conversion.go index 1e8b0a7fec9c..f65a7d417112 100644 --- a/internal/apis/core/v1alpha3/conversion.go +++ b/internal/apis/core/v1alpha3/conversion.go @@ -21,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apimachineryconversion "k8s.io/apimachinery/pkg/conversion" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" @@ -161,6 +162,7 @@ func (src *Machine) ConvertTo(dstRaw conversion.Hub) error { return err } + dst.Spec.MinReadySeconds = restored.Spec.MinReadySeconds dst.Spec.ReadinessGates = restored.Spec.ReadinessGates dst.Spec.NodeDeletionTimeout = restored.Spec.NodeDeletionTimeout dst.Spec.NodeVolumeDetachTimeout = restored.Spec.NodeVolumeDetachTimeout @@ -228,6 +230,12 @@ func (src *MachineSet) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Deprecated.V1Beta1.AvailableReplicas = src.Status.AvailableReplicas dst.Status.Deprecated.V1Beta1.FullyLabeledReplicas = src.Status.FullyLabeledReplicas + if src.Spec.MinReadySeconds == 0 { + dst.Spec.Template.Spec.MinReadySeconds = nil + } else { + dst.Spec.Template.Spec.MinReadySeconds = &src.Spec.MinReadySeconds + } + // Manually restore data. restored := &clusterv1.MachineSet{} if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { @@ -273,6 +281,8 @@ func (dst *MachineSet) ConvertFrom(srcRaw conversion.Hub) error { } } + dst.Spec.MinReadySeconds = ptr.Deref(src.Spec.Template.Spec.MinReadySeconds, 0) + // Preserve Hub data on down-conversion except for metadata if err := utilconversion.MarshalData(src, dst); err != nil { return err @@ -299,6 +309,8 @@ func (src *MachineDeployment) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Deprecated.V1Beta1.UpdatedReplicas = src.Status.UpdatedReplicas dst.Status.Deprecated.V1Beta1.UnavailableReplicas = src.Status.UnavailableReplicas + dst.Spec.Template.Spec.MinReadySeconds = src.Spec.MinReadySeconds + // Manually restore data. restored := &clusterv1.MachineDeployment{} if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { @@ -359,6 +371,8 @@ func (dst *MachineDeployment) ConvertFrom(srcRaw conversion.Hub) error { } } + dst.Spec.MinReadySeconds = src.Spec.Template.Spec.MinReadySeconds + // Preserve Hub data on down-conversion except for metadata if err := utilconversion.MarshalData(src, dst); err != nil { return err @@ -435,7 +449,7 @@ func Convert_v1beta2_MachineSetStatus_To_v1alpha3_MachineSetStatus(in *clusterv1 func Convert_v1beta2_ClusterSpec_To_v1alpha3_ClusterSpec(in *clusterv1.ClusterSpec, out *ClusterSpec, s apimachineryconversion.Scope) error { // NOTE: custom conversion func is required because spec.Topology does not exist in v1alpha3 - // AvailabilityGates was added in v1beta1. + // AvailabilityGates was added in v1beta1 return autoConvert_v1beta2_ClusterSpec_To_v1alpha3_ClusterSpec(in, out, s) } @@ -567,3 +581,7 @@ func Convert_v1alpha3_Conditions_To_v1beta2_Deprecated_V1Beta1_Conditions(in *Co (*out)[i] = *(*clusterv1.Condition)(unsafe.Pointer(&(*in)[i])) } } + +func Convert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *clusterv1.MachineSetSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(in, out, s) +} diff --git a/internal/apis/core/v1alpha3/zz_generated.conversion.go b/internal/apis/core/v1alpha3/zz_generated.conversion.go index b3c65aa871e7..c535a3bf4cca 100644 --- a/internal/apis/core/v1alpha3/zz_generated.conversion.go +++ b/internal/apis/core/v1alpha3/zz_generated.conversion.go @@ -214,11 +214,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*MachineSetSpec)(nil), (*v1beta2.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta2.MachineSetSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*MachineSpec)(nil), (*v1beta2.MachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_MachineSpec_To_v1beta2_MachineSpec(a.(*MachineSpec), b.(*v1beta2.MachineSpec), scope) }); err != nil { @@ -284,6 +279,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*MachineSetSpec)(nil), (*v1beta2.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta2.MachineSetSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*MachineSetStatus)(nil), (*v1beta2.MachineSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_MachineSetStatus_To_v1beta2_MachineSetStatus(a.(*MachineSetStatus), b.(*v1beta2.MachineSetStatus), scope) }); err != nil { @@ -772,7 +772,7 @@ func autoConvert_v1alpha3_MachineDeploymentSpec_To_v1beta2_MachineDeploymentSpec } else { out.Strategy = nil } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused // WARNING: in.ProgressDeadlineSeconds requires manual conversion: does not exist in peer-type @@ -797,7 +797,6 @@ func autoConvert_v1beta2_MachineDeploymentSpec_To_v1alpha3_MachineDeploymentSpec out.Strategy = nil } // WARNING: in.MachineNamingStrategy requires manual conversion: does not exist in peer-type - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused return nil @@ -1148,7 +1147,7 @@ func Convert_v1beta2_MachineSetList_To_v1alpha3_MachineSetList(in *v1beta2.Machi func autoConvert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *v1beta2.MachineSetSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) - out.MinReadySeconds = in.MinReadySeconds + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.DeletePolicy = in.DeletePolicy out.Selector = in.Selector if err := Convert_v1alpha3_MachineTemplateSpec_To_v1beta2_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { @@ -1157,15 +1156,9 @@ func autoConvert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSe return nil } -// Convert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec is an autogenerated conversion function. -func Convert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *v1beta2.MachineSetSpec, s conversion.Scope) error { - return autoConvert_v1alpha3_MachineSetSpec_To_v1beta2_MachineSetSpec(in, out, s) -} - func autoConvert_v1beta2_MachineSetSpec_To_v1alpha3_MachineSetSpec(in *v1beta2.MachineSetSpec, out *MachineSetSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) - out.MinReadySeconds = in.MinReadySeconds out.DeletePolicy = in.DeletePolicy out.Selector = in.Selector if err := Convert_v1beta2_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { @@ -1234,6 +1227,7 @@ func autoConvert_v1beta2_MachineSpec_To_v1alpha3_MachineSpec(in *v1beta2.Machine out.Version = (*string)(unsafe.Pointer(in.Version)) out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) out.FailureDomain = (*string)(unsafe.Pointer(in.FailureDomain)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type // WARNING: in.ReadinessGates requires manual conversion: does not exist in peer-type out.NodeDrainTimeout = (*v1.Duration)(unsafe.Pointer(in.NodeDrainTimeout)) // WARNING: in.NodeVolumeDetachTimeout requires manual conversion: does not exist in peer-type diff --git a/internal/apis/core/v1alpha4/conversion.go b/internal/apis/core/v1alpha4/conversion.go index 586b54e02bac..6b457a274ffa 100644 --- a/internal/apis/core/v1alpha4/conversion.go +++ b/internal/apis/core/v1alpha4/conversion.go @@ -21,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apimachineryconversion "k8s.io/apimachinery/pkg/conversion" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta2" @@ -249,6 +250,7 @@ func (src *Machine) ConvertTo(dstRaw conversion.Hub) error { return err } + dst.Spec.MinReadySeconds = restored.Spec.MinReadySeconds dst.Spec.ReadinessGates = restored.Spec.ReadinessGates dst.Spec.NodeDeletionTimeout = restored.Spec.NodeDeletionTimeout dst.Status.CertificatesExpiryDate = restored.Status.CertificatesExpiryDate @@ -318,6 +320,12 @@ func (src *MachineSet) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Deprecated.V1Beta1.AvailableReplicas = src.Status.AvailableReplicas dst.Status.Deprecated.V1Beta1.FullyLabeledReplicas = src.Status.FullyLabeledReplicas + if src.Spec.MinReadySeconds == 0 { + dst.Spec.Template.Spec.MinReadySeconds = nil + } else { + dst.Spec.Template.Spec.MinReadySeconds = &src.Spec.MinReadySeconds + } + // Manually restore data. restored := &clusterv1.MachineSet{} if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { @@ -369,6 +377,8 @@ func (dst *MachineSet) ConvertFrom(srcRaw conversion.Hub) error { } } + dst.Spec.MinReadySeconds = ptr.Deref(src.Spec.Template.Spec.MinReadySeconds, 0) + // Preserve Hub data on down-conversion except for metadata return utilconversion.MarshalData(src, dst) } @@ -395,6 +405,8 @@ func (src *MachineDeployment) ConvertTo(dstRaw conversion.Hub) error { dst.Status.Deprecated.V1Beta1.UpdatedReplicas = src.Status.UpdatedReplicas dst.Status.Deprecated.V1Beta1.UnavailableReplicas = src.Status.UnavailableReplicas + dst.Spec.Template.Spec.MinReadySeconds = src.Spec.MinReadySeconds + // Manually restore data. restored := &clusterv1.MachineDeployment{} if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { @@ -453,6 +465,8 @@ func (dst *MachineDeployment) ConvertFrom(srcRaw conversion.Hub) error { } } + dst.Spec.MinReadySeconds = src.Spec.Template.Spec.MinReadySeconds + // Preserve Hub data on down-conversion except for metadata return utilconversion.MarshalData(src, dst) } @@ -711,3 +725,7 @@ func Convert_v1alpha4_Conditions_To_v1beta2_Deprecated_V1Beta1_Conditions(in *Co (*out)[i] = *(*clusterv1.Condition)(unsafe.Pointer(&(*in)[i])) } } + +func Convert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *clusterv1.MachineSetSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(in, out, s) +} diff --git a/internal/apis/core/v1alpha4/zz_generated.conversion.go b/internal/apis/core/v1alpha4/zz_generated.conversion.go index 8156f2ad427e..3635bf7c9209 100644 --- a/internal/apis/core/v1alpha4/zz_generated.conversion.go +++ b/internal/apis/core/v1alpha4/zz_generated.conversion.go @@ -284,11 +284,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*MachineSetSpec)(nil), (*v1beta2.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta2.MachineSetSpec), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*MachineSpec)(nil), (*v1beta2.MachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_MachineSpec_To_v1beta2_MachineSpec(a.(*MachineSpec), b.(*v1beta2.MachineSpec), scope) }); err != nil { @@ -369,6 +364,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*MachineSetSpec)(nil), (*v1beta2.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta2.MachineSetSpec), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*MachineSetStatus)(nil), (*v1beta2.MachineSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_MachineSetStatus_To_v1beta2_MachineSetStatus(a.(*MachineSetStatus), b.(*v1beta2.MachineSetStatus), scope) }); err != nil { @@ -1166,7 +1166,7 @@ func autoConvert_v1alpha4_MachineDeploymentSpec_To_v1beta2_MachineDeploymentSpec } else { out.Strategy = nil } - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused // WARNING: in.ProgressDeadlineSeconds requires manual conversion: does not exist in peer-type @@ -1191,7 +1191,6 @@ func autoConvert_v1beta2_MachineDeploymentSpec_To_v1alpha4_MachineDeploymentSpec out.Strategy = nil } // WARNING: in.MachineNamingStrategy requires manual conversion: does not exist in peer-type - out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) out.Paused = in.Paused return nil @@ -1588,7 +1587,7 @@ func Convert_v1beta2_MachineSetList_To_v1alpha4_MachineSetList(in *v1beta2.Machi func autoConvert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *v1beta2.MachineSetSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) - out.MinReadySeconds = in.MinReadySeconds + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type out.DeletePolicy = in.DeletePolicy out.Selector = in.Selector if err := Convert_v1alpha4_MachineTemplateSpec_To_v1beta2_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { @@ -1597,15 +1596,9 @@ func autoConvert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSe return nil } -// Convert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec is an autogenerated conversion function. -func Convert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(in *MachineSetSpec, out *v1beta2.MachineSetSpec, s conversion.Scope) error { - return autoConvert_v1alpha4_MachineSetSpec_To_v1beta2_MachineSetSpec(in, out, s) -} - func autoConvert_v1beta2_MachineSetSpec_To_v1alpha4_MachineSetSpec(in *v1beta2.MachineSetSpec, out *MachineSetSpec, s conversion.Scope) error { out.ClusterName = in.ClusterName out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) - out.MinReadySeconds = in.MinReadySeconds out.DeletePolicy = in.DeletePolicy out.Selector = in.Selector if err := Convert_v1beta2_MachineTemplateSpec_To_v1alpha4_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { @@ -1695,6 +1688,7 @@ func autoConvert_v1beta2_MachineSpec_To_v1alpha4_MachineSpec(in *v1beta2.Machine out.Version = (*string)(unsafe.Pointer(in.Version)) out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) out.FailureDomain = (*string)(unsafe.Pointer(in.FailureDomain)) + // WARNING: in.MinReadySeconds requires manual conversion: does not exist in peer-type // WARNING: in.ReadinessGates requires manual conversion: does not exist in peer-type out.NodeDrainTimeout = (*v1.Duration)(unsafe.Pointer(in.NodeDrainTimeout)) // WARNING: in.NodeVolumeDetachTimeout requires manual conversion: does not exist in peer-type diff --git a/internal/controllers/machine/machine_controller_status.go b/internal/controllers/machine/machine_controller_status.go index 575ca851d828..9ab7588ca2da 100644 --- a/internal/controllers/machine/machine_controller_status.go +++ b/internal/controllers/machine/machine_controller_status.go @@ -764,7 +764,7 @@ func setAvailableCondition(ctx context.Context, machine *clusterv1.Machine) { return } - if time.Since(readyCondition.LastTransitionTime.Time) >= 0*time.Second { // TODO: use MinReadySeconds as soon as it is available (and fix corresponding unit test) + if time.Since(readyCondition.LastTransitionTime.Time) >= time.Duration(ptr.Deref(machine.Spec.MinReadySeconds, 0))*time.Second { conditions.Set(machine, metav1.Condition{ Type: clusterv1.MachineAvailableCondition, Status: metav1.ConditionTrue, diff --git a/internal/controllers/machinedeployment/machinedeployment_controller_test.go b/internal/controllers/machinedeployment/machinedeployment_controller_test.go index 5327d9f5f830..8838316da36d 100644 --- a/internal/controllers/machinedeployment/machinedeployment_controller_test.go +++ b/internal/controllers/machinedeployment/machinedeployment_controller_test.go @@ -107,7 +107,6 @@ func TestMachineDeploymentReconciler(t *testing.T) { }, Spec: clusterv1.MachineDeploymentSpec{ ClusterName: testCluster.Name, - MinReadySeconds: ptr.To[int32](0), Replicas: ptr.To[int32](2), RevisionHistoryLimit: ptr.To[int32](0), Selector: metav1.LabelSelector{ @@ -536,7 +535,6 @@ func TestMachineDeploymentReconciler_CleanUpManagedFieldsForSSAAdoption(t *testi Spec: clusterv1.MachineDeploymentSpec{ Paused: true, // Set this to true as we do not want to test the other parts of the reconciler in this test. ClusterName: testCluster.Name, - MinReadySeconds: ptr.To[int32](0), Replicas: ptr.To[int32](2), RevisionHistoryLimit: ptr.To[int32](0), Selector: metav1.LabelSelector{ @@ -617,9 +615,8 @@ func TestMachineDeploymentReconciler_CleanUpManagedFieldsForSSAAdoption(t *testi Labels: labels, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testCluster.Name, - Replicas: ptr.To[int32](0), - MinReadySeconds: 0, + ClusterName: testCluster.Name, + Replicas: ptr.To[int32](0), Selector: metav1.LabelSelector{ MatchLabels: labels, }, diff --git a/internal/controllers/machinedeployment/machinedeployment_sync.go b/internal/controllers/machinedeployment/machinedeployment_sync.go index 7ea66b4d7284..5b5d24bbc0e5 100644 --- a/internal/controllers/machinedeployment/machinedeployment_sync.go +++ b/internal/controllers/machinedeployment/machinedeployment_sync.go @@ -320,7 +320,7 @@ func (r *Reconciler) computeDesiredMachineSet(ctx context.Context, deployment *c desiredMS.Spec.Template.Annotations = cloneStringMap(deployment.Spec.Template.Annotations) // Set all other in-place mutable fields. - desiredMS.Spec.MinReadySeconds = ptr.Deref(deployment.Spec.MinReadySeconds, 0) + desiredMS.Spec.Template.Spec.MinReadySeconds = deployment.Spec.Template.Spec.MinReadySeconds if deployment.Spec.Strategy != nil && deployment.Spec.Strategy.RollingUpdate != nil { desiredMS.Spec.DeletePolicy = ptr.Deref(deployment.Spec.Strategy.RollingUpdate.DeletePolicy, "") } else { diff --git a/internal/controllers/machinedeployment/machinedeployment_sync_test.go b/internal/controllers/machinedeployment/machinedeployment_sync_test.go index b2ec72f49cec..f509f2a90ab2 100644 --- a/internal/controllers/machinedeployment/machinedeployment_sync_test.go +++ b/internal/controllers/machinedeployment/machinedeployment_sync_test.go @@ -539,9 +539,8 @@ func TestComputeDesiredMachineSet(t *testing.T) { Annotations: map[string]string{"top-level-annotation": "top-level-annotation-value"}, }, Spec: clusterv1.MachineDeploymentSpec{ - ClusterName: "test-cluster", - Replicas: ptr.To[int32](3), - MinReadySeconds: ptr.To[int32](10), + ClusterName: "test-cluster", + Replicas: ptr.To[int32](3), Strategy: &clusterv1.MachineDeploymentStrategy{ Type: clusterv1.RollingUpdateMachineDeploymentStrategyType, RollingUpdate: &clusterv1.MachineRollingUpdateDeployment{ @@ -567,6 +566,7 @@ func TestComputeDesiredMachineSet(t *testing.T) { Bootstrap: clusterv1.Bootstrap{ ConfigRef: &bootstrapRef, }, + MinReadySeconds: ptr.To[int32](3), ReadinessGates: []clusterv1.MachineReadinessGate{{ConditionType: "foo"}}, NodeDrainTimeout: duration10s, NodeVolumeDetachTimeout: duration10s, @@ -583,12 +583,11 @@ func TestComputeDesiredMachineSet(t *testing.T) { Annotations: map[string]string{"top-level-annotation": "top-level-annotation-value"}, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: "test-cluster", - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, - DeletePolicy: string(clusterv1.RandomMachineSetDeletePolicy), - Selector: metav1.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}}, - Template: *deployment.Spec.Template.DeepCopy(), + ClusterName: "test-cluster", + Replicas: ptr.To[int32](3), + DeletePolicy: string(clusterv1.RandomMachineSetDeletePolicy), + Selector: metav1.LabelSelector{MatchLabels: map[string]string{"k1": "v1"}}, + Template: *deployment.Spec.Template.DeepCopy(), MachineNamingStrategy: &clusterv1.MachineNamingStrategy{ Template: "{{ .machineSet.name }}" + namingTemplateKey + "-{{ .random }}", }, @@ -643,7 +642,7 @@ func TestComputeDesiredMachineSet(t *testing.T) { existingMS.Spec.Template.Spec.NodeDeletionTimeout = duration5s existingMS.Spec.Template.Spec.NodeVolumeDetachTimeout = duration5s existingMS.Spec.DeletePolicy = string(clusterv1.NewestMachineSetDeletePolicy) - existingMS.Spec.MinReadySeconds = 0 + existingMS.Spec.Template.Spec.MinReadySeconds = ptr.To[int32](0) expectedMS := skeletonMSBasedOnMD.DeepCopy() expectedMS.UID = existingMSUID @@ -683,7 +682,7 @@ func TestComputeDesiredMachineSet(t *testing.T) { existingMS.Spec.Template.Spec.NodeDeletionTimeout = duration5s existingMS.Spec.Template.Spec.NodeVolumeDetachTimeout = duration5s existingMS.Spec.DeletePolicy = string(clusterv1.NewestMachineSetDeletePolicy) - existingMS.Spec.MinReadySeconds = 0 + existingMS.Spec.Template.Spec.MinReadySeconds = ptr.To[int32](0) oldMS := skeletonMSBasedOnMD.DeepCopy() oldMS.Spec.Replicas = ptr.To[int32](2) @@ -737,7 +736,7 @@ func TestComputeDesiredMachineSet(t *testing.T) { existingMS.Spec.Template.Spec.NodeDeletionTimeout = duration5s existingMS.Spec.Template.Spec.NodeVolumeDetachTimeout = duration5s existingMS.Spec.DeletePolicy = string(clusterv1.NewestMachineSetDeletePolicy) - existingMS.Spec.MinReadySeconds = 0 + existingMS.Spec.Template.Spec.MinReadySeconds = ptr.To[int32](0) expectedMS := skeletonMSBasedOnMD.DeepCopy() expectedMS.UID = existingMSUID @@ -797,7 +796,7 @@ func assertMachineSet(g *WithT, actualMS *clusterv1.MachineSet, expectedMS *clus } // Check MinReadySeconds - g.Expect(actualMS.Spec.MinReadySeconds).Should(Equal(expectedMS.Spec.MinReadySeconds)) + g.Expect(actualMS.Spec.Template.Spec.MinReadySeconds).Should(Equal(expectedMS.Spec.Template.Spec.MinReadySeconds)) // Check DeletePolicy g.Expect(actualMS.Spec.DeletePolicy).Should(Equal(expectedMS.Spec.DeletePolicy)) diff --git a/internal/controllers/machinedeployment/mdutil/util.go b/internal/controllers/machinedeployment/mdutil/util.go index e39f07c4f82d..5105b2523845 100644 --- a/internal/controllers/machinedeployment/mdutil/util.go +++ b/internal/controllers/machinedeployment/mdutil/util.go @@ -432,6 +432,7 @@ func MachineTemplateDeepCopyRolloutFields(template *clusterv1.MachineTemplateSpe templateCopy.Annotations = nil // Drop node timeout values + templateCopy.Spec.MinReadySeconds = nil templateCopy.Spec.ReadinessGates = nil templateCopy.Spec.NodeDrainTimeout = nil templateCopy.Spec.NodeDeletionTimeout = nil diff --git a/internal/controllers/machinedeployment/mdutil/util_test.go b/internal/controllers/machinedeployment/mdutil/util_test.go index f5228b732470..1489ae35abd7 100644 --- a/internal/controllers/machinedeployment/mdutil/util_test.go +++ b/internal/controllers/machinedeployment/mdutil/util_test.go @@ -184,6 +184,7 @@ func TestMachineTemplateUpToDate(t *testing.T) { ClusterName: "cluster1", Version: ptr.To("v1.25.0"), FailureDomain: ptr.To("failure-domain1"), + MinReadySeconds: ptr.To[int32](10), InfrastructureRef: corev1.ObjectReference{ Name: "infra1", Namespace: "default", @@ -220,6 +221,7 @@ func TestMachineTemplateUpToDate(t *testing.T) { machineTemplateWithDifferentInPlaceMutableSpecFields.Spec.NodeDrainTimeout = &metav1.Duration{Duration: 20 * time.Second} machineTemplateWithDifferentInPlaceMutableSpecFields.Spec.NodeDeletionTimeout = &metav1.Duration{Duration: 20 * time.Second} machineTemplateWithDifferentInPlaceMutableSpecFields.Spec.NodeVolumeDetachTimeout = &metav1.Duration{Duration: 20 * time.Second} + machineTemplateWithDifferentInPlaceMutableSpecFields.Spec.MinReadySeconds = ptr.To[int32](20) machineTemplateWithDifferentClusterName := machineTemplate.DeepCopy() machineTemplateWithDifferentClusterName.Spec.ClusterName = "cluster2" diff --git a/internal/controllers/machineset/machineset_controller.go b/internal/controllers/machineset/machineset_controller.go index e0389b0c5c8b..7e594e00e26d 100644 --- a/internal/controllers/machineset/machineset_controller.go +++ b/internal/controllers/machineset/machineset_controller.go @@ -517,6 +517,7 @@ func (r *Reconciler) syncMachines(ctx context.Context, s *scope) (ctrl.Result, e m.Spec.NodeDrainTimeout = machineSet.Spec.Template.Spec.NodeDrainTimeout m.Spec.NodeDeletionTimeout = machineSet.Spec.Template.Spec.NodeDeletionTimeout m.Spec.NodeVolumeDetachTimeout = machineSet.Spec.Template.Spec.NodeVolumeDetachTimeout + m.Spec.MinReadySeconds = machineSet.Spec.Template.Spec.MinReadySeconds // Set machine's up to date condition if upToDateCondition != nil { @@ -930,6 +931,7 @@ func (r *Reconciler) computeDesiredMachine(machineSet *clusterv1.MachineSet, exi desiredMachine.Spec.NodeDrainTimeout = machineSet.Spec.Template.Spec.NodeDrainTimeout desiredMachine.Spec.NodeDeletionTimeout = machineSet.Spec.Template.Spec.NodeDeletionTimeout desiredMachine.Spec.NodeVolumeDetachTimeout = machineSet.Spec.Template.Spec.NodeVolumeDetachTimeout + desiredMachine.Spec.MinReadySeconds = machineSet.Spec.Template.Spec.MinReadySeconds return desiredMachine, nil } @@ -1200,7 +1202,7 @@ func (r *Reconciler) reconcileV1Beta1Status(ctx context.Context, s *scope) error if noderefutil.IsNodeReady(node) { readyReplicasCount++ - if noderefutil.IsNodeAvailable(node, ms.Spec.MinReadySeconds, metav1.Now()) { + if noderefutil.IsNodeAvailable(node, ptr.Deref(ms.Spec.Template.Spec.MinReadySeconds, 0), metav1.Now()) { availableReplicasCount++ } } else if machine.GetDeletionTimestamp().IsZero() { @@ -1249,19 +1251,20 @@ func (r *Reconciler) reconcileV1Beta1Status(ctx context.Context, s *scope) error } func shouldRequeueForReplicaCountersRefresh(s *scope) ctrl.Result { + minReadySeconds := ptr.Deref(s.machineSet.Spec.Template.Spec.MinReadySeconds, 0) replicas := ptr.Deref(s.machineSet.Spec.Replicas, 0) - // Resync the MachineSet after MinReadySeconds as a last line of defense to guard against clock-skew. + // Resync the MachineSet after minReadySeconds as a last line of defense to guard against clock-skew. // Clock-skew is an issue as it may impact whether an available replica is counted as a ready replica. - // A replica is available if the amount of time since last transition exceeds MinReadySeconds. + // A replica is available if the amount of time since last transition exceeds minReadySeconds. // If there was a clock skew, checking whether the amount of time since last transition to ready state - // exceeds MinReadySeconds could be incorrect. - // To avoid an available replica stuck in the ready state, we force a reconcile after MinReadySeconds, + // exceeds minReadySeconds could be incorrect. + // To avoid an available replica stuck in the ready state, we force a reconcile after minReadySeconds, // at which point it should confirm any available replica to be available. - if s.machineSet.Spec.MinReadySeconds > 0 && + if minReadySeconds > 0 && ptr.Deref(s.machineSet.Status.ReadyReplicas, 0) == replicas && ptr.Deref(s.machineSet.Status.AvailableReplicas, 0) != replicas { - minReadyResult := ctrl.Result{RequeueAfter: time.Duration(s.machineSet.Spec.MinReadySeconds) * time.Second} + minReadyResult := ctrl.Result{RequeueAfter: time.Duration(minReadySeconds) * time.Second} return minReadyResult } diff --git a/internal/controllers/machineset/machineset_controller_test.go b/internal/controllers/machineset/machineset_controller_test.go index 5916db4e59bd..d36610fc056d 100644 --- a/internal/controllers/machineset/machineset_controller_test.go +++ b/internal/controllers/machineset/machineset_controller_test.go @@ -134,6 +134,7 @@ func TestMachineSetReconciler(t *testing.T) { NodeDrainTimeout: duration10m, NodeDeletionTimeout: duration10m, NodeVolumeDetachTimeout: duration10m, + MinReadySeconds: ptr.To[int32](0), }, } @@ -1381,6 +1382,7 @@ func TestMachineSetReconciler_syncMachines(t *testing.T) { ms.Spec.Template.Spec.NodeDrainTimeout = duration10s ms.Spec.Template.Spec.NodeDeletionTimeout = duration10s ms.Spec.Template.Spec.NodeVolumeDetachTimeout = duration10s + ms.Spec.Template.Spec.MinReadySeconds = ptr.To[int32](10) s = &scope{ machineSet: ms, machines: []*clusterv1.Machine{updatedInPlaceMutatingMachine, deletingMachine}, @@ -1410,6 +1412,10 @@ func TestMachineSetReconciler_syncMachines(t *testing.T) { Not(BeNil()), HaveValue(Equal(*ms.Spec.Template.Spec.NodeVolumeDetachTimeout)), )) + g.Expect(updatedInPlaceMutatingMachine.Spec.MinReadySeconds).Should(And( + Not(BeNil()), + HaveValue(Equal(*ms.Spec.Template.Spec.MinReadySeconds)), + )) // Verify readiness gates. g.Expect(updatedInPlaceMutatingMachine.Spec.ReadinessGates).Should(Equal(readinessGates)) }, timeout).Should(Succeed()) @@ -1461,12 +1467,14 @@ func TestMachineSetReconciler_syncMachines(t *testing.T) { g.Expect(updatedDeletingMachine.Spec.NodeDrainTimeout).Should(Equal(deletingMachine.Spec.NodeDrainTimeout)) g.Expect(updatedDeletingMachine.Spec.NodeDeletionTimeout).Should(Equal(deletingMachine.Spec.NodeDeletionTimeout)) g.Expect(updatedDeletingMachine.Spec.NodeVolumeDetachTimeout).Should(Equal(deletingMachine.Spec.NodeVolumeDetachTimeout)) + g.Expect(updatedDeletingMachine.Spec.MinReadySeconds).Should(Equal(deletingMachine.Spec.MinReadySeconds)) }, 5*time.Second).Should(Succeed()) // Verify in-place mutable fields are updated on the deleting machine ms.Spec.Template.Spec.NodeDrainTimeout = duration11s ms.Spec.Template.Spec.NodeDeletionTimeout = duration11s ms.Spec.Template.Spec.NodeVolumeDetachTimeout = duration11s + ms.Spec.Template.Spec.MinReadySeconds = ptr.To[int32](11) s = &scope{ machineSet: ms, machines: []*clusterv1.Machine{updatedInPlaceMutatingMachine, deletingMachine}, @@ -1490,6 +1498,10 @@ func TestMachineSetReconciler_syncMachines(t *testing.T) { Not(BeNil()), HaveValue(Equal(*ms.Spec.Template.Spec.NodeVolumeDetachTimeout)), )) + g.Expect(updatedDeletingMachine.Spec.MinReadySeconds).Should(And( + Not(BeNil()), + HaveValue(Equal(*ms.Spec.Template.Spec.MinReadySeconds)), + )) } func TestMachineSetReconciler_reconcileUnhealthyMachines(t *testing.T) { @@ -2304,6 +2316,7 @@ func TestMachineSetReconciler_syncReplicas_WithErrors(t *testing.T) { NodeDrainTimeout: duration10m, NodeDeletionTimeout: duration10m, NodeVolumeDetachTimeout: duration10m, + MinReadySeconds: ptr.To[int32](10), }, }, }, @@ -2453,6 +2466,7 @@ func TestComputeDesiredMachine(t *testing.T) { NodeDrainTimeout: duration10s, NodeVolumeDetachTimeout: duration10s, NodeDeletionTimeout: duration10s, + MinReadySeconds: ptr.To[int32](10), }, } @@ -2473,6 +2487,7 @@ func TestComputeDesiredMachine(t *testing.T) { NodeDrainTimeout: duration10s, NodeVolumeDetachTimeout: duration10s, NodeDeletionTimeout: duration10s, + MinReadySeconds: ptr.To[int32](10), }, } @@ -2500,6 +2515,7 @@ func TestComputeDesiredMachine(t *testing.T) { existingMachine.Spec.NodeDrainTimeout = duration5s existingMachine.Spec.NodeDeletionTimeout = duration5s existingMachine.Spec.NodeVolumeDetachTimeout = duration5s + existingMachine.Spec.MinReadySeconds = ptr.To[int32](5) expectedUpdatedMachine := skeletonMachine.DeepCopy() expectedUpdatedMachine.Name = existingMachine.Name @@ -2521,9 +2537,8 @@ func TestComputeDesiredMachine(t *testing.T) { }, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testClusterName, - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, + ClusterName: testClusterName, + Replicas: ptr.To[int32](3), Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, @@ -2551,9 +2566,8 @@ func TestComputeDesiredMachine(t *testing.T) { }, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testClusterName, - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, + ClusterName: testClusterName, + Replicas: ptr.To[int32](3), Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, @@ -2577,9 +2591,8 @@ func TestComputeDesiredMachine(t *testing.T) { }, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testClusterName, - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, + ClusterName: testClusterName, + Replicas: ptr.To[int32](3), Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, @@ -2607,9 +2620,8 @@ func TestComputeDesiredMachine(t *testing.T) { }, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testClusterName, - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, + ClusterName: testClusterName, + Replicas: ptr.To[int32](3), Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, @@ -2633,9 +2645,8 @@ func TestComputeDesiredMachine(t *testing.T) { }, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testClusterName, - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, + ClusterName: testClusterName, + Replicas: ptr.To[int32](3), Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, @@ -2659,9 +2670,8 @@ func TestComputeDesiredMachine(t *testing.T) { }, }, Spec: clusterv1.MachineSetSpec{ - ClusterName: testClusterName, - Replicas: ptr.To[int32](3), - MinReadySeconds: 10, + ClusterName: testClusterName, + Replicas: ptr.To[int32](3), Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"k1": "v1"}, }, diff --git a/internal/webhooks/machinedeployment.go b/internal/webhooks/machinedeployment.go index a13916bb10fc..e1b1fd39c922 100644 --- a/internal/webhooks/machinedeployment.go +++ b/internal/webhooks/machinedeployment.go @@ -100,10 +100,6 @@ func (webhook *MachineDeployment) Default(ctx context.Context, obj runtime.Objec } m.Spec.Replicas = ptr.To[int32](replicas) - if m.Spec.MinReadySeconds == nil { - m.Spec.MinReadySeconds = ptr.To[int32](0) - } - if m.Spec.RevisionHistoryLimit == nil { m.Spec.RevisionHistoryLimit = ptr.To[int32](1) } diff --git a/internal/webhooks/machinedeployment_test.go b/internal/webhooks/machinedeployment_test.go index 426a48ea31f0..9555053f35c2 100644 --- a/internal/webhooks/machinedeployment_test.go +++ b/internal/webhooks/machinedeployment_test.go @@ -67,7 +67,6 @@ func TestMachineDeploymentDefault(t *testing.T) { g.Expect(md.Labels[clusterv1.ClusterNameLabel]).To(Equal(md.Spec.ClusterName)) - g.Expect(md.Spec.MinReadySeconds).To(Equal(ptr.To[int32](0))) g.Expect(md.Spec.Replicas).To(Equal(ptr.To[int32](1))) g.Expect(md.Spec.RevisionHistoryLimit).To(Equal(ptr.To[int32](1))) g.Expect(md.Spec.Strategy).ToNot(BeNil()) diff --git a/test/e2e/clusterclass_changes.go b/test/e2e/clusterclass_changes.go index 470c6a9d9935..5b015c5db792 100644 --- a/test/e2e/clusterclass_changes.go +++ b/test/e2e/clusterclass_changes.go @@ -684,7 +684,7 @@ func assertMachineDeploymentTopologyFields(g Gomega, md clusterv1.MachineDeploym } if mdTopology.MinReadySeconds != nil { - g.Expect(md.Spec.MinReadySeconds).To(Equal(mdTopology.MinReadySeconds)) + g.Expect(md.Spec.Template.Spec.MinReadySeconds).To(Equal(mdTopology.MinReadySeconds)) } if mdTopology.Strategy != nil { @@ -722,7 +722,7 @@ func assertMachinePoolTopologyFields(g Gomega, mp expv1.MachinePool, mpTopology } if mpTopology.MinReadySeconds != nil { - g.Expect(mp.Spec.MinReadySeconds).To(Equal(mpTopology.MinReadySeconds)) + g.Expect(mp.Spec.Template.Spec.MinReadySeconds).To(Equal(mpTopology.MinReadySeconds)) } if mpTopology.FailureDomains != nil { diff --git a/util/test/builder/builders.go b/util/test/builder/builders.go index aa44a45c0133..1e074cc00e5d 100644 --- a/util/test/builder/builders.go +++ b/util/test/builder/builders.go @@ -1674,9 +1674,8 @@ func (m *MachinePoolBuilder) Build() *expv1.MachinePool { Annotations: m.annotations, }, Spec: expv1.MachinePoolSpec{ - ClusterName: m.clusterName, - Replicas: m.replicas, - MinReadySeconds: m.minReadySeconds, + ClusterName: m.clusterName, + Replicas: m.replicas, Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Version: m.version, @@ -1685,6 +1684,9 @@ func (m *MachinePoolBuilder) Build() *expv1.MachinePool { }, }, } + if m.minReadySeconds != nil { + obj.Spec.Template.Spec.MinReadySeconds = m.minReadySeconds + } if m.bootstrap != nil { obj.Spec.Template.Spec.Bootstrap.ConfigRef = objToRef(m.bootstrap) } @@ -1832,7 +1834,9 @@ func (m *MachineDeploymentBuilder) Build() *clusterv1.MachineDeployment { clusterv1.ClusterNameLabel: m.clusterName, } } - obj.Spec.MinReadySeconds = m.minReadySeconds + if m.minReadySeconds != nil { + obj.Spec.Template.Spec.MinReadySeconds = m.minReadySeconds + } return obj }