diff --git a/api/v1beta1/rabbitmqcluster_types.go b/api/v1beta1/rabbitmqcluster_types.go index 627cf76d8..f2aeb61fc 100644 --- a/api/v1beta1/rabbitmqcluster_types.go +++ b/api/v1beta1/rabbitmqcluster_types.go @@ -243,6 +243,13 @@ type StatefulSetSpec struct { // Template. // +optional UpdateStrategy *appsv1.StatefulSetUpdateStrategy `json:"updateStrategy,omitempty" protobuf:"bytes,7,opt,name=updateStrategy"` + + // The minimum number of seconds for which a newly created StatefulSet pod should + // be ready without any of its container crashing, for it to be considered + // available. Defaults to 0 (pod will be considered available as soon as it + // is ready). + // +optional + MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,4,opt,name=minReadySeconds"` } // EmbeddedLabelsAnnotations is an embedded subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta. diff --git a/config/crd/bases/rabbitmq.com_rabbitmqclusters.yaml b/config/crd/bases/rabbitmq.com_rabbitmqclusters.yaml index 783e03c1b..99323dd4e 100644 --- a/config/crd/bases/rabbitmq.com_rabbitmqclusters.yaml +++ b/config/crd/bases/rabbitmq.com_rabbitmqclusters.yaml @@ -665,6 +665,9 @@ spec: type: object spec: properties: + minReadySeconds: + format: int32 + type: integer podManagementPolicy: type: string replicas: diff --git a/docs/api/rabbitmq.com.ref.asciidoc b/docs/api/rabbitmq.com.ref.asciidoc index 04919eb70..59e3500f7 100644 --- a/docs/api/rabbitmq.com.ref.asciidoc +++ b/docs/api/rabbitmq.com.ref.asciidoc @@ -409,6 +409,7 @@ StatefulSetSpec contains a subset of the fields included in k8s.io/api/apps/v1.S | *`serviceName`* __string__ | serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where "pod-specific-string" is managed by the StatefulSet controller. | *`podManagementPolicy`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podmanagementpolicytype-v1-apps[$$PodManagementPolicyType$$]__ | podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once. | *`updateStrategy`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#statefulsetupdatestrategy-v1-apps[$$StatefulSetUpdateStrategy$$]__ | updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template. +| *`minReadySeconds`* __integer__ | The minimum number of seconds for which a newly created StatefulSet pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready). |=== diff --git a/internal/resource/statefulset.go b/internal/resource/statefulset.go index 11430bddb..2fb655705 100644 --- a/internal/resource/statefulset.go +++ b/internal/resource/statefulset.go @@ -83,6 +83,7 @@ func (builder *StatefulSetBuilder) Build() (client.Object, error) { if overrideSts.Spec.ServiceName != "" { sts.Spec.ServiceName = overrideSts.Spec.ServiceName } + } return sts, nil @@ -162,6 +163,10 @@ func applyStsOverride(instance *rabbitmqv1beta1.RabbitmqCluster, scheme *runtime sts.Spec.PodManagementPolicy = stsOverride.Spec.PodManagementPolicy } + if stsOverride.Spec.MinReadySeconds != 0 { + sts.Spec.MinReadySeconds = stsOverride.Spec.MinReadySeconds + } + if len(stsOverride.Spec.VolumeClaimTemplates) != 0 { // If spec.persistence.storage == 0, ignore PVC overrides. // Main reason for that is that there is no default PVC in such case (emptyDir is used instead) diff --git a/internal/resource/statefulset_test.go b/internal/resource/statefulset_test.go index 6f9af5189..21bc2811a 100644 --- a/internal/resource/statefulset_test.go +++ b/internal/resource/statefulset_test.go @@ -1608,6 +1608,18 @@ default_pass = {{ .Data.data.password }} Expect(*statefulSet.Spec.Replicas).To(Equal(int32(10))) }) + It("overrides statefulSet.spec.MinReadySeconds", func() { + instance.Spec.Override.StatefulSet = &rabbitmqv1beta1.StatefulSet{ + Spec: &rabbitmqv1beta1.StatefulSetSpec{ + MinReadySeconds: 10, + }, + } + + stsBuilder := builder.StatefulSet() + Expect(stsBuilder.Update(statefulSet)).To(Succeed()) + Expect(statefulSet.Spec.MinReadySeconds).To(Equal(int32(10))) + }) + It("overrides statefulSet.spec.podManagementPolicy", func() { instance.Spec.Override.StatefulSet = &rabbitmqv1beta1.StatefulSet{ Spec: &rabbitmqv1beta1.StatefulSetSpec{