Skip to content

Commit

Permalink
Add timed pause between switching active selector
Browse files Browse the repository at this point in the history
  • Loading branch information
dthomson25 committed Apr 30, 2019
1 parent 8a6b715 commit 3438a08
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 1 deletion.
7 changes: 6 additions & 1 deletion controller/bluegreen.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,13 @@ func (c *Controller) reconcileBlueGreenPause(activeSvc *corev1.Service, rollout
if _, ok := activeSvc.Spec.Selector[v1alpha1.DefaultRolloutUniqueLabelKey]; !ok {
return false
}
pauseStartTime := rollout.Status.PauseStartTime
autoPromoteActiveServiceDelaySeconds := rollout.Spec.Strategy.BlueGreenStrategy.AutoPromoteActiveServiceDelaySeconds
if autoPromoteActiveServiceDelaySeconds != nil && pauseStartTime != nil {
c.checkEnqueueRolloutDuringWait(rollout, *pauseStartTime, *autoPromoteActiveServiceDelaySeconds)
}

return rollout.Spec.Paused && rollout.Status.PauseStartTime != nil
return rollout.Spec.Paused && pauseStartTime != nil
}

// scaleDownOldReplicaSetsForBlueGreen scales down old replica sets when rollout strategy is "Blue Green".
Expand Down
81 changes: 81 additions & 0 deletions controller/bluegreen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,87 @@ func TestBlueGreenHandlePause(t *testing.T) {
assert.Equal(t, calculatePatch(r2, OnlyObservedGenerationPatch), patch)
})

t.Run("NoAutoPromoteBeforeDelayTimePasses", func(t *testing.T) {
f := newFixture(t)

r1 := newBlueGreenRollout("foo", 1, nil, "active", "preview")
r2 := bumpVersion(r1)
r2.Spec.Strategy.BlueGreenStrategy.AutoPromoteActiveServiceDelaySeconds = pointer.Int32Ptr(10)

rs1 := newReplicaSetWithStatus(r1, "foo-895c6c4f9", 1, 1)
rs2 := newReplicaSetWithStatus(r2, "foo-5f79b78d7f", 1, 1)
rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]

r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs1PodHash, 2, 1, 1, true, true)
pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, r2.Name)
conditions.SetRolloutCondition(&r2.Status, pausedCondition)

previewSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash}
previewSvc := newService("preview", 80, previewSelector)
activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash}
activeSvc := newService("active", 80, activeSelector)

f.objects = append(f.objects, r2)
f.kubeobjects = append(f.kubeobjects, previewSvc, activeSvc, rs1, rs2)
f.rolloutLister = append(f.rolloutLister, r2)
f.replicaSetLister = append(f.replicaSetLister, rs1, rs2)

f.expectGetServiceAction(activeSvc)
f.expectGetServiceAction(previewSvc)
patchIndex := f.expectPatchRolloutActionWithPatch(r2, OnlyObservedGenerationPatch)
f.run(getKey(r2, t))
patch := f.getPatchedRollout(patchIndex)
assert.Equal(t, calculatePatch(r2, OnlyObservedGenerationPatch), patch)
})

t.Run("AutoPromoteAfterDelayTimePasses", func(t *testing.T) {
f := newFixture(t)

r1 := newBlueGreenRollout("foo", 1, nil, "active", "preview")
r2 := bumpVersion(r1)
r2.Spec.Strategy.BlueGreenStrategy.AutoPromoteActiveServiceDelaySeconds = pointer.Int32Ptr(10)

rs1 := newReplicaSetWithStatus(r1, "foo-895c6c4f9", 1, 1)
rs2 := newReplicaSetWithStatus(r2, "foo-5f79b78d7f", 1, 1)
rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]

r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs1PodHash, 2, 1, 1, true, true)
now := metav1.Now()
before := metav1.NewTime(now.Add(-1 * time.Minute))
r2.Status.PauseStartTime = &before
pausedCondition, _ := newProgressingCondition(conditions.PausedRolloutReason, rs2.Name)
conditions.SetRolloutCondition(&r2.Status, pausedCondition)

activeSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash}
activeSvc := newService("active", 80, activeSelector)
previewSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash}
previewSvc := newService("preview", 80, previewSelector)

f.objects = append(f.objects, r2)
f.kubeobjects = append(f.kubeobjects, activeSvc, previewSvc, rs1, rs2)
f.rolloutLister = append(f.rolloutLister, r2)
f.replicaSetLister = append(f.replicaSetLister, rs1, rs2)

f.expectGetServiceAction(activeSvc)
f.expectGetServiceAction(previewSvc)
expectedPatchWithoutSubs := `{
"spec": {
"paused": null
},
"status": {
"pauseStartTime": null
}
}`
expectedPatch := calculatePatch(r2, expectedPatchWithoutSubs)
patchRolloutIndex := f.expectPatchRolloutActionWithPatch(r2, expectedPatch)
f.run(getKey(r2, t))

rolloutPatch := f.getPatchedRollout(patchRolloutIndex)
assert.Equal(t, expectedPatch, rolloutPatch)
})

t.Run("SkipWhenNoPreviewSpecified", func(t *testing.T) {
f := newFixture(t)

Expand Down
15 changes: 15 additions & 0 deletions controller/pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func calculatePauseStatus(rollout *v1alpha1.Rollout, addPause bool) (*metav1.Tim
if !paused {
pauseStartTime = nil
}

if addPause {
if pauseStartTime == nil {
now := metav1.Now()
Expand All @@ -58,5 +59,19 @@ func calculatePauseStatus(rollout *v1alpha1.Rollout, addPause bool) (*metav1.Tim
paused = true
}
}

if paused && rollout.Spec.Strategy.BlueGreenStrategy != nil {
if pauseStartTime != nil && rollout.Spec.Strategy.BlueGreenStrategy.AutoPromoteActiveServiceDelaySeconds != nil {
now := metav1.Now()
autoPromoteActiveServiceDelaySeconds := *rollout.Spec.Strategy.BlueGreenStrategy.AutoPromoteActiveServiceDelaySeconds
switchDeadline := pauseStartTime.Add(time.Duration(autoPromoteActiveServiceDelaySeconds) * time.Second)
if now.After(switchDeadline) {
return nil, false
}
return pauseStartTime, true

}

}
return pauseStartTime, paused
}
6 changes: 6 additions & 0 deletions manifests/crds/rollout-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ spec:
description: Name of the service that the rollout modifies as
the active service.
type: string
autoPromoteActiveServiceDelaySeconds:
description: AutoPromoteActiveServiceDelaySeconds add a delay
before automatically promoting the ReplicaSet under the preview
service to the active service.
format: int32
type: integer
previewReplicaCount:
description: PreviewReplica the number of replicas to run under
the preview service before the switchover. Once the rollout
Expand Down
6 changes: 6 additions & 0 deletions manifests/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ spec:
description: Name of the service that the rollout modifies as
the active service.
type: string
autoPromoteActiveServiceDelaySeconds:
description: AutoPromoteActiveServiceDelaySeconds add a delay
before automatically promoting the ReplicaSet under the preview
service to the active service.
format: int32
type: integer
previewReplicaCount:
description: PreviewReplica the number of replicas to run under
the preview service before the switchover. Once the rollout
Expand Down
6 changes: 6 additions & 0 deletions manifests/namespace-install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ spec:
description: Name of the service that the rollout modifies as
the active service.
type: string
autoPromoteActiveServiceDelaySeconds:
description: AutoPromoteActiveServiceDelaySeconds add a delay
before automatically promoting the ReplicaSet under the preview
service to the active service.
format: int32
type: integer
previewReplicaCount:
description: PreviewReplica the number of replicas to run under
the preview service before the switchover. Once the rollout
Expand Down
7 changes: 7 additions & 0 deletions pkg/apis/rollouts/v1alpha1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pkg/apis/rollouts/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ type BlueGreenStrategy struct {
// resumed the new replicaset will be full scaled up before the switch occurs
// +optional
PreviewReplicaCount *int32 `json:"previewReplicaCount,omitempty"`
// AutoPromoteActiveServiceDelaySeconds add a delay before automatically promoting the ReplicaSet under the preview
// service to the active service.
AutoPromoteActiveServiceDelaySeconds *int32 `json:"autoPromoteActiveServiceDelaySeconds,omitempty"`
// ScaleDownDelaySeconds adds a delay before scaling down the previous replicaset. See
// https://github.com/argoproj/argo-rollouts/issues/19#issuecomment-476329960 for more information
// +optional
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3438a08

Please sign in to comment.