Skip to content

Commit e66c5ab

Browse files
committed
Start new informers if they have not been started yet
On-behalf-of: SAP <marvin.beckers@sap.com> Signed-off-by: Marvin Beckers <marvin@kubermatic.com>
1 parent ec5cf12 commit e66c5ab

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

examples/apiexport/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func main() {
121121
return reconcile.Result{}, fmt.Errorf("failed to get configmap: %w", err)
122122
}
123123

124-
log.Info("Reconciling configmap", "name", s.Name, "uuid", s.UID)
124+
log.Info("Reconciling ConfigMap", "name", s.Name, "uuid", s.UID)
125125

126126
return reconcile.Result{}, nil
127127
},

virtualworkspace/cache.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,10 @@ func (c *scopedCache) IndexField(ctx context.Context, obj client.Object, field s
5252

5353
// Get returns a single object from the cache.
5454
func (c *scopedCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
55-
inf, gvk, scope, found, err := c.base.getSharedInformer(obj)
55+
inf, gvk, scope, err := c.base.getSharedInformer(obj)
5656
if err != nil {
5757
return fmt.Errorf("failed to get informer for %T %s: %w", obj, obj.GetObjectKind().GroupVersionKind(), err)
5858
}
59-
if !found {
60-
return fmt.Errorf("no informer found for %T %s", obj, obj.GetObjectKind().GroupVersionKind())
61-
}
6259

6360
cr := cacheReader{
6461
indexer: inf.GetIndexer(),
@@ -73,13 +70,10 @@ func (c *scopedCache) Get(ctx context.Context, key client.ObjectKey, obj client.
7370

7471
// List returns a list of objects from the cache.
7572
func (c *scopedCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
76-
inf, gvk, scope, found, err := c.base.getSharedInformer(list)
73+
inf, gvk, scope, err := c.base.getSharedInformer(list)
7774
if err != nil {
7875
return fmt.Errorf("failed to get informer for %T %s: %w", list, list.GetObjectKind().GroupVersionKind(), err)
7976
}
80-
if !found {
81-
return fmt.Errorf("no informer found for %T %s", list, list.GetObjectKind().GroupVersionKind())
82-
}
8377

8478
cr := cacheReader{
8579
indexer: inf.GetIndexer(),

virtualworkspace/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func (p *Provider) Run(ctx context.Context, mgr mcmanager.Manager) error {
109109
if err != nil {
110110
return fmt.Errorf("failed to get logical cluster informer: %w", err)
111111
}
112-
shInf, _, _, _, err := p.cache.getSharedInformer(p.object)
112+
shInf, _, _, err := p.cache.getSharedInformer(p.object)
113113
if err != nil {
114114
return fmt.Errorf("failed to get shared informer: %w", err)
115115
}

virtualworkspace/wildcard.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import (
4343
// WildcardCache is a cache that operates on a /clusters/* endpoint.
4444
type WildcardCache interface {
4545
cache.Cache
46-
getSharedInformer(obj runtime.Object) (k8scache.SharedIndexInformer, schema.GroupVersionKind, apimeta.RESTScopeName, bool, error)
46+
getSharedInformer(obj runtime.Object) (k8scache.SharedIndexInformer, schema.GroupVersionKind, apimeta.RESTScopeName, error)
4747
}
4848

4949
// NewWildcardCache returns a cache.Cache that handles multi-cluster watches
@@ -80,6 +80,8 @@ func NewWildcardCache(config *rest.Config, opts cache.Options) (WildcardCache, e
8080
Unstructured: make(map[schema.GroupVersionKind]k8scache.SharedIndexInformer),
8181
Metadata: make(map[schema.GroupVersionKind]k8scache.SharedIndexInformer),
8282
},
83+
84+
readerFailOnMissingInformer: opts.ReaderFailOnMissingInformer,
8385
}
8486

8587
opts.NewInformer = func(watcher k8scache.ListerWatcher, obj runtime.Object, duration time.Duration, indexers k8scache.Indexers) k8scache.SharedIndexInformer {
@@ -121,25 +123,60 @@ type wildcardCache struct {
121123
scheme *runtime.Scheme
122124
mapper apimeta.RESTMapper
123125
tracker informerTracker
126+
127+
readerFailOnMissingInformer bool
124128
}
125129

126-
func (c *wildcardCache) getSharedInformer(obj runtime.Object) (k8scache.SharedIndexInformer, schema.GroupVersionKind, apimeta.RESTScopeName, bool, error) {
130+
func (c *wildcardCache) getSharedInformer(obj runtime.Object) (k8scache.SharedIndexInformer, schema.GroupVersionKind, apimeta.RESTScopeName, error) {
127131
gvk, err := apiutil.GVKForObject(obj, c.scheme)
128132
if err != nil {
129-
return nil, gvk, "", false, err
133+
return nil, gvk, "", fmt.Errorf("failed to get GVK for object: %w", err)
130134
}
131135

136+
// We need the non-list GVK, so chop off the "List" from the end of the kind.
137+
gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
138+
132139
mapping, err := c.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
133140
if err != nil {
134-
return nil, gvk, "", false, err
141+
return nil, gvk, "", fmt.Errorf("failed to get REST mapping: %w", err)
135142
}
136143

137144
infs := c.tracker.informersByType(obj)
138145
c.tracker.lock.RLock()
139146
inf, ok := infs[gvk]
140147
c.tracker.lock.RUnlock()
141148

142-
return inf, gvk, mapping.Scope.Name(), ok, nil
149+
// we need to create a new informer here.
150+
if !ok {
151+
// we have been instructed to fail if the informer is missing.
152+
if c.readerFailOnMissingInformer {
153+
return nil, gvk, "", &cache.ErrResourceNotCached{}
154+
}
155+
156+
// Let's generate a new object from the chopped GVK, since the original obj might be of *List type.
157+
o, err := c.scheme.New(gvk)
158+
if err != nil {
159+
return nil, gvk, "", fmt.Errorf("failed to create object for GVK: %w", err)
160+
}
161+
162+
// Call GetInformer, but we don't care about the output. We just need to make sure that our NewInformer
163+
// func has been called, which registers the new informer in our tracker.
164+
if _, err := c.Cache.GetInformer(context.TODO(), o.(client.Object)); err != nil {
165+
return nil, gvk, "", fmt.Errorf("failed to create informer: %w", err)
166+
}
167+
168+
// Now we should be able to find the informer.
169+
infs := c.tracker.informersByType(obj)
170+
c.tracker.lock.RLock()
171+
inf, ok = infs[gvk]
172+
c.tracker.lock.RUnlock()
173+
174+
if !ok {
175+
return nil, gvk, "", fmt.Errorf("failed to find newly started informer for %v", gvk)
176+
}
177+
}
178+
179+
return inf, gvk, mapping.Scope.Name(), nil
143180
}
144181

145182
// IndexField adds an index for the given object kind.

0 commit comments

Comments
 (0)