@@ -87,7 +87,7 @@ func (c *DeploymentConfigController) Handle(config *appsapi.DeploymentConfig) er
87
87
glog .V (5 ).Infof ("Reconciling %s/%s" , config .Namespace , config .Name )
88
88
// There's nothing to reconcile until the version is nonzero.
89
89
if appsutil .IsInitialDeployment (config ) && ! appsutil .HasTrigger (config ) {
90
- return c .updateStatus (config , []* v1.ReplicationController {})
90
+ return c .updateStatus (config , []* v1.ReplicationController {}, true )
91
91
}
92
92
93
93
// List all ReplicationControllers to find also those we own but that no longer match our selector.
@@ -118,7 +118,18 @@ func (c *DeploymentConfigController) Handle(config *appsapi.DeploymentConfig) er
118
118
// the latest available information. Some deletions make take some time to complete so there
119
119
// is value in doing this.
120
120
if config .DeletionTimestamp != nil {
121
- return c .updateStatus (config , existingDeployments )
121
+ return c .updateStatus (config , existingDeployments , true )
122
+ }
123
+
124
+ // If the config is paused we shouldn't create new deployments for it.
125
+ if config .Spec .Paused {
126
+ // in order for revision history limit cleanup to work for paused
127
+ // deployments, we need to trigger it here
128
+ if err := c .cleanupOldDeployments (existingDeployments , config ); err != nil {
129
+ c .recorder .Eventf (config , v1 .EventTypeWarning , "DeploymentCleanupFailed" , "Couldn't clean up deployments: %v" , err )
130
+ }
131
+
132
+ return c .updateStatus (config , existingDeployments , true )
122
133
}
123
134
124
135
latestExists , latestDeployment := appsutil .LatestDeploymentInfo (config , existingDeployments )
@@ -128,38 +139,52 @@ func (c *DeploymentConfigController) Handle(config *appsapi.DeploymentConfig) er
128
139
return err
129
140
}
130
141
}
142
+
143
+ // Never deploy with invalid or unresolved images
144
+ for i , container := range config .Spec .Template .Spec .Containers {
145
+ if len (strings .TrimSpace (container .Image )) == 0 {
146
+ glog .V (4 ).Infof ("Postponing rollout #%d for DeploymentConfig %s/%s because of invalid or unresolved image for container #%d (name=%s)" , config .Status .LatestVersion , config .Namespace , config .Name , i , container .Name )
147
+ return c .updateStatus (config , existingDeployments , true )
148
+ }
149
+ }
150
+
131
151
configCopy := config .DeepCopy ()
132
152
// Process triggers and start an initial rollouts
133
- shouldTrigger , shouldSkip := triggerActivated (configCopy , latestExists , latestDeployment , c .codec )
134
- if ! shouldSkip && shouldTrigger {
135
- configCopy .Status .LatestVersion ++
136
- return c .updateStatus (configCopy , existingDeployments )
153
+ shouldTrigger , shouldSkip , err := triggerActivated (configCopy , latestExists , latestDeployment , c .codec )
154
+ if err != nil {
155
+ return fmt .Errorf ("triggerActivated failed: %v" , err )
137
156
}
138
- // Have to wait for the image trigger to get the image before proceeding.
139
- if shouldSkip && appsutil . IsInitialDeployment ( config ) {
140
- return c .updateStatus (configCopy , existingDeployments )
157
+
158
+ if shouldSkip {
159
+ return c .updateStatus (configCopy , existingDeployments , true )
141
160
}
161
+
162
+ if shouldTrigger {
163
+ configCopy .Status .LatestVersion ++
164
+ _ , err := c .dn .DeploymentConfigs (configCopy .Namespace ).UpdateStatus (configCopy )
165
+ return err
166
+ }
167
+
142
168
// If the latest deployment already exists, reconcile existing deployments
143
169
// and return early.
144
170
if latestExists {
145
171
// If the latest deployment is still running, try again later. We don't
146
172
// want to compete with the deployer.
147
173
if ! appsutil .IsTerminatedDeployment (latestDeployment ) {
148
- return c .updateStatus (config , existingDeployments )
174
+ return c .updateStatus (config , existingDeployments , false )
149
175
}
150
176
151
177
return c .reconcileDeployments (existingDeployments , config , cm )
152
178
}
153
- // If the config is paused we shouldn't create new deployments for it.
154
- if config .Spec .Paused {
155
- // in order for revision history limit cleanup to work for paused
156
- // deployments, we need to trigger it here
157
- if err := c .cleanupOldDeployments (existingDeployments , config ); err != nil {
158
- c .recorder .Eventf (config , v1 .EventTypeWarning , "DeploymentCleanupFailed" , "Couldn't clean up deployments: %v" , err )
159
- }
160
179
161
- return c .updateStatus (config , existingDeployments )
180
+ // Never deploy with invalid or unresolved images
181
+ for i , container := range config .Spec .Template .Spec .Containers {
182
+ if len (strings .TrimSpace (container .Image )) == 0 {
183
+ glog .V (4 ).Infof ("Postponing rollout #%d for DeploymentConfig %s/%s because of invalid or unresolved image for container #%d (name=%s)" , config .Status .LatestVersion , config .Namespace , config .Name , i , container .Name )
184
+ return c .updateStatus (config , existingDeployments , true )
185
+ }
162
186
}
187
+
163
188
// No deployments are running and the latest deployment doesn't exist, so
164
189
// create the new deployment.
165
190
deployment , err := appsutil .MakeDeploymentV1 (config , c .codec )
@@ -182,17 +207,17 @@ func (c *DeploymentConfigController) Handle(config *appsapi.DeploymentConfig) er
182
207
if isOurs {
183
208
// If the deployment was already created, just move on. The cache could be
184
209
// stale, or another process could have already handled this update.
185
- return c .updateStatus (config , existingDeployments )
210
+ return c .updateStatus (config , existingDeployments , true )
186
211
} else {
187
- err = fmt .Errorf ("replication controller %s already exists and deployment config is not allowed to claim it. " , deployment .Name )
212
+ err = fmt .Errorf ("replication controller %s already exists and deployment config is not allowed to claim it" , deployment .Name )
188
213
c .recorder .Eventf (config , v1 .EventTypeWarning , "DeploymentCreationFailed" , "Couldn't deploy version %d: %v" , config .Status .LatestVersion , err )
189
- return c .updateStatus (config , existingDeployments )
214
+ return c .updateStatus (config , existingDeployments , true )
190
215
}
191
216
}
192
217
c .recorder .Eventf (config , v1 .EventTypeWarning , "DeploymentCreationFailed" , "Couldn't deploy version %d: %s" , config .Status .LatestVersion , err )
193
218
// We don't care about this error since we need to report the create failure.
194
219
cond := appsutil .NewDeploymentCondition (appsapi .DeploymentProgressing , kapi .ConditionFalse , appsapi .FailedRcCreateReason , err .Error ())
195
- _ = c .updateStatus (config , existingDeployments , * cond )
220
+ _ = c .updateStatus (config , existingDeployments , true , * cond )
196
221
return fmt .Errorf ("couldn't create deployment for deployment config %s: %v" , appsutil .LabelForDeploymentConfig (config ), err )
197
222
}
198
223
msg := fmt .Sprintf ("Created new replication controller %q for version %d" , created .Name , config .Status .LatestVersion )
@@ -206,7 +231,7 @@ func (c *DeploymentConfigController) Handle(config *appsapi.DeploymentConfig) er
206
231
}
207
232
208
233
cond := appsutil .NewDeploymentCondition (appsapi .DeploymentProgressing , kapi .ConditionTrue , appsapi .NewReplicationControllerReason , msg )
209
- return c .updateStatus (config , existingDeployments , * cond )
234
+ return c .updateStatus (config , existingDeployments , true , * cond )
210
235
}
211
236
212
237
// reconcileDeployments reconciles existing deployment replica counts which
@@ -285,13 +310,13 @@ func (c *DeploymentConfigController) reconcileDeployments(existingDeployments []
285
310
c .recorder .Eventf (config , v1 .EventTypeWarning , "ReplicationControllerCleanupFailed" , "Couldn't clean up replication controllers: %v" , err )
286
311
}
287
312
288
- return c .updateStatus (config , updatedDeployments )
313
+ return c .updateStatus (config , updatedDeployments , true )
289
314
}
290
315
291
316
// Update the status of the provided deployment config. Additional conditions will override any other condition in the
292
317
// deployment config status.
293
- func (c * DeploymentConfigController ) updateStatus (config * appsapi.DeploymentConfig , deployments []* v1.ReplicationController , additional ... appsapi.DeploymentCondition ) error {
294
- newStatus := calculateStatus (config , deployments , additional ... )
318
+ func (c * DeploymentConfigController ) updateStatus (config * appsapi.DeploymentConfig , deployments []* v1.ReplicationController , updateObservedGeneration bool , additional ... appsapi.DeploymentCondition ) error {
319
+ newStatus := calculateStatus (config , deployments , updateObservedGeneration , additional ... )
295
320
296
321
// NOTE: We should update the status of the deployment config only if we need to, otherwise
297
322
// we hotloop between updates.
@@ -376,7 +401,7 @@ func (c *DeploymentConfigController) cancelRunningRollouts(config *appsapi.Deplo
376
401
return nil
377
402
}
378
403
379
- func calculateStatus (config * appsapi.DeploymentConfig , rcs []* v1.ReplicationController , additional ... appsapi.DeploymentCondition ) appsapi.DeploymentConfigStatus {
404
+ func calculateStatus (config * appsapi.DeploymentConfig , rcs []* v1.ReplicationController , updateObservedGeneration bool , additional ... appsapi.DeploymentCondition ) appsapi.DeploymentConfigStatus {
380
405
// UpdatedReplicas represents the replicas that use the current deployment config template which means
381
406
// we should inform about the replicas of the latest deployment and not the active.
382
407
latestReplicas := int32 (0 )
@@ -394,10 +419,15 @@ func calculateStatus(config *appsapi.DeploymentConfig, rcs []*v1.ReplicationCont
394
419
unavailableReplicas = 0
395
420
}
396
421
422
+ generation := config .Status .ObservedGeneration
423
+ if updateObservedGeneration {
424
+ generation = config .Generation
425
+ }
426
+
397
427
status := appsapi.DeploymentConfigStatus {
398
428
LatestVersion : config .Status .LatestVersion ,
399
429
Details : config .Status .Details ,
400
- ObservedGeneration : config . Generation ,
430
+ ObservedGeneration : generation ,
401
431
Replicas : appsutil .GetStatusReplicaCountForDeployments (rcs ),
402
432
UpdatedReplicas : latestReplicas ,
403
433
AvailableReplicas : available ,
@@ -519,17 +549,17 @@ func (c *DeploymentConfigController) cleanupOldDeployments(existingDeployments [
519
549
// triggers were activated (config change or image change). The first bool indicates that
520
550
// the triggers are active and second indicates if we should skip the rollout because we
521
551
// are waiting for the trigger to complete update (waiting for image for example).
522
- func triggerActivated (config * appsapi.DeploymentConfig , latestExists bool , latestDeployment * v1.ReplicationController , codec runtime.Codec ) (bool , bool ) {
552
+ func triggerActivated (config * appsapi.DeploymentConfig , latestExists bool , latestDeployment * v1.ReplicationController , codec runtime.Codec ) (bool , bool , error ) {
523
553
if config .Spec .Paused {
524
- return false , false
554
+ return false , false , nil
525
555
}
526
556
imageTrigger := appsutil .HasImageChangeTrigger (config )
527
557
configTrigger := appsutil .HasChangeTrigger (config )
528
558
hasTrigger := imageTrigger || configTrigger
529
559
530
560
// no-op when no triggers are defined.
531
561
if ! hasTrigger {
532
- return false , false
562
+ return false , false , nil
533
563
}
534
564
535
565
// Handle initial rollouts
@@ -542,50 +572,49 @@ func triggerActivated(config *appsapi.DeploymentConfig, latestExists bool, lates
542
572
// TODO: Technically this is not a config change cause, but we will have to report the image that caused the trigger.
543
573
// In some cases it might be difficult because config can have multiple ICT.
544
574
appsutil .RecordConfigChangeCause (config )
545
- return true , false
575
+ return true , false , nil
546
576
}
547
577
glog .V (4 ).Infof ("Rolling out initial deployment for %s/%s deferred until its images are ready" , config .Namespace , config .Name )
548
- return false , true
578
+ return false , true , nil
549
579
}
550
580
// Rollout if we only have config change trigger.
551
581
if configTrigger {
552
582
glog .V (4 ).Infof ("Rolling out initial deployment for %s/%s" , config .Namespace , config .Name )
553
583
appsutil .RecordConfigChangeCause (config )
554
- return true , false
584
+ return true , false , nil
555
585
}
556
586
// We are waiting for the initial RC to be created.
557
- return false , false
587
+ return false , false , nil
558
588
}
559
589
560
590
// Wait for the RC to be created
561
591
if ! latestExists {
562
- return false , true
592
+ return false , false , nil
563
593
}
564
594
565
595
// We need existing deployment at this point to compare its template with current config template.
566
596
if latestDeployment == nil {
567
- return false , false
597
+ return false , false , nil
568
598
}
569
599
570
600
if imageTrigger {
571
601
if ok , imageNames := appsutil .HasUpdatedImages (config , latestDeployment ); ok {
572
602
glog .V (4 ).Infof ("Rolling out #%d deployment for %s/%s caused by image changes (%s)" , config .Status .LatestVersion + 1 , config .Namespace , config .Name , strings .Join (imageNames , "," ))
573
603
appsutil .RecordImageChangeCauses (config , imageNames )
574
- return true , false
604
+ return true , false , nil
575
605
}
576
606
}
577
607
578
608
if configTrigger {
579
609
isLatest , changes , err := appsutil .HasLatestPodTemplate (config , latestDeployment , codec )
580
610
if err != nil {
581
- glog .Errorf ("Error while checking for latest pod template in replication controller: %v" , err )
582
- return false , true
611
+ return false , false , fmt .Errorf ("error while checking for latest pod template in replication controller: %v" , err )
583
612
}
584
613
if ! isLatest {
585
614
glog .V (4 ).Infof ("Rolling out #%d deployment for %s/%s caused by config change, diff: %s" , config .Status .LatestVersion + 1 , config .Namespace , config .Name , changes )
586
615
appsutil .RecordConfigChangeCause (config )
587
- return true , false
616
+ return true , false , nil
588
617
}
589
618
}
590
- return false , false
619
+ return false , false , nil
591
620
}
0 commit comments