Skip to content

Commit 3408659

Browse files
benminter-treatwellmeeech
authored andcommitted
fix(controller): use the stableRS from the rollout context rather tha… (argoproj#3664)
* fix(controller): use the stableRS from the rollout context rather than inferring it from the active selector, to deal with the edge case where the stableRS != activeRS during analysis templates Signed-off-by: ben.minter <[email protected]> * fix(controller): update tests which were relying on this bug(?) Signed-off-by: ben.minter <[email protected]> * fix(controller): add clarity to comment in the case there is no stableRS Signed-off-by: ben.minter <[email protected]> * fix(controller): add a test to assert that the stablers is not scaled by the reconiliation on start, by checking the log Signed-off-by: ben.minter <[email protected]> --------- Signed-off-by: ben.minter <[email protected]>
1 parent c287f18 commit 3408659

File tree

4 files changed

+98
-12
lines changed

4 files changed

+98
-12
lines changed

rollout/analysis_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -2532,7 +2532,7 @@ func TestRolloutPostPromotionAnalysisSuccess(t *testing.T) {
25322532
Status: v1alpha1.AnalysisPhaseRunning,
25332533
}
25342534

2535-
rs1 := newReplicaSetWithStatus(r1, 0, 0)
2535+
rs1 := newReplicaSetWithStatus(r1, 1, 1)
25362536
rs2 := newReplicaSetWithStatus(r2, 1, 1)
25372537
rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
25382538
rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
@@ -2558,6 +2558,7 @@ func TestRolloutPostPromotionAnalysisSuccess(t *testing.T) {
25582558
patch := f.getPatchedRollout(patchIndex)
25592559
expectedPatch := fmt.Sprintf(`{
25602560
"status": {
2561+
"replicas":2,
25612562
"stableRS": "%s",
25622563
"blueGreen": {
25632564
"postPromotionAnalysisRunStatus":{"status":"Successful"}

rollout/bluegreen.go

+6-10
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,14 @@ func (c *rolloutContext) rolloutBlueGreen() error {
7171
return c.syncRolloutStatusBlueGreen(previewSvc, activeSvc)
7272
}
7373

74-
func (c *rolloutContext) reconcileBlueGreenStableReplicaSet(activeSvc *corev1.Service) error {
75-
if _, ok := activeSvc.Spec.Selector[v1alpha1.DefaultRolloutUniqueLabelKey]; !ok {
76-
return nil
77-
}
78-
activeRS, _ := replicasetutil.GetReplicaSetByTemplateHash(c.allRSs, activeSvc.Spec.Selector[v1alpha1.DefaultRolloutUniqueLabelKey])
79-
if activeRS == nil {
80-
c.log.Warn("There shouldn't be a nil active replicaset if the active Service selector is set")
74+
func (c *rolloutContext) reconcileBlueGreenStableReplicaSet() error {
75+
if c.stableRS == nil {
76+
c.log.Info("Stable ReplicaSet doesn't exist and hence no reconciliation is required.")
8177
return nil
8278
}
8379

84-
c.log.Infof("Reconciling stable ReplicaSet '%s'", activeRS.Name)
85-
_, _, err := c.scaleReplicaSetAndRecordEvent(activeRS, defaults.GetReplicasOrDefault(c.rollout.Spec.Replicas))
80+
c.log.Infof("Reconciling stable ReplicaSet '%s'", c.stableRS.Name)
81+
_, _, err := c.scaleReplicaSetAndRecordEvent(c.stableRS, defaults.GetReplicasOrDefault(c.rollout.Spec.Replicas))
8682
if err != nil {
8783
return fmt.Errorf("failed to scaleReplicaSetAndRecordEvent in reconcileBlueGreenStableReplicaSet: %w", err)
8884
}
@@ -94,7 +90,7 @@ func (c *rolloutContext) reconcileBlueGreenReplicaSets(activeSvc *corev1.Service
9490
if err != nil {
9591
return err
9692
}
97-
err = c.reconcileBlueGreenStableReplicaSet(activeSvc)
93+
err = c.reconcileBlueGreenStableReplicaSet()
9894
if err != nil {
9995
return err
10096
}

rollout/bluegreen_test.go

+89
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package rollout
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"fmt"
67
"strconv"
8+
"strings"
79
"testing"
810
"time"
911

12+
log "github.com/sirupsen/logrus"
1013
"github.com/stretchr/testify/assert"
1114
corev1 "k8s.io/api/core/v1"
1215
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -1007,6 +1010,92 @@ func TestBlueGreenRolloutScaleUpdateActiveRS(t *testing.T) {
10071010
f.run(getKey(r2, t))
10081011
}
10091012

1013+
func TestBlueGreenRolloutScaleUpdateStableRS(t *testing.T) {
1014+
f := newFixture(t)
1015+
defer f.Close()
1016+
1017+
r1 := newBlueGreenRollout("foo", 1, nil, "active", "")
1018+
rs1 := newReplicaSetWithStatus(r1, 1, 1)
1019+
r2 := bumpVersion(r1)
1020+
1021+
rs2 := newReplicaSetWithStatus(r2, 1, 1)
1022+
f.kubeobjects = append(f.kubeobjects, rs1, rs2)
1023+
f.replicaSetLister = append(f.replicaSetLister, rs1, rs2)
1024+
1025+
rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
1026+
rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
1027+
1028+
// Make the new RS the active and the old one stable to simulate post-promotion analysis step.
1029+
r2 = updateBlueGreenRolloutStatus(r2, rs2PodHash, rs2PodHash, rs1PodHash, 1, 1, 2, 1, false, true, false)
1030+
1031+
f.rolloutLister = append(f.rolloutLister, r2)
1032+
1033+
f.objects = append(f.objects, r2)
1034+
activeSvc := newService("active", 80, map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash}, r2)
1035+
f.kubeobjects = append(f.kubeobjects, activeSvc)
1036+
f.serviceLister = append(f.serviceLister, activeSvc)
1037+
1038+
f.expectPatchRolloutAction(r1)
1039+
1040+
// Patch the rollout to get it in the state we want (old RS is stable and new is active)
1041+
f.run(getKey(r2, t))
1042+
// Actually update the replicas now that we are in the desired state (old RS is stable and new is active)
1043+
r2.Spec.Replicas = pointer.Int32Ptr(2)
1044+
1045+
f.expectUpdateReplicaSetAction(rs1)
1046+
f.expectUpdateReplicaSetAction(rs2)
1047+
f.run(getKey(r2, t))
1048+
}
1049+
1050+
func TestBlueGreenStableRSReconciliationShouldNotScaleOnFirstTimeRollout(t *testing.T) {
1051+
f := newFixture(t)
1052+
prevOutput := log.StandardLogger().Out
1053+
defer func() {
1054+
log.SetOutput(prevOutput)
1055+
}()
1056+
defer f.Close()
1057+
1058+
// Setup Logging capture
1059+
buf := bytes.NewBufferString("")
1060+
log.SetOutput(buf)
1061+
1062+
r := newBlueGreenRollout("foo", 1, nil, "active", "preview")
1063+
r.Status.Conditions = []v1alpha1.RolloutCondition{}
1064+
f.rolloutLister = append(f.rolloutLister, r)
1065+
f.objects = append(f.objects, r)
1066+
previewSvc := newService("preview", 80, nil, r)
1067+
activeSvc := newService("active", 80, nil, r)
1068+
f.kubeobjects = append(f.kubeobjects, previewSvc, activeSvc)
1069+
f.serviceLister = append(f.serviceLister, activeSvc, previewSvc)
1070+
1071+
rs := newReplicaSet(r, 1)
1072+
rsPodHash := rs.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]
1073+
generatedConditions := generateConditionsPatchWithCompleted(false, conditions.ReplicaSetUpdatedReason, rs, false, "", true)
1074+
1075+
f.expectCreateReplicaSetAction(rs)
1076+
f.expectPatchServiceAction(previewSvc, rsPodHash)
1077+
f.expectUpdateReplicaSetAction(rs) // scale up RS
1078+
f.expectUpdateRolloutStatusAction(r)
1079+
expectedPatchWithoutSubs := `{
1080+
"status":{
1081+
"blueGreen" : {
1082+
"previewSelector": "%s"
1083+
},
1084+
"conditions": %s,
1085+
"selector": "foo=bar",
1086+
"stableRS": "%s",
1087+
"phase": "Progressing",
1088+
"message": "more replicas need to be updated"
1089+
}
1090+
}`
1091+
expectedPatch := calculatePatch(r, fmt.Sprintf(expectedPatchWithoutSubs, rsPodHash, generatedConditions, rsPodHash))
1092+
f.expectPatchRolloutActionWithPatch(r, expectedPatch)
1093+
f.run(getKey(r, t))
1094+
1095+
logMessage := buf.String()
1096+
assert.True(t, strings.Contains(logMessage, "msg=\"Stable ReplicaSet doesn't exist and hence no reconciliation is required.\""), logMessage)
1097+
}
1098+
10101099
func TestPreviewReplicaCountHandleScaleUpPreviewCheckPoint(t *testing.T) {
10111100
t.Run("TrueAfterMeetingMinAvailable", func(t *testing.T) {
10121101
f := newFixture(t)

rollout/ephemeralmetadata_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func TestSyncBlueGreenEphemeralMetadataSecondRevision(t *testing.T) {
169169
f := newFixture(t)
170170
defer f.Close()
171171

172-
r1 := newBlueGreenRollout("foo", 1, nil, "active", "preview")
172+
r1 := newBlueGreenRollout("foo", 3, nil, "active", "preview")
173173
r1.Spec.Strategy.BlueGreen.AutoPromotionEnabled = pointer.BoolPtr(false)
174174
r1.Annotations[annotations.RevisionAnnotation] = "1"
175175
r1.Spec.Strategy.BlueGreen.PreviewMetadata = &v1alpha1.PodTemplateMetadata{

0 commit comments

Comments
 (0)