diff --git a/pkg/server/container_stop.go b/pkg/server/container_stop.go index 8ad044bbf..4184fa9db 100644 --- a/pkg/server/container_stop.go +++ b/pkg/server/container_stop.go @@ -20,10 +20,10 @@ import ( "syscall" "time" + "github.com/containerd/containerd" eventtypes "github.com/containerd/containerd/api/events" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" - "github.com/docker/docker/pkg/signal" "github.com/pkg/errors" "golang.org/x/net/context" @@ -125,11 +125,18 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore } } } - sig, err := signal.ParseSignal(stopSignal) + + sandboxPlatform, err := c.getSandboxPlatform(container.Metadata.SandboxID) + if err != nil { + return errors.Wrapf(err, "failed to get container's sandbox platform") + } + + sig, err := containerd.ParsePlatformSignal(stopSignal, sandboxPlatform) if err != nil { return errors.Wrapf(err, "failed to parse stop signal %q", stopSignal) } log.G(ctx).Infof("Stop container %q with signal %v", id, sig) + if err = task.Kill(ctx, sig); err != nil && !errdefs.IsNotFound(err) { return errors.Wrapf(err, "failed to stop container %q", id) } diff --git a/pkg/server/helpers_unix.go b/pkg/server/helpers_unix.go index ae9194171..9b932bcce 100644 --- a/pkg/server/helpers_unix.go +++ b/pkg/server/helpers_unix.go @@ -22,6 +22,7 @@ import ( "fmt" "regexp" + "github.com/containerd/containerd/platforms" "github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" @@ -65,3 +66,7 @@ func checkSelinuxLevel(level string) (bool, error) { } return true, nil } + +func (c *criService) getSandboxPlatform(_ string) (string, error) { + return platforms.DefaultString(), nil +} diff --git a/pkg/server/helpers_windows.go b/pkg/server/helpers_windows.go index 7ba63b7f8..58ad1567d 100644 --- a/pkg/server/helpers_windows.go +++ b/pkg/server/helpers_windows.go @@ -19,6 +19,9 @@ limitations under the License. package server import ( + runhcsoptions "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options" + criconfig "github.com/containerd/cri/pkg/config" + "github.com/pkg/errors" runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" ) @@ -26,3 +29,28 @@ import ( func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error) { return "", "", nil } + +func (c *criService) getSandboxPlatform(sandboxID string) (string, error) { + sandbox, err := c.sandboxStore.Get(sandboxID) + if err != nil { + return "", err + } + + // Get the RuntimeHandler config overrides + var ociRuntime criconfig.Runtime + if sandbox.RuntimeHandler != "" { + ociRuntime = c.config.Runtimes[sandbox.RuntimeHandler] + } else { + ociRuntime = c.config.DefaultRuntime + } + runtimeOpts, err := generateRuntimeOptions(ociRuntime, c.config) + if err != nil { + return "", errors.Wrap(err, "failed to generate runtime options") + } + rhcso := runtimeOpts.(*runhcsoptions.Options) + sandboxPlatform := rhcso.SandboxPlatform + if sandboxPlatform == "" { + sandboxPlatform = "windows/amd64" + } + return sandboxPlatform, nil +} diff --git a/vendor.conf b/vendor.conf index 7125a6284..9ff37570a 100644 --- a/vendor.conf +++ b/vendor.conf @@ -3,12 +3,12 @@ github.com/blang/semver v3.1.0 github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/containerd/cgroups caf71576c8b19daf80ab4685916e4d5b4c74887e github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23 -github.com/containerd/containerd 12e49bbd4d6124ebdbbc3f66919416f360b46dda https://github.com/kevpar/containerd.git # fork/release/1.4 +github.com/containerd/containerd 17959a99a417e21d67e8fab630f85a3279839a3c https://github.com/kevpar/containerd.git # fork/release/1.4 github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4 github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90 github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3 -github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f +github.com/containerd/ttrpc a43d9fd2cb85a767787a707cfbdd7fe798316b61 https://github.com/kevpar/ttrpc.git # deadlock github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 github.com/containernetworking/cni v0.6.0 github.com/containernetworking/plugins v0.7.0 diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go index 9fe4e3892..8251b1edd 100644 --- a/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go @@ -25,6 +25,7 @@ import ( "os/signal" "path/filepath" "runtime" + "strings" "time" "github.com/containerd/containerd/errdefs" @@ -314,7 +315,15 @@ func dumpStacks(writeToFile bool) { bufferLen *= 2 } buf = buf[:stackSize] - logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf) + stacks := strings.Split(string(buf), "\n\n") + logrus.WithField("stackCount", len(stacks)).Info("Begin goroutine stack dump") + for i, stack := range stacks { + logrus.WithFields(logrus.Fields{ + "index": i, + "stack": stack, + }).Info("Dumping goroutine stack") + } + logrus.Info("End goroutine stack dump") if writeToFile { // Also write to file to aid gathering diagnostics diff --git a/vendor/github.com/containerd/containerd/signals.go b/vendor/github.com/containerd/containerd/signals.go index ca64ecd02..eac5563b5 100644 --- a/vendor/github.com/containerd/containerd/signals.go +++ b/vendor/github.com/containerd/containerd/signals.go @@ -24,6 +24,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/platforms" v1 "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -48,10 +49,6 @@ func GetStopSignal(ctx context.Context, container Container, defaultSignal sysca // GetOCIStopSignal retrieves the stop signal specified in the OCI image config func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (string, error) { - _, err := ParseSignal(defaultSignal) - if err != nil { - return "", err - } ic, err := image.Config(ctx) if err != nil { return "", err @@ -59,6 +56,7 @@ func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (s var ( ociimage v1.Image config v1.ImageConfig + platform string = platforms.DefaultSpec().OS ) switch ic.MediaType { case v1.MediaTypeImageConfig, images.MediaTypeDockerSchema2Config: @@ -71,10 +69,16 @@ func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (s return "", err } config = ociimage.Config + platform = ociimage.OS default: return "", fmt.Errorf("unknown image config media type %s", ic.MediaType) } + // verify that default signal is valid + if _, err := ParsePlatformSignal(defaultSignal, platform); err != nil { + return "", err + } + if config.StopSignal == "" { return defaultSignal, nil } diff --git a/vendor/github.com/containerd/containerd/signals_unix.go b/vendor/github.com/containerd/containerd/signals_unix.go index 14916a9ff..d1ad107b0 100644 --- a/vendor/github.com/containerd/containerd/signals_unix.go +++ b/vendor/github.com/containerd/containerd/signals_unix.go @@ -31,6 +31,14 @@ import ( // the rawSignal can be a string with "SIG" prefix, // or a signal number in string format. func ParseSignal(rawSignal string) (syscall.Signal, error) { + return parseSignalUnix(rawSignal) +} + +func ParsePlatformSignal(rawSignal string, _ string) (syscall.Signal, error) { + return parseSignalUnix(rawSignal) +} + +func parseSignalUnix(rawSignal string) (syscall.Signal, error) { s, err := strconv.Atoi(rawSignal) if err == nil { return syscall.Signal(s), nil diff --git a/vendor/github.com/containerd/containerd/signals_windows.go b/vendor/github.com/containerd/containerd/signals_windows.go index 0018e191e..e608743f9 100644 --- a/vendor/github.com/containerd/containerd/signals_windows.go +++ b/vendor/github.com/containerd/containerd/signals_windows.go @@ -25,35 +25,125 @@ import ( "golang.org/x/sys/windows" ) -var signalMap = map[string]syscall.Signal{ - "HUP": syscall.Signal(windows.SIGHUP), - "INT": syscall.Signal(windows.SIGINT), - "QUIT": syscall.Signal(windows.SIGQUIT), - "SIGILL": syscall.Signal(windows.SIGILL), - "TRAP": syscall.Signal(windows.SIGTRAP), - "ABRT": syscall.Signal(windows.SIGABRT), - "BUS": syscall.Signal(windows.SIGBUS), - "FPE": syscall.Signal(windows.SIGFPE), - "KILL": syscall.Signal(windows.SIGKILL), - "SEGV": syscall.Signal(windows.SIGSEGV), - "PIPE": syscall.Signal(windows.SIGPIPE), - "ALRM": syscall.Signal(windows.SIGALRM), - "TERM": syscall.Signal(windows.SIGTERM), +const ( + linuxSigrtmin = 34 + linuxSigrtmax = 64 +) + +var signalMapWindows = map[string]syscall.Signal{ + "HUP": syscall.Signal(windows.SIGHUP), + "INT": syscall.Signal(windows.SIGINT), + "QUIT": syscall.Signal(windows.SIGQUIT), + "ILL": syscall.Signal(windows.SIGILL), + "TRAP": syscall.Signal(windows.SIGTRAP), + "ABRT": syscall.Signal(windows.SIGABRT), + "BUS": syscall.Signal(windows.SIGBUS), + "FPE": syscall.Signal(windows.SIGFPE), + "KILL": syscall.Signal(windows.SIGKILL), + "SEGV": syscall.Signal(windows.SIGSEGV), + "PIPE": syscall.Signal(windows.SIGPIPE), + "ALRM": syscall.Signal(windows.SIGALRM), + "TERM": syscall.Signal(windows.SIGTERM), +} + +// manually define signals for linux since we may be running an LCOW container, but +// the unix syscalls do not get built when running on windows +var signalMapLinux = map[string]syscall.Signal{ + "ABRT": syscall.Signal(0x6), + "ALRM": syscall.Signal(0xe), + "BUS": syscall.Signal(0x7), + "CHLD": syscall.Signal(0x11), + "CLD": syscall.Signal(0x11), + "CONT": syscall.Signal(0x12), + "FPE": syscall.Signal(0x8), + "HUP": syscall.Signal(0x1), + "ILL": syscall.Signal(0x4), + "INT": syscall.Signal(0x2), + "IO": syscall.Signal(0x1d), + "IOT": syscall.Signal(0x6), + "KILL": syscall.Signal(0x9), + "PIPE": syscall.Signal(0xd), + "POLL": syscall.Signal(0x1d), + "PROF": syscall.Signal(0x1b), + "PWR": syscall.Signal(0x1e), + "QUIT": syscall.Signal(0x3), + "SEGV": syscall.Signal(0xb), + "STKFLT": syscall.Signal(0x10), + "STOP": syscall.Signal(0x13), + "SYS": syscall.Signal(0x1f), + "TERM": syscall.Signal(0xf), + "TRAP": syscall.Signal(0x5), + "TSTP": syscall.Signal(0x14), + "TTIN": syscall.Signal(0x15), + "TTOU": syscall.Signal(0x16), + "URG": syscall.Signal(0x17), + "USR1": syscall.Signal(0xa), + "USR2": syscall.Signal(0xc), + "VTALRM": syscall.Signal(0x1a), + "WINCH": syscall.Signal(0x1c), + "XCPU": syscall.Signal(0x18), + "XFSZ": syscall.Signal(0x19), + "RTMIN": linuxSigrtmin, + "RTMIN+1": linuxSigrtmin + 1, + "RTMIN+2": linuxSigrtmin + 2, + "RTMIN+3": linuxSigrtmin + 3, + "RTMIN+4": linuxSigrtmin + 4, + "RTMIN+5": linuxSigrtmin + 5, + "RTMIN+6": linuxSigrtmin + 6, + "RTMIN+7": linuxSigrtmin + 7, + "RTMIN+8": linuxSigrtmin + 8, + "RTMIN+9": linuxSigrtmin + 9, + "RTMIN+10": linuxSigrtmin + 10, + "RTMIN+11": linuxSigrtmin + 11, + "RTMIN+12": linuxSigrtmin + 12, + "RTMIN+13": linuxSigrtmin + 13, + "RTMIN+14": linuxSigrtmin + 14, + "RTMIN+15": linuxSigrtmin + 15, + "RTMAX-14": linuxSigrtmax - 14, + "RTMAX-13": linuxSigrtmax - 13, + "RTMAX-12": linuxSigrtmax - 12, + "RTMAX-11": linuxSigrtmax - 11, + "RTMAX-10": linuxSigrtmax - 10, + "RTMAX-9": linuxSigrtmax - 9, + "RTMAX-8": linuxSigrtmax - 8, + "RTMAX-7": linuxSigrtmax - 7, + "RTMAX-6": linuxSigrtmax - 6, + "RTMAX-5": linuxSigrtmax - 5, + "RTMAX-4": linuxSigrtmax - 4, + "RTMAX-3": linuxSigrtmax - 3, + "RTMAX-2": linuxSigrtmax - 2, + "RTMAX-1": linuxSigrtmax - 1, + "RTMAX": linuxSigrtmax, } // ParseSignal parses a given string into a syscall.Signal // the rawSignal can be a string with "SIG" prefix, // or a signal number in string format. func ParseSignal(rawSignal string) (syscall.Signal, error) { + return parseSignalGeneric(rawSignal, "windows") +} + +// ParsePlatformSignal parses a given string into a syscall.Signal based on +// the OS platform specified in `platform`. +func ParsePlatformSignal(rawSignal, platform string) (syscall.Signal, error) { + return parseSignalGeneric(rawSignal, platform) +} + +func parseSignalGeneric(rawSignal, platform string) (syscall.Signal, error) { + signalMap := getSignalMapForPlatform(platform) s, err := strconv.Atoi(rawSignal) if err == nil { sig := syscall.Signal(s) + if platform != "windows" { + return sig, nil + } + // on windows, make sure we support this signal for _, msig := range signalMap { if sig == msig { return sig, nil } } - return -1, fmt.Errorf("unknown signal %q", rawSignal) + return sig, fmt.Errorf("unknown signal %q", rawSignal) } signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] if !ok { @@ -61,3 +151,10 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) { } return signal, nil } + +func getSignalMapForPlatform(platform string) map[string]syscall.Signal { + if platform != "windows" { + return signalMapLinux + } + return signalMapWindows +} diff --git a/vendor/github.com/containerd/ttrpc/client.go b/vendor/github.com/containerd/ttrpc/client.go index bdd1d12e7..e5b7997a9 100644 --- a/vendor/github.com/containerd/ttrpc/client.go +++ b/vendor/github.com/containerd/ttrpc/client.go @@ -47,8 +47,9 @@ type Client struct { ctx context.Context closed func() - closeOnce sync.Once - userCloseFunc func() + closeOnce sync.Once + userCloseFunc func() + userCloseWaitCh chan struct{} errOnce sync.Once err error @@ -75,14 +76,15 @@ func WithUnaryClientInterceptor(i UnaryClientInterceptor) ClientOpts { func NewClient(conn net.Conn, opts ...ClientOpts) *Client { ctx, cancel := context.WithCancel(context.Background()) c := &Client{ - codec: codec{}, - conn: conn, - channel: newChannel(conn), - calls: make(chan *callRequest), - closed: cancel, - ctx: ctx, - userCloseFunc: func() {}, - interceptor: defaultClientInterceptor, + codec: codec{}, + conn: conn, + channel: newChannel(conn), + calls: make(chan *callRequest), + closed: cancel, + ctx: ctx, + userCloseFunc: func() {}, + userCloseWaitCh: make(chan struct{}), + interceptor: defaultClientInterceptor, } for _, o := range opts { @@ -175,6 +177,17 @@ func (c *Client) Close() error { return nil } +// UserOnCloseWait is used to blocks untils the user's on-close callback +// finishes. +func (c *Client) UserOnCloseWait(ctx context.Context) error { + select { + case <-c.userCloseWaitCh: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + type message struct { messageHeader p []byte @@ -221,13 +234,19 @@ func (r *receiver) run(ctx context.Context, c *channel) { } func (c *Client) run() { + type streamCall struct { + streamID uint32 + call *callRequest + } var ( - streamID uint32 = 1 - waiters = make(map[uint32]*callRequest) - calls = c.calls - incoming = make(chan *message) - receiversDone = make(chan struct{}) - wg sync.WaitGroup + streamID uint32 = 1 + waiters = make(map[uint32]*callRequest) + calls = c.calls + requests = make(chan streamCall) + requestsFailed = make(chan streamCall) + incoming = make(chan *message) + receiversDone = make(chan struct{}) + wg sync.WaitGroup ) // broadcast the shutdown error to the remaining waiters. @@ -248,21 +267,41 @@ func (c *Client) run() { }() go recv.run(c.ctx, c.channel) + go func(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case streamCall := <-requests: + if err := c.send(streamCall.streamID, messageTypeRequest, streamCall.call.req); err != nil { + streamCall.call.errs <- err // errs is buffered so should not block. + requestsFailed <- streamCall + continue + } + } + } + }(c.ctx) + defer func() { c.conn.Close() c.userCloseFunc() + close(c.userCloseWaitCh) }() for { select { case call := <-calls: - if err := c.send(streamID, messageTypeRequest, call.req); err != nil { - call.errs <- err - continue - } - + go func(streamID uint32, call *callRequest) { + requests <- streamCall{ + streamID: streamID, + call: call, + } + }(streamID, call) waiters[streamID] = call streamID += 2 // enforce odd client initiated request ids + case streamCall := <-requestsFailed: + // Sending the request failed, so stop tracking this stream ID. + delete(waiters, streamCall.streamID) case msg := <-incoming: call, ok := waiters[msg.StreamID] if !ok { @@ -338,9 +377,13 @@ func filterCloseErr(err error) error { case strings.Contains(err.Error(), "use of closed network connection"): return ErrClosed default: - // if we have an epipe on a write, we cast to errclosed - if oerr, ok := err.(*net.OpError); ok && oerr.Op == "write" { - if serr, ok := oerr.Err.(*os.SyscallError); ok && serr.Err == syscall.EPIPE { + // if we have an epipe on a write or econnreset on a read , we cast to errclosed + var oerr *net.OpError + if errors.As(err, &oerr) && (oerr.Op == "write" || oerr.Op == "read") { + serr, sok := oerr.Err.(*os.SyscallError) + if sok && ((serr.Err == syscall.EPIPE && oerr.Op == "write") || + (serr.Err == syscall.ECONNRESET && oerr.Op == "read")) { + return ErrClosed } } diff --git a/vendor/github.com/containerd/ttrpc/go.mod b/vendor/github.com/containerd/ttrpc/go.mod new file mode 100644 index 000000000..4ed7512f9 --- /dev/null +++ b/vendor/github.com/containerd/ttrpc/go.mod @@ -0,0 +1,14 @@ +module github.com/containerd/ttrpc + +go 1.13 + +require ( + github.com/gogo/protobuf v1.3.1 + github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect + github.com/pkg/errors v0.9.1 + github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1 + github.com/sirupsen/logrus v1.4.2 + golang.org/x/sys v0.0.0-20200120151820-655fe14d7479 + google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24 + google.golang.org/grpc v1.26.0 +) diff --git a/vendor/github.com/containerd/ttrpc/server.go b/vendor/github.com/containerd/ttrpc/server.go index 1d4f1df65..4ecf8b322 100644 --- a/vendor/github.com/containerd/ttrpc/server.go +++ b/vendor/github.com/containerd/ttrpc/server.go @@ -209,6 +209,20 @@ func (s *Server) addConnection(c *serverConn) { s.connections[c] = struct{}{} } +func (s *Server) delConnection(c *serverConn) { + s.mu.Lock() + defer s.mu.Unlock() + + delete(s.connections, c) +} + +func (s *Server) countConnection() int { + s.mu.Lock() + defer s.mu.Unlock() + + return len(s.connections) +} + func (s *Server) closeIdleConns() bool { s.mu.Lock() defer s.mu.Unlock() @@ -304,6 +318,7 @@ func (c *serverConn) run(sctx context.Context) { active int state connState = connStateIdle responses = make(chan response) + responseErr = make(chan error) requests = make(chan request) recvErr = make(chan error, 1) shutdown = c.shutdown @@ -313,6 +328,7 @@ func (c *serverConn) run(sctx context.Context) { defer c.conn.Close() defer cancel() defer close(done) + defer c.server.delConnection(c) go func(recvErr chan error) { defer close(recvErr) @@ -397,6 +413,36 @@ func (c *serverConn) run(sctx context.Context) { } }(recvErr) + go func(responseErr chan error) { + for { + select { + // We don't want a case for c.shutdown here, as that would cause us to exit + // immediately when it is signaled, rather than waiting for any active requests + // to complete first. Instead, once all the active requests have completed, + // the main loop will return and close done, which will cause us to exit as well. + case <-done: + return + case response := <-responses: + p, err := c.server.codec.Marshal(response.resp) + if err != nil { + logrus.WithError(err).Error("failed marshaling response") + responseErr <- err + return + } + + if err := ch.send(response.id, messageTypeResponse, p); err != nil { + logrus.WithError(err).Error("failed sending message on channel") + responseErr <- err + return + } + + // Send a nil error so that the main loop knows an active request has + // completed successfully. + responseErr <- nil + } + } + }(responseErr) + for { newstate := state switch { @@ -434,18 +480,12 @@ func (c *serverConn) run(sctx context.Context) { case <-done: } }(request.id) - case response := <-responses: - p, err := c.server.codec.Marshal(response.resp) + case err := <-responseErr: + // responseErr sends nil if no error occurred in sending the response. + // In that case we just decrement the active count and continue. if err != nil { - logrus.WithError(err).Error("failed marshaling response") - return - } - - if err := ch.send(response.id, messageTypeResponse, p); err != nil { - logrus.WithError(err).Error("failed sending message on channel") return } - active-- case err := <-recvErr: // TODO(stevvooe): Not wildly clear what we should do in this diff --git a/vendor/github.com/containerd/ttrpc/services.go b/vendor/github.com/containerd/ttrpc/services.go index 0eacfd79a..2a83ba88a 100644 --- a/vendor/github.com/containerd/ttrpc/services.go +++ b/vendor/github.com/containerd/ttrpc/services.go @@ -21,6 +21,7 @@ import ( "io" "os" "path" + "unsafe" "github.com/gogo/protobuf/proto" "github.com/pkg/errors" @@ -95,6 +96,10 @@ func (s *serviceSet) dispatch(ctx context.Context, serviceName, methodName strin return nil, err } + if isNil(resp) { + return nil, errors.New("ttrpc: marshal called with nil") + } + switch v := resp.(type) { case proto.Message: r, err := proto.Marshal(v) @@ -154,3 +159,7 @@ func convertCode(err error) codes.Code { func fullPath(service, method string) string { return "/" + path.Join(service, method) } + +func isNil(resp interface{}) bool { + return (*[2]uintptr)(unsafe.Pointer(&resp))[1] == 0 +} 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 -}