@@ -58,8 +58,7 @@ func (c *Controller) scheduleCanaries() {
58
58
for canaryName , targetName := range current {
59
59
for name , target := range current {
60
60
if name != canaryName && target == targetName {
61
- c .logger .Errorf ("Bad things will happen! Found more than one canary with the same target %s" ,
62
- targetName )
61
+ c .logger .With ("canary" , canaryName ).Errorf ("Bad things will happen! Found more than one canary with the same target %s" , targetName )
63
62
}
64
63
}
65
64
}
@@ -70,7 +69,7 @@ func (c *Controller) scheduleCanaries() {
70
69
}
71
70
}
72
71
73
- func (c * Controller ) advanceCanary (name string , namespace string ) {
72
+ func (c * Controller ) advanceCanary (name string , namespace string , skipLivenessChecks bool ) {
74
73
begin := time .Now ()
75
74
// check if the canary exists
76
75
cd , err := c .flaggerClient .FlaggerV1alpha3 ().Canaries (namespace ).Get (name , v1.GetOptions {})
@@ -105,9 +104,11 @@ func (c *Controller) advanceCanary(name string, namespace string) {
105
104
}
106
105
107
106
// check primary deployment status
108
- if _ , err := c .deployer .IsPrimaryReady (cd ); err != nil {
109
- c .recordEventWarningf (cd , "%v" , err )
110
- return
107
+ if ! skipLivenessChecks {
108
+ if _ , err := c .deployer .IsPrimaryReady (cd ); err != nil {
109
+ c .recordEventWarningf (cd , "%v" , err )
110
+ return
111
+ }
111
112
}
112
113
113
114
// check if virtual service exists
@@ -121,7 +122,33 @@ func (c *Controller) advanceCanary(name string, namespace string) {
121
122
c .recorder .SetWeight (cd , primaryRoute .Weight , canaryRoute .Weight )
122
123
123
124
// check if canary analysis should start (canary revision has changes) or continue
124
- if ok := c .checkCanaryStatus (cd , c .deployer ); ! ok {
125
+ if ok := c .checkCanaryStatus (cd ); ! ok {
126
+ return
127
+ }
128
+
129
+ // check if canary revision changed during analysis
130
+ if restart := c .hasCanaryRevisionChanged (cd ); restart {
131
+ c .recordEventInfof (cd , "New revision detected! Restarting analysis for %s.%s" ,
132
+ cd .Spec .TargetRef .Name , cd .Namespace )
133
+
134
+ // route all traffic back to primary
135
+ primaryRoute .Weight = 100
136
+ canaryRoute .Weight = 0
137
+ if err := c .router .SetRoutes (cd , primaryRoute , canaryRoute ); err != nil {
138
+ c .recordEventWarningf (cd , "%v" , err )
139
+ return
140
+ }
141
+
142
+ // reset status
143
+ status := flaggerv1.CanaryStatus {
144
+ Phase : flaggerv1 .CanaryProgressing ,
145
+ CanaryWeight : 0 ,
146
+ FailedChecks : 0 ,
147
+ }
148
+ if err := c .deployer .SyncStatus (cd , status ); err != nil {
149
+ c .recordEventWarningf (cd , "%v" , err )
150
+ return
151
+ }
125
152
return
126
153
}
127
154
@@ -130,10 +157,13 @@ func (c *Controller) advanceCanary(name string, namespace string) {
130
157
}()
131
158
132
159
// check canary deployment status
133
- retriable , err := c .deployer .IsCanaryReady (cd )
134
- if err != nil && retriable {
135
- c .recordEventWarningf (cd , "%v" , err )
136
- return
160
+ var retriable = true
161
+ if ! skipLivenessChecks {
162
+ retriable , err = c .deployer .IsCanaryReady (cd )
163
+ if err != nil && retriable {
164
+ c .recordEventWarningf (cd , "%v" , err )
165
+ return
166
+ }
137
167
}
138
168
139
169
// check if the number of failed checks reached the threshold
@@ -185,7 +215,7 @@ func (c *Controller) advanceCanary(name string, namespace string) {
185
215
// check if the canary success rate is above the threshold
186
216
// skip check if no traffic is routed to canary
187
217
if canaryRoute .Weight == 0 {
188
- c .recordEventInfof (cd , "Starting canary deployment for %s.%s" , cd .Name , cd .Namespace )
218
+ c .recordEventInfof (cd , "Starting canary analysis for %s.%s" , cd . Spec . TargetRef .Name , cd .Namespace )
189
219
} else {
190
220
if ok := c .analyseCanary (cd ); ! ok {
191
221
if err := c .deployer .SetStatusFailedChecks (cd , cd .Status .FailedChecks + 1 ); err != nil {
@@ -260,14 +290,14 @@ func (c *Controller) advanceCanary(name string, namespace string) {
260
290
}
261
291
}
262
292
263
- func (c * Controller ) checkCanaryStatus (cd * flaggerv1.Canary , deployer CanaryDeployer ) bool {
293
+ func (c * Controller ) checkCanaryStatus (cd * flaggerv1.Canary ) bool {
264
294
c .recorder .SetStatus (cd )
265
295
if cd .Status .Phase == flaggerv1 .CanaryProgressing {
266
296
return true
267
297
}
268
298
269
299
if cd .Status .Phase == "" {
270
- if err := deployer .SyncStatus (cd , flaggerv1.CanaryStatus {Phase : flaggerv1 .CanaryInitialized }); err != nil {
300
+ if err := c . deployer .SyncStatus (cd , flaggerv1.CanaryStatus {Phase : flaggerv1 .CanaryInitialized }); err != nil {
271
301
c .logger .With ("canary" , fmt .Sprintf ("%s.%s" , cd .Name , cd .Namespace )).Errorf ("%v" , err )
272
302
return false
273
303
}
@@ -278,15 +308,15 @@ func (c *Controller) checkCanaryStatus(cd *flaggerv1.Canary, deployer CanaryDepl
278
308
return false
279
309
}
280
310
281
- if diff , err := deployer .IsNewSpec (cd ); diff {
311
+ if diff , err := c . deployer .IsNewSpec (cd ); diff {
282
312
c .recordEventInfof (cd , "New revision detected! Scaling up %s.%s" , cd .Spec .TargetRef .Name , cd .Namespace )
283
313
c .sendNotification (cd , "New revision detected, starting canary analysis." ,
284
314
true , false )
285
- if err = deployer .Scale (cd , 1 ); err != nil {
315
+ if err = c . deployer .Scale (cd , 1 ); err != nil {
286
316
c .recordEventErrorf (cd , "%v" , err )
287
317
return false
288
318
}
289
- if err := deployer .SyncStatus (cd , flaggerv1.CanaryStatus {Phase : flaggerv1 .CanaryProgressing }); err != nil {
319
+ if err := c . deployer .SyncStatus (cd , flaggerv1.CanaryStatus {Phase : flaggerv1 .CanaryProgressing }); err != nil {
290
320
c .logger .With ("canary" , fmt .Sprintf ("%s.%s" , cd .Name , cd .Namespace )).Errorf ("%v" , err )
291
321
return false
292
322
}
@@ -296,6 +326,15 @@ func (c *Controller) checkCanaryStatus(cd *flaggerv1.Canary, deployer CanaryDepl
296
326
return false
297
327
}
298
328
329
+ func (c * Controller ) hasCanaryRevisionChanged (cd * flaggerv1.Canary ) bool {
330
+ if cd .Status .Phase == flaggerv1 .CanaryProgressing {
331
+ if diff , _ := c .deployer .IsNewSpec (cd ); diff {
332
+ return true
333
+ }
334
+ }
335
+ return false
336
+ }
337
+
299
338
func (c * Controller ) analyseCanary (r * flaggerv1.Canary ) bool {
300
339
// run metrics checks
301
340
for _ , metric := range r .Spec .CanaryAnalysis .Metrics {
0 commit comments