diff --git a/rollout/sync.go b/rollout/sync.go index 167430a702..875949ee55 100644 --- a/rollout/sync.go +++ b/rollout/sync.go @@ -578,6 +578,19 @@ func isIndefiniteStep(r *v1alpha1.Rollout) bool { return false } +// isWaitingForReplicaSetScaleDown returns whether or not the rollout still has other replica sets with a scale down deadline annotation +func isWaitingForReplicaSetScaleDown(r *v1alpha1.Rollout, newRS, stableRS *appsv1.ReplicaSet, allRSs []*appsv1.ReplicaSet) bool { + otherRSs := replicasetutil.GetOtherRSs(r, newRS, stableRS, allRSs) + + for _, rs := range otherRSs { + if replicasetutil.HasScaleDownDeadline(rs) { + return true + } + } + + return false +} + func (c *rolloutContext) calculateRolloutConditions(newStatus v1alpha1.RolloutStatus) v1alpha1.RolloutStatus { isPaused := len(c.rollout.Status.PauseConditions) > 0 || c.rollout.Spec.Paused isAborted := c.pauseContext.IsAborted() @@ -663,7 +676,8 @@ func (c *rolloutContext) calculateRolloutConditions(newStatus v1alpha1.RolloutSt conditions.RemoveRolloutCondition(&newStatus, v1alpha1.RolloutProgressing) } conditions.SetRolloutCondition(&newStatus, *condition) - case !isIndefiniteStep(c.rollout) && conditions.RolloutTimedOut(c.rollout, &newStatus): + case !isIndefiniteStep(c.rollout) && !isWaitingForReplicaSetScaleDown(c.rollout, c.newRS, c.stableRS, c.allRSs) && conditions.RolloutTimedOut(c.rollout, &newStatus): + // Update the rollout with a timeout condition. If the condition already exists, // we ignore this update. msg := fmt.Sprintf(conditions.RolloutTimeOutMessage, c.rollout.Name) diff --git a/test/e2e/canary_test.go b/test/e2e/canary_test.go index d42abb6a79..2c68ec8bd7 100644 --- a/test/e2e/canary_test.go +++ b/test/e2e/canary_test.go @@ -465,6 +465,31 @@ spec: WaitForRolloutStatus("Healthy") } +// TestCanaryScaleDownDelayWithProgressDeadline verifies that a rollout with a pending scale down doesn't trigger a ProgressDeadlineExceeded event and renders the rollout degraded +func (s *CanarySuite) TestCanaryScaleDownDelayWithProgressDeadline() { + s.Given(). + HealthyRollout(`@functional/canary-scaledowndelay.yaml`). + When(). + UpdateSpec(` +spec: + progressDeadlineSeconds: 5`). + Then(). + When(). + UpdateSpec(` +spec: + template: + metadata: + annotations: + rev: two`). // update to revision 2 + WaitForRolloutStatus("Healthy"). + Sleep(10 * time.Second). // sleep > progressDeadlineSeconds + Then(). + Assert(func(t *fixtures.Then) { + status := string(t.GetRollout().Status.Phase) + assert.Equal(s.T(), "Healthy", status) + }) +} + // TestCanaryScaleDownDelay verifies canary uses a scaleDownDelay when traffic routing is used, // and verifies the annotation is properly managed func (s *CanarySuite) TestCanaryScaleDownDelay() {