Skip to content

Commit 5afaa1d

Browse files
committed
Fix for resolution error on channels with deprecated inner entries.
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 6e2db16 commit 5afaa1d

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
@@ -400,9 +400,6 @@ type OperatorPredicate interface {
400400
func (s *CatalogSnapshot) Find(p ...OperatorPredicate) []*Operator {
401401
s.m.RLock()
402402
defer s.m.RUnlock()
403-
if len(p) > 0 {
404-
p = append(p, WithoutDeprecatedProperty())
405-
}
406403
return Filter(s.operators, p...)
407404
}
408405

@@ -461,17 +458,6 @@ func WithPackage(pkg string) OperatorPredicate {
461458
})
462459
}
463460

464-
func WithoutDeprecatedProperty() OperatorPredicate {
465-
return OperatorPredicateFunc(func(o *Operator) bool {
466-
for _, p := range o.bundle.GetProperties() {
467-
if p.GetType() == opregistry.DeprecatedType {
468-
return false
469-
}
470-
}
471-
return true
472-
})
473-
}
474-
475461
func WithVersionInRange(r semver.Range) OperatorPredicate {
476462
return OperatorPredicateFunc(func(o *Operator) bool {
477463
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
@@ -317,19 +317,17 @@ func (r *SatResolver) getBundleInstallables(catalog registry.CatalogKey, predica
317317
bundle := bundleStack[len(bundleStack)-1]
318318
bundleStack = bundleStack[:len(bundleStack)-1]
319319

320-
bundleSource := bundle.SourceInfo()
321-
if bundleSource == nil {
322-
err := fmt.Errorf("unable to resolve the source of bundle %s, invalid cache", bundle.Identifier())
323-
errs = append(errs, err)
320+
if b, ok := visited[bundle]; ok {
321+
installables[b.identifier] = b
324322
continue
325323
}
326324

327-
if b, ok := visited[bundle]; ok {
328-
installables[b.identifier] = b
325+
bundleInstallable, err := NewBundleInstallableFromOperator(bundle)
326+
if err != nil {
327+
errs = append(errs, err)
329328
continue
330329
}
331330

332-
bundleInstallable := NewBundleInstallable(bundle.Identifier(), bundle.Channel(), bundleSource.Catalog)
333331
visited[bundle] = &bundleInstallable
334332

335333
dependencyPredicates, err := bundle.DependencyPredicates()
@@ -371,14 +369,11 @@ func (r *SatResolver) getBundleInstallables(catalog registry.CatalogKey, predica
371369
// (after sorting) to remove all bundles that
372370
// don't satisfy the dependency.
373371
for _, b := range Filter(sortedBundles, d) {
374-
src := b.SourceInfo()
375-
if src == nil {
376-
err := fmt.Errorf("unable to resolve the source of bundle %s, invalid cache", bundle.Identifier())
372+
i, err := NewBundleInstallableFromOperator(b)
373+
if err != nil {
377374
errs = append(errs, err)
378375
continue
379376
}
380-
381-
i := NewBundleInstallable(b.Identifier(), b.Channel(), src.Catalog)
382377
installables[i.Identifier()] = &i
383378
bundleDependencies = append(bundleDependencies, i.Identifier())
384379
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)