-
Notifications
You must be signed in to change notification settings - Fork 64
🐛 Fix: installed bundle provider no longer requires catalog #916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,7 +94,7 @@ type ClusterExtensionReconciler struct { | |
} | ||
|
||
type InstalledBundleGetter interface { | ||
GetInstalledBundle(ctx context.Context, acg helmclient.ActionClientGetter, allBundles []*catalogmetadata.Bundle, ext *ocv1alpha1.ClusterExtension) (*catalogmetadata.Bundle, error) | ||
GetInstalledBundle(ctx context.Context, ext *ocv1alpha1.ClusterExtension) (*ocv1alpha1.BundleMetadata, error) | ||
} | ||
|
||
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions,verbs=get;list;watch | ||
|
@@ -370,7 +370,7 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, ext ocv1alpha1 | |
channelName := ext.Spec.Channel | ||
versionRange := ext.Spec.Version | ||
|
||
installedBundle, err := r.InstalledBundleGetter.GetInstalledBundle(ctx, r.ActionClientGetter, allBundles, &ext) | ||
installedBundle, err := r.InstalledBundleGetter.GetInstalledBundle(ctx, &ext) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -392,7 +392,7 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, ext ocv1alpha1 | |
} | ||
|
||
if ext.Spec.UpgradeConstraintPolicy != ocv1alpha1.UpgradeConstraintPolicyIgnore && installedBundle != nil { | ||
upgradePredicate, err := SuccessorsPredicate(installedBundle) | ||
upgradePredicate, err := SuccessorsPredicate(ext.Spec.PackageName, installedBundle) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be covered separately/later, but I wonder if the successors predicate should actually care about the package name? I could envision a separate predicate that gets to decide which package names are acceptable to be upgraded from, where the default would be what it is now (i.e. "spec.packageName"). Something like that may make it easier for us if we wanted to help users do an upgrade between bundles that come from a different package. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But perhaps There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 on covering later. I think there is some additional nuance here of deciding the ordering of bundles between different packages. How would you decide between a newer version of a bundle in the same package versus a different one? I think for now the current escape hatch should work? |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -404,7 +404,7 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, ext ocv1alpha1 | |
|
||
var upgradeErrorPrefix string | ||
if installedBundle != nil { | ||
installedBundleVersion, err := installedBundle.Version() | ||
installedBundleVersion, err := mmsemver.NewVersion(installedBundle.Version) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -568,6 +568,7 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error { | |
r.controller = controller | ||
r.cache = mgr.GetCache() | ||
r.dynamicWatchGVKs = map[schema.GroupVersionKind]struct{}{} | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -663,10 +664,12 @@ func (r *ClusterExtensionReconciler) getReleaseState(cl helmclient.ActionInterfa | |
return currentRelease, stateUnchanged, nil | ||
} | ||
|
||
type DefaultInstalledBundleGetter struct{} | ||
type DefaultInstalledBundleGetter struct { | ||
helmclient.ActionClientGetter | ||
} | ||
|
||
func (d *DefaultInstalledBundleGetter) GetInstalledBundle(ctx context.Context, acg helmclient.ActionClientGetter, allBundles []*catalogmetadata.Bundle, ext *ocv1alpha1.ClusterExtension) (*catalogmetadata.Bundle, error) { | ||
cl, err := acg.ActionClientFor(ctx, ext) | ||
func (d *DefaultInstalledBundleGetter) GetInstalledBundle(ctx context.Context, ext *ocv1alpha1.ClusterExtension) (*ocv1alpha1.BundleMetadata, error) { | ||
cl, err := d.ActionClientFor(ctx, ext) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -679,27 +682,10 @@ func (d *DefaultInstalledBundleGetter) GetInstalledBundle(ctx context.Context, a | |
return nil, nil | ||
} | ||
|
||
// Bundle must match installed version exactly | ||
vr, err := mmsemver.NewConstraint(release.Labels[labels.BundleVersionKey]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// find corresponding bundle for the installed content | ||
resultSet := catalogfilter.Filter(allBundles, catalogfilter.And( | ||
catalogfilter.WithPackageName(release.Labels[labels.PackageNameKey]), | ||
catalogfilter.WithBundleName(release.Labels[labels.BundleNameKey]), | ||
catalogfilter.InMastermindsSemverRange(vr), | ||
)) | ||
if len(resultSet) == 0 { | ||
return nil, fmt.Errorf("bundle %q for package %q not found in available catalogs but is currently installed in namespace %q", release.Labels[labels.BundleNameKey], ext.Spec.PackageName, release.Namespace) | ||
} | ||
|
||
sort.SliceStable(resultSet, func(i, j int) bool { | ||
return catalogsort.ByVersion(resultSet[i], resultSet[j]) | ||
}) | ||
|
||
return resultSet[0], nil | ||
return &ocv1alpha1.BundleMetadata{ | ||
Name: release.Labels[labels.BundleNameKey], | ||
Version: release.Labels[labels.BundleVersionKey], | ||
}, nil | ||
} | ||
|
||
type postrenderer struct { | ||
|
@@ -749,7 +735,7 @@ func bundleMetadataFor(bundle *catalogmetadata.Bundle) *ocv1alpha1.BundleMetadat | |
} | ||
|
||
func (r *ClusterExtensionReconciler) validateBundle(bundle *catalogmetadata.Bundle) error { | ||
unsupportedProps := sets.New( | ||
unsupportedProps := sets.New[string]( | ||
property.TypePackageRequired, | ||
property.TypeGVKRequired, | ||
property.TypeConstraint, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both the before and after code just silently ignore edges if the installed bundle version or the skipRange cannot be parsed.
I'm tempted to actually fail here if the bundle version or skip range fail to parse.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the impact to non-semver versions if we fail here? Do we know how many packages use versioning schemes incompatible with semver in the commonly used catalogs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure FBC requires valid semver and
opm validate
checks both places. So in theory, this should never fail, and if it does, it is because someone has invalid FBC.Which is why I think I'd rather just fail here. If we ignore it, it's this sorta weird fence-straddling position of accepting it, but then not doing anything with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is validation that the versions must be valid semver then I am fine with failing here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it would be a significant change to bubble errors up through the predicate API. Probably better to handle this in a follow-up. I think we should do one of the following:
(bool, error)
. This is a big change because lots of stuff implements the predicate interface.