Skip to content

Commit 7fe8851

Browse files
Merge pull request operator-framework#2290 from benluddy/resolver-cache-catalog-error
Expose errors generated while retrieving catalog content.
2 parents 167e031 + 6ab5f16 commit 7fe8851

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

pkg/controller/registry/resolver/cache.go

+25
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"sync"
99
"time"
1010

11+
"k8s.io/apimachinery/pkg/util/errors"
12+
1113
"github.com/sirupsen/logrus"
1214

1315
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
@@ -79,6 +81,19 @@ type NamespacedOperatorCache struct {
7981
snapshots map[registry.CatalogKey]*CatalogSnapshot
8082
}
8183

84+
func (c *NamespacedOperatorCache) Error() error {
85+
var errs []error
86+
for key, snapshot := range c.snapshots {
87+
snapshot.m.Lock()
88+
err := snapshot.err
89+
snapshot.m.Unlock()
90+
if err != nil {
91+
errs = append(errs, fmt.Errorf("error using catalog %s (in namespace %s): %w", key.Name, key.Namespace, err))
92+
}
93+
}
94+
return errors.NewAggregate(errs)
95+
}
96+
8297
func (c *OperatorCache) Expire(catalog registry.CatalogKey) {
8398
c.m.Lock()
8499
defer c.m.Unlock()
@@ -183,6 +198,12 @@ func (c *OperatorCache) Namespaced(namespaces ...string) MultiCatalogOperatorFin
183198

184199
func (c *OperatorCache) populate(ctx context.Context, snapshot *CatalogSnapshot, registry client.Interface) {
185200
defer snapshot.m.Unlock()
201+
defer func() {
202+
// Don't cache an errorred snapshot.
203+
if snapshot.err != nil {
204+
snapshot.expiry = time.Time{}
205+
}
206+
}()
186207

187208
c.sem <- struct{}{}
188209
defer func() { <-c.sem }()
@@ -195,6 +216,7 @@ func (c *OperatorCache) populate(ctx context.Context, snapshot *CatalogSnapshot,
195216
it, err := registry.ListBundles(ctx)
196217
if err != nil {
197218
snapshot.logger.Errorf("failed to list bundles: %s", err.Error())
219+
snapshot.err = err
198220
return
199221
}
200222
c.logger.WithField("catalog", snapshot.key.String()).Debug("updating cache")
@@ -223,6 +245,7 @@ func (c *OperatorCache) populate(ctx context.Context, snapshot *CatalogSnapshot,
223245
}
224246
if err := it.Error(); err != nil {
225247
snapshot.logger.Warnf("error encountered while listing bundles: %s", err.Error())
248+
snapshot.err = err
226249
}
227250
snapshot.operators = operators
228251
}
@@ -293,6 +316,7 @@ type CatalogSnapshot struct {
293316
m sync.RWMutex
294317
pop context.CancelFunc
295318
priority catalogSourcePriority
319+
err error
296320
}
297321

298322
func (s *CatalogSnapshot) Cancel() {
@@ -400,6 +424,7 @@ type MultiCatalogOperatorFinder interface {
400424
Catalog(registry.CatalogKey) OperatorFinder
401425
FindPreferred(*registry.CatalogKey, ...OperatorPredicate) []*Operator
402426
WithExistingOperators(*CatalogSnapshot) MultiCatalogOperatorFinder
427+
Error() error
403428
OperatorFinder
404429
}
405430

pkg/controller/registry/resolver/cache_test.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package resolver
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"io"
78
"math/rand"
@@ -10,6 +11,7 @@ import (
1011
"time"
1112

1213
"github.com/sirupsen/logrus"
14+
"github.com/sirupsen/logrus/hooks/test"
1315
"github.com/stretchr/testify/assert"
1416
"github.com/stretchr/testify/require"
1517

@@ -35,6 +37,8 @@ func (s *BundleStreamStub) Recv() (*api.Bundle, error) {
3537

3638
type RegistryClientStub struct {
3739
BundleIterator *client.BundleIterator
40+
41+
ListBundlesError error
3842
}
3943

4044
func (s *RegistryClientStub) Get() (client.Interface, error) {
@@ -58,7 +62,7 @@ func (s *RegistryClientStub) GetBundleThatProvides(ctx context.Context, group, v
5862
}
5963

6064
func (s *RegistryClientStub) ListBundles(ctx context.Context) (*client.BundleIterator, error) {
61-
return s.BundleIterator, nil
65+
return s.BundleIterator, s.ListBundlesError
6266
}
6367

6468
func (s *RegistryClientStub) GetPackage(ctx context.Context, packageName string) (*api.Package, error) {
@@ -339,3 +343,21 @@ func TestStripPluralRequiredAndProvidedAPIKeys(t *testing.T) {
339343
assert.Equal(t, "K.v1.g", result[0].providedAPIs.String())
340344
assert.Equal(t, "K2.v2.g2", result[0].requiredAPIs.String())
341345
}
346+
347+
func TestNamespaceOperatorCacheError(t *testing.T) {
348+
rcp := RegistryClientProviderStub{}
349+
catsrcLister := operatorlister.NewLister().OperatorsV1alpha1().CatalogSourceLister()
350+
key := registry.CatalogKey{Namespace: "dummynamespace", Name: "dummyname"}
351+
rcp[key] = &RegistryClientStub{
352+
ListBundlesError: errors.New("testing"),
353+
}
354+
355+
logger, _ := test.NewNullLogger()
356+
c := NewOperatorCache(rcp, logger, catsrcLister)
357+
require.EqualError(t, c.Namespaced("dummynamespace").Error(), "error using catalog dummyname (in namespace dummynamespace): testing")
358+
if snapshot, ok := c.snapshots[key]; !ok {
359+
t.Fatalf("cache snapshot not found")
360+
} else {
361+
require.Zero(t, snapshot.expiry)
362+
}
363+
}

pkg/controller/registry/resolver/resolver.go

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ func (r *SatResolver) SolveOperators(namespaces []string, csvs []*v1alpha1.Clust
103103

104104
r.addInvariants(namespacedCache, installables)
105105

106+
if err := namespacedCache.Error(); err != nil {
107+
return nil, err
108+
}
109+
106110
input := make([]solver.Installable, 0)
107111
for _, i := range installables {
108112
input = append(input, i)

pkg/controller/registry/types.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (k *CatalogKey) Virtual() bool {
3333

3434
func NewVirtualCatalogKey(namespace string) CatalogKey {
3535
return CatalogKey{
36-
Name: ExistingOperatorKey,
36+
Name: ExistingOperatorKey,
3737
Namespace: namespace,
3838
}
3939
}

0 commit comments

Comments
 (0)