@@ -351,6 +351,16 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) {
351
351
// Initialize the internal context.
352
352
cm .internalCtx , cm .internalCancel = context .WithCancel (ctx )
353
353
354
+ // Leader elector must be created before defer that contains engageStopProcedure function
355
+ // https://github.com/kubernetes-sigs/controller-runtime/issues/2873
356
+ var leaderElector * leaderelection.LeaderElector
357
+ if cm .resourceLock != nil {
358
+ leaderElector , err = cm .initLeaderElector ()
359
+ if err != nil {
360
+ return fmt .Errorf ("failed during initialization leader election process: %w" , err )
361
+ }
362
+ }
363
+
354
364
// This chan indicates that stop is complete, in other words all runnables have returned or timeout on stop request
355
365
stopComplete := make (chan struct {})
356
366
defer close (stopComplete )
@@ -433,19 +443,22 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) {
433
443
{
434
444
ctx , cancel := context .WithCancel (context .Background ())
435
445
cm .leaderElectionCancel = cancel
436
- go func () {
437
- if cm .resourceLock != nil {
438
- if err := cm .startLeaderElection (ctx ); err != nil {
439
- cm .errChan <- err
440
- }
441
- } else {
446
+ if leaderElector != nil {
447
+ // Start the leader elector process
448
+ go func () {
449
+ leaderElector .Run (ctx )
450
+ <- ctx .Done ()
451
+ close (cm .leaderElectionStopped )
452
+ }()
453
+ } else {
454
+ go func () {
442
455
// Treat not having leader election enabled the same as being elected.
443
456
if err := cm .startLeaderElectionRunnables (); err != nil {
444
457
cm .errChan <- err
445
458
}
446
459
close (cm .elected )
447
- }
448
- }()
460
+ }()
461
+ }
449
462
}
450
463
451
464
ready = true
@@ -564,12 +577,8 @@ func (cm *controllerManager) engageStopProcedure(stopComplete <-chan struct{}) e
564
577
return nil
565
578
}
566
579
567
- func (cm * controllerManager ) startLeaderElectionRunnables () error {
568
- return cm .runnables .LeaderElection .Start (cm .internalCtx )
569
- }
570
-
571
- func (cm * controllerManager ) startLeaderElection (ctx context.Context ) (err error ) {
572
- l , err := leaderelection .NewLeaderElector (leaderelection.LeaderElectionConfig {
580
+ func (cm * controllerManager ) initLeaderElector () (* leaderelection.LeaderElector , error ) {
581
+ leaderElector , err := leaderelection .NewLeaderElector (leaderelection.LeaderElectionConfig {
573
582
Lock : cm .resourceLock ,
574
583
LeaseDuration : cm .leaseDuration ,
575
584
RenewDeadline : cm .renewDeadline ,
@@ -599,16 +608,14 @@ func (cm *controllerManager) startLeaderElection(ctx context.Context) (err error
599
608
Name : cm .leaderElectionID ,
600
609
})
601
610
if err != nil {
602
- return err
611
+ return nil , err
603
612
}
604
613
605
- // Start the leader elector process
606
- go func () {
607
- l .Run (ctx )
608
- <- ctx .Done ()
609
- close (cm .leaderElectionStopped )
610
- }()
611
- return nil
614
+ return leaderElector , nil
615
+ }
616
+
617
+ func (cm * controllerManager ) startLeaderElectionRunnables () error {
618
+ return cm .runnables .LeaderElection .Start (cm .internalCtx )
612
619
}
613
620
614
621
func (cm * controllerManager ) Elected () <- chan struct {} {
0 commit comments