@@ -48,8 +48,10 @@ import (
4848 gutil "github.com/gardener/gardener/pkg/utils/gardener"
4949 "github.com/gardener/gardener/pkg/utils/imagevector"
5050 kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
51+ "github.com/gardener/gardener/pkg/utils/retry"
5152
5253 corev1 "k8s.io/api/core/v1"
54+ "k8s.io/apimachinery/pkg/api/meta"
5355 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5456 "k8s.io/apimachinery/pkg/util/runtime"
5557 "k8s.io/client-go/tools/cache"
@@ -136,7 +138,8 @@ func (f *GardenletControllerFactory) Run(ctx context.Context) error {
136138 // Initialize the workqueue metrics collection.
137139 gardenmetrics .RegisterWorkqueMetrics ()
138140
139- seedClient , err := f .clientMap .GetClient (ctx , keys .ForSeedWithName (f .cfg .SeedConfig .Name ))
141+ seedName := f .cfg .SeedConfig .Name
142+ seedClient , err := f .clientMap .GetClient (ctx , keys .ForSeedWithName (seedName ))
140143 if err != nil {
141144 return fmt .Errorf ("failed to get seed client: %w" , err )
142145 }
@@ -167,10 +170,7 @@ func (f *GardenletControllerFactory) Run(ctx context.Context) error {
167170 return fmt .Errorf ("failed initializing NetworkPolicy controller: %w" , err )
168171 }
169172
170- extensionsController , err := extensionscontroller .NewController (ctx , k8sGardenClient , seedClient , f .cfg .SeedConfig .Name , logger .Logger , f .recorder )
171- if err != nil {
172- return fmt .Errorf ("failed initializing extensions controller: %w" , err )
173- }
173+ extensionsController := extensionscontroller .NewController (k8sGardenClient , seedClient , f .cfg .SeedConfig .Name , logger .Logger , f .recorder )
174174
175175 managedSeedController , err := managedseedcontroller .NewManagedSeedController (ctx , f .clientMap , f .cfg , imageVector , f .recorder , logger .Logger )
176176 if err != nil {
@@ -192,20 +192,40 @@ func (f *GardenletControllerFactory) Run(ctx context.Context) error {
192192 extensionsController ,
193193 )
194194
195- go networkpolicyController .Run (ctx , * f .cfg .Controllers .SeedAPIServerNetworkPolicy .ConcurrentSyncs )
196- go extensionsController .Run (ctx , * f .cfg .Controllers .ControllerInstallationRequired .ConcurrentSyncs , * f .cfg .Controllers .ShootStateSync .ConcurrentSyncs )
197- go backupBucketController .Run (ctx , * f .cfg .Controllers .BackupBucket .ConcurrentSyncs )
198- go backupEntryController .Run (ctx , * f .cfg .Controllers .BackupEntry .ConcurrentSyncs )
199- go bastionController .Run (ctx , * f .cfg .Controllers .Bastion .ConcurrentSyncs )
200- go controllerInstallationController .Run (ctx , * f .cfg .Controllers .ControllerInstallation .ConcurrentSyncs , * f .cfg .Controllers .ControllerInstallationCare .ConcurrentSyncs )
201- go seedController .Run (ctx , * f .cfg .Controllers .Seed .ConcurrentSyncs )
202- go shootController .Run (ctx , * f .cfg .Controllers .Shoot .ConcurrentSyncs , * f .cfg .Controllers .ShootCare .ConcurrentSyncs )
203- go managedSeedController .Run (ctx , * f .cfg .Controllers .ManagedSeed .ConcurrentSyncs )
195+ controllerCtx , cancel := context .WithCancel (ctx )
196+
197+ go networkpolicyController .Run (controllerCtx , * f .cfg .Controllers .SeedAPIServerNetworkPolicy .ConcurrentSyncs )
198+ go backupBucketController .Run (controllerCtx , * f .cfg .Controllers .BackupBucket .ConcurrentSyncs )
199+ go backupEntryController .Run (controllerCtx , * f .cfg .Controllers .BackupEntry .ConcurrentSyncs )
200+ go bastionController .Run (controllerCtx , * f .cfg .Controllers .Bastion .ConcurrentSyncs )
201+ go controllerInstallationController .Run (controllerCtx , * f .cfg .Controllers .ControllerInstallation .ConcurrentSyncs , * f .cfg .Controllers .ControllerInstallationCare .ConcurrentSyncs )
202+ go seedController .Run (controllerCtx , * f .cfg .Controllers .Seed .ConcurrentSyncs )
203+ go shootController .Run (controllerCtx , * f .cfg .Controllers .Shoot .ConcurrentSyncs , * f .cfg .Controllers .ShootCare .ConcurrentSyncs )
204+ go managedSeedController .Run (controllerCtx , * f .cfg .Controllers .ManagedSeed .ConcurrentSyncs )
205+
206+ if err := retry .Until (ctx , 10 * time .Second , func (ctx context.Context ) (bool , error ) {
207+ if err := extensionsController .Initialize (ctx , seedClient ); err != nil {
208+ // A NoMatchError most probably indicates that the necessary CRDs haven't been deployed to the affected seed cluster yet.
209+ // This can either be the case if the seed cluster is new or if a new extension CRD was added.
210+ if meta .IsNoMatchError (err ) {
211+ logger .Logger .Errorf ("An error occurred when initializing extension controllers: %v. Will retry." , err )
212+ return retry .MinorError (err )
213+ }
214+ return retry .SevereError (err )
215+ }
216+ return retry .Ok ()
217+ }); err != nil {
218+ cancel ()
219+ return err
220+ }
221+
222+ go extensionsController .Run (controllerCtx , * f .cfg .Controllers .ControllerInstallationRequired .ConcurrentSyncs , * f .cfg .Controllers .ShootStateSync .ConcurrentSyncs )
204223
205224 logger .Logger .Infof ("Gardenlet (version %s) initialized." , version .Get ().GitVersion )
206225
207226 // Shutdown handling
208227 <- ctx .Done ()
228+ cancel ()
209229
210230 logger .Logger .Infof ("I have received a stop signal and will no longer watch resources." )
211231 logger .Logger .Infof ("Bye Bye!" )
0 commit comments