@@ -100,13 +100,15 @@ func (c *Controller) sync(key queueKey) error {
100100 pendingTags = []* imagev1.TagReference {releaseTag }
101101 }
102102
103+ var syncErrors []error
104+
103105 // ensure any pending tags have the necessary jobs/mirrors created
104106 if err := c .syncPending (release , pendingTags , inputImageHash ); err != nil {
105107 if errors .IsConflict (err ) {
106108 return nil
107109 }
108110 c .eventRecorder .Eventf (release .Source , corev1 .EventTypeWarning , "UnableToProcessRelease" , "%v" , err )
109- return err
111+ syncErrors = append ( syncErrors , err )
110112 }
111113
112114 // ensure verification steps are run on the ready tags
@@ -115,7 +117,7 @@ func (c *Controller) sync(key queueKey) error {
115117 return nil
116118 }
117119 c .eventRecorder .Eventf (release .Source , corev1 .EventTypeWarning , "UnableToVerifyRelease" , "%v" , err )
118- return err
120+ syncErrors = append ( syncErrors , err )
119121 }
120122
121123 // ensure publish steps are run on the accepted tags
@@ -124,7 +126,7 @@ func (c *Controller) sync(key queueKey) error {
124126 return nil
125127 }
126128 c .eventRecorder .Eventf (release .Source , corev1 .EventTypeWarning , "UnableToVerifyRelease" , "%v" , err )
127- return err
129+ syncErrors = append ( syncErrors , err )
128130 }
129131
130132 // if we're waiting for an interval to elapse, go ahead and queue to be woken
@@ -133,7 +135,7 @@ func (c *Controller) sync(key queueKey) error {
133135 }
134136
135137 c .gcQueue .AddAfter ("" , 15 * time .Second )
136- return nil
138+ return utilerrors . NewAggregate ( syncErrors )
137139}
138140
139141func calculateSyncActions (release * releasecontroller.Release , now time.Time ) (adoptTags , pendingTags , removeTags []* imagev1.TagReference , hasNewImages bool , inputImageHash string , queueAfter time.Duration ) {
@@ -290,109 +292,14 @@ func (c *Controller) syncAdopted(release *releasecontroller.Release, adoptTags [
290292func (c * Controller ) syncPending (release * releasecontroller.Release , pendingTags []* imagev1.TagReference , inputImageHash string ) (err error ) {
291293 switch release .Config .As {
292294 case releasecontroller .ReleaseConfigModeStable :
295+ var errs []error
293296 for _ , tag := range pendingTags {
294- // wait for import, then determine whether the requested version (tag name) matches the source version (label on image)
295- id := releasecontroller .FindImageIDForTag (release .Source , tag .Name )
296- if len (id ) == 0 {
297- klog .V (2 ).Infof ("Waiting for release %s to be imported before we can retrieve metadata" , tag .Name )
298- continue
299- }
300- klog .V (2 ).Infof ("Processing pending release %s" , tag .Name )
301- rewriteValue := tag .Annotations [releasecontroller .ReleaseAnnotationRewrite ]
302- if len (rewriteValue ) == 0 {
303- klog .V (2 ).Infof ("Rewriting pending release %s" , tag .Name )
304- isi , err := c .imageClient .ImageStreamImages (release .Source .Namespace ).Get (context .TODO (), fmt .Sprintf ("%s@%s" , release .Source .Name , id ), metav1.GetOptions {})
305- if err != nil {
306- return err
307- }
308- // Handle manifest list based releases...
309- for _ , m := range isi .Image .DockerImageManifests {
310- if m .Architecture == "amd64" {
311- isi , err = c .imageClient .ImageStreamImages (release .Source .Namespace ).Get (context .TODO (), fmt .Sprintf ("%s@%s" , release .Source .Name , m .Digest ), metav1.GetOptions {})
312- if err != nil {
313- return err
314- }
315- break
316- }
317- }
318- metadata := & docker10.DockerImage {}
319- if len (isi .Image .DockerImageMetadata .Raw ) == 0 {
320- return fmt .Errorf ("could not fetch Docker image metadata for release %s" , tag .Name )
321- }
322- if err := json .Unmarshal (isi .Image .DockerImageMetadata .Raw , metadata ); err != nil {
323- return fmt .Errorf ("malformed Docker image metadata on ImageStreamTag: %v" , err )
324- }
325- var name string
326- if metadata .Config != nil {
327- name = metadata .Config .Labels ["io.openshift.release" ]
328- }
329- rewriteValue = fmt .Sprintf ("%t" , name != tag .Name )
330- if err := c .setReleaseAnnotation (release , tag .Annotations [releasecontroller .ReleaseAnnotationPhase ], map [string ]string {releasecontroller .ReleaseAnnotationRewrite : rewriteValue }, tag .Name ); err != nil {
331- return err
332- }
333- continue
334- }
335- rewrite := rewriteValue == "true"
336-
337- hash := fmt .Sprintf ("%s-%d" , tag .Name , * tag .Generation )
338- // mirror any internal images
339- // rewrite payload for internal images with metadata
340- mirror , err := c .ensureReleaseMirror (release , tag .Name , hash )
341- if err != nil {
342- return err
343- }
344- if len (tag .Annotations [releasecontroller .ReleaseAnnotationImageHash ]) == 0 {
345- if err := c .setReleaseAnnotation (release , tag .Annotations [releasecontroller .ReleaseAnnotationPhase ], map [string ]string {releasecontroller .ReleaseAnnotationImageHash : mirror .Annotations [releasecontroller .ReleaseAnnotationImageHash ]}, tag .Name ); err != nil {
346- return err
347- }
348- continue
349- }
350- if mirror .Annotations [releasecontroller .ReleaseAnnotationImageHash ] != tag .Annotations [releasecontroller .ReleaseAnnotationImageHash ] {
351- // delete the mirror and exit
352- return fmt .Errorf ("unimplemented, should regenerate contents of tag" )
353- }
354- // Create the corresponding ReleasePayload object...
355- _ , err = c .ensureReleasePayload (release , tag )
356- if err != nil {
357- return err
358- }
359- // get metadata about the release
360- // get upgrade graph edges
361- // check to see any required edges are missing? wait for latest edge? wait for pending edges?
362- // how do we calculate required edge set?
363- var job * batchv1.Job
364- if rewrite {
365- job , err = c .ensureRewriteJob (release , tag .Name , mirror , `{}` )
366- } else {
367- job , err = c .ensureImportJob (release , tag .Name , mirror )
368- }
369- if err != nil || job == nil {
370- return err
371- }
372- payload , err := c .releasePayloadLister .ReleasePayloads (release .Target .Namespace ).Get (tag .Name )
373- if err != nil {
374- if ! errors .IsNotFound (err ) {
375- return err
376- }
377- return c .ensureRewriteJobImageRetrieved (release , job , mirror )
378- }
379- phase := releasecontroller .GetReleasePhase (payload )
380- switch phase {
381- case releasecontroller .ReleasePhaseReady :
382- if err := c .markReleaseReady (release , nil , tag .Name ); err != nil {
383- return err
384- }
385- c .precacheChangelog (release , tag )
386- case releasecontroller .ReleasePhaseFailed :
387- log , _ , _ := ensureJobTerminationMessageRetrieved (c .podClient , job , "status.phase=Failed" , "build" , false )
388- if err := c .transitionReleasePhaseFailure (release , []string {releasecontroller .ReleasePhasePending }, releasecontroller .ReleasePhaseFailed , withLog (reasonAndMessage ("CreateReleaseFailed" , "Could not create the release image" ), log ), tag .Name ); err != nil {
389- return err
390- }
391- default :
392- return c .ensureRewriteJobImageRetrieved (release , job , mirror )
297+ if err := c .syncPendingStableTag (release , tag ); err != nil {
298+ klog .Errorf ("Error processing pending stable tag %s: %v" , tag .Name , err )
299+ errs = append (errs , err )
393300 }
394301 }
395- return nil
302+ return utilerrors . NewAggregate ( errs )
396303 }
397304
398305 if len (pendingTags ) > 1 {
@@ -452,6 +359,100 @@ func (c *Controller) syncPending(release *releasecontroller.Release, pendingTags
452359 return nil
453360}
454361
362+ func (c * Controller ) syncPendingStableTag (release * releasecontroller.Release , tag * imagev1.TagReference ) error {
363+ id := releasecontroller .FindImageIDForTag (release .Source , tag .Name )
364+ if len (id ) == 0 {
365+ klog .V (2 ).Infof ("Waiting for release %s to be imported before we can retrieve metadata" , tag .Name )
366+ return nil
367+ }
368+ klog .V (2 ).Infof ("Processing pending release %s" , tag .Name )
369+ rewriteValue := tag .Annotations [releasecontroller .ReleaseAnnotationRewrite ]
370+ if len (rewriteValue ) == 0 {
371+ klog .V (2 ).Infof ("Rewriting pending release %s" , tag .Name )
372+ isi , err := c .imageClient .ImageStreamImages (release .Source .Namespace ).Get (context .TODO (), fmt .Sprintf ("%s@%s" , release .Source .Name , id ), metav1.GetOptions {})
373+ if err != nil {
374+ return err
375+ }
376+ for _ , m := range isi .Image .DockerImageManifests {
377+ if m .Architecture == "amd64" {
378+ isi , err = c .imageClient .ImageStreamImages (release .Source .Namespace ).Get (context .TODO (), fmt .Sprintf ("%s@%s" , release .Source .Name , m .Digest ), metav1.GetOptions {})
379+ if err != nil {
380+ return err
381+ }
382+ break
383+ }
384+ }
385+ metadata := & docker10.DockerImage {}
386+ if len (isi .Image .DockerImageMetadata .Raw ) == 0 {
387+ return fmt .Errorf ("could not fetch Docker image metadata for release %s" , tag .Name )
388+ }
389+ if err := json .Unmarshal (isi .Image .DockerImageMetadata .Raw , metadata ); err != nil {
390+ return fmt .Errorf ("malformed Docker image metadata on ImageStreamTag: %v" , err )
391+ }
392+ var name string
393+ if metadata .Config != nil {
394+ name = metadata .Config .Labels ["io.openshift.release" ]
395+ }
396+ rewriteValue = fmt .Sprintf ("%t" , name != tag .Name )
397+ if err := c .setReleaseAnnotation (release , tag .Annotations [releasecontroller .ReleaseAnnotationPhase ], map [string ]string {releasecontroller .ReleaseAnnotationRewrite : rewriteValue }, tag .Name ); err != nil {
398+ return err
399+ }
400+ return nil
401+ }
402+ rewrite := rewriteValue == "true"
403+
404+ hash := fmt .Sprintf ("%s-%d" , tag .Name , * tag .Generation )
405+ mirror , err := c .ensureReleaseMirror (release , tag .Name , hash )
406+ if err != nil {
407+ return err
408+ }
409+ if len (tag .Annotations [releasecontroller .ReleaseAnnotationImageHash ]) == 0 {
410+ if err := c .setReleaseAnnotation (release , tag .Annotations [releasecontroller .ReleaseAnnotationPhase ], map [string ]string {releasecontroller .ReleaseAnnotationImageHash : mirror .Annotations [releasecontroller .ReleaseAnnotationImageHash ]}, tag .Name ); err != nil {
411+ return err
412+ }
413+ return nil
414+ }
415+ if mirror .Annotations [releasecontroller .ReleaseAnnotationImageHash ] != tag .Annotations [releasecontroller .ReleaseAnnotationImageHash ] {
416+ return fmt .Errorf ("unimplemented, should regenerate contents of tag %s" , tag .Name )
417+ }
418+ _ , err = c .ensureReleasePayload (release , tag )
419+ if err != nil {
420+ return err
421+ }
422+ var job * batchv1.Job
423+ if rewrite {
424+ job , err = c .ensureRewriteJob (release , tag .Name , mirror , `{}` )
425+ } else {
426+ job , err = c .ensureImportJob (release , tag .Name , mirror )
427+ }
428+ if err != nil || job == nil {
429+ return err
430+ }
431+ payload , err := c .releasePayloadLister .ReleasePayloads (release .Target .Namespace ).Get (tag .Name )
432+ if err != nil {
433+ if ! errors .IsNotFound (err ) {
434+ return err
435+ }
436+ return c .ensureRewriteJobImageRetrieved (release , job , mirror )
437+ }
438+ phase := releasecontroller .GetReleasePhase (payload )
439+ switch phase {
440+ case releasecontroller .ReleasePhaseReady :
441+ if err := c .markReleaseReady (release , nil , tag .Name ); err != nil {
442+ return err
443+ }
444+ c .precacheChangelog (release , tag )
445+ case releasecontroller .ReleasePhaseFailed :
446+ log , _ , _ := ensureJobTerminationMessageRetrieved (c .podClient , job , "status.phase=Failed" , "build" , false )
447+ if err := c .transitionReleasePhaseFailure (release , []string {releasecontroller .ReleasePhasePending }, releasecontroller .ReleasePhaseFailed , withLog (reasonAndMessage ("CreateReleaseFailed" , "Could not create the release image" ), log ), tag .Name ); err != nil {
448+ return err
449+ }
450+ default :
451+ return c .ensureRewriteJobImageRetrieved (release , job , mirror )
452+ }
453+ return nil
454+ }
455+
455456func (c * Controller ) syncReady (release * releasecontroller.Release ) error {
456457 readyTags := releasecontroller .SortedRawReleaseTags (release , releasecontroller .ReleasePhaseReady )
457458
0 commit comments