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") + } } }) } 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: