Skip to content

Commit

Permalink
Add previewReplicaCount to BG
Browse files Browse the repository at this point in the history
  • Loading branch information
dthomson25 committed Apr 29, 2019
1 parent 4b59abf commit d401101
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 106 deletions.
16 changes: 13 additions & 3 deletions controller/bluegreen.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (c *Controller) rolloutBlueGreen(r *v1alpha1.Rollout, rsList []*appsv1.Repl

if previewSvc != nil {
logCtx.Infof("Reconciling preview service '%s'", previewSvc.Name)
if !annotations.IsSaturated(r, newRS) {
if !replicasetutil.ReadyForPreview(r, newRS, allRSs) {
logutil.WithRollout(r).Infof("New RS '%s' is not fully saturated", newRS.Name)
return c.syncRolloutStatusBlueGreen(oldRSs, newRS, previewSvc, activeSvc, r, false)
}
Expand Down Expand Up @@ -197,6 +197,12 @@ func (c *Controller) syncRolloutStatusBlueGreen(oldRSs []*appsv1.ReplicaSet, new
}

pauseStartTime, paused := calculatePauseStatus(r, addPause)
newStatus.BlueGreen.ScaleUpPreviewCheckPoint = r.Status.BlueGreen.ScaleUpPreviewCheckPoint
if paused && r.Spec.Strategy.BlueGreenStrategy.PreviewReplicaCount != nil {
newStatus.BlueGreen.ScaleUpPreviewCheckPoint = true
} else if newRS != nil && activeRS != nil && activeRS.Name == newRS.Name {
newStatus.BlueGreen.ScaleUpPreviewCheckPoint = false
}
newStatus.PauseStartTime = pauseStartTime
newStatus = c.calculateRolloutConditions(r, newStatus, allRSs, newRS)
return c.persistRolloutStatus(r, &newStatus, &paused)
Expand Down Expand Up @@ -233,8 +239,12 @@ func (c *Controller) scaleBlueGreen(rollout *v1alpha1.Rollout, newRS *appsv1.Rep
}

if newRS != nil {
if *(newRS.Spec.Replicas) != rolloutReplicas {
_, _, err := c.scaleReplicaSetAndRecordEvent(newRS, rolloutReplicas, rollout)
newRSReplicaCount, err := replicasetutil.NewRSNewReplicas(rollout, allRS, newRS)
if err != nil {
return err
}
if *(newRS.Spec.Replicas) != newRSReplicaCount {
_, _, err := c.scaleReplicaSetAndRecordEvent(newRS, newRSReplicaCount, rollout)
return err
}
}
Expand Down
2 changes: 2 additions & 0 deletions controller/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ func (c *Controller) getNewReplicaSet(rollout *v1alpha1.Rollout, rsList, oldRSs

// sync is responsible for reconciling rollouts on scaling events.
func (c *Controller) sync(r *v1alpha1.Rollout, rsList []*appsv1.ReplicaSet) error {
logCtx := logutil.WithRollout(r)
logCtx.Info("Reconciling scaling event")
newRS, oldRSs, err := c.getAllReplicaSetsAndSyncRevision(r, rsList, false)
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion controller/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

func newRolloutWithStatus(name string, replicas int, revisionHistoryLimit *int32, selector map[string]string) *v1alpha1.Rollout {
rollout := newRollout(name, replicas, revisionHistoryLimit, selector)
rollout.Spec.Strategy.BlueGreenStrategy = &v1alpha1.BlueGreenStrategy{}
return rollout
}

Expand All @@ -46,7 +47,7 @@ func rs(name string, replicas int, selector map[string]string, timestamp metav1.
}
}

func TestScaleBlueGreen(t *testing.T) {
func TestScaleBlueGreen(t *testing.T) {
newTimestamp := metav1.Date(2016, 5, 20, 3, 0, 0, 0, time.UTC)
oldTimestamp := metav1.Date(2016, 5, 20, 2, 0, 0, 0, time.UTC)
olderTimestamp := metav1.Date(2016, 5, 20, 1, 0, 0, 0, time.UTC)
Expand Down
12 changes: 12 additions & 0 deletions manifests/crds/rollout-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ spec:
description: Name of the service that the rollout modifies as
the active service.
type: string
previewReplicaCount:
description: PreviewReplica the number of replicas to run under
the preview service before the switchover. Once the rollout
is resumed the new replicaset will be full scaled up before
the switch occurs
format: int32
type: integer
previewService:
description: Name of the service that the rollout modifies as
the preview service.
Expand Down Expand Up @@ -148,6 +155,11 @@ spec:
service is serving traffic to
type: string
scaleDownDelayStartTime: {}
scaleUpPreviewCheckPoint:
description: ScaleUpPreviewCheckPoint indicates that the Replicaset
receiving traffic from the preview service is ready to be scaled
up after the rollout is unpaused
type: boolean
canary:
description: CanaryStatus status fields that only pertain to the canary
rollout
Expand Down
12 changes: 12 additions & 0 deletions manifests/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ spec:
description: Name of the service that the rollout modifies as
the active service.
type: string
previewReplicaCount:
description: PreviewReplica the number of replicas to run under
the preview service before the switchover. Once the rollout
is resumed the new replicaset will be full scaled up before
the switch occurs
format: int32
type: integer
previewService:
description: Name of the service that the rollout modifies as
the preview service.
Expand Down Expand Up @@ -149,6 +156,11 @@ spec:
service is serving traffic to
type: string
scaleDownDelayStartTime: {}
scaleUpPreviewCheckPoint:
description: ScaleUpPreviewCheckPoint indicates that the Replicaset
receiving traffic from the preview service is ready to be scaled
up after the rollout is unpaused
type: boolean
canary:
description: CanaryStatus status fields that only pertain to the canary
rollout
Expand Down
12 changes: 12 additions & 0 deletions manifests/namespace-install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ spec:
description: Name of the service that the rollout modifies as
the active service.
type: string
previewReplicaCount:
description: PreviewReplica the number of replicas to run under
the preview service before the switchover. Once the rollout
is resumed the new replicaset will be full scaled up before
the switch occurs
format: int32
type: integer
previewService:
description: Name of the service that the rollout modifies as
the preview service.
Expand Down Expand Up @@ -149,6 +156,11 @@ spec:
service is serving traffic to
type: string
scaleDownDelayStartTime: {}
scaleUpPreviewCheckPoint:
description: ScaleUpPreviewCheckPoint indicates that the Replicaset
receiving traffic from the preview service is ready to be scaled
up after the rollout is unpaused
type: boolean
canary:
description: CanaryStatus status fields that only pertain to the canary
rollout
Expand Down
40 changes: 14 additions & 26 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.

13 changes: 7 additions & 6 deletions pkg/apis/rollouts/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ type BlueGreenStrategy struct {
// Name of the service that the rollout modifies as the preview service.
// +optional
PreviewService string `json:"previewService,omitempty"`
// PreviewReplica the number of replicas to run under the preview service before the switchover. Once the rollout is
// resumed the new replicaset will be full scaled up before the switch occurs
// +optional
PreviewReplicaCount *int32 `json:"previewReplicaCount,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 Expand Up @@ -124,12 +128,6 @@ type CanaryStep struct {
Pause *RolloutPause `json:"pause,omitempty"`
}

// SetPreview empty struct to indicate the SetPreview step
type SetPreview struct{}

// SwitchActive empty struct to indicate the SetActive step
type SwitchActive struct{}

// RolloutPause defines a pause stage for a rollout
type RolloutPause struct {
// Duration the amount of time to wait before moving to the next step.
Expand Down Expand Up @@ -201,6 +199,9 @@ type BlueGreenStatus struct {
// ScaleDownDelayStartTime indicates the start of the scaleDownDelay
// +optional
ScaleDownDelayStartTime *metav1.Time `json:"scaleDownDelayStartTime,omitempty"`
// ScaleUpPreviewCheckPoint indicates that the Replicaset receiving traffic from the preview service is ready to be scaled up after the rollout is unpaused
// +optional
ScaleUpPreviewCheckPoint bool `json:"scaleUpPreviewCheckPoint,omitempty""`
}

// CanaryStatus status fields that only pertain to the canary rollout
Expand Down
37 changes: 5 additions & 32 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.

34 changes: 34 additions & 0 deletions utils/replicaset/bluegreen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package replicaset

import (
appsv1 "k8s.io/api/apps/v1"

v1alpha1 "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
)

// GetActiveReplicaSet finds the replicaset that is serving traffic from the active service or returns nil
func GetActiveReplicaSet(allRS []*appsv1.ReplicaSet, activeSelector string) *appsv1.ReplicaSet {
if activeSelector == "" {
return nil
}
for _, rs := range allRS {
if rs == nil {
continue
}
if podHash, ok := rs.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]; ok {
if podHash == activeSelector {
return rs
}
}
}
return nil
}

func ReadyForPreview(rollout *v1alpha1.Rollout, newRS *appsv1.ReplicaSet, allRSs []*appsv1.ReplicaSet) bool {
newRSReplicaCount, err := NewRSNewReplicas(rollout, allRSs, newRS)
if err != nil {
return false
}
return *(newRS.Spec.Replicas) == newRSReplicaCount &&
newRS.Status.AvailableReplicas == newRSReplicaCount
}
66 changes: 66 additions & 0 deletions utils/replicaset/bluegreen_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package replicaset

import (
"testing"

"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"

"github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
)

func TestGetActiveReplicaSet(t *testing.T) {
assert.Nil(t, GetActiveReplicaSet(nil, ""))
rs1 := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: "abcd"},
},
}
assert.Nil(t, GetActiveReplicaSet([]*appsv1.ReplicaSet{rs1}, "1234"))

rs2 := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: "1234"},
},
}
assert.Equal(t, rs2, GetActiveReplicaSet([]*appsv1.ReplicaSet{nil, rs1, rs2}, "1234"))
}

func TestReadyForPreview(t *testing.T) {
rollout := &v1alpha1.Rollout{
Spec: v1alpha1.RolloutSpec{
Strategy: v1alpha1.RolloutStrategy{
BlueGreenStrategy: &v1alpha1.BlueGreenStrategy{},
},
},
}

readyRS := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: "abcd"},
},
Spec: appsv1.ReplicaSetSpec{
Replicas: pointer.Int32Ptr(1),
},
Status: appsv1.ReplicaSetStatus{
AvailableReplicas: 1,
},
}

notReadyRS := &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: "abcd"},
},
Spec: appsv1.ReplicaSetSpec{
Replicas: pointer.Int32Ptr(1),
},
Status: appsv1.ReplicaSetStatus{
AvailableReplicas: 0,
},
}
assert.False(t, ReadyForPreview(&v1alpha1.Rollout{}, nil, nil))
assert.True(t, ReadyForPreview(rollout, readyRS, []*appsv1.ReplicaSet{readyRS}))
assert.False(t, ReadyForPreview(rollout, notReadyRS, []*appsv1.ReplicaSet{readyRS}))
}
Loading

0 comments on commit d401101

Please sign in to comment.