From 2d53896079ef991a8031f6779719dd6f8b8ce86b Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Tue, 19 May 2026 10:23:50 +0200 Subject: [PATCH 1/2] Downgrade SIGTERM process terminations to warning Some processes prefer to re-raise SIGTERM instead of exiting with a zero exit code. In that case, k0s cannot determine whether the process had a clean shutdown or if it even had a proper signal handler to begin with. Downgrade this case from an error to a warning and make the log message reflect that the process terminated with SIGTERM instead of exiting cleanly. Signed-off-by: Tom Wieczorek --- pkg/supervisor/supervisor.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/supervisor/supervisor.go b/pkg/supervisor/supervisor.go index 377289f88071..11279ef79b03 100644 --- a/pkg/supervisor/supervisor.go +++ b/pkg/supervisor/supervisor.go @@ -66,7 +66,11 @@ func (s *Supervisor) processWaitQuit(ctx context.Context, cmd *exec.Cmd) bool { case <-ctx.Done(): s.log.Debugf("Attempting to terminate supervised process (%v)", context.Cause(ctx)) if err := s.terminateSupervisedProcess(cmd, waitresult); err != nil { - s.log.WithError(err).Error("Error while terminating process") + if errors.Is(err, errTerminated) { + s.log.Warn("Process ", errTerminated) + } else { + s.log.WithError(err).Error("Error while terminating process") + } } else { s.log.Info("Process terminated successfully") } @@ -88,6 +92,12 @@ func (s *Supervisor) processWaitQuit(ctx context.Context, cmd *exec.Cmd) bool { } } +// Indicates that a process terminated with SIGTERM. Some processes prefer to +// re-raise SIGTERM instead of exiting with a zero exit code. In that case, k0s +// cannot determine whether the process had a clean shutdown or if it even had a +// proper signal handler to begin with. +var errTerminated = errors.New("terminated with SIGTERM instead of exiting cleanly") + func (s *Supervisor) terminateSupervisedProcess(cmd *exec.Cmd, waitresult <-chan error) error { err := requestGracefulTermination(cmd.Process) switch { @@ -103,7 +113,7 @@ func (s *Supervisor) terminateSupervisedProcess(cmd *exec.Cmd, waitresult <-chan return nil case errors.As(err, &exitErr): if status, ok := exitErr.Sys().(syscall.WaitStatus); ok && status.Signal() == syscall.SIGTERM { - return errors.New("process terminated without handling SIGTERM") + return errTerminated } return exitErr default: From ebd5273824ed2951a8ee0bbc87c1f9f9f3d3cfa9 Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Wed, 20 May 2026 13:21:38 +0200 Subject: [PATCH 2/2] Don't log an error when dropping controller lease on shutdown When the controller lease counter was stopped, an error was logged about losing the controller lease. This is actually the expected behavior. Downgrade that log to info. Signed-off-by: Tom Wieczorek --- pkg/component/controller/controllersleasecounter.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/component/controller/controllersleasecounter.go b/pkg/component/controller/controllersleasecounter.go index 23ac82826caa..040c8d0f11bb 100644 --- a/pkg/component/controller/controllersleasecounter.go +++ b/pkg/component/controller/controllersleasecounter.go @@ -5,6 +5,7 @@ package controller import ( "context" + "errors" "fmt" "sync" "time" @@ -63,13 +64,13 @@ func (l *K0sControllersLeaseCounter) Start(context.Context) error { return err } - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done(); l.runLeaderElection(ctx, client) }() go func() { defer wg.Done(); l.runLeaseCounter(ctx, kubeClient) }() - l.stop = func() { cancel(); wg.Wait() } + l.stop = func() { cancel(errors.New("component is stopping")); wg.Wait() } return nil } @@ -88,7 +89,11 @@ func (l *K0sControllersLeaseCounter) runLeaderElection(ctx context.Context, clie if status == leaderelection.StatusLeading { l.log.Info("Holding the controller lease") } else { - l.log.Error("Lost the controller lease") + if err := context.Cause(ctx); err != nil { + l.log.Info("Lost the controller lease: ", err) + } else { + l.log.Error("Lost the controller lease") + } } }) }