@@ -411,6 +411,11 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, ext ocv1alpha1
411411 channelName := ext .Spec .Channel
412412 versionRange := ext .Spec .Version
413413
414+ installedBundle , err := r .installedBundle (ctx , allBundles , & ext )
415+ if err != nil {
416+ return nil , err
417+ }
418+
414419 predicates := []catalogfilter.Predicate [catalogmetadata.Bundle ]{
415420 catalogfilter .WithPackageName (packageName ),
416421 }
@@ -427,35 +432,35 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, ext ocv1alpha1
427432 predicates = append (predicates , catalogfilter .InMastermindsSemverRange (vr ))
428433 }
429434
430- var installedVersion string
431- var upgradeErrorPrefix string
432- if ext .Spec .UpgradeConstraintPolicy != ocv1alpha1 .UpgradeConstraintPolicyIgnore {
433- installedBundle , err := r .getInstalledVersion (ctx , ext )
435+ if ext .Spec .UpgradeConstraintPolicy != ocv1alpha1 .UpgradeConstraintPolicyIgnore && installedBundle != nil {
436+ upgradePredicate , err := SuccessorsPredicate (installedBundle )
434437 if err != nil {
435- return nil , utilerrors .NewAggregate ([]error {fmt .Errorf ("error fetching installed version: %w" , err )})
436- }
437- if installedBundle != nil {
438- installedVersion = installedBundle .String ()
439- upgradeErrorPrefix = fmt .Sprintf ("error upgrading from currently installed version %q: " , installedVersion )
440- wantedVersionRangeConstraint , err := mmsemver .NewConstraint (fmt .Sprintf ("^%s" , installedVersion ))
441- if err != nil {
442- return nil , utilerrors .NewAggregate ([]error {fmt .Errorf ("%serror creating version constraint: %w" , upgradeErrorPrefix , err )})
443- }
444- predicates = append (predicates , catalogfilter .InMastermindsSemverRange (wantedVersionRangeConstraint ))
438+ return nil , err
445439 }
440+
441+ predicates = append (predicates , upgradePredicate )
446442 }
447443
448444 resultSet := catalogfilter .Filter (allBundles , catalogfilter .And (predicates ... ))
445+
446+ var upgradeErrorPrefix string
447+ if installedBundle != nil {
448+ installedBundleVersion , err := installedBundle .Version ()
449+ if err != nil {
450+ return nil , err
451+ }
452+ upgradeErrorPrefix = fmt .Sprintf ("error upgrading from currently installed version %q: " , installedBundleVersion .String ())
453+ }
449454 if len (resultSet ) == 0 {
450455 switch {
451456 case versionRange != "" && channelName != "" :
452- return nil , fmt .Errorf ("no package %q matching version %q in channel %q found" , packageName , versionRange , channelName )
457+ return nil , fmt .Errorf ("%sno package %q matching version %q in channel %q found" , upgradeErrorPrefix , packageName , versionRange , channelName )
453458 case versionRange != "" :
454- return nil , fmt .Errorf ("no package %q matching version %q found" , packageName , versionRange )
459+ return nil , fmt .Errorf ("%sno package %q matching version %q found" , upgradeErrorPrefix , packageName , versionRange )
455460 case channelName != "" :
456- return nil , fmt .Errorf ("no package %q in channel %q found" , packageName , channelName )
461+ return nil , fmt .Errorf ("%sno package %q in channel %q found" , upgradeErrorPrefix , packageName , channelName )
457462 default :
458- return nil , fmt .Errorf ("no package %q found" , packageName )
463+ return nil , fmt .Errorf ("%sno package %q found" , upgradeErrorPrefix , packageName )
459464 }
460465 }
461466
@@ -682,32 +687,43 @@ func clusterExtensionRequestsForCatalog(c client.Reader, logger logr.Logger) crh
682687 }
683688}
684689
685- // getInstalledVersion fetches the installed version of a particular bundle from the cluster. To do so, we read the release label
686- // which are added during install.
687- func (r * ClusterExtensionReconciler ) getInstalledVersion (ctx context.Context , clusterExtension ocv1alpha1.ClusterExtension ) (* bsemver.Version , error ) {
688- cl , err := r .ActionClientGetter .ActionClientFor (ctx , & clusterExtension )
690+ func (r * ClusterExtensionReconciler ) installedBundle (ctx context.Context , allBundles []* catalogmetadata.Bundle , ext * ocv1alpha1.ClusterExtension ) (* catalogmetadata.Bundle , error ) {
691+ cl , err := r .ActionClientGetter .ActionClientFor (ctx , ext )
689692 if err != nil {
690693 return nil , err
691694 }
692695
693- release , err := cl .Get (clusterExtension .GetName ())
696+ release , err := cl .Get (ext .GetName ())
694697 if err != nil && ! errors .Is (err , driver .ErrReleaseNotFound ) {
695698 return nil , err
696699 }
697700 if release == nil {
698701 return nil , nil
699702 }
700703
701- existingVersion , ok := release .Labels [labels .BundleVersionKey ]
702- if ! ok {
703- return nil , fmt .Errorf ("release %q: missing bundle version" , release .Name )
704+ // Bundle must match installed version exactly
705+ vr , err := mmsemver .NewConstraint (release .Labels [labels .BundleVersionKey ])
706+ if err != nil {
707+ return nil , err
704708 }
705709
706- existingVersionSemver , err := bsemver .New (existingVersion )
707- if err != nil {
708- return nil , fmt .Errorf ("could not determine bundle version for the chart %q: %w" , release .Name , err )
710+ // TODO (dfranz) Are the PackageName + BundleName + BundleVersion enough to
711+ // be 100% sure we have the correct bundle?
712+ // find corresponding bundle for the installed content
713+ resultSet := catalogfilter .Filter (allBundles , catalogfilter .And (
714+ catalogfilter .WithPackageName (release .Labels [labels .PackageNameKey ]),
715+ catalogfilter .WithBundleName (release .Labels [labels .BundleNameKey ]),
716+ catalogfilter .InMastermindsSemverRange (vr ),
717+ ))
718+ if len (resultSet ) == 0 {
719+ return nil , fmt .Errorf ("bundle %q for package %q not found in available catalogs but is currently installed via Helm Chart %q" , release .Labels [labels .BundleNameKey ], ext .Spec .PackageName , release .Labels [labels .BundleNameKey ])
709720 }
710- return existingVersionSemver , nil
721+
722+ sort .SliceStable (resultSet , func (i , j int ) bool {
723+ return catalogsort .ByVersion (resultSet [i ], resultSet [j ])
724+ })
725+
726+ return resultSet [0 ], nil
711727}
712728
713729type releaseState string
0 commit comments