moby/cmd/dockerd/trap/trap.go
Cory Snider 993ca8c6de cmd/dockerd/trap: log to logrus directly
Logging through a dependency-injected interface value was a vestige of
when Trap was in pkg/signal to avoid importing logrus in a reusable
package: cc4da81128.
Now that Trap lives under cmd/dockerd, nobody will be importing this so
we no longer need to worry about minimizing the package's dependencies.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-04-26 09:53:01 -04:00

46 lines
1.2 KiB
Go

package trap // import "github.com/docker/docker/cmd/dockerd/trap"
import (
"os"
"os/signal"
"syscall"
"github.com/sirupsen/logrus"
)
const (
// Immediately terminate the process when this many SIGINT or SIGTERM
// signals are received.
forceQuitCount = 3
)
// Trap sets up a simplified signal "trap", appropriate for common
// behavior expected from a vanilla unix command-line tool in general
// (and the Docker engine in particular).
//
// The first time a SIGINT or SIGTERM signal is received, `cleanup` is called in
// a new goroutine.
//
// If SIGINT or SIGTERM are received 3 times, the process is terminated
// immediately with an exit code of 128 + the signal number.
func Trap(cleanup func()) {
c := make(chan os.Signal, forceQuitCount)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
var interruptCount int
for sig := range c {
logrus.Infof("Processing signal '%v'", sig)
if interruptCount < forceQuitCount {
interruptCount++
// Initiate the cleanup only once
if interruptCount == 1 {
go cleanup()
}
continue
}
logrus.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
os.Exit(128 + int(sig.(syscall.Signal)))
}
}()
}