From c3310bb72496e97237008f5f9fafa52f5d7d69a9 Mon Sep 17 00:00:00 2001 From: Bhavin Gandhi Date: Tue, 23 Nov 2021 12:50:31 +0530 Subject: [PATCH] fix(pkg/kube): statefulSetReady: handle partition cases correctly The partition value can be greater than number of replicas, in that case no pods are rolled out. The expectedReplicas becomes a negative number. https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions In the cases where the update does not change anything in the pod template, the updatedReplicas value from StatefulSet status remains unchanged. Such updates can still set some partition value, and UpdatedReplicas is always greater than expectedReplicas. Basically, the StatefulSet is ready / rolled-out. In both the above scenarios, providing `--wait` flag causes it to timeout waiting indefinitely. Because updatedReplicas can never be negative, or be equal to the expectedReplicas for the second case. This commit handles both the scenarios by checking if UpdatedReplicas is smaller than expectedReplicas. If it is, then the StatefulSet is not ready yet. Based on the code from kubectl rollout: https://github.com/kubernetes/kubectl/blob/a450ebd59c1e8917df23d37c6f05d8e16c3746aa/pkg/polymorphichelpers/rollout_status.go#L138-L141 Closes #8674 Signed-off-by: Bhavin Gandhi --- pkg/kube/ready.go | 2 +- pkg/kube/ready_test.go | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/kube/ready.go b/pkg/kube/ready.go index 106c0be51..5d080d9bf 100644 --- a/pkg/kube/ready.go +++ b/pkg/kube/ready.go @@ -377,7 +377,7 @@ func (c *ReadyChecker) statefulSetReady(sts *appsv1.StatefulSet) bool { expectedReplicas := replicas - partition // Make sure all the updated pods have been scheduled - if int(sts.Status.UpdatedReplicas) != expectedReplicas { + if int(sts.Status.UpdatedReplicas) < expectedReplicas { c.log("StatefulSet is not ready: %s/%s. %d out of %d expected pods have been scheduled", sts.Namespace, sts.Name, sts.Status.UpdatedReplicas, expectedReplicas) return false } diff --git a/pkg/kube/ready_test.go b/pkg/kube/ready_test.go index cece5352d..931b8fa19 100644 --- a/pkg/kube/ready_test.go +++ b/pkg/kube/ready_test.go @@ -157,10 +157,24 @@ func Test_ReadyChecker_statefulSetReady(t *testing.T) { { name: "statefulset is not ready when partition is set", args: args{ - sts: newStatefulSet("foo", 1, 1, 1, 1), + sts: newStatefulSet("foo", 2, 1, 1, 0), }, want: false, }, + { + name: "statefulset is ready when partition is set and no change in template", + args: args{ + sts: newStatefulSet("foo", 2, 1, 2, 2), + }, + want: true, + }, + { + name: "statefulset is ready when partition is greater than replicas", + args: args{ + sts: newStatefulSet("foo", 1, 2, 1, 1), + }, + want: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {