From 8decbe7670fe3dfe752de354940089f0a8e4a2db Mon Sep 17 00:00:00 2001 From: blotus Date: Wed, 13 Jul 2022 11:54:12 +0200 Subject: [PATCH] Properly handle service shutdown on windows (#1662) --- cmd/crowdsec/main.go | 6 ++++ cmd/crowdsec/run_in_svc_windows.go | 10 ------ cmd/crowdsec/serve.go | 4 +-- cmd/crowdsec/win_service.go | 56 ++++++++++++++---------------- config/config_win.yaml | 2 +- 5 files changed, 36 insertions(+), 42 deletions(-) diff --git a/cmd/crowdsec/main.go b/cmd/crowdsec/main.go index a3b56e4e1..f1bbe75ca 100644 --- a/cmd/crowdsec/main.go +++ b/cmd/crowdsec/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "os" + "runtime" "sort" "strings" @@ -265,6 +266,11 @@ func LoadConfig(cConfig *csconfig.Config) error { log.Warn("Deprecation warning: the pid_dir config can be safely removed and is not required") } + if cConfig.Common.Daemonize && runtime.GOOS == "windows" { + log.Debug("Daemonization is not supported on Windows, disabling") + cConfig.Common.Daemonize = false + } + return nil } diff --git a/cmd/crowdsec/run_in_svc_windows.go b/cmd/crowdsec/run_in_svc_windows.go index d69f532b4..caa1b960b 100644 --- a/cmd/crowdsec/run_in_svc_windows.go +++ b/cmd/crowdsec/run_in_svc_windows.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "os" "github.com/crowdsecurity/crowdsec/pkg/csconfig" "github.com/crowdsecurity/crowdsec/pkg/cwversion" @@ -10,7 +9,6 @@ import ( "github.com/crowdsecurity/crowdsec/pkg/types" "github.com/pkg/errors" log "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/writer" "golang.org/x/sys/windows/svc" ) @@ -60,14 +58,6 @@ func WindowsRun() error { err error ) - log.AddHook(&writer.Hook{ // Send logs with level higher than warning to stderr - Writer: os.Stderr, - LogLevels: []log.Level{ - log.PanicLevel, - log.FatalLevel, - }, - }) - cConfig, err = csconfig.NewConfig(flags.ConfigFile, flags.DisableAgent, flags.DisableAPI) if err != nil { return err diff --git a/cmd/crowdsec/serve.go b/cmd/crowdsec/serve.go index 0d1df3707..fe8e161d5 100644 --- a/cmd/crowdsec/serve.go +++ b/cmd/crowdsec/serve.go @@ -304,10 +304,10 @@ func Serve(cConfig *csconfig.Config, apiReady chan bool, agentReady chan bool) e select { case <-apiTomb.Dead(): log.Infof("api shutdown") - os.Exit(0) + return nil case <-crowdsecTomb.Dead(): log.Infof("crowdsec shutdown") - os.Exit(0) + return nil } } } diff --git a/cmd/crowdsec/win_service.go b/cmd/crowdsec/win_service.go index 169ab06fd..9be89c7eb 100644 --- a/cmd/crowdsec/win_service.go +++ b/cmd/crowdsec/win_service.go @@ -22,43 +22,41 @@ type crowdsec_winservice struct { } func (m *crowdsec_winservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { - const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue + const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown changes <- svc.Status{State: svc.StartPending} - fasttick := time.Tick(500 * time.Millisecond) - slowtick := time.Tick(2 * time.Second) - tick := fasttick + tick := time.Tick(500 * time.Millisecond) changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} - go WindowsRun() -loop: - for { - select { - case <-tick: + go func() { + loop: + for { + select { + case <-tick: - case c := <-r: - switch c.Cmd { - case svc.Interrogate: - changes <- c.CurrentStatus - case svc.Stop, svc.Shutdown: - changes <- svc.Status{State: svc.StopPending} - err := shutdown(nil, m.config) - if err != nil { - log.Errorf("Error while shutting down: %s", err) - //don't return, we still want to notify windows that we are stopped ? + case c := <-r: + switch c.Cmd { + case svc.Interrogate: + changes <- c.CurrentStatus + case svc.Stop, svc.Shutdown: + changes <- svc.Status{State: svc.StopPending} + err := shutdown(nil, m.config) + if err != nil { + log.Errorf("Error while shutting down: %s", err) + //don't return, we still want to notify windows that we are stopped ? + } + break loop + default: + log.Errorf("unexpected control request #%d", c) } - break loop - case svc.Pause: - changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted} - tick = slowtick - case svc.Continue: - changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} - tick = fasttick - default: - log.Errorf("unexpected control request #%d", c) } } - } + }() + + err := WindowsRun() changes <- svc.Status{State: svc.Stopped} + if err != nil { + log.Fatalf(err.Error()) + } return } diff --git a/config/config_win.yaml b/config/config_win.yaml index 10721e62e..021f9836c 100644 --- a/config/config_win.yaml +++ b/config/config_win.yaml @@ -1,5 +1,5 @@ common: - daemonize: true + daemonize: false log_media: file log_level: info log_dir: C:\ProgramData\CrowdSec\log\