@@ -49,21 +49,19 @@ import (
4949var _ multicluster.Provider = & Provider {}
5050
5151// Provider is a [sigs.k8s.io/multicluster-runtime/pkg/multicluster.Provider] that represents each [logical cluster]
52- // (in the kcp sense) having specific initializer and exposed via initializingworkspaces virtual workspace endpoint as a cluster in the [sigs.k8s.io/multicluster-runtime] sense.
52+ // (in the kcp sense) having a specific initializer and exposed via the initializingworkspaces virtual workspace endpoint as a cluster in the [sigs.k8s.io/multicluster-runtime] sense.
5353//
5454// [logical cluster]: https://docs.kcp.io/kcp/latest/concepts/terminology/#logical-cluster
5555type Provider struct {
5656 config * rest.Config
5757 scheme * runtime.Scheme
58- cache cache.Cache
5958 wildcardCache mcpcache.WildcardCache
60- object client.Object
6159 initializerName string
6260
6361 log logr.Logger
6462
6563 lock sync.RWMutex
66- Clusters map [logicalcluster.Name ]cluster.Cluster
64+ clusters map [logicalcluster.Name ]cluster.Cluster
6765 cancelFns map [logicalcluster.Name ]context.CancelFunc
6866}
6967
@@ -75,9 +73,6 @@ type Options struct {
7573 // WildcardCache is the wildcard cache to use for the provider. If this is
7674 // nil, a new wildcard cache will be created for the given rest.Config.
7775 WildcardCache mcpcache.WildcardCache
78- // ObjectToWatch is the object type that the provider watches. If this is nil,
79- // it defaults to LogicalCluster.
80- ObjectToWatch client.Object
8176
8277 // InitializerName is the name of the initializer to watch for in LogicalCluster.Status.Initializers
8378 InitializerName string
@@ -87,9 +82,6 @@ type Options struct {
8782func New (cfg * rest.Config , options Options ) (* Provider , error ) {
8883 if options .Scheme == nil {
8984 options .Scheme = scheme .Scheme
90- if err := kcpcorev1alpha1 .AddToScheme (options .Scheme ); err != nil {
91- return nil , fmt .Errorf ("failed to add kcp core scheme: %w" , err )
92- }
9385 }
9486
9587 if options .WildcardCache == nil {
@@ -102,10 +94,6 @@ func New(cfg *rest.Config, options Options) (*Provider, error) {
10294 }
10395 }
10496
105- if options .ObjectToWatch == nil {
106- options .ObjectToWatch = & kcpcorev1alpha1.LogicalCluster {}
107- }
108-
10997 if options .InitializerName == "" {
11098 return nil , fmt .Errorf ("initializer name cannot be empty" )
11199 }
@@ -114,22 +102,20 @@ func New(cfg *rest.Config, options Options) (*Provider, error) {
114102 config : cfg ,
115103 scheme : options .Scheme ,
116104 wildcardCache : options .WildcardCache ,
117- object : options .ObjectToWatch ,
118105 initializerName : options .InitializerName ,
106+ log : log .Log .WithName ("kcp-initializing-workspaces-provider" ),
119107
120- log : log .Log .WithName ("kcp-initializing-workspaces-provider" ),
121-
122- Clusters : map [logicalcluster.Name ]cluster.Cluster {},
108+ clusters : map [logicalcluster.Name ]cluster.Cluster {},
123109 cancelFns : map [logicalcluster.Name ]context.CancelFunc {},
124110 }, nil
125111}
126112
127113// Run starts the provider and blocks.
128114func (p * Provider ) Run (ctx context.Context , mgr mcmanager.Manager ) error {
129115 g , ctx := errgroup .WithContext (ctx )
130- inf , err := p .wildcardCache .GetInformer (ctx , p . object , cache .BlockUntilSynced (true ))
116+ inf , err := p .wildcardCache .GetInformer (ctx , & kcpcorev1alpha1. LogicalCluster {} , cache .BlockUntilSynced (true ))
131117 if err != nil {
132- return fmt .Errorf ("failed to get %T informer: %w" , p . object , err )
118+ return fmt .Errorf ("failed to get informer: %w" , err )
133119 }
134120
135121 if _ , err := inf .AddEventHandler (toolscache.ResourceEventHandlerFuncs {
@@ -162,7 +148,7 @@ func (p *Provider) Run(ctx context.Context, mgr mcmanager.Manager) error {
162148 p .log .Info ("disengaging non-initializing workspace" , "cluster" , clusterName )
163149 cancel ()
164150 delete (p .cancelFns , clusterName )
165- delete (p .Clusters , clusterName )
151+ delete (p .clusters , clusterName )
166152 }
167153 p .lock .Unlock ()
168154 } else {
@@ -174,14 +160,18 @@ func (p *Provider) Run(ctx context.Context, mgr mcmanager.Manager) error {
174160 }
175161
176162 g .Go (func () error {
177- return p .wildcardCache .Start (ctx )
163+ err := p .wildcardCache .Start (ctx )
164+ if err != nil {
165+ return err
166+ }
167+ return nil
178168 })
179169
180170 syncCtx , cancel := context .WithTimeout (ctx , 30 * time .Second )
181171 defer cancel ()
182172
183- if _ , err := p .wildcardCache .GetInformer (syncCtx , p . object , cache .BlockUntilSynced (true )); err != nil {
184- return fmt .Errorf ("failed to sync %T informer: %w" , p . object , err )
173+ if _ , err := p .wildcardCache .GetInformer (syncCtx , & kcpcorev1alpha1. LogicalCluster {} , cache .BlockUntilSynced (true )); err != nil {
174+ return fmt .Errorf ("failed to sync informer: %w" , err )
185175 }
186176
187177 return g .Wait ()
@@ -207,35 +197,37 @@ func (p *Provider) handleLogicalClusterEvent(ctx context.Context, obj any, mgr m
207197 // If our initializer is not present, we need to disengage the cluster if it exists
208198 if ! hasInitializer {
209199 p .lock .Lock ()
200+ defer p .lock .Unlock ()
210201 cancel , ok := p .cancelFns [clusterName ]
211202 if ok {
212203 p .log .Info ("disengaging non-initializing workspace" , "cluster" , clusterName )
213204 cancel ()
214205 delete (p .cancelFns , clusterName )
215- delete (p .Clusters , clusterName )
206+ delete (p .clusters , clusterName )
216207 }
217- p .lock .Unlock ()
218208 return
219209 }
220210
221- p .log .Info ("LogicalCluster added" , "object" , clusterName )
222211 // fast path: cluster exists already, there is nothing to do.
223212 p .lock .RLock ()
224- if _ , ok := p .Clusters [clusterName ]; ok {
213+ if _ , ok := p .clusters [clusterName ]; ok {
225214 p .lock .RUnlock ()
226215 return
227216 }
228217 p .lock .RUnlock ()
229218
230219 // slow path: take write lock to add a new cluster (unless it appeared in the meantime).
231220 p .lock .Lock ()
232- if _ , ok := p .Clusters [clusterName ]; ok {
221+ if _ , ok := p .clusters [clusterName ]; ok {
233222 p .lock .Unlock ()
234223 return
235224 }
236225
226+ p .log .Info ("LogicalCluster added" , "object" , clusterName )
237227 // create new specific cluster with correct host endpoint for fetching specific logical cluster.
238- ctx , cancel := context .WithCancel (ctx )
228+ clusterCtx , cancel := context .WithCancel (ctx )
229+ defer cancel ()
230+
239231 cfg := rest .CopyConfig (p .config )
240232 host := cfg .Host
241233 host = strings .TrimSuffix (host , "/clusters/*" )
@@ -248,20 +240,17 @@ func (p *Provider) handleLogicalClusterEvent(ctx context.Context, obj any, mgr m
248240 p .lock .Unlock ()
249241 return
250242 }
251- p .Clusters [clusterName ] = cl
243+ p .clusters [clusterName ] = cl
252244 p .cancelFns [clusterName ] = cancel
253245 p .lock .Unlock ()
254246
255- _ , syncCancel := context .WithTimeout (ctx , 10 * time .Second )
256- defer syncCancel ()
257-
258247 p .log .Info ("engaging cluster" , "cluster" , clusterName )
259- if err := mgr .Engage (ctx , clusterName .String (), cl ); err != nil {
248+ if err := mgr .Engage (clusterCtx , clusterName .String (), cl ); err != nil {
260249 p .log .Error (err , "failed to engage cluster" , "cluster" , clusterName )
261250 p .lock .Lock ()
262251 cancel ()
263- if p .Clusters [clusterName ] == cl {
264- delete (p .Clusters , clusterName )
252+ if p .clusters [clusterName ] == cl {
253+ delete (p .clusters , clusterName )
265254 delete (p .cancelFns , clusterName )
266255 }
267256 p .lock .Unlock ()
@@ -273,7 +262,7 @@ func (p *Provider) handleLogicalClusterEvent(ctx context.Context, obj any, mgr m
273262func (p * Provider ) Get (_ context.Context , name string ) (cluster.Cluster , error ) {
274263 p .lock .RLock ()
275264 defer p .lock .RUnlock ()
276- if cl , ok := p .Clusters [logicalcluster .Name (name )]; ok {
265+ if cl , ok := p .clusters [logicalcluster .Name (name )]; ok {
277266 return cl , nil
278267 }
279268
@@ -282,5 +271,5 @@ func (p *Provider) Get(_ context.Context, name string) (cluster.Cluster, error)
282271
283272// IndexField indexes the given object by the given field on all engaged clusters, current and future.
284273func (p * Provider ) IndexField (ctx context.Context , obj client.Object , field string , extractValue client.IndexerFunc ) error {
285- return p .cache .IndexField (ctx , obj , field , extractValue )
274+ return p .wildcardCache .IndexField (ctx , obj , field , extractValue )
286275}
0 commit comments