@@ -35,6 +35,7 @@ import (
3535 "helm.sh/helm/v3/pkg/postrender"
3636 "helm.sh/helm/v3/pkg/release"
3737 "helm.sh/helm/v3/pkg/storage/driver"
38+ corev1 "k8s.io/api/core/v1"
3839 "k8s.io/apimachinery/pkg/api/equality"
3940 apierrors "k8s.io/apimachinery/pkg/api/errors"
4041 apimeta "k8s.io/apimachinery/pkg/api/meta"
@@ -49,6 +50,7 @@ import (
4950 ctrl "sigs.k8s.io/controller-runtime"
5051 "sigs.k8s.io/controller-runtime/pkg/cache"
5152 "sigs.k8s.io/controller-runtime/pkg/client"
53+ "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
5254 crcontroller "sigs.k8s.io/controller-runtime/pkg/controller"
5355 crhandler "sigs.k8s.io/controller-runtime/pkg/handler"
5456 "sigs.k8s.io/controller-runtime/pkg/log"
@@ -156,6 +158,12 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
156158 return ctrl.Result {}, err
157159 }
158160
161+ bundleVersion , err := bundle .Version ()
162+ if err != nil {
163+ setInstalledStatusConditionFailed (& ext .Status .Conditions , fmt .Sprintf ("%s:%v" , "unable to get resolved bundle version" , err ), ext .Generation )
164+ return ctrl.Result {}, err
165+ }
166+
159167 // Now we can set the Resolved Condition, and the resolvedBundleSource field to the bundle.Image value.
160168 ext .Status .ResolvedBundle = bundleMetadataFor (bundle )
161169 setResolvedStatusConditionSuccess (& ext .Status .Conditions , fmt .Sprintf ("resolved to %q" , bundle .Image ), ext .GetGeneration ())
@@ -164,7 +172,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
164172 // Considering only image source.
165173
166174 // Generate a BundleSource, and then pass this and the ClusterExtension to Unpack
167- bs := r .GenerateExpectedBundleSource (* ext , bundle .Image )
175+ bs := r .GenerateExpectedBundleSource (bundle .Image )
168176 unpackResult , err := r .Unpacker .Unpack (ctx , bs , ext )
169177 if err != nil {
170178 return ctrl.Result {}, updateStatusUnpackFailing (& ext .Status , fmt .Errorf ("source bundle content: %v" , err ))
@@ -223,8 +231,11 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
223231
224232 post := & postrenderer {
225233 labels : map [string ]string {
226- util .CoreOwnerKindKey : ocv1alpha1 .ClusterExtensionKind ,
227- util .CoreOwnerNameKey : ext .GetName (),
234+ util .CoreOwnerKindKey : ocv1alpha1 .ClusterExtensionKind ,
235+ util .CoreOwnerNameKey : ext .GetName (),
236+ util .ResolvedbundleName : bundle .Name ,
237+ util .ResolvedbundlePackageName : bundle .Package ,
238+ util .ResolvedbundleVersion : bundleVersion .String (),
228239 },
229240 }
230241
@@ -390,7 +401,7 @@ func SetDeprecationStatus(ext *ocv1alpha1.ClusterExtension, bundle *catalogmetad
390401 }
391402}
392403
393- func (r * ClusterExtensionReconciler ) GenerateExpectedBundleSource (o ocv1alpha1. ClusterExtension , bundlePath string ) * rukpakapi.BundleSource {
404+ func (r * ClusterExtensionReconciler ) GenerateExpectedBundleSource (bundlePath string ) * rukpakapi.BundleSource {
394405 return & rukpakapi.BundleSource {
395406 Type : rukpakapi .SourceTypeImage ,
396407 Image : rukpakapi.ImageSource {
@@ -449,7 +460,7 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
449460 For (& ocv1alpha1.ClusterExtension {}).
450461 Watches (& catalogd.Catalog {},
451462 crhandler .EnqueueRequestsFromMapFunc (clusterExtensionRequestsForCatalog (mgr .GetClient (), mgr .GetLogger ()))).
452- Owns ( & rukpakv1alpha2. BundleDeployment {} ).
463+ Watches ( & corev1. Pod {}, mapOwneeToOwnerHandler ( mgr . GetClient (), mgr . GetLogger (), & ocv1alpha1. ClusterExtension {}) ).
453464 Build (r )
454465
455466 if err != nil {
@@ -460,6 +471,58 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
460471 return nil
461472}
462473
474+ func mapOwneeToOwnerHandler (cl client.Client , log logr.Logger , owner client.Object ) crhandler.EventHandler {
475+ return crhandler .EnqueueRequestsFromMapFunc (func (ctx context.Context , obj client.Object ) []reconcile.Request {
476+ ownerGVK , err := apiutil .GVKForObject (owner , cl .Scheme ())
477+ if err != nil {
478+ log .Error (err , "map ownee to owner: lookup GVK for owner" )
479+ return nil
480+ }
481+ owneeGVK , err := apiutil .GVKForObject (obj , cl .Scheme ())
482+ if err != nil {
483+ log .Error (err , "map ownee to owner: lookup GVK for ownee" )
484+ return nil
485+ }
486+
487+ type ownerInfo struct {
488+ key types.NamespacedName
489+ gvk schema.GroupVersionKind
490+ }
491+ var oi * ownerInfo
492+
493+ for _ , ref := range obj .GetOwnerReferences () {
494+ gv , err := schema .ParseGroupVersion (ref .APIVersion )
495+ if err != nil {
496+ log .Error (err , fmt .Sprintf ("map ownee to owner: parse ownee's owner reference group version %q" , ref .APIVersion ))
497+ return nil
498+ }
499+ refGVK := gv .WithKind (ref .Kind )
500+ if refGVK == ownerGVK && ref .Controller != nil && * ref .Controller {
501+ oi = & ownerInfo {
502+ key : types.NamespacedName {Name : ref .Name },
503+ gvk : ownerGVK ,
504+ }
505+ break
506+ }
507+ }
508+ if oi == nil {
509+ return nil
510+ }
511+
512+ if err := cl .Get (ctx , oi .key , owner ); client .IgnoreNotFound (err ) != nil {
513+ log .Info ("map ownee to owner: get owner" ,
514+ "ownee" , client .ObjectKeyFromObject (obj ),
515+ "owneeKind" , owneeGVK ,
516+ "owner" , oi .key ,
517+ "ownerKind" , oi .gvk ,
518+ "error" , err .Error (),
519+ )
520+ return nil
521+ }
522+ return []reconcile.Request {{NamespacedName : oi .key }}
523+ })
524+ }
525+
463526// Generate reconcile requests for all cluster extensions affected by a catalog change
464527func clusterExtensionRequestsForCatalog (c client.Reader , logger logr.Logger ) crhandler.MapFunc {
465528 return func (ctx context.Context , _ client.Object ) []reconcile.Request {
@@ -513,7 +576,7 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, clusterExtensi
513576 var installedVersion string
514577 // Do not include bundle versions older than currently installed unless UpgradeConstraintPolicy = 'Ignore'
515578 if clusterExtension .Spec .UpgradeConstraintPolicy != ocv1alpha1 .UpgradeConstraintPolicyIgnore {
516- installedVersionSemver , err := r .getInstalledVersion (ctx , clusterExtension )
579+ installedVersionSemver , err := r .getInstalledVersion (clusterExtension )
517580 if err != nil && ! apierrors .IsNotFound (err ) {
518581 return nil , err
519582 }
@@ -548,14 +611,17 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, clusterExtensi
548611 return resultSet [0 ], nil
549612}
550613
551- func (r * ClusterExtensionReconciler ) getInstalledVersion (ctx context. Context , clusterExtension ocv1alpha1.ClusterExtension ) (* bsemver.Version , error ) {
614+ func (r * ClusterExtensionReconciler ) getInstalledVersion (clusterExtension ocv1alpha1.ClusterExtension ) (* bsemver.Version , error ) {
552615 cl , err := r .ActionClientGetter .ActionClientFor (& clusterExtension )
553616 if err != nil {
554617 return nil , err
555618 }
556619
557620 // Clarify - Every release will have a unique name as the cluster extension?
558621 // Also filter relases whose owner is the operator controller?
622+ // I think this should work, given we are setting the release Name to the clusterExtension name.
623+ // If not, the other option is to get the Helm secret in the release namespace, list all the releases,
624+ // get the chart annotations.
559625 release , err := cl .Get (clusterExtension .GetName ())
560626 if err != nil {
561627 return nil , err
@@ -570,7 +636,7 @@ func (r *ClusterExtensionReconciler) getInstalledVersion(ctx context.Context, cl
570636 }
571637
572638 // TODO: when the chart is created these annotations are to be added.
573- existingVersion , ok := chart .Metadata .Annotations [bundleVersionKey ]
639+ existingVersion , ok := chart .Metadata .Annotations [util . ResolvedbundleVersion ]
574640 if ! ok {
575641 return nil , fmt .Errorf ("chart %q: missing bundle version" , chart .Name ())
576642 }
0 commit comments