Compare commits

...

6 commits

Author SHA1 Message Date
marco
bcbfb9fd09 context.TODO 2024-04-23 09:41:41 +02:00
marco
406eeb6c5e Merge branch 'master' into systemd-notify 2024-04-23 09:39:38 +02:00
marco
39e6657cf3 watchdog 2024-04-22 13:10:36 +02:00
marco
33674a1617 systemd: notify start, stopping, reloading 2024-04-22 13:10:36 +02:00
marco
d40720e061 simplify signal handler 2024-04-22 13:10:36 +02:00
marco
0674a34ee8 drop log.debug 2024-04-22 13:10:36 +02:00
5 changed files with 45 additions and 20 deletions

View file

@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"runtime" "runtime"
"time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -62,7 +61,6 @@ func serveAPIServer(apiServer *apiserver.APIServer) {
defer trace.CatchPanic("crowdsec/serveAPIServer") defer trace.CatchPanic("crowdsec/serveAPIServer")
go func() { go func() {
defer trace.CatchPanic("crowdsec/runAPIServer") defer trace.CatchPanic("crowdsec/runAPIServer")
log.Debugf("serving API after %s ms", time.Since(crowdsecT0))
if err := apiServer.Run(apiReady); err != nil { if err := apiServer.Run(apiReady); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View file

@ -1,6 +1,7 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
@ -23,7 +24,7 @@ import (
) )
//nolint:deadcode,unused // debugHandler is kept as a dev convenience: it shuts down and serialize internal state //nolint:deadcode,unused // debugHandler is kept as a dev convenience: it shuts down and serialize internal state
func debugHandler(sig os.Signal, cConfig *csconfig.Config) error { func debugHandler(cConfig *csconfig.Config) error {
var ( var (
tmpFile string tmpFile string
err error err error
@ -48,7 +49,7 @@ func debugHandler(sig os.Signal, cConfig *csconfig.Config) error {
return nil return nil
} }
func reloadHandler(sig os.Signal) (*csconfig.Config, error) { func reloadHandler() (*csconfig.Config, error) {
var tmpFile string var tmpFile string
// re-initialize tombs // re-initialize tombs
@ -206,7 +207,7 @@ func shutdownCrowdsec() error {
return nil return nil
} }
func shutdown(sig os.Signal, cConfig *csconfig.Config) error { func shutdown(cConfig *csconfig.Config) error {
if !cConfig.DisableAgent { if !cConfig.DisableAgent {
if err := shutdownCrowdsec(); err != nil { if err := shutdownCrowdsec(); err != nil {
return fmt.Errorf("failed to shut down crowdsec: %w", err) return fmt.Errorf("failed to shut down crowdsec: %w", err)
@ -239,6 +240,22 @@ func drainChan(c chan types.Event) {
} }
} }
// watchdog sends a watchdog signal to systemd every 15 seconds
func watchdog(ctx context.Context, logger log.FieldLogger) {
ticker := time.NewTicker(15 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
csdaemon.Notify(csdaemon.Watchdog, logger)
}
}
}
func HandleSignals(cConfig *csconfig.Config) error { func HandleSignals(cConfig *csconfig.Config) error {
var ( var (
newConfig *csconfig.Config newConfig *csconfig.Config
@ -262,24 +279,31 @@ func HandleSignals(cConfig *csconfig.Config) error {
go func() { go func() {
defer trace.CatchPanic("crowdsec/HandleSignals") defer trace.CatchPanic("crowdsec/HandleSignals")
Loop:
for { logger := log.StandardLogger()
s := <-signalChan
csdaemon.Notify(csdaemon.Ready, logger)
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
go watchdog(ctx, logger)
for s := range signalChan {
switch s { switch s {
// kill -SIGHUP XXXX // kill -SIGHUP XXXX
case syscall.SIGHUP: case syscall.SIGHUP:
log.Warning("SIGHUP received, reloading") log.Warning("SIGHUP received, reloading")
csdaemon.Notify(csdaemon.Reloading, logger)
if err = shutdown(s, cConfig); err != nil { if err = shutdown(cConfig); err != nil {
exitChan <- fmt.Errorf("failed shutdown: %w", err) exitChan <- fmt.Errorf("failed shutdown: %w", err)
return
break Loop
} }
if newConfig, err = reloadHandler(s); err != nil { if newConfig, err = reloadHandler(); err != nil {
exitChan <- fmt.Errorf("reload handler failure: %w", err) exitChan <- fmt.Errorf("reload handler failure: %w", err)
return
break Loop
} }
if newConfig != nil { if newConfig != nil {
@ -288,10 +312,11 @@ func HandleSignals(cConfig *csconfig.Config) error {
// ctrl+C, kill -SIGINT XXXX, kill -SIGTERM XXXX // ctrl+C, kill -SIGINT XXXX, kill -SIGTERM XXXX
case os.Interrupt, syscall.SIGTERM: case os.Interrupt, syscall.SIGTERM:
log.Warning("SIGTERM received, shutting down") log.Warning("SIGTERM received, shutting down")
if err = shutdown(s, cConfig); err != nil { csdaemon.Notify(csdaemon.Stopping, logger)
exitChan <- fmt.Errorf("failed shutdown: %w", err)
break Loop if err = shutdown(cConfig); err != nil {
exitChan <- fmt.Errorf("failed shutdown: %w", err)
return
} }
exitChan <- nil exitChan <- nil
} }
@ -411,9 +436,9 @@ func Serve(cConfig *csconfig.Config, agentReady chan bool) error {
switch ch { switch ch {
case apiTomb.Dead(): case apiTomb.Dead():
log.Infof("api shutdown") log.Info("api shutdown")
case crowdsecTomb.Dead(): case crowdsecTomb.Dead():
log.Infof("crowdsec shutdown") log.Info("crowdsec shutdown")
} }
} }

View file

@ -41,7 +41,7 @@ func (m *crowdsec_winservice) Execute(args []string, r <-chan svc.ChangeRequest,
changes <- c.CurrentStatus changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown: case svc.Stop, svc.Shutdown:
changes <- svc.Status{State: svc.StopPending} changes <- svc.Status{State: svc.StopPending}
err := shutdown(nil, m.config) err := shutdown(m.config)
if err != nil { if err != nil {
log.Errorf("Error while shutting down: %s", err) log.Errorf("Error while shutting down: %s", err)
// don't return, we still want to notify windows that we are stopped ? // don't return, we still want to notify windows that we are stopped ?

View file

@ -12,6 +12,7 @@ ExecReload=/usr/local/bin/crowdsec -c /etc/crowdsec/config.yaml -t -error
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
Restart=always Restart=always
RestartSec=60 RestartSec=60
WatchdogSec=30
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View file

@ -12,6 +12,7 @@ ExecReload=/usr/bin/crowdsec -c /etc/crowdsec/config.yaml -t -error
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
Restart=always Restart=always
RestartSec=60 RestartSec=60
WatchdogSec=30
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target