Skip to content

Commit b0453a0

Browse files
authored
Fix for resolution error on channels with deprecated inner entries. (#2313)
Resolution would fail with an error in the presence of channels containing more than two entries with a deprecated inner entry (e.g. V1 -> V2 -> V3, with deprecated V2). This was due to special handling that filtered out deprecated bundles at the cache query layer. A channel's complete replaces-chain must be returned from cache queries in order to correctly determine the relative order between entries in the channel. Signed-off-by: Ben Luddy <[email protected]>
1 parent dcbab9a commit b0453a0

File tree

4 files changed

+59
-31
lines changed

4 files changed

+59
-31
lines changed

pkg/controller/registry/resolver/cache.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,6 @@ type OperatorPredicate func(*Operator) bool
392392
func (s *CatalogSnapshot) Find(p ...OperatorPredicate) []*Operator {
393393
s.m.RLock()
394394
defer s.m.RUnlock()
395-
if len(p) > 0 {
396-
p = append(p, WithoutDeprecatedProperty())
397-
}
398395
return Filter(s.operators, p...)
399396
}
400397

@@ -453,17 +450,6 @@ func WithPackage(pkg string) OperatorPredicate {
453450
}
454451
}
455452

456-
func WithoutDeprecatedProperty() OperatorPredicate {
457-
return func(o *Operator) bool {
458-
for _, p := range o.bundle.GetProperties() {
459-
if p.GetType() == opregistry.DeprecatedType {
460-
return false
461-
}
462-
}
463-
return true
464-
}
465-
}
466-
467453
func WithVersionInRange(r semver.Range) OperatorPredicate {
468454
return func(o *Operator) bool {
469455
for _, p := range o.Properties() {

pkg/controller/registry/resolver/installabletypes.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
88
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/solver"
9+
operatorregistry "github.com/operator-framework/operator-registry/pkg/registry"
910
)
1011

1112
type BundleInstallable struct {
@@ -54,6 +55,24 @@ func bundleId(bundle, channel string, catalog registry.CatalogKey) solver.Identi
5455
return solver.IdentifierFromString(fmt.Sprintf("%s/%s/%s", catalog.String(), channel, bundle))
5556
}
5657

58+
func NewBundleInstallableFromOperator(o *Operator) (BundleInstallable, error) {
59+
src := o.SourceInfo()
60+
if src == nil {
61+
return BundleInstallable{}, fmt.Errorf("unable to resolve the source of bundle %s", o.Identifier())
62+
}
63+
var constraints []solver.Constraint
64+
for _, p := range o.bundle.GetProperties() {
65+
if p.GetType() == operatorregistry.DeprecatedType {
66+
constraints = append(constraints, PrettyConstraint(
67+
solver.Prohibited(),
68+
fmt.Sprintf("bundle %s is deprecated", bundleId(o.Identifier(), o.Channel(), src.Catalog)),
69+
))
70+
break
71+
}
72+
}
73+
return NewBundleInstallable(o.Identifier(), o.Channel(), src.Catalog, constraints...), nil
74+
}
75+
5776
func NewBundleInstallable(bundle, channel string, catalog registry.CatalogKey, constraints ...solver.Constraint) BundleInstallable {
5877
return BundleInstallable{
5978
identifier: bundleId(bundle, channel, catalog),

pkg/controller/registry/resolver/resolver.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -294,19 +294,17 @@ func (r *SatResolver) getBundleInstallables(catalog registry.CatalogKey, predica
294294
bundle := bundleStack[len(bundleStack)-1]
295295
bundleStack = bundleStack[:len(bundleStack)-1]
296296

297-
bundleSource := bundle.SourceInfo()
298-
if bundleSource == nil {
299-
err := fmt.Errorf("unable to resolve the source of bundle %s, invalid cache", bundle.Identifier())
300-
errs = append(errs, err)
297+
if b, ok := visited[bundle]; ok {
298+
installables[b.identifier] = b
301299
continue
302300
}
303301

304-
if b, ok := visited[bundle]; ok {
305-
installables[b.identifier] = b
302+
bundleInstallable, err := NewBundleInstallableFromOperator(bundle)
303+
if err != nil {
304+
errs = append(errs, err)
306305
continue
307306
}
308307

309-
bundleInstallable := NewBundleInstallable(bundle.Identifier(), bundle.Channel(), bundleSource.Catalog)
310308
visited[bundle] = &bundleInstallable
311309

312310
dependencyPredicates, err := bundle.DependencyPredicates()
@@ -348,14 +346,11 @@ func (r *SatResolver) getBundleInstallables(catalog registry.CatalogKey, predica
348346
// (after sorting) to remove all bundles that
349347
// don't satisfy the dependency.
350348
for _, b := range Filter(sortedBundles, d) {
351-
src := b.SourceInfo()
352-
if src == nil {
353-
err := fmt.Errorf("unable to resolve the source of bundle %s, invalid cache", bundle.Identifier())
349+
i, err := NewBundleInstallableFromOperator(b)
350+
if err != nil {
354351
errs = append(errs, err)
355352
continue
356353
}
357-
358-
i := NewBundleInstallable(b.Identifier(), b.Channel(), src.Catalog)
359354
installables[i.Identifier()] = &i
360355
bundleDependencies = append(bundleDependencies, i.Identifier())
361356
bundleStack = append(bundleStack, b)

pkg/controller/registry/resolver/resolver_test.go

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,19 +1335,18 @@ func stripBundle(o *Operator) *Operator {
13351335
}
13361336

13371337
func TestSolveOperators_WithoutDeprecated(t *testing.T) {
1338-
namespace := "olm"
1339-
catalog := registry.CatalogKey{"community", namespace}
1338+
catalog := registry.CatalogKey{Name: "catalog", Namespace: "namespace"}
13401339

13411340
subs := []*v1alpha1.Subscription{
1342-
newSub(namespace, "packageA", "alpha", catalog),
1341+
newSub(catalog.Namespace, "packageA", "alpha", catalog),
13431342
}
13441343

13451344
fakeNamespacedOperatorCache := NamespacedOperatorCache{
13461345
snapshots: map[registry.CatalogKey]*CatalogSnapshot{
13471346
catalog: {
13481347
key: catalog,
13491348
operators: []*Operator{
1350-
genOperator("packageA.v1", "0.0.1", "packageA.v1", "packageA", "alpha", "community", "olm", nil, nil, nil, "", true),
1349+
genOperator("packageA.v1", "0.0.1", "packageA.v1", "packageA", "alpha", catalog.Name, catalog.Namespace, nil, nil, nil, "", true),
13511350
},
13521351
},
13531352
},
@@ -1357,11 +1356,40 @@ func TestSolveOperators_WithoutDeprecated(t *testing.T) {
13571356
log: logrus.New(),
13581357
}
13591358

1360-
operators, err := satResolver.SolveOperators([]string{"olm"}, nil, subs)
1359+
operators, err := satResolver.SolveOperators([]string{catalog.Namespace}, nil, subs)
13611360
assert.Empty(t, operators)
13621361
assert.IsType(t, solver.NotSatisfiable{}, err)
13631362
}
13641363

1364+
func TestSolveOperatorsWithDeprecatedInnerChannelEntry(t *testing.T) {
1365+
catalog := registry.CatalogKey{Name: "catalog", Namespace: "namespace"}
1366+
1367+
subs := []*v1alpha1.Subscription{
1368+
newSub(catalog.Namespace, "a", "c", catalog),
1369+
}
1370+
logger, _ := test.NewNullLogger()
1371+
resolver := SatResolver{
1372+
cache: getFakeOperatorCache(NamespacedOperatorCache{
1373+
snapshots: map[registry.CatalogKey]*CatalogSnapshot{
1374+
catalog: {
1375+
key: catalog,
1376+
operators: []*Operator{
1377+
genOperator("a-1", "1.0.0", "", "a", "c", catalog.Name, catalog.Namespace, nil, nil, nil, "", false),
1378+
genOperator("a-2", "2.0.0", "a-1", "a", "c", catalog.Name, catalog.Namespace, nil, nil, nil, "", true),
1379+
genOperator("a-3", "3.0.0", "a-2", "a", "c", catalog.Name, catalog.Namespace, nil, nil, nil, "", false),
1380+
},
1381+
},
1382+
},
1383+
}),
1384+
log: logger,
1385+
}
1386+
1387+
operators, err := resolver.SolveOperators([]string{catalog.Namespace}, nil, subs)
1388+
assert.NoError(t, err)
1389+
assert.Len(t, operators, 1)
1390+
assert.Contains(t, operators, "a-3")
1391+
}
1392+
13651393
func TestSolveOperators_WithSkipsAndStartingCSV(t *testing.T) {
13661394
APISet := APISet{opregistry.APIKey{"g", "v", "k", "ks"}: struct{}{}}
13671395
Provides := APISet

0 commit comments

Comments
 (0)