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:
a450ebd59c/pkg/polymorphichelpers/rollout_status.go (L138-L141)

Closes #8674

Signed-off-by: Bhavin Gandhi <bhavin7392@gmail.com>
pull/10387/head
Bhavin Gandhi 4 years ago
parent e03d20d8f4
commit c3310bb724

@ -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
}

@ -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) {

Loading…
Cancel
Save