From 156ce5cd7d6f0f1514d263a74ffe3dd42f7c7caf Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 12 Feb 2020 10:47:48 +0100 Subject: add pkg/capabilities Add pkg/capabibilities to deal with capabilities. The code has been copied from Docker (and attributed with the copyright) but changed significantly to only do what we really need. The code has also been simplified and will perform better due to removed redundancy. Signed-off-by: Valentin Rothberg --- go.sum | 1 + libpod/container_api.go | 4 +- pkg/capabilities/capabilities.go | 129 ++++++++++++++++ pkg/spec/security.go | 6 +- .../github.com/docker/docker/oci/caps/defaults.go | 21 --- vendor/github.com/docker/docker/oci/caps/utils.go | 169 --------------------- vendor/modules.txt | 1 - 7 files changed, 135 insertions(+), 196 deletions(-) create mode 100644 pkg/capabilities/capabilities.go delete mode 100644 vendor/github.com/docker/docker/oci/caps/defaults.go delete mode 100644 vendor/github.com/docker/docker/oci/caps/utils.go diff --git a/go.sum b/go.sum index 691c580ec..860b80a3d 100644 --- a/go.sum +++ b/go.sum @@ -616,6 +616,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/libpod/container_api.go b/libpod/container_api.go index d74a14f15..d612341bc 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -11,8 +11,8 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" + "github.com/containers/libpod/pkg/capabilities" "github.com/containers/storage/pkg/stringid" - "github.com/docker/docker/oci/caps" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -237,7 +237,7 @@ func (c *Container) Exec(tty, privileged bool, env map[string]string, cmd []stri } if privileged || c.config.Privileged { - capList = caps.GetAllCapabilities() + capList = capabilities.AllCapabilities() } // Generate exec session ID diff --git a/pkg/capabilities/capabilities.go b/pkg/capabilities/capabilities.go new file mode 100644 index 000000000..ea22498b8 --- /dev/null +++ b/pkg/capabilities/capabilities.go @@ -0,0 +1,129 @@ +package capabilities + +// Copyright 2013-2018 Docker, Inc. + +// NOTE: this package has been copied from github.com/docker/docker but been +// changed significantly to fit the needs of libpod. + +import ( + "strings" + + "github.com/containers/libpod/pkg/util" + "github.com/pkg/errors" + "github.com/syndtr/gocapability/capability" +) + +var ( + // Used internally and populated during init(). + capabilityList []string + + // ErrUnknownCapability is thrown when an unknown capability is processed. + ErrUnknownCapability = errors.New("unknown capability") +) + +// All is a special value used to add/drop all known capababilities. +// Useful on the CLI for `--cap-add=all` etc. +const All = "ALL" + +func init() { + last := capability.CAP_LAST_CAP + // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap + if last == capability.Cap(63) { + last = capability.CAP_BLOCK_SUSPEND + } + for _, cap := range capability.List() { + if cap > last { + continue + } + capabilityList = append(capabilityList, "CAP_"+strings.ToUpper(cap.String())) + } +} + +// AllCapabilities returns all known capabilities. +func AllCapabilities() []string { + return capabilityList +} + +// normalizeCapabilities normalizes caps by adding a "CAP_" prefix (if not yet +// present). +func normalizeCapabilities(caps []string) ([]string, error) { + normalized := make([]string, len(caps)) + for i, c := range caps { + c = strings.ToUpper(c) + if c == All { + normalized = append(normalized, c) + continue + } + if !strings.HasPrefix(c, "CAP_") { + c = "CAP_" + c + } + if !util.StringInSlice(c, capabilityList) { + return nil, errors.Wrapf(ErrUnknownCapability, "%q", c) + } + normalized[i] = c + } + return normalized, nil +} + +// ValidateCapabilities validates if caps only contains valid capabilities. +func ValidateCapabilities(caps []string) error { + for _, c := range caps { + if !util.StringInSlice(c, capabilityList) { + return errors.Wrapf(ErrUnknownCapability, "%q", c) + } + } + return nil +} + +// MergeCapabilities computes a set of capabilities by adding capapbitilities +// to or dropping them from base. +// +// Note that "ALL" will cause all known capabilities to be added/dropped but +// the ones specified to be dropped/added. +func MergeCapabilities(base, adds, drops []string) ([]string, error) { + if len(adds) == 0 && len(drops) == 0 { + // Nothing to tweak; we're done + return base, nil + } + + capDrop, err := normalizeCapabilities(drops) + if err != nil { + return nil, err + } + capAdd, err := normalizeCapabilities(adds) + if err != nil { + return nil, err + } + + // Make sure that capDrop and capAdd are distinct sets. + for _, drop := range capDrop { + if util.StringInSlice(drop, capAdd) { + return nil, errors.Errorf("capability %q cannot be dropped and added", drop) + } + } + + var caps []string + + switch { + case util.StringInSlice(All, capAdd): + // Add all capabilities except ones on capDrop + for _, c := range capabilityList { + if !util.StringInSlice(c, capDrop) { + caps = append(caps, c) + } + } + case util.StringInSlice(All, capDrop): + // "Drop" all capabilities; use what's in capAdd instead + caps = capAdd + default: + // First drop some capabilities + for _, c := range base { + if !util.StringInSlice(c, capDrop) { + caps = append(caps, c) + } + } + // Then add the list of capabilities from capAdd + caps = append(caps, capAdd...) + } + return caps, nil +} diff --git a/pkg/spec/security.go b/pkg/spec/security.go index 372fe87c6..3bad9f97a 100644 --- a/pkg/spec/security.go +++ b/pkg/spec/security.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/containers/libpod/libpod" - "github.com/docker/docker/oci/caps" + "github.com/containers/libpod/pkg/capabilities" "github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" @@ -118,7 +118,7 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon if useNotRoot(user.User) { configSpec.Process.Capabilities.Bounding = caplist } - caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop, nil, false) + caplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop) if err != nil { return err } @@ -129,7 +129,7 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Ambient = caplist if useNotRoot(user.User) { - caplist, err = caps.TweakCapabilities(bounding, c.CapAdd, c.CapDrop, nil, false) + caplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop) if err != nil { return err } diff --git a/vendor/github.com/docker/docker/oci/caps/defaults.go b/vendor/github.com/docker/docker/oci/caps/defaults.go deleted file mode 100644 index 242ee5811..000000000 --- a/vendor/github.com/docker/docker/oci/caps/defaults.go +++ /dev/null @@ -1,21 +0,0 @@ -package caps // import "github.com/docker/docker/oci/caps" - -// DefaultCapabilities returns a Linux kernel default capabilities -func DefaultCapabilities() []string { - return []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - } -} diff --git a/vendor/github.com/docker/docker/oci/caps/utils.go b/vendor/github.com/docker/docker/oci/caps/utils.go deleted file mode 100644 index ffd3f6f50..000000000 --- a/vendor/github.com/docker/docker/oci/caps/utils.go +++ /dev/null @@ -1,169 +0,0 @@ -package caps // import "github.com/docker/docker/oci/caps" - -import ( - "fmt" - "strings" - - "github.com/docker/docker/errdefs" - "github.com/syndtr/gocapability/capability" -) - -var capabilityList Capabilities - -func init() { - last := capability.CAP_LAST_CAP - // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap - if last == capability.Cap(63) { - last = capability.CAP_BLOCK_SUSPEND - } - for _, cap := range capability.List() { - if cap > last { - continue - } - capabilityList = append(capabilityList, - &CapabilityMapping{ - Key: "CAP_" + strings.ToUpper(cap.String()), - Value: cap, - }, - ) - } -} - -type ( - // CapabilityMapping maps linux capability name to its value of capability.Cap type - // Capabilities is one of the security systems in Linux Security Module (LSM) - // framework provided by the kernel. - // For more details on capabilities, see http://man7.org/linux/man-pages/man7/capabilities.7.html - CapabilityMapping struct { - Key string `json:"key,omitempty"` - Value capability.Cap `json:"value,omitempty"` - } - // Capabilities contains all CapabilityMapping - Capabilities []*CapabilityMapping -) - -// String returns of CapabilityMapping -func (c *CapabilityMapping) String() string { - return c.Key -} - -// GetCapability returns CapabilityMapping which contains specific key -func GetCapability(key string) *CapabilityMapping { - for _, capp := range capabilityList { - if capp.Key == key { - cpy := *capp - return &cpy - } - } - return nil -} - -// GetAllCapabilities returns all of the capabilities -func GetAllCapabilities() []string { - output := make([]string, len(capabilityList)) - for i, capability := range capabilityList { - output[i] = capability.String() - } - return output -} - -// inSlice tests whether a string is contained in a slice of strings or not. -func inSlice(slice []string, s string) bool { - for _, ss := range slice { - if s == ss { - return true - } - } - return false -} - -const allCapabilities = "ALL" - -// NormalizeLegacyCapabilities normalizes, and validates CapAdd/CapDrop capabilities -// by upper-casing them, and adding a CAP_ prefix (if not yet present). -// -// This function also accepts the "ALL" magic-value, that's used by CapAdd/CapDrop. -func NormalizeLegacyCapabilities(caps []string) ([]string, error) { - var normalized []string - - valids := GetAllCapabilities() - for _, c := range caps { - c = strings.ToUpper(c) - if c == allCapabilities { - normalized = append(normalized, c) - continue - } - if !strings.HasPrefix(c, "CAP_") { - c = "CAP_" + c - } - if !inSlice(valids, c) { - return nil, errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c)) - } - normalized = append(normalized, c) - } - return normalized, nil -} - -// ValidateCapabilities validates if caps only contains valid capabilities -func ValidateCapabilities(caps []string) error { - valids := GetAllCapabilities() - for _, c := range caps { - if !inSlice(valids, c) { - return errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c)) - } - } - return nil -} - -// TweakCapabilities tweaks capabilities by adding, dropping, or overriding -// capabilities in the basics capabilities list. -func TweakCapabilities(basics, adds, drops, capabilities []string, privileged bool) ([]string, error) { - switch { - case privileged: - // Privileged containers get all capabilities - return GetAllCapabilities(), nil - case capabilities != nil: - // Use custom set of capabilities - if err := ValidateCapabilities(capabilities); err != nil { - return nil, err - } - return capabilities, nil - case len(adds) == 0 && len(drops) == 0: - // Nothing to tweak; we're done - return basics, nil - } - - capDrop, err := NormalizeLegacyCapabilities(drops) - if err != nil { - return nil, err - } - capAdd, err := NormalizeLegacyCapabilities(adds) - if err != nil { - return nil, err - } - - var caps []string - - switch { - case inSlice(capAdd, allCapabilities): - // Add all capabilities except ones on capDrop - for _, c := range GetAllCapabilities() { - if !inSlice(capDrop, c) { - caps = append(caps, c) - } - } - case inSlice(capDrop, allCapabilities): - // "Drop" all capabilities; use what's in capAdd instead - caps = capAdd - default: - // First drop some capabilities - for _, c := range basics { - if !inSlice(capDrop, c) { - caps = append(caps, c) - } - } - // Then add the list of capabilities from capAdd - caps = append(caps, capAdd...) - } - return caps, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 73bca1ef8..3c03fbdfb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -227,7 +227,6 @@ github.com/docker/docker/api/types/versions github.com/docker/docker/api/types/volume github.com/docker/docker/client github.com/docker/docker/errdefs -github.com/docker/docker/oci/caps github.com/docker/docker/pkg/archive github.com/docker/docker/pkg/fileutils github.com/docker/docker/pkg/homedir -- cgit v1.2.3-54-g00ecf From 85b7374491e842c44bec3ce5ec800794cae10295 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 12 Feb 2020 11:10:55 +0100 Subject: add pkg/signal Add pkg/signal to deal with parts of signal processing and translating signals from string to numeric representations. The code has been copied from docker/docker (and attributed with the copyright) but been reduced to only what libpod needs (on Linux). Signed-off-by: Valentin Rothberg --- go.mod | 1 + go.sum | 3 + pkg/adapter/sigproxy_linux.go | 4 +- pkg/adapter/terminal.go | 6 +- pkg/api/handlers/containers_create.go | 2 +- pkg/signal/signal_linux.go | 127 +++++++++++++++++++++ pkg/signal/signal_unsupported.go | 28 +++++ pkg/util/utils.go | 2 +- test/system/130-kill.bats | 6 +- .../github.com/docker/docker/pkg/signal/README.md | 1 - .../github.com/docker/docker/pkg/signal/signal.go | 54 --------- .../docker/docker/pkg/signal/signal_darwin.go | 41 ------- .../docker/docker/pkg/signal/signal_freebsd.go | 43 ------- .../docker/docker/pkg/signal/signal_linux.go | 83 -------------- .../docker/docker/pkg/signal/signal_linux_mipsx.go | 84 -------------- .../docker/docker/pkg/signal/signal_unix.go | 21 ---- .../docker/docker/pkg/signal/signal_unsupported.go | 10 -- .../docker/docker/pkg/signal/signal_windows.go | 26 ----- vendor/github.com/docker/docker/pkg/signal/trap.go | 104 ----------------- vendor/modules.txt | 1 - 20 files changed, 169 insertions(+), 478 deletions(-) create mode 100644 pkg/signal/signal_linux.go create mode 100644 pkg/signal/signal_unsupported.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/README.md delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_darwin.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_linux.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_unix.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/signal_windows.go delete mode 100644 vendor/github.com/docker/docker/pkg/signal/trap.go diff --git a/go.mod b/go.mod index 076a22808..f9a8e4b49 100644 --- a/go.mod +++ b/go.mod @@ -77,6 +77,7 @@ require ( google.golang.org/appengine v1.6.1 // indirect google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601 // indirect gopkg.in/yaml.v2 v2.2.8 + gotest.tools/v3 v3.0.2 // indirect k8s.io/api v0.17.3 k8s.io/apimachinery v0.17.3 k8s.io/client-go v0.0.0-20190620085101-78d2af792bab diff --git a/go.sum b/go.sum index 860b80a3d..748fc3242 100644 --- a/go.sum +++ b/go.sum @@ -574,6 +574,7 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -618,6 +619,8 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= diff --git a/pkg/adapter/sigproxy_linux.go b/pkg/adapter/sigproxy_linux.go index 35745a6aa..8295e4250 100644 --- a/pkg/adapter/sigproxy_linux.go +++ b/pkg/adapter/sigproxy_linux.go @@ -5,7 +5,7 @@ import ( "syscall" "github.com/containers/libpod/libpod" - "github.com/docker/docker/pkg/signal" + "github.com/containers/libpod/pkg/signal" "github.com/sirupsen/logrus" ) @@ -20,7 +20,7 @@ func ProxySignals(ctr *libpod.Container) { for s := range sigBuffer { // Ignore SIGCHLD and SIGPIPE - these are mostly likely // intended for the podman command itself. - if s == signal.SIGCHLD || s == signal.SIGPIPE { + if s == syscall.SIGCHLD || s == syscall.SIGPIPE { continue } diff --git a/pkg/adapter/terminal.go b/pkg/adapter/terminal.go index 51b747d23..499e77def 100644 --- a/pkg/adapter/terminal.go +++ b/pkg/adapter/terminal.go @@ -3,9 +3,9 @@ package adapter import ( "context" "os" - gosignal "os/signal" + "os/signal" - "github.com/docker/docker/pkg/signal" + lsignal "github.com/containers/libpod/pkg/signal" "github.com/docker/docker/pkg/term" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -33,7 +33,7 @@ func getResize() *remotecommand.TerminalSize { // Helper for prepareAttach - set up a goroutine to generate terminal resize events func resizeTty(ctx context.Context, resize chan remotecommand.TerminalSize) { sigchan := make(chan os.Signal, 1) - gosignal.Notify(sigchan, signal.SIGWINCH) + signal.Notify(sigchan, lsignal.SIGWINCH) go func() { defer close(resize) // Update the terminal size immediately without waiting diff --git a/pkg/api/handlers/containers_create.go b/pkg/api/handlers/containers_create.go index 4781b23bc..48f0de94d 100644 --- a/pkg/api/handlers/containers_create.go +++ b/pkg/api/handlers/containers_create.go @@ -12,9 +12,9 @@ import ( image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/namespaces" + "github.com/containers/libpod/pkg/signal" createconfig "github.com/containers/libpod/pkg/spec" "github.com/containers/storage" - "github.com/docker/docker/pkg/signal" "github.com/gorilla/schema" "github.com/pkg/errors" log "github.com/sirupsen/logrus" diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go new file mode 100644 index 000000000..3d549898f --- /dev/null +++ b/pkg/signal/signal_linux.go @@ -0,0 +1,127 @@ +// +build linux + +// Signal handling for Linux only. +package signal + +// Copyright 2013-2018 Docker, Inc. + +// NOTE: this package has originally been copied from github.com/docker/docker. + +import ( + "fmt" + "os" + "os/signal" + "strconv" + "strings" + "syscall" + + "golang.org/x/sys/unix" +) + +const ( + sigrtmin = 34 + sigrtmax = 64 + + SIGWINCH = syscall.SIGWINCH // For cross-compilation with Windows +) + +// signalMap is a map of Linux signals. +var signalMap = map[string]syscall.Signal{ + "ABRT": unix.SIGABRT, + "ALRM": unix.SIGALRM, + "BUS": unix.SIGBUS, + "CHLD": unix.SIGCHLD, + "CLD": unix.SIGCLD, + "CONT": unix.SIGCONT, + "FPE": unix.SIGFPE, + "HUP": unix.SIGHUP, + "ILL": unix.SIGILL, + "INT": unix.SIGINT, + "IO": unix.SIGIO, + "IOT": unix.SIGIOT, + "KILL": unix.SIGKILL, + "PIPE": unix.SIGPIPE, + "POLL": unix.SIGPOLL, + "PROF": unix.SIGPROF, + "PWR": unix.SIGPWR, + "QUIT": unix.SIGQUIT, + "SEGV": unix.SIGSEGV, + "STKFLT": unix.SIGSTKFLT, + "STOP": unix.SIGSTOP, + "SYS": unix.SIGSYS, + "TERM": unix.SIGTERM, + "TRAP": unix.SIGTRAP, + "TSTP": unix.SIGTSTP, + "TTIN": unix.SIGTTIN, + "TTOU": unix.SIGTTOU, + "URG": unix.SIGURG, + "USR1": unix.SIGUSR1, + "USR2": unix.SIGUSR2, + "VTALRM": unix.SIGVTALRM, + "WINCH": unix.SIGWINCH, + "XCPU": unix.SIGXCPU, + "XFSZ": unix.SIGXFSZ, + "RTMIN": sigrtmin, + "RTMIN+1": sigrtmin + 1, + "RTMIN+2": sigrtmin + 2, + "RTMIN+3": sigrtmin + 3, + "RTMIN+4": sigrtmin + 4, + "RTMIN+5": sigrtmin + 5, + "RTMIN+6": sigrtmin + 6, + "RTMIN+7": sigrtmin + 7, + "RTMIN+8": sigrtmin + 8, + "RTMIN+9": sigrtmin + 9, + "RTMIN+10": sigrtmin + 10, + "RTMIN+11": sigrtmin + 11, + "RTMIN+12": sigrtmin + 12, + "RTMIN+13": sigrtmin + 13, + "RTMIN+14": sigrtmin + 14, + "RTMIN+15": sigrtmin + 15, + "RTMAX-14": sigrtmax - 14, + "RTMAX-13": sigrtmax - 13, + "RTMAX-12": sigrtmax - 12, + "RTMAX-11": sigrtmax - 11, + "RTMAX-10": sigrtmax - 10, + "RTMAX-9": sigrtmax - 9, + "RTMAX-8": sigrtmax - 8, + "RTMAX-7": sigrtmax - 7, + "RTMAX-6": sigrtmax - 6, + "RTMAX-5": sigrtmax - 5, + "RTMAX-4": sigrtmax - 4, + "RTMAX-3": sigrtmax - 3, + "RTMAX-2": sigrtmax - 2, + "RTMAX-1": sigrtmax - 1, + "RTMAX": sigrtmax, +} + +// ParseSignal translates a string to a valid syscall signal. +// It returns an error if the signal map doesn't include the given signal. +func ParseSignal(rawSignal string) (syscall.Signal, error) { + s, err := strconv.Atoi(rawSignal) + if err == nil { + if s == 0 { + return -1, fmt.Errorf("invalid signal: %s", rawSignal) + } + return syscall.Signal(s), nil + } + signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] + if !ok { + return -1, fmt.Errorf("invalid signal: %s", rawSignal) + } + return signal, nil +} + +// CatchAll catches all signals and relays them to the specified channel. +func CatchAll(sigc chan os.Signal) { + var handledSigs []os.Signal + for _, s := range signalMap { + handledSigs = append(handledSigs, s) + } + signal.Notify(sigc, handledSigs...) +} + +// StopCatch stops catching the signals and closes the specified channel. +func StopCatch(sigc chan os.Signal) { + signal.Stop(sigc) + close(sigc) +} diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go new file mode 100644 index 000000000..0a92a5b3a --- /dev/null +++ b/pkg/signal/signal_unsupported.go @@ -0,0 +1,28 @@ +// +build !linux + +// Signal handling for Linux only. +package signal + +import ( + "fmt" + "os" + "syscall" +) + +const SIGWINCH = syscall.Signal(0xff) + +// ParseSignal translates a string to a valid syscall signal. +// It returns an error if the signal map doesn't include the given signal. +func ParseSignal(rawSignal string) (syscall.Signal, error) { + return 0, fmt.Errorf("unsupported on non-linux platforms") +} + +// CatchAll catches all signals and relays them to the specified channel. +func CatchAll(sigc chan os.Signal) { + panic("Unsupported on non-linux platforms") +} + +// StopCatch stops catching the signals and closes the specified channel. +func StopCatch(sigc chan os.Signal) { + panic("Unsupported on non-linux platforms") +} diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 6aa3c221e..4a52ea68d 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -18,9 +18,9 @@ import ( "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/namespaces" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/signal" "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" - "github.com/docker/docker/pkg/signal" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/test/system/130-kill.bats b/test/system/130-kill.bats index aae7f114f..5e098d754 100644 --- a/test/system/130-kill.bats +++ b/test/system/130-kill.bats @@ -70,10 +70,10 @@ load helpers for s in ${bad_signal_names[@]}; do # 'nosuchcontainer' is fine: podman should bail before it gets there run_podman 125 kill -s $s nosuchcontainer - is "$output" "Error: Invalid signal: $s" "Error from kill -s $s" + is "$output" "Error: invalid signal: $s" "Error from kill -s $s" run_podman 125 pod kill -s $s nosuchpod - is "$output" "Error: Invalid signal: $s" "Error from pod kill -s $s" + is "$output" "Error: invalid signal: $s" "Error from pod kill -s $s" done # Special case: these too are thrown by docker/signal.ParseSignal(), @@ -82,7 +82,7 @@ load helpers local -a bad_dash_signals=(-0 -SIGBADSIG -SIG -BADSIG -) for s in ${bad_dash_signals[@]}; do run_podman 125 kill -s $s nosuchcontainer - is "$output" "Error: Invalid signal: ${s##-}" "Error from kill -s $s" + is "$output" "Error: invalid signal: ${s##-}" "Error from kill -s $s" done # This error (signal out of range) is thrown by our wrapper diff --git a/vendor/github.com/docker/docker/pkg/signal/README.md b/vendor/github.com/docker/docker/pkg/signal/README.md deleted file mode 100644 index 2b237a594..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/README.md +++ /dev/null @@ -1 +0,0 @@ -This package provides helper functions for dealing with signals across various operating systems \ No newline at end of file diff --git a/vendor/github.com/docker/docker/pkg/signal/signal.go b/vendor/github.com/docker/docker/pkg/signal/signal.go deleted file mode 100644 index 88ef7b5ea..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal.go +++ /dev/null @@ -1,54 +0,0 @@ -// Package signal provides helper functions for dealing with signals across -// various operating systems. -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "fmt" - "os" - "os/signal" - "strconv" - "strings" - "syscall" -) - -// CatchAll catches all signals and relays them to the specified channel. -func CatchAll(sigc chan os.Signal) { - var handledSigs []os.Signal - for _, s := range SignalMap { - handledSigs = append(handledSigs, s) - } - signal.Notify(sigc, handledSigs...) -} - -// StopCatch stops catching the signals and closes the specified channel. -func StopCatch(sigc chan os.Signal) { - signal.Stop(sigc) - close(sigc) -} - -// ParseSignal translates a string to a valid syscall signal. -// It returns an error if the signal map doesn't include the given signal. -func ParseSignal(rawSignal string) (syscall.Signal, error) { - s, err := strconv.Atoi(rawSignal) - if err == nil { - if s == 0 { - return -1, fmt.Errorf("Invalid signal: %s", rawSignal) - } - return syscall.Signal(s), nil - } - signal, ok := SignalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] - if !ok { - return -1, fmt.Errorf("Invalid signal: %s", rawSignal) - } - return signal, nil -} - -// ValidSignalForPlatform returns true if a signal is valid on the platform -func ValidSignalForPlatform(sig syscall.Signal) bool { - for _, v := range SignalMap { - if v == sig { - return true - } - } - return false -} diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_darwin.go b/vendor/github.com/docker/docker/pkg/signal/signal_darwin.go deleted file mode 100644 index ee5501e3d..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_darwin.go +++ /dev/null @@ -1,41 +0,0 @@ -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" -) - -// SignalMap is a map of Darwin signals. -var SignalMap = map[string]syscall.Signal{ - "ABRT": syscall.SIGABRT, - "ALRM": syscall.SIGALRM, - "BUG": syscall.SIGBUS, - "CHLD": syscall.SIGCHLD, - "CONT": syscall.SIGCONT, - "EMT": syscall.SIGEMT, - "FPE": syscall.SIGFPE, - "HUP": syscall.SIGHUP, - "ILL": syscall.SIGILL, - "INFO": syscall.SIGINFO, - "INT": syscall.SIGINT, - "IO": syscall.SIGIO, - "IOT": syscall.SIGIOT, - "KILL": syscall.SIGKILL, - "PIPE": syscall.SIGPIPE, - "PROF": syscall.SIGPROF, - "QUIT": syscall.SIGQUIT, - "SEGV": syscall.SIGSEGV, - "STOP": syscall.SIGSTOP, - "SYS": syscall.SIGSYS, - "TERM": syscall.SIGTERM, - "TRAP": syscall.SIGTRAP, - "TSTP": syscall.SIGTSTP, - "TTIN": syscall.SIGTTIN, - "TTOU": syscall.SIGTTOU, - "URG": syscall.SIGURG, - "USR1": syscall.SIGUSR1, - "USR2": syscall.SIGUSR2, - "VTALRM": syscall.SIGVTALRM, - "WINCH": syscall.SIGWINCH, - "XCPU": syscall.SIGXCPU, - "XFSZ": syscall.SIGXFSZ, -} diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go b/vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go deleted file mode 100644 index 764f90e26..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go +++ /dev/null @@ -1,43 +0,0 @@ -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" -) - -// SignalMap is a map of FreeBSD signals. -var SignalMap = map[string]syscall.Signal{ - "ABRT": syscall.SIGABRT, - "ALRM": syscall.SIGALRM, - "BUF": syscall.SIGBUS, - "CHLD": syscall.SIGCHLD, - "CONT": syscall.SIGCONT, - "EMT": syscall.SIGEMT, - "FPE": syscall.SIGFPE, - "HUP": syscall.SIGHUP, - "ILL": syscall.SIGILL, - "INFO": syscall.SIGINFO, - "INT": syscall.SIGINT, - "IO": syscall.SIGIO, - "IOT": syscall.SIGIOT, - "KILL": syscall.SIGKILL, - "LWP": syscall.SIGLWP, - "PIPE": syscall.SIGPIPE, - "PROF": syscall.SIGPROF, - "QUIT": syscall.SIGQUIT, - "SEGV": syscall.SIGSEGV, - "STOP": syscall.SIGSTOP, - "SYS": syscall.SIGSYS, - "TERM": syscall.SIGTERM, - "THR": syscall.SIGTHR, - "TRAP": syscall.SIGTRAP, - "TSTP": syscall.SIGTSTP, - "TTIN": syscall.SIGTTIN, - "TTOU": syscall.SIGTTOU, - "URG": syscall.SIGURG, - "USR1": syscall.SIGUSR1, - "USR2": syscall.SIGUSR2, - "VTALRM": syscall.SIGVTALRM, - "WINCH": syscall.SIGWINCH, - "XCPU": syscall.SIGXCPU, - "XFSZ": syscall.SIGXFSZ, -} diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_linux.go b/vendor/github.com/docker/docker/pkg/signal/signal_linux.go deleted file mode 100644 index 4013bded1..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_linux.go +++ /dev/null @@ -1,83 +0,0 @@ -// +build !mips,!mipsle,!mips64,!mips64le - -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" - - "golang.org/x/sys/unix" -) - -const ( - sigrtmin = 34 - sigrtmax = 64 -) - -// SignalMap is a map of Linux signals. -var SignalMap = map[string]syscall.Signal{ - "ABRT": unix.SIGABRT, - "ALRM": unix.SIGALRM, - "BUS": unix.SIGBUS, - "CHLD": unix.SIGCHLD, - "CLD": unix.SIGCLD, - "CONT": unix.SIGCONT, - "FPE": unix.SIGFPE, - "HUP": unix.SIGHUP, - "ILL": unix.SIGILL, - "INT": unix.SIGINT, - "IO": unix.SIGIO, - "IOT": unix.SIGIOT, - "KILL": unix.SIGKILL, - "PIPE": unix.SIGPIPE, - "POLL": unix.SIGPOLL, - "PROF": unix.SIGPROF, - "PWR": unix.SIGPWR, - "QUIT": unix.SIGQUIT, - "SEGV": unix.SIGSEGV, - "STKFLT": unix.SIGSTKFLT, - "STOP": unix.SIGSTOP, - "SYS": unix.SIGSYS, - "TERM": unix.SIGTERM, - "TRAP": unix.SIGTRAP, - "TSTP": unix.SIGTSTP, - "TTIN": unix.SIGTTIN, - "TTOU": unix.SIGTTOU, - "URG": unix.SIGURG, - "USR1": unix.SIGUSR1, - "USR2": unix.SIGUSR2, - "VTALRM": unix.SIGVTALRM, - "WINCH": unix.SIGWINCH, - "XCPU": unix.SIGXCPU, - "XFSZ": unix.SIGXFSZ, - "RTMIN": sigrtmin, - "RTMIN+1": sigrtmin + 1, - "RTMIN+2": sigrtmin + 2, - "RTMIN+3": sigrtmin + 3, - "RTMIN+4": sigrtmin + 4, - "RTMIN+5": sigrtmin + 5, - "RTMIN+6": sigrtmin + 6, - "RTMIN+7": sigrtmin + 7, - "RTMIN+8": sigrtmin + 8, - "RTMIN+9": sigrtmin + 9, - "RTMIN+10": sigrtmin + 10, - "RTMIN+11": sigrtmin + 11, - "RTMIN+12": sigrtmin + 12, - "RTMIN+13": sigrtmin + 13, - "RTMIN+14": sigrtmin + 14, - "RTMIN+15": sigrtmin + 15, - "RTMAX-14": sigrtmax - 14, - "RTMAX-13": sigrtmax - 13, - "RTMAX-12": sigrtmax - 12, - "RTMAX-11": sigrtmax - 11, - "RTMAX-10": sigrtmax - 10, - "RTMAX-9": sigrtmax - 9, - "RTMAX-8": sigrtmax - 8, - "RTMAX-7": sigrtmax - 7, - "RTMAX-6": sigrtmax - 6, - "RTMAX-5": sigrtmax - 5, - "RTMAX-4": sigrtmax - 4, - "RTMAX-3": sigrtmax - 3, - "RTMAX-2": sigrtmax - 2, - "RTMAX-1": sigrtmax - 1, - "RTMAX": sigrtmax, -} diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go b/vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go deleted file mode 100644 index 4c7989121..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go +++ /dev/null @@ -1,84 +0,0 @@ -// +build linux -// +build mips mipsle mips64 mips64le - -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" - - "golang.org/x/sys/unix" -) - -const ( - sigrtmin = 34 - sigrtmax = 127 -) - -// SignalMap is a map of Linux signals. -var SignalMap = map[string]syscall.Signal{ - "ABRT": unix.SIGABRT, - "ALRM": unix.SIGALRM, - "BUS": unix.SIGBUS, - "CHLD": unix.SIGCHLD, - "CLD": unix.SIGCLD, - "CONT": unix.SIGCONT, - "FPE": unix.SIGFPE, - "HUP": unix.SIGHUP, - "ILL": unix.SIGILL, - "INT": unix.SIGINT, - "IO": unix.SIGIO, - "IOT": unix.SIGIOT, - "KILL": unix.SIGKILL, - "PIPE": unix.SIGPIPE, - "POLL": unix.SIGPOLL, - "PROF": unix.SIGPROF, - "PWR": unix.SIGPWR, - "QUIT": unix.SIGQUIT, - "SEGV": unix.SIGSEGV, - "SIGEMT": unix.SIGEMT, - "STOP": unix.SIGSTOP, - "SYS": unix.SIGSYS, - "TERM": unix.SIGTERM, - "TRAP": unix.SIGTRAP, - "TSTP": unix.SIGTSTP, - "TTIN": unix.SIGTTIN, - "TTOU": unix.SIGTTOU, - "URG": unix.SIGURG, - "USR1": unix.SIGUSR1, - "USR2": unix.SIGUSR2, - "VTALRM": unix.SIGVTALRM, - "WINCH": unix.SIGWINCH, - "XCPU": unix.SIGXCPU, - "XFSZ": unix.SIGXFSZ, - "RTMIN": sigrtmin, - "RTMIN+1": sigrtmin + 1, - "RTMIN+2": sigrtmin + 2, - "RTMIN+3": sigrtmin + 3, - "RTMIN+4": sigrtmin + 4, - "RTMIN+5": sigrtmin + 5, - "RTMIN+6": sigrtmin + 6, - "RTMIN+7": sigrtmin + 7, - "RTMIN+8": sigrtmin + 8, - "RTMIN+9": sigrtmin + 9, - "RTMIN+10": sigrtmin + 10, - "RTMIN+11": sigrtmin + 11, - "RTMIN+12": sigrtmin + 12, - "RTMIN+13": sigrtmin + 13, - "RTMIN+14": sigrtmin + 14, - "RTMIN+15": sigrtmin + 15, - "RTMAX-14": sigrtmax - 14, - "RTMAX-13": sigrtmax - 13, - "RTMAX-12": sigrtmax - 12, - "RTMAX-11": sigrtmax - 11, - "RTMAX-10": sigrtmax - 10, - "RTMAX-9": sigrtmax - 9, - "RTMAX-8": sigrtmax - 8, - "RTMAX-7": sigrtmax - 7, - "RTMAX-6": sigrtmax - 6, - "RTMAX-5": sigrtmax - 5, - "RTMAX-4": sigrtmax - 4, - "RTMAX-3": sigrtmax - 3, - "RTMAX-2": sigrtmax - 2, - "RTMAX-1": sigrtmax - 1, - "RTMAX": sigrtmax, -} diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_unix.go b/vendor/github.com/docker/docker/pkg/signal/signal_unix.go deleted file mode 100644 index a2aa4248f..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_unix.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !windows - -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" -) - -// Signals used in cli/command (no windows equivalent, use -// invalid signals so they don't get handled) - -const ( - // SIGCHLD is a signal sent to a process when a child process terminates, is interrupted, or resumes after being interrupted. - SIGCHLD = syscall.SIGCHLD - // SIGWINCH is a signal sent to a process when its controlling terminal changes its size - SIGWINCH = syscall.SIGWINCH - // SIGPIPE is a signal sent to a process when a pipe is written to before the other end is open for reading - SIGPIPE = syscall.SIGPIPE - // DefaultStopSignal is the syscall signal used to stop a container in unix systems. - DefaultStopSignal = "SIGTERM" -) diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go b/vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go deleted file mode 100644 index 1fd25a83c..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !linux,!darwin,!freebsd,!windows - -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" -) - -// SignalMap is an empty map of signals for unsupported platform. -var SignalMap = map[string]syscall.Signal{} diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_windows.go b/vendor/github.com/docker/docker/pkg/signal/signal_windows.go deleted file mode 100644 index 65752f24a..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/signal_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "syscall" -) - -// Signals used in cli/command (no windows equivalent, use -// invalid signals so they don't get handled) -const ( - SIGCHLD = syscall.Signal(0xff) - SIGWINCH = syscall.Signal(0xff) - SIGPIPE = syscall.Signal(0xff) - // DefaultStopSignal is the syscall signal used to stop a container in windows systems. - DefaultStopSignal = "15" -) - -// SignalMap is a map of "supported" signals. As per the comment in GOLang's -// ztypes_windows.go: "More invented values for signals". Windows doesn't -// really support signals in any way, shape or form that Unix does. -// -// We have these so that docker kill can be used to gracefully (TERM) and -// forcibly (KILL) terminate a container on Windows. -var SignalMap = map[string]syscall.Signal{ - "KILL": syscall.SIGKILL, - "TERM": syscall.SIGTERM, -} diff --git a/vendor/github.com/docker/docker/pkg/signal/trap.go b/vendor/github.com/docker/docker/pkg/signal/trap.go deleted file mode 100644 index a277b9562..000000000 --- a/vendor/github.com/docker/docker/pkg/signal/trap.go +++ /dev/null @@ -1,104 +0,0 @@ -package signal // import "github.com/docker/docker/pkg/signal" - -import ( - "fmt" - "os" - gosignal "os/signal" - "path/filepath" - "runtime" - "strings" - "sync/atomic" - "syscall" - "time" - - "github.com/pkg/errors" -) - -// 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). -// -// * If SIGINT or SIGTERM are received, `cleanup` is called, then the process is terminated. -// * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is -// skipped and the process is terminated immediately (allows force quit of stuck daemon) -// * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit. -// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while -// the docker daemon is not restarted and also running under systemd. -// Fixes https://github.com/docker/docker/issues/19728 -// -func Trap(cleanup func(), logger interface { - Info(args ...interface{}) -}) { - c := make(chan os.Signal, 1) - // we will handle INT, TERM, QUIT, SIGPIPE here - signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE} - gosignal.Notify(c, signals...) - go func() { - interruptCount := uint32(0) - for sig := range c { - if sig == syscall.SIGPIPE { - continue - } - - go func(sig os.Signal) { - logger.Info(fmt.Sprintf("Processing signal '%v'", sig)) - switch sig { - case os.Interrupt, syscall.SIGTERM: - if atomic.LoadUint32(&interruptCount) < 3 { - // Initiate the cleanup only once - if atomic.AddUint32(&interruptCount, 1) == 1 { - // Call the provided cleanup handler - cleanup() - os.Exit(0) - } else { - return - } - } else { - // 3 SIGTERM/INT signals received; force exit without cleanup - logger.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received") - } - case syscall.SIGQUIT: - DumpStacks("") - logger.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT") - } - // for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal # - os.Exit(128 + int(sig.(syscall.Signal))) - }(sig) - } - }() -} - -const stacksLogNameTemplate = "goroutine-stacks-%s.log" - -// DumpStacks appends the runtime stack into file in dir and returns full path -// to that file. -func DumpStacks(dir string) (string, error) { - var ( - buf []byte - stackSize int - ) - bufferLen := 16384 - for stackSize == len(buf) { - buf = make([]byte, bufferLen) - stackSize = runtime.Stack(buf, true) - bufferLen *= 2 - } - buf = buf[:stackSize] - var f *os.File - if dir != "" { - path := filepath.Join(dir, fmt.Sprintf(stacksLogNameTemplate, strings.Replace(time.Now().Format(time.RFC3339), ":", "", -1))) - var err error - f, err = os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666) - if err != nil { - return "", errors.Wrap(err, "failed to open file to write the goroutine stacks") - } - defer f.Close() - defer f.Sync() - } else { - f = os.Stderr - } - if _, err := f.Write(buf); err != nil { - return "", errors.Wrap(err, "failed to write goroutine stacks") - } - return f.Name(), nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 3c03fbdfb..69f2bed8e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -238,7 +238,6 @@ github.com/docker/docker/pkg/mount github.com/docker/docker/pkg/namesgenerator github.com/docker/docker/pkg/parsers github.com/docker/docker/pkg/pools -github.com/docker/docker/pkg/signal github.com/docker/docker/pkg/stdcopy github.com/docker/docker/pkg/system github.com/docker/docker/pkg/term -- cgit v1.2.3-54-g00ecf