diff --git a/pkg/apis/rollouts/v1alpha1/types.go b/pkg/apis/rollouts/v1alpha1/types.go index 3dc68e930c..aec5ac377a 100644 --- a/pkg/apis/rollouts/v1alpha1/types.go +++ b/pkg/apis/rollouts/v1alpha1/types.go @@ -639,6 +639,8 @@ const ( // RolloutReplicaFailure ReplicaFailure is added in a deployment when one of its pods // fails to be created or deleted. RolloutReplicaFailure RolloutConditionType = "ReplicaFailure" + // RolloutPaused means that rollout is in a paused state. It is still progressing at this point. + RolloutPaused RolloutConditionType = "Paused" ) // RolloutCondition describes the state of a rollout at a certain point. diff --git a/rollout/analysis_test.go b/rollout/analysis_test.go index 576e3e2712..ff6b01b0d7 100644 --- a/rollout/analysis_test.go +++ b/rollout/analysis_test.go @@ -1443,7 +1443,11 @@ func TestDoNotCreateBackgroundAnalysisRunAfterInconclusiveRun(t *testing.T) { Reason: v1alpha1.PauseReasonInconclusiveAnalysis, StartTime: metav1.Now(), }} - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) f.rolloutLister = append(f.rolloutLister, r2) @@ -1454,6 +1458,13 @@ func TestDoNotCreateBackgroundAnalysisRunAfterInconclusiveRun(t *testing.T) { f.run(getKey(r2, t)) patch := f.getPatchedRollout(patchIndex) + + //expectedPatch := fmt.Sprintf(`{ + // "status":{ + // "conditions":[%s, %s], + // "observedGeneration": "" + // } + //}`, progressingConditionString, pausedConditionString) assert.Equal(t, calculatePatch(r2, OnlyObservedGenerationPatch), patch) } @@ -1543,7 +1554,10 @@ func TestCreatePrePromotionAnalysisRun(t *testing.T) { rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs1PodHash, rs1PodHash, 1, 1, 2, 1, true, true) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) previewSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} @@ -1723,7 +1737,10 @@ func TestRolloutPrePromotionAnalysisBecomesInconclusive(t *testing.T) { Name: ar.Name, Status: v1alpha1.AnalysisPhaseRunning, } - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -1788,7 +1805,10 @@ func TestRolloutPrePromotionAnalysisSwitchServiceAfterSuccess(t *testing.T) { Name: ar.Name, Status: v1alpha1.AnalysisPhaseRunning, } - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -1851,7 +1871,10 @@ func TestRolloutPrePromotionAnalysisHonorAutoPromotionSeconds(t *testing.T) { r2 = updateBlueGreenRolloutStatus(r2, "", rs1PodHash, rs1PodHash, 1, 1, 2, 1, true, true) now := metav1.NewTime(metav1.Now().Add(-10 * time.Second)) r2.Status.PauseConditions[0].StartTime = now - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -1914,7 +1937,10 @@ func TestRolloutPrePromotionAnalysisDoNothingOnInconclusiveAnalysis(t *testing.T } r2.Status.PauseConditions = append(r2.Status.PauseConditions, inconclusivePauseCondition) r2.Status.ObservedGeneration = strconv.Itoa(int(r2.Generation)) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -1957,7 +1983,10 @@ func TestAbortRolloutOnErrorPrePromotionAnalysis(t *testing.T) { rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] r2 = updateBlueGreenRolloutStatus(r2, "", rs1PodHash, rs1PodHash, 1, 1, 2, 1, true, true) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -2122,7 +2151,10 @@ func TestPostPromotionAnalysisRunHandleInconclusive(t *testing.T) { Reason: v1alpha1.PauseReasonInconclusiveAnalysis, StartTime: metav1.Now(), }} - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} @@ -2175,7 +2207,10 @@ func TestAbortRolloutOnErrorPostPromotionAnalysis(t *testing.T) { rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] r2 = updateBlueGreenRolloutStatus(r2, "", rs2PodHash, rs1PodHash, 1, 1, 2, 1, true, true) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} diff --git a/rollout/bluegreen_test.go b/rollout/bluegreen_test.go index 0976a75438..64a8c8d02b 100644 --- a/rollout/bluegreen_test.go +++ b/rollout/bluegreen_test.go @@ -248,7 +248,7 @@ func TestBlueGreenHandlePause(t *testing.T) { "conditions": %s } }` - addedConditions := generateConditionsPatch(true, conditions.PausedRolloutReason, rs2, true, "") + addedConditions := generateConditionsPatchWithPause(true, conditions.PausedRolloutReason, rs2, true, "", true) assert.Equal(t, calculatePatch(r2, fmt.Sprintf(expectedPatch, addedConditions)), patch) }) @@ -266,7 +266,10 @@ func TestBlueGreenHandlePause(t *testing.T) { rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs1PodHash, rs1PodHash, 1, 1, 2, 1, true, true) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) previewSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} @@ -310,7 +313,10 @@ func TestBlueGreenHandlePause(t *testing.T) { Reason: v1alpha1.PauseReasonInconclusiveAnalysis, StartTime: now, }) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) previewSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} @@ -347,7 +353,10 @@ func TestBlueGreenHandlePause(t *testing.T) { rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs1PodHash, rs1PodHash, 1, 1, 2, 1, true, true) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) previewSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} @@ -385,7 +394,10 @@ func TestBlueGreenHandlePause(t *testing.T) { before := metav1.NewTime(now.Add(-1 * time.Minute)) r2.Status.PauseConditions[0].StartTime = before r2.Status.ControllerPause = true - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -439,7 +451,10 @@ func TestBlueGreenHandlePause(t *testing.T) { r2.Status.PauseConditions[0].StartTime = before r2.Status.ControllerPause = true r2.Spec.Paused = true - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} @@ -731,7 +746,10 @@ func TestBlueGreenRolloutStatusHPAStatusFieldsActiveSelectorSet(t *testing.T) { r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs1PodHash, rs1PodHash, 0, 0, 0, 0, true, false) r2.Status.Selector = "" - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) f.rolloutLister = append(f.rolloutLister, r2) diff --git a/rollout/canary_test.go b/rollout/canary_test.go index 4e4e37bc46..6ea1fdda1a 100644 --- a/rollout/canary_test.go +++ b/rollout/canary_test.go @@ -189,6 +189,9 @@ func TestCanaryRolloutNoProgressWhilePaused(t *testing.T) { progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") conditions.SetRolloutCondition(&r2.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) + conditions.SetRolloutCondition(&r2.Status, pausedCondition) + rs1 := newReplicaSetWithStatus(r1, 10, 10) rs2 := newReplicaSetWithStatus(r2, 0, 0) @@ -216,9 +219,12 @@ func TestCanaryRolloutUpdatePauseConditionWhilePaused(t *testing.T) { r1 := newCanaryRollout("foo", 10, nil, steps, pointer.Int32Ptr(0), intstr.FromInt(1), intstr.FromInt(0)) r2 := bumpVersion(r1) - progressingCondition, _ := newProgressingCondition(conditions.ReplicaSetUpdatedReason, r2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") conditions.SetRolloutCondition(&r2.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) + conditions.SetRolloutCondition(&r2.Status, pausedCondition) + rs1 := newReplicaSetWithStatus(r1, 10, 10) rs2 := newReplicaSetWithStatus(r2, 0, 0) @@ -231,17 +237,10 @@ func TestCanaryRolloutUpdatePauseConditionWhilePaused(t *testing.T) { f.objects = append(f.objects, r2) addPausedConditionPatch := f.expectPatchRolloutAction(r2) - f.expectPatchRolloutAction(r2) f.run(getKey(r2, t)) patch := f.getPatchedRollout(addPausedConditionPatch) - _, pausedCondition := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") - expectedPatch := fmt.Sprintf(`{ - "status": { - "conditions": [%s] - } - }`, pausedCondition) - assert.Equal(t, calculatePatch(r2, expectedPatch), patch) + assert.Equal(t, calculatePatch(r2, OnlyObservedGenerationPatch), patch) } func TestCanaryRolloutResetProgressDeadlineOnRetry(t *testing.T) { @@ -885,6 +884,9 @@ func TestSyncRolloutWaitAddToQueue(t *testing.T) { progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") conditions.SetRolloutCondition(&r2.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) + conditions.SetRolloutCondition(&r2.Status, pausedCondition) + r2.Status.ObservedGeneration = strconv.Itoa(int(r2.Generation)) f.rolloutLister = append(f.rolloutLister, r2) f.objects = append(f.objects, r2) @@ -927,6 +929,9 @@ func TestSyncRolloutIgnoreWaitOutsideOfReconciliationPeriod(t *testing.T) { progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") conditions.SetRolloutCondition(&r2.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) + conditions.SetRolloutCondition(&r2.Status, pausedCondition) + f.rolloutLister = append(f.rolloutLister, r2) f.objects = append(f.objects, r2) @@ -964,7 +969,10 @@ func TestSyncRolloutWaitIncrementStepIndex(t *testing.T) { f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 10, 1, 10, false) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) earlier := metav1.Now() @@ -1008,6 +1016,9 @@ func TestCanaryRolloutStatusHPAStatusFields(t *testing.T) { progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") conditions.SetRolloutCondition(&r2.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) + conditions.SetRolloutCondition(&r2.Status, pausedCondition) + rs1 := newReplicaSetWithStatus(r1, 4, 4) rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] rs2 := newReplicaSetWithStatus(r2, 1, 1) @@ -1249,7 +1260,10 @@ func TestCanaryRolloutScaleWhilePaused(t *testing.T) { r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 5, 0, 5, true) r2.Spec.Replicas = pointer.Int32Ptr(10) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) f.rolloutLister = append(f.rolloutLister, r2) @@ -1343,7 +1357,9 @@ func TestNoResumeAfterPauseDurationIfUserPaused(t *testing.T) { Reason: v1alpha1.PauseReasonCanaryPauseStep, StartTime: overAMinuteAgo, }} - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs1, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs1, "") + conditions.SetRolloutCondition(&r1.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r1.Status, pausedCondition) r1.Spec.Paused = true f.kubeobjects = append(f.kubeobjects, rs1) @@ -1380,7 +1396,10 @@ func TestHandleNilNewRSOnScaleAndImageChange(t *testing.T) { r2 := bumpVersion(r1) r2.Spec.Replicas = pointer.Int32Ptr(3) r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 3, 0, 3, true) - pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs1, "") + progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs1, "") + conditions.SetRolloutCondition(&r2.Status, progressingCondition) + + pausedCondition, _ := newPausedCondition(true) conditions.SetRolloutCondition(&r2.Status, pausedCondition) f.kubeobjects = append(f.kubeobjects, rs1) diff --git a/rollout/controller_test.go b/rollout/controller_test.go index e3b4bedc96..c3c7157db0 100644 --- a/rollout/controller_test.go +++ b/rollout/controller_test.go @@ -165,6 +165,26 @@ func newReplicaSetWithStatus(r *v1alpha1.Rollout, replicas int, availableReplica return rs } +func newPausedCondition(isPaused bool) (v1alpha1.RolloutCondition, string) { + status := corev1.ConditionTrue + if !isPaused { + status = corev1.ConditionFalse + } + condition := v1alpha1.RolloutCondition{ + LastTransitionTime: metav1.Now(), + LastUpdateTime: metav1.Now(), + Message: conditions.PausedRolloutMessage, + Reason: conditions.PausedRolloutReason, + Status: status, + Type: v1alpha1.RolloutPaused, + } + conditionBytes, err := json.Marshal(condition) + if err != nil { + panic(err) + } + return condition, string(conditionBytes) +} + func newProgressingCondition(reason string, resourceObj runtime.Object, optionalMessage string) (v1alpha1.RolloutCondition, string) { status := corev1.ConditionTrue msg := "" @@ -277,6 +297,16 @@ func generateConditionsPatch(available bool, progressingReason string, progressi return fmt.Sprintf("[%s, %s]", progressingCondition, availableCondition) } +func generateConditionsPatchWithPause(available bool, progressingReason string, progressingResource runtime.Object, availableConditionFirst bool, progressingMessage string, isPaused bool) string { + _, availableCondition := newAvailableCondition(available) + _, progressingCondition := newProgressingCondition(progressingReason, progressingResource, progressingMessage) + _, pauseCondition := newPausedCondition(isPaused) + if availableConditionFirst { + return fmt.Sprintf("[%s, %s, %s]", availableCondition, progressingCondition, pauseCondition) + } + return fmt.Sprintf("[%s, %s, %s]", progressingCondition, pauseCondition, availableCondition) +} + // func updateBlueGreenRolloutStatus(r *v1alpha1.Rollout, preview, active string, availableReplicas, updatedReplicas, hpaReplicas int32, pause bool, available bool, progressingStatus string) *v1alpha1.Rollout { func updateBlueGreenRolloutStatus(r *v1alpha1.Rollout, preview, active, stable string, availableReplicas, updatedReplicas, totalReplicas, hpaReplicas int32, pause bool, available bool) *v1alpha1.Rollout { newRollout := updateBaseRolloutStatus(r, availableReplicas, updatedReplicas, totalReplicas, hpaReplicas) diff --git a/rollout/sync.go b/rollout/sync.go index 3b3d20e522..7f2a8337aa 100644 --- a/rollout/sync.go +++ b/rollout/sync.go @@ -483,34 +483,52 @@ func (c *rolloutContext) cleanupRollouts(oldRSs []*appsv1.ReplicaSet) error { // These conditions are needed so that we won't accidentally report lack of progress for resumed rollouts // that were paused for longer than progressDeadlineSeconds. func (c *rolloutContext) checkPausedConditions() error { - cond := conditions.GetRolloutCondition(c.rollout.Status, v1alpha1.RolloutProgressing) - pausedCondExists := cond != nil && cond.Reason == conditions.PausedRolloutReason + // Progressing condition + progCond := conditions.GetRolloutCondition(c.rollout.Status, v1alpha1.RolloutProgressing) + progCondPaused := progCond != nil && progCond.Reason == conditions.PausedRolloutReason isPaused := len(c.rollout.Status.PauseConditions) > 0 || c.rollout.Spec.Paused - var updatedCondition *v1alpha1.RolloutCondition - if isPaused && !pausedCondExists { - updatedCondition = conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionUnknown, conditions.PausedRolloutReason, conditions.PausedRolloutMessage) - } else if !isPaused && pausedCondExists { - updatedCondition = conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionUnknown, conditions.ResumedRolloutReason, conditions.ResumeRolloutMessage) + abortCondExists := progCond != nil && progCond.Reason == conditions.RolloutAbortedReason + + var updatedConditions []*v1alpha1.RolloutCondition + + if (isPaused != progCondPaused) && !abortCondExists { + if isPaused { + updatedConditions = append(updatedConditions, conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionUnknown, conditions.PausedRolloutReason, conditions.PausedRolloutMessage)) + } else { + updatedConditions = append(updatedConditions, conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionUnknown, conditions.ResumedRolloutReason, conditions.ResumeRolloutMessage)) + } } - abortCondExists := cond != nil && cond.Reason == conditions.RolloutAbortedReason if !c.rollout.Status.Abort && abortCondExists { - updatedCondition = conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionUnknown, conditions.RolloutRetryReason, conditions.RolloutRetryMessage) + updatedConditions = append(updatedConditions, conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionUnknown, conditions.RolloutRetryReason, conditions.RolloutRetryMessage)) } - if updatedCondition == nil { + pauseCond := conditions.GetRolloutCondition(c.rollout.Status, v1alpha1.RolloutPaused) + pausedCondTrue := pauseCond != nil && pauseCond.Status == corev1.ConditionTrue + + if (isPaused != pausedCondTrue) && !abortCondExists { + condStatus := corev1.ConditionFalse + if isPaused { + condStatus = corev1.ConditionTrue + } + updatedConditions = append(updatedConditions, conditions.NewRolloutCondition(v1alpha1.RolloutPaused, condStatus, conditions.PausedRolloutReason, conditions.PausedRolloutMessage)) + } + + if len(updatedConditions) == 0 { return nil } newStatus := c.rollout.Status.DeepCopy() - err := c.patchCondition(c.rollout, newStatus, updatedCondition) + err := c.patchCondition(c.rollout, newStatus, updatedConditions...) return err } -func (c *rolloutContext) patchCondition(r *v1alpha1.Rollout, newStatus *v1alpha1.RolloutStatus, condition *v1alpha1.RolloutCondition) error { +func (c *rolloutContext) patchCondition(r *v1alpha1.Rollout, newStatus *v1alpha1.RolloutStatus, conditionList ...*v1alpha1.RolloutCondition) error { ctx := context.TODO() - conditions.SetRolloutCondition(newStatus, *condition) + for _, condition := range conditionList { + conditions.SetRolloutCondition(newStatus, *condition) + } newStatus.ObservedGeneration = strconv.Itoa(int(c.rollout.Generation)) logCtx := logutil.WithVersionFields(c.log, r) patch, modified, err := diff.CreateTwoWayMergePatch( diff --git a/rollout/trafficrouting_test.go b/rollout/trafficrouting_test.go index 26894a5ebe..167450e940 100644 --- a/rollout/trafficrouting_test.go +++ b/rollout/trafficrouting_test.go @@ -135,6 +135,9 @@ func TestRolloutUseDesiredWeight(t *testing.T) { progressingCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2, "") conditions.SetRolloutCondition(&r2.Status, progressingCondition) + pausedCondition, _ := newPausedCondition(true) + conditions.SetRolloutCondition(&r2.Status, pausedCondition) + rs1 := newReplicaSetWithStatus(r1, 10, 10) rs2 := newReplicaSetWithStatus(r2, 1, 1) diff --git a/test/e2e/functional_test.go b/test/e2e/functional_test.go index c5e0ba4c5e..4bab71b3d6 100644 --- a/test/e2e/functional_test.go +++ b/test/e2e/functional_test.go @@ -3,6 +3,9 @@ package e2e import ( + "fmt" + "os/exec" + "strings" "testing" "time" @@ -11,6 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" "github.com/argoproj/argo-rollouts/test/fixtures" ) @@ -838,3 +842,65 @@ spec: ExpectRevisionPodCount("1", 0). ExpectReplicaCounts(1, 2, 1, 1, 1) } + +func (s *FunctionalSuite) TestKubectlWaitForPaused() { + s.Given(). + RolloutObjects(` +kind: Service +apiVersion: v1 +metadata: + name: rollout-bluegreen-active +spec: + selector: + app: rollout-bluegreen + ports: + - protocol: TCP + port: 80 + targetPort: 8080 +--- +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: rollout-bluegreen +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: rollout-bluegreen + template: + metadata: + labels: + app: rollout-bluegreen + spec: + containers: + - name: rollouts-demo + image: argoproj/rollouts-demo:blue + imagePullPolicy: Always + ports: + - containerPort: 8080 + strategy: + blueGreen: + activeService: rollout-bluegreen-active + autoPromotionEnabled: false +`). + When(). + ApplyManifests(). + WaitForRolloutReplicas(1). + WaitForRolloutStatus("Healthy"). + UpdateSpec(). + Then(). + ExpectRollout("Paused", func(r *v1alpha1.Rollout) bool { + cmd := exec.Command("kubectl", "wait", "--for=condition=Paused", fmt.Sprintf("rollout/%s", r.Name)) + out, err := cmd.CombinedOutput() + return err == nil && strings.Contains(string(out), "rollout.argoproj.io/rollout-bluegreen condition met") + }). + When(). + PromoteRollout(). + Then(). + ExpectRollout("UnPaused", func(r *v1alpha1.Rollout) bool { + cmd := exec.Command("kubectl", "wait", "--for=condition=Paused=False", fmt.Sprintf("rollout/%s", r.Name)) + return cmd.Run() == nil + }). + ExpectActiveRevision("2") +}