Skip to content

Commit

Permalink
feat: scaleDownOnAbort for rollout strategies
Browse files Browse the repository at this point in the history
- if an update is aborted, the preview RS and canary RS will be
  aborted.
- scaleDownOnAbort is false by default
- updated doc
- added e2e test

Signed-off-by: Hui Kang <[email protected]>
  • Loading branch information
Hui Kang committed May 21, 2021
1 parent 60092c3 commit b33ed06
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/features/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ spec:
# than or equal to this value.
restartAt: "2020-03-30T21:19:35Z"

# Scale down the preview replicasets or canary replicasets (if
# canary's setCanaryScale.replicas is set) on aborted update
# Defaults to false
scaleDownOnAbort: false

strategy:

# Blue-green update strategy
Expand Down
2 changes: 2 additions & 0 deletions manifests/crds/rollout-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ spec:
revisionHistoryLimit:
format: int32
type: integer
scaleDownOnAbort:
type: boolean
selector:
properties:
matchExpressions:
Expand Down
2 changes: 2 additions & 0 deletions manifests/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9753,6 +9753,8 @@ spec:
revisionHistoryLimit:
format: int32
type: integer
scaleDownOnAbort:
type: boolean
selector:
properties:
matchExpressions:
Expand Down
2 changes: 2 additions & 0 deletions manifests/namespace-install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9753,6 +9753,8 @@ spec:
revisionHistoryLimit:
format: int32
type: integer
scaleDownOnAbort:
type: boolean
selector:
properties:
matchExpressions:
Expand Down
4 changes: 4 additions & 0 deletions pkg/apiclient/rollout/rollout.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,10 @@
"restartAt": {
"$ref": "#/definitions/k8s.io.apimachinery.pkg.apis.meta.v1.Time",
"title": "RestartAt indicates when all the pods of a Rollout should be restarted"
},
"scaleDownOnAbort": {
"type": "boolean",
"title": "ScaleDownOnAbort scales down"
}
},
"title": "RolloutSpec is the spec for a Rollout resource"
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/rollouts/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ type RolloutSpec struct {
ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty" protobuf:"varint,8,opt,name=progressDeadlineSeconds"`
// RestartAt indicates when all the pods of a Rollout should be restarted
RestartAt *metav1.Time `json:"restartAt,omitempty" protobuf:"bytes,9,opt,name=restartAt"`
// ScaleDownOnAbort scales down
ScaleDownOnAbort bool `json:"scaleDownOnAbort,omitempty" protobuf:"varint,11,opt,name=scaleDownOnAbort"`
}

func (s *RolloutSpec) SetResolvedSelector(selector *metav1.LabelSelector) {
Expand Down
6 changes: 6 additions & 0 deletions rollout/replicaset.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ func (c *rolloutContext) reconcileNewReplicaSet() (bool, error) {
if err != nil {
return false, err
}

if c.pauseContext != nil && c.pauseContext.IsAborted() && c.rollout.Spec.ScaleDownOnAbort {
c.log.Info("scale down on abort")
newReplicasCount = int32(0)
}

scaled, _, err := c.scaleReplicaSetAndRecordEvent(c.newRS, newReplicasCount)
return scaled, err
}
Expand Down
17 changes: 17 additions & 0 deletions rollout/replicaset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func TestReconcileNewReplicaSet(t *testing.T) {
rolloutReplicas int
newReplicas int
scaleExpected bool
ScaleDownOnAbort bool
expectedNewReplicas int
}{
{
Expand All @@ -147,6 +148,14 @@ func TestReconcileNewReplicaSet(t *testing.T) {
scaleExpected: true,
expectedNewReplicas: 10,
},
{
name: "New Replica scaled down to 0: scale down on abort",
rolloutReplicas: 10,
newReplicas: 10,
ScaleDownOnAbort: true,
scaleExpected: true,
expectedNewReplicas: 0,
},
}
for i := range tests {
test := tests[i]
Expand All @@ -166,6 +175,14 @@ func TestReconcileNewReplicaSet(t *testing.T) {
recorder: record.NewFakeEventRecorder(),
},
}
if test.ScaleDownOnAbort {
roCtx.pauseContext = &pauseContext{
rollout: rollout,
}
rollout.Status.Abort = true
rollout.Spec.ScaleDownOnAbort = true
}

scaled, err := roCtx.reconcileNewReplicaSet()
if err != nil {
t.Errorf("unexpected error: %v", err)
Expand Down
4 changes: 4 additions & 0 deletions utils/replicaset/canary.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ func GetCanaryReplicasOrWeight(rollout *v1alpha1.Rollout) (*int32, int32) {
return nil, 100
}
if scs := UseSetCanaryScale(rollout); scs != nil {
if rollout.Status.Abort && rollout.Spec.ScaleDownOnAbort {
return nil, 0
}

if scs.Replicas != nil {
return scs.Replicas, 0
} else if scs.Weight != nil {
Expand Down
18 changes: 18 additions & 0 deletions utils/replicaset/canary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func TestCalculateReplicaCountsForCanary(t *testing.T) {
maxSurge intstr.IntOrString
maxUnavailable intstr.IntOrString
promoteFull bool
scaleDownOnAbort bool

stableSpecReplica int32
stableAvailableReplica int32
Expand Down Expand Up @@ -571,12 +572,29 @@ func TestCalculateReplicaCountsForCanary(t *testing.T) {
expectedStableReplicaCount: 4,
expectedCanaryReplicaCount: 3,
},
{
name: "Ignore setCanaryScale when scaleDownonAbort is true and rollout is aborted",
rolloutSpecReplicas: 10,
setWeight: 20,
scaleDownOnAbort: true,

stableSpecReplica: 10,
stableAvailableReplica: 10,

setCanaryScale: newSetCanaryScale(intPnt(3), intPnt(25), false),
trafficRouting: &v1alpha1.RolloutTrafficRouting{},

expectedStableReplicaCount: 10,
expectedCanaryReplicaCount: 0,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
rollout := newRollout(test.rolloutSpecReplicas, test.setWeight, test.maxSurge, test.maxUnavailable, "canary", "stable", test.setCanaryScale, test.trafficRouting)
rollout.Status.PromoteFull = test.promoteFull
rollout.Spec.ScaleDownOnAbort = test.scaleDownOnAbort
rollout.Status.Abort = test.scaleDownOnAbort
stableRS := newRS("stable", test.stableSpecReplica, test.stableAvailableReplica)
canaryRS := newRS("canary", test.canarySpecReplica, test.canaryAvailableReplica)
newRSReplicaCount, stableRSReplicaCount := CalculateReplicaCountsForCanary(rollout, canaryRS, stableRS, []*appsv1.ReplicaSet{test.olderRS})
Expand Down

0 comments on commit b33ed06

Please sign in to comment.