From 3a4e2b5b00abc716d954583b113536cbc39513f1 Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Wed, 28 Aug 2024 21:22:09 +0200 Subject: [PATCH] Fix panic in ExtensionsController when reacquring the lease The contexts don't need to be stored in the struct. In fact, one of the stored contexts was never initialized. Prevents panics like the following when reacquiring leader leases: > panic: cannot create context from nil parent > > goroutine 1963 [running]: > context.withCancel(...) > context/context.go:270 > context.WithCancel({0x0?, 0x0?}) > context/context.go:236 +0xb4 > github.com/k0sproject/k0s/pkg/component/controller.(*ExtensionsController).watchStartChan(0xc00096d200) > github.com/k0sproject/k0s/pkg/component/controller/extensions_controller.go:430 +0x194 > created by github.com/k0sproject/k0s/pkg/component/controller.(*ExtensionsController).Start in goroutine 1 > github.com/k0sproject/k0s/pkg/component/controller/extensions_controller.go:411 +0x3ec Fixes: c849e9e98 ("[helm] don't start reonciler before leaderelection") Signed-off-by: Tom Wieczorek --- .../controller/extensions_controller.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pkg/component/controller/extensions_controller.go b/pkg/component/controller/extensions_controller.go index e89475d14741..86879aff7ca1 100644 --- a/pkg/component/controller/extensions_controller.go +++ b/pkg/component/controller/extensions_controller.go @@ -68,9 +68,7 @@ type ExtensionsController struct { startChan chan struct{} mux sync.Mutex mgr crman.Manager - mgrCtx context.Context mgrCancelFn context.CancelFunc - controllerCtx context.Context } var _ manager.Component = (*ExtensionsController)(nil) @@ -388,12 +386,10 @@ func (ec *ExtensionsController) Start(ctx context.Context) error { ec.startChan = make(chan struct{}, 1) // Do the first validation before setting callbacks - ec.mgrCtx, ec.mgrCancelFn = context.WithCancel(ctx) var err error - ec.mgr, err = ec.instantiateManager(ec.mgrCtx) + ec.mgr, err = ec.instantiateManager(ctx) if err != nil { ec.L.WithError(err).Error("Can't instantiate controller-runtime manager") - ec.mgrCancelFn() return err } @@ -425,11 +421,12 @@ func (ec *ExtensionsController) watchStartChan() { for range ec.startChan { ec.L.Info("Acquired leader lease") ec.mux.Lock() + ctx, cancel := context.WithCancel(context.Background()) + ec.mgrCancelFn = cancel if ec.mgr == nil { ec.L.Info("Instantiating controller-runtime manager") - ec.mgrCtx, ec.mgrCancelFn = context.WithCancel(ec.controllerCtx) var err error - ec.mgr, err = ec.instantiateManager(ec.controllerCtx) + ec.mgr, err = ec.instantiateManager(ctx) if err != nil { ec.L.WithError(err).Error("Can't instantiate controller-runtime manager") ec.mux.Unlock() @@ -437,7 +434,7 @@ func (ec *ExtensionsController) watchStartChan() { } } ec.mux.Unlock() - ec.startControllerManager() + ec.startControllerManager(ctx) } ec.L.Info("Start channel closed, stopping controller-manager") } @@ -506,10 +503,10 @@ func (ec *ExtensionsController) instantiateManager(ctx context.Context) (crman.M return mgr, nil } -func (ec *ExtensionsController) startControllerManager() { +func (ec *ExtensionsController) startControllerManager(ctx context.Context) { go func() { ec.L.Info("Starting controller-manager") - if err := ec.mgr.Start(ec.mgrCtx); err != nil { + if err := ec.mgr.Start(ctx); err != nil { ec.L.WithError(err).Error("Controller manager working loop exited") } }()