From 79f3d2bcb7e2fefb5053e28f979d65e62b0d9fe1 Mon Sep 17 00:00:00 2001 From: Nitish Chauhan <72253189+nitishchauhan0022@users.noreply.github.com> Date: Thu, 6 Jul 2023 07:46:10 +0530 Subject: [PATCH] adding updatedAvailableReplicas field (#1317) * adding updatedAvailableReplicas field * resolving linting error and some check for updatedavailabel replica * fixing typo --------- --- apis/apps/v1alpha1/cloneset_types.go | 4 ++++ apis/apps/v1beta1/statefulset_types.go | 4 ++++ .../crd/bases/apps.kruise.io_clonesets.yaml | 7 +++++++ .../bases/apps.kruise.io_statefulsets.yaml | 6 ++++++ pkg/controller/cloneset/cloneset_status.go | 4 ++++ .../statefulset/stateful_set_control.go | 3 +++ .../statefulset/stateful_set_control_test.go | 21 +++++++++++++++++++ 7 files changed, 49 insertions(+) diff --git a/apis/apps/v1alpha1/cloneset_types.go b/apis/apps/v1alpha1/cloneset_types.go index 37b9905476..e9652e9514 100644 --- a/apis/apps/v1alpha1/cloneset_types.go +++ b/apis/apps/v1alpha1/cloneset_types.go @@ -176,6 +176,10 @@ type CloneSetStatus struct { // indicated by updateRevision and have a Ready Condition. UpdatedReadyReplicas int32 `json:"updatedReadyReplicas"` + // UpdatedAvailableReplicas is the number of Pods created by the CloneSet controller from the CloneSet version + // indicated by updateRevision and have a Ready Condition for at least minReadySeconds. + UpdatedAvailableReplicas int32 `json:"updatedAvailableReplicas"` + // ExpectedUpdatedReplicas is the number of Pods that should be updated by CloneSet controller. // This field is calculated via Replicas - Partition. ExpectedUpdatedReplicas int32 `json:"expectedUpdatedReplicas,omitempty"` diff --git a/apis/apps/v1beta1/statefulset_types.go b/apis/apps/v1beta1/statefulset_types.go index b3aea90f10..d30d998548 100644 --- a/apis/apps/v1beta1/statefulset_types.go +++ b/apis/apps/v1beta1/statefulset_types.go @@ -267,6 +267,10 @@ type StatefulSetStatus struct { // updatedReadyReplicas is the number of updated Pods created by the StatefulSet controller that have a Ready Condition. UpdatedReadyReplicas int32 `json:"updatedReadyReplicas,omitempty"` + // updatedAvailableReplicas is the number of updated Pods created by the StatefulSet controller that have a Ready condition + //for atleast minReadySeconds. + UpdatedAvailableReplicas int32 `json:"updatedAvailableReplicas,omitempty"` + // currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the // sequence [0,currentReplicas). CurrentRevision string `json:"currentRevision,omitempty"` diff --git a/config/crd/bases/apps.kruise.io_clonesets.yaml b/config/crd/bases/apps.kruise.io_clonesets.yaml index 302f299d1c..e3ec051a88 100644 --- a/config/crd/bases/apps.kruise.io_clonesets.yaml +++ b/config/crd/bases/apps.kruise.io_clonesets.yaml @@ -498,6 +498,12 @@ spec: description: UpdateRevision, if not empty, indicates the latest revision of the CloneSet. type: string + updatedAvailableReplicas: + description: UpdatedAvailableReplicas is the number of Pods created + by the CloneSet controller from the CloneSet version indicated by + updateRevision and have a Ready Condition for at least minReadySeconds. + format: int32 + type: integer updatedReadyReplicas: description: UpdatedReadyReplicas is the number of Pods created by the CloneSet controller from the CloneSet version indicated by updateRevision @@ -513,6 +519,7 @@ spec: - availableReplicas - readyReplicas - replicas + - updatedAvailableReplicas - updatedReadyReplicas - updatedReplicas type: object diff --git a/config/crd/bases/apps.kruise.io_statefulsets.yaml b/config/crd/bases/apps.kruise.io_statefulsets.yaml index 6a2e10e739..eef8089d97 100644 --- a/config/crd/bases/apps.kruise.io_statefulsets.yaml +++ b/config/crd/bases/apps.kruise.io_statefulsets.yaml @@ -965,6 +965,12 @@ spec: description: updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas) type: string + updatedAvailableReplicas: + description: updatedAvailableReplicas is the number of updated Pods + created by the StatefulSet controller that have a Ready condition + for atleast minReadySeconds. + format: int32 + type: integer updatedReadyReplicas: description: updatedReadyReplicas is the number of updated Pods created by the StatefulSet controller that have a Ready Condition. diff --git a/pkg/controller/cloneset/cloneset_status.go b/pkg/controller/cloneset/cloneset_status.go index 588ebdc44b..e2823614cc 100644 --- a/pkg/controller/cloneset/cloneset_status.go +++ b/pkg/controller/cloneset/cloneset_status.go @@ -77,6 +77,7 @@ func (r *realStatusUpdater) inconsistentStatus(cs *appsv1alpha1.CloneSet, newSta newStatus.AvailableReplicas != oldStatus.AvailableReplicas || newStatus.UpdatedReadyReplicas != oldStatus.UpdatedReadyReplicas || newStatus.UpdatedReplicas != oldStatus.UpdatedReplicas || + newStatus.UpdatedAvailableReplicas != oldStatus.UpdatedAvailableReplicas || newStatus.ExpectedUpdatedReplicas != oldStatus.ExpectedUpdatedReplicas || newStatus.UpdateRevision != oldStatus.UpdateRevision || newStatus.CurrentRevision != oldStatus.CurrentRevision || @@ -99,6 +100,9 @@ func (r *realStatusUpdater) calculateStatus(cs *appsv1alpha1.CloneSet, newStatus if clonesetutils.EqualToRevisionHash("", pod, newStatus.UpdateRevision) && coreControl.IsPodUpdateReady(pod, 0) { newStatus.UpdatedReadyReplicas++ } + if clonesetutils.EqualToRevisionHash("", pod, newStatus.UpdateRevision) && sync.IsPodAvailable(coreControl, pod, cs.Spec.MinReadySeconds) { + newStatus.UpdatedAvailableReplicas++ + } } // Consider the update revision as stable if revisions of all pods are consistent to it, no need to wait all of them ready if newStatus.UpdatedReplicas == newStatus.Replicas { diff --git a/pkg/controller/statefulset/stateful_set_control.go b/pkg/controller/statefulset/stateful_set_control.go index 426af6bff8..17c5fbef8b 100644 --- a/pkg/controller/statefulset/stateful_set_control.go +++ b/pkg/controller/statefulset/stateful_set_control.go @@ -403,6 +403,9 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet( status.ReadyReplicas++ if getPodRevision(pods[i]) == updateRevision.Name { status.UpdatedReadyReplicas++ + if avail, _ := isRunningAndAvailable(pods[i], minReadySeconds); avail { + status.UpdatedAvailableReplicas++ + } } if avail, _ := isRunningAndAvailable(pods[i], minReadySeconds); avail { status.AvailableReplicas++ diff --git a/pkg/controller/statefulset/stateful_set_control_test.go b/pkg/controller/statefulset/stateful_set_control_test.go index cdc866a8e0..c187c68958 100644 --- a/pkg/controller/statefulset/stateful_set_control_test.go +++ b/pkg/controller/statefulset/stateful_set_control_test.go @@ -225,6 +225,9 @@ func CreatesPods(t *testing.T, set *appsv1beta1.StatefulSet, invariants invarian if set.Status.UpdatedReplicas != 3 { t.Error("Failed to set UpdatedReplicas correctly") } + if set.Status.UpdatedAvailableReplicas != 3 { + t.Error("Failed to set UpdatedAvailableReplicas correctly") + } } func ScalesUp(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariantFunc) { @@ -257,6 +260,9 @@ func ScalesUp(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariantFu if set.Status.UpdatedReplicas != 4 { t.Error("Failed to set updatedReplicas correctly") } + if set.Status.UpdatedAvailableReplicas != 4 { + t.Error("Failed to set updatedAvailableReplicas correctly") + } } func ScalesDown(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariantFunc) { @@ -295,6 +301,9 @@ func ScalesDown(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariant if set.Status.UpdatedReplicas != 0 { t.Error("Failed to set updatedReplicas correctly") } + if set.Status.UpdatedAvailableReplicas != 0 { + t.Error("Failed to set updatedAvailableReplicas correctly") + } } func ReplacesPods(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariantFunc) { @@ -459,6 +468,9 @@ func CreatePodFailure(t *testing.T, set *appsv1beta1.StatefulSet, invariants inv if set.Status.UpdatedReplicas != 3 { t.Error("Failed to updatedReplicas correctly") } + if set.Status.UpdatedAvailableReplicas != 4 { + t.Error("Failed to set updatedAvailableReplicas correctly") + } } func UpdatePodFailure(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariantFunc) { @@ -489,6 +501,9 @@ func UpdatePodFailure(t *testing.T, set *appsv1beta1.StatefulSet, invariants inv if set.Status.UpdatedReplicas != 3 { t.Error("Failed to set updatedReplicas correctly") } + if set.Status.UpdatedAvailableReplicas != 3 { + t.Error("Failed to set updatedAvailableReplicas correctly") + } // now mutate a pod's identity pods, err := om.podsLister.List(labels.Everything()) @@ -543,6 +558,9 @@ func UpdateSetStatusFailure(t *testing.T, set *appsv1beta1.StatefulSet, invarian if set.Status.UpdatedReplicas != 3 { t.Error("Failed to set updatedReplicas to 3") } + if set.Status.UpdatedAvailableReplicas != 4 { + t.Error("Failed to set updatedAvailableReplicas correctly") + } } func PodRecreateDeleteFailure(t *testing.T, set *appsv1beta1.StatefulSet, invariants invariantFunc) { @@ -637,6 +655,9 @@ func TestStatefulSetControlScaleDownDeleteError(t *testing.T) { if set.Status.UpdatedReplicas != 0 { t.Error("Failed to set updatedReplicas to 0") } + if set.Status.UpdatedAvailableReplicas != 0 { + t.Error("Failed to set updatedAvailableReplicas to 0") + } }) }