Skip to content

Commit cf12580

Browse files
Merge pull request openshift#842 from anik120/resolver-cache-fix-backport
[release-4.14] OCPBUGS-38544: (fix) Resolver: list CatSrc using client, instead of referring to registry-server cache (#3349)
2 parents b1d51eb + 3c294a9 commit cf12580

File tree

10 files changed

+149
-32
lines changed

10 files changed

+149
-32
lines changed

staging/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo
192192
clientFactory: clients.NewFactory(config),
193193
}
194194
op.sources = grpc.NewSourceStore(logger, 10*time.Second, 10*time.Minute, op.syncSourceState)
195-
op.sourceInvalidator = resolver.SourceProviderFromRegistryClientProvider(op.sources, logger)
195+
op.sourceInvalidator = resolver.SourceProviderFromRegistryClientProvider(op.sources, lister.OperatorsV1alpha1().CatalogSourceLister(), logger)
196196
resolverSourceProvider := NewOperatorGroupToggleSourceProvider(op.sourceInvalidator, logger, op.lister.OperatorsV1().OperatorGroupLister())
197197
op.reconciler = reconciler.NewRegistryReconcilerFactory(lister, opClient, configmapRegistryImage, op.now, ssaClient, workloadUserID)
198198
res := resolver.NewOperatorStepResolver(lister, crClient, operatorNamespace, resolverSourceProvider, logger)

staging/operator-lifecycle-manager/pkg/controller/registry/resolver/cache/cache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func (c *NamespacedOperatorCache) Error() error {
139139
err := snapshot.err
140140
snapshot.m.RUnlock()
141141
if err != nil {
142-
errs = append(errs, fmt.Errorf("failed to populate resolver cache from source %v: %w", key.String(), err))
142+
errs = append(errs, fmt.Errorf("error using catalogsource %s/%s: %w", key.Namespace, key.Name, err))
143143
}
144144
}
145145
return errors.NewAggregate(errs)

staging/operator-lifecycle-manager/pkg/controller/registry/resolver/cache/cache_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,5 +238,5 @@ func TestNamespaceOperatorCacheError(t *testing.T) {
238238
key: ErrorSource{Error: errors.New("testing")},
239239
})
240240

241-
require.EqualError(t, c.Namespaced("dummynamespace").Error(), "failed to populate resolver cache from source dummyname/dummynamespace: testing")
241+
require.EqualError(t, c.Namespaced("dummynamespace").Error(), "error using catalogsource dummynamespace/dummyname: testing")
242242
}

staging/operator-lifecycle-manager/pkg/controller/registry/resolver/source_registry.go

+49-12
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ import (
88
"time"
99

1010
"github.com/blang/semver/v4"
11+
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
12+
v1alpha1listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
1113
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
1214
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache"
1315
"github.com/operator-framework/operator-registry/pkg/api"
1416
"github.com/operator-framework/operator-registry/pkg/client"
1517
opregistry "github.com/operator-framework/operator-registry/pkg/registry"
1618
"github.com/sirupsen/logrus"
19+
"k8s.io/apimachinery/pkg/labels"
1720
)
1821

1922
// todo: move to pkg/controller/operators/catalog
@@ -65,31 +68,65 @@ func (i *sourceInvalidator) GetValidChannel(key cache.SourceKey) <-chan struct{}
6568
}
6669

6770
type RegistrySourceProvider struct {
68-
rcp RegistryClientProvider
69-
logger logrus.StdLogger
70-
invalidator *sourceInvalidator
71+
rcp RegistryClientProvider
72+
catsrcLister v1alpha1listers.CatalogSourceLister
73+
logger logrus.StdLogger
74+
invalidator *sourceInvalidator
7175
}
7276

73-
func SourceProviderFromRegistryClientProvider(rcp RegistryClientProvider, logger logrus.StdLogger) *RegistrySourceProvider {
77+
func SourceProviderFromRegistryClientProvider(rcp RegistryClientProvider, catsrcLister v1alpha1listers.CatalogSourceLister, logger logrus.StdLogger) *RegistrySourceProvider {
7478
return &RegistrySourceProvider{
75-
rcp: rcp,
76-
logger: logger,
79+
rcp: rcp,
80+
logger: logger,
81+
catsrcLister: catsrcLister,
7782
invalidator: &sourceInvalidator{
7883
validChans: make(map[cache.SourceKey]chan struct{}),
7984
ttl: 5 * time.Minute,
8085
},
8186
}
8287
}
8388

89+
type errorSource struct {
90+
error
91+
}
92+
93+
func (s errorSource) Snapshot(_ context.Context) (*cache.Snapshot, error) {
94+
return nil, s.error
95+
}
96+
8497
func (a *RegistrySourceProvider) Sources(namespaces ...string) map[cache.SourceKey]cache.Source {
8598
result := make(map[cache.SourceKey]cache.Source)
86-
for key, client := range a.rcp.ClientsForNamespaces(namespaces...) {
87-
result[cache.SourceKey(key)] = &registrySource{
88-
key: cache.SourceKey(key),
89-
client: client,
90-
logger: a.logger,
91-
invalidator: a.invalidator,
99+
100+
cats := []*operatorsv1alpha1.CatalogSource{}
101+
for _, ns := range namespaces {
102+
catsInNamespace, err := a.catsrcLister.CatalogSources(ns).List(labels.Everything())
103+
if err != nil {
104+
result[cache.SourceKey{Name: "", Namespace: ns}] = errorSource{
105+
error: fmt.Errorf("failed to list catalogsources for namespace %q: %w", ns, err),
106+
}
107+
return result
92108
}
109+
cats = append(cats, catsInNamespace...)
110+
}
111+
112+
clients := a.rcp.ClientsForNamespaces(namespaces...)
113+
for _, cat := range cats {
114+
key := cache.SourceKey{Name: cat.Name, Namespace: cat.Namespace}
115+
if client, ok := clients[registry.CatalogKey{Name: cat.Name, Namespace: cat.Namespace}]; ok {
116+
result[key] = &registrySource{
117+
key: key,
118+
client: client,
119+
logger: a.logger,
120+
invalidator: a.invalidator,
121+
}
122+
} else {
123+
result[key] = errorSource{
124+
error: fmt.Errorf("no registry client established for catalogsource %s/%s", cat.Namespace, cat.Name),
125+
}
126+
}
127+
}
128+
if len(result) == 0 {
129+
return nil
93130
}
94131
return result
95132
}

staging/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver.go

+21-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99
corev1 "k8s.io/api/core/v1"
1010
"k8s.io/apimachinery/pkg/api/errors"
1111
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/labels"
1213

1314
"github.com/operator-framework/api/pkg/operators/v1alpha1"
1415
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
16+
v1listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1"
1517
v1alpha1listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
1618
controllerbundle "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/bundle"
1719
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache"
@@ -21,6 +23,7 @@ import (
2123

2224
const (
2325
BundleLookupConditionPacked v1alpha1.BundleLookupConditionType = "BundleLookupNotPersisted"
26+
exclusionAnnotation string = "olm.operatorframework.io/exclude-global-namespace-resolution"
2427
)
2528

2629
// init hooks provides the downstream a way to modify the upstream behavior
@@ -33,6 +36,7 @@ type StepResolver interface {
3336
type OperatorStepResolver struct {
3437
subLister v1alpha1listers.SubscriptionLister
3538
csvLister v1alpha1listers.ClusterServiceVersionLister
39+
ogLister v1listers.OperatorGroupLister
3640
client versioned.Interface
3741
globalCatalogNamespace string
3842
resolver *Resolver
@@ -69,6 +73,7 @@ func NewOperatorStepResolver(lister operatorlister.OperatorLister, client versio
6973
stepResolver := &OperatorStepResolver{
7074
subLister: lister.OperatorsV1alpha1().SubscriptionLister(),
7175
csvLister: lister.OperatorsV1alpha1().ClusterServiceVersionLister(),
76+
ogLister: lister.OperatorsV1().OperatorGroupLister(),
7277
client: client,
7378
globalCatalogNamespace: globalCatalogNamespace,
7479
resolver: NewDefaultResolver(cacheSourceProvider, catsrcPriorityProvider{lister: lister.OperatorsV1alpha1().CatalogSourceLister()}, log),
@@ -91,7 +96,22 @@ func (r *OperatorStepResolver) ResolveSteps(namespace string) ([]*v1alpha1.Step,
9196
return nil, nil, nil, err
9297
}
9398

94-
namespaces := []string{namespace, r.globalCatalogNamespace}
99+
namespaces := []string{namespace}
100+
ogs, err := r.ogLister.OperatorGroups(namespace).List(labels.Everything())
101+
if err != nil {
102+
return nil, nil, nil, fmt.Errorf("listing operatorgroups in namespace %s: %s", namespace, err)
103+
}
104+
if len(ogs) != 1 {
105+
return nil, nil, nil, fmt.Errorf("expected 1 OperatorGroup in the namespace, found %d", len(ogs))
106+
}
107+
og := ogs[0]
108+
if val, ok := og.Annotations[exclusionAnnotation]; ok && val == "true" {
109+
// Exclusion specified
110+
// Ignore the globalNamespace for the purposes of resolution in this namespace
111+
r.log.Printf("excluding global catalogs from resolution in namespace %s", namespace)
112+
} else {
113+
namespaces = append(namespaces, r.globalCatalogNamespace)
114+
}
95115
operators, err := r.resolver.Resolve(namespaces, subs)
96116
if err != nil {
97117
return nil, nil, nil, err

staging/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ func TestResolver(t *testing.T) {
12161216
steps: [][]*v1alpha1.Step{},
12171217
subs: []*v1alpha1.Subscription{},
12181218
errAssert: func(t *testing.T, err error) {
1219-
assert.Contains(t, err.Error(), "failed to populate resolver cache from source @existing/catsrc-namespace: csv")
1219+
assert.Contains(t, err.Error(), "error using catalogsource catsrc-namespace/@existing: csv")
12201220
assert.Contains(t, err.Error(), "in phase Failed instead of Replacing")
12211221
},
12221222
},
@@ -1362,6 +1362,7 @@ func TestNamespaceResolverRBAC(t *testing.T) {
13621362
name: "NewSubscription/Permissions/ClusterPermissions",
13631363
clusterState: []runtime.Object{
13641364
newSub(namespace, "a", "alpha", catalog),
1365+
newOperatorGroup("test-og", namespace),
13651366
},
13661367
bundlesInCatalog: []*api.Bundle{bundle},
13671368
out: out{
@@ -1377,6 +1378,7 @@ func TestNamespaceResolverRBAC(t *testing.T) {
13771378
name: "don't create default service accounts",
13781379
clusterState: []runtime.Object{
13791380
newSub(namespace, "a", "alpha", catalog),
1381+
newOperatorGroup("test-og", namespace),
13801382
},
13811383
bundlesInCatalog: []*api.Bundle{bundleWithDefaultServiceAccount},
13821384
out: out{
@@ -1403,6 +1405,7 @@ func TestNamespaceResolverRBAC(t *testing.T) {
14031405
lister := operatorlister.NewLister()
14041406
lister.OperatorsV1alpha1().RegisterSubscriptionLister(namespace, informerFactory.Operators().V1alpha1().Subscriptions().Lister())
14051407
lister.OperatorsV1alpha1().RegisterClusterServiceVersionLister(namespace, informerFactory.Operators().V1alpha1().ClusterServiceVersions().Lister())
1408+
lister.OperatorsV1().RegisterOperatorGroupLister(namespace, informerFactory.Operators().V1().OperatorGroups().Lister())
14061409

14071410
stubSnapshot := &resolvercache.Snapshot{}
14081411
for _, bundle := range tt.bundlesInCatalog {

vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache/cache.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/source_registry.go

+49-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/step_resolver.go

+21-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)