@@ -20,6 +20,8 @@ import (
2020
2121 mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
2222 mcfgv1alpha1 "github.com/openshift/api/machineconfiguration/v1alpha1"
23+ configinformersv1 "github.com/openshift/client-go/config/informers/externalversions/config/v1"
24+ configlistersv1 "github.com/openshift/client-go/config/listers/config/v1"
2325 mcfgclientset "github.com/openshift/client-go/machineconfiguration/clientset/versioned"
2426 "github.com/openshift/client-go/machineconfiguration/clientset/versioned/scheme"
2527 mcfginformersv1 "github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1"
@@ -28,6 +30,7 @@ import (
2830 mcfglistersv1alpha1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1alpha1"
2931 ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
3032 templatectrl "github.com/openshift/machine-config-operator/pkg/controller/template"
33+ "github.com/openshift/machine-config-operator/pkg/osimagestream"
3134 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3235)
3336
@@ -64,6 +67,9 @@ type Controller struct {
6467 mcLister mcfglistersv1.MachineConfigLister
6568 mcListerSynced cache.InformerSynced
6669
70+ clusterVersionLister configlistersv1.ClusterVersionLister
71+ clusterVersionListerSynced cache.InformerSynced
72+
6773 queue workqueue.TypedRateLimitingInterface [string ]
6874}
6975
@@ -72,6 +78,7 @@ func New(
7278 iriInformer mcfginformersv1alpha1.InternalReleaseImageInformer ,
7379 ccInformer mcfginformersv1.ControllerConfigInformer ,
7480 mcInformer mcfginformersv1.MachineConfigInformer ,
81+ clusterVersionInformer configinformersv1.ClusterVersionInformer ,
7582 kubeClient clientset.Interface ,
7683 mcfgClient mcfgclientset.Interface ,
7784) * Controller {
@@ -115,6 +122,9 @@ func New(
115122 ctrl .mcLister = mcInformer .Lister ()
116123 ctrl .mcListerSynced = mcInformer .Informer ().HasSynced
117124
125+ ctrl .clusterVersionLister = clusterVersionInformer .Lister ()
126+ ctrl .clusterVersionListerSynced = clusterVersionInformer .Informer ().HasSynced
127+
118128 return ctrl
119129}
120130
@@ -123,7 +133,7 @@ func (ctrl *Controller) Run(workers int, stopCh <-chan struct{}) {
123133 defer utilruntime .HandleCrash ()
124134 defer ctrl .queue .ShutDown ()
125135
126- if ! cache .WaitForCacheSync (stopCh , ctrl .iriListerSynced ) {
136+ if ! cache .WaitForCacheSync (stopCh , ctrl .iriListerSynced , ctrl . ccListerSynced , ctrl . mcListerSynced , ctrl . clusterVersionListerSynced ) {
127137 return
128138 }
129139
@@ -336,6 +346,61 @@ func (ctrl *Controller) syncInternalReleaseImage(key string) error {
336346 }
337347 }
338348
349+ // Initialize status if empty
350+ if err := ctrl .initializeInternalReleaseImageStatus (iri ); err != nil {
351+ return err
352+ }
353+
354+ return nil
355+ }
356+
357+ // initializeInternalReleaseImageStatus initializes the status of an InternalReleaseImage
358+ // if it is empty. It populates the status with release bundle entries from the spec,
359+ // setting the Image field from the current ClusterVersion and adding initial conditions.
360+ func (ctrl * Controller ) initializeInternalReleaseImageStatus (iri * mcfgv1alpha1.InternalReleaseImage ) error {
361+ // Only initialize if status is empty and spec has releases
362+ if len (iri .Status .Releases ) != 0 || len (iri .Spec .Releases ) == 0 {
363+ return nil
364+ }
365+
366+ klog .V (4 ).Infof ("Initializing status for InternalReleaseImage %s" , iri .Name )
367+
368+ // Get the release payload image from ClusterVersion
369+ releaseImage , err := osimagestream .GetReleasePayloadImage (ctrl .clusterVersionLister )
370+ if err != nil {
371+ return fmt .Errorf ("error getting Release Image from ClusterVersion for InternalReleaseImage status initialization: %w" , err )
372+ }
373+
374+ // Build status releases from spec releases
375+ statusReleases := make ([]mcfgv1alpha1.InternalReleaseImageBundleStatus , 0 , len (iri .Spec .Releases ))
376+ for _ , specRelease := range iri .Spec .Releases {
377+ statusRelease := mcfgv1alpha1.InternalReleaseImageBundleStatus {
378+ Name : specRelease .Name ,
379+ Image : releaseImage ,
380+ Conditions : []metav1.Condition {
381+ {
382+ Type : string (mcfgv1alpha1 .InternalReleaseImageConditionTypeAvailable ),
383+ Status : metav1 .ConditionTrue ,
384+ LastTransitionTime : metav1 .Now (),
385+ Reason : "Installed" ,
386+ Message : "Release bundle is available" ,
387+ },
388+ },
389+ }
390+ statusReleases = append (statusReleases , statusRelease )
391+ }
392+
393+ iri .Status .Releases = statusReleases
394+
395+ // Update the status subresource
396+ if err := retry .RetryOnConflict (updateBackoff , func () error {
397+ _ , err := ctrl .client .MachineconfigurationV1alpha1 ().InternalReleaseImages ().UpdateStatus (context .TODO (), iri , metav1.UpdateOptions {})
398+ return err
399+ }); err != nil {
400+ return fmt .Errorf ("failed to update InternalReleaseImage status: %w" , err )
401+ }
402+
403+ klog .V (2 ).Infof ("Initialized status for InternalReleaseImage %s with %d releases" , iri .Name , len (statusReleases ))
339404 return nil
340405}
341406
0 commit comments