From ffd0d2ef58eaa625050105cfa29c01019d2c200a Mon Sep 17 00:00:00 2001 From: Jess Valarezo Date: Thu, 26 Oct 2017 14:41:04 -0400 Subject: [PATCH] ctr: move signals to commands package Signed-off-by: Jess Valarezo --- cmd/ctr/attach.go | 4 +- cmd/ctr/commands/signals.go | 59 +++++++++++++++++++++++++ cmd/ctr/{ => commands}/signals_linux.go | 2 +- cmd/ctr/{ => commands}/signals_unix.go | 2 +- cmd/ctr/commands/signals_windows.go | 23 ++++++++++ cmd/ctr/exec.go | 5 ++- cmd/ctr/kill.go | 4 +- cmd/ctr/run.go | 9 +--- cmd/ctr/start.go | 4 +- cmd/ctr/utils.go | 42 ------------------ cmd/ctr/utils_windows.go | 18 -------- 11 files changed, 96 insertions(+), 76 deletions(-) create mode 100644 cmd/ctr/commands/signals.go rename cmd/ctr/{ => commands}/signals_linux.go (98%) rename cmd/ctr/{ => commands}/signals_unix.go (98%) create mode 100644 cmd/ctr/commands/signals_windows.go diff --git a/cmd/ctr/attach.go b/cmd/ctr/attach.go index 9772141b8..f1af6ab30 100644 --- a/cmd/ctr/attach.go +++ b/cmd/ctr/attach.go @@ -55,8 +55,8 @@ var taskAttachCommand = cli.Command{ logrus.WithError(err).Error("console resize") } } else { - sigc := forwardAllSignals(ctx, task) - defer stopCatch(sigc) + sigc := commands.ForwardAllSignals(ctx, task) + defer commands.StopCatch(sigc) } ec := <-statusC diff --git a/cmd/ctr/commands/signals.go b/cmd/ctr/commands/signals.go new file mode 100644 index 000000000..f42e3b523 --- /dev/null +++ b/cmd/ctr/commands/signals.go @@ -0,0 +1,59 @@ +package commands + +import ( + gocontext "context" + "fmt" + "os" + "os/signal" + "strconv" + "strings" + "syscall" + + "github.com/containerd/containerd" + "github.com/sirupsen/logrus" +) + +type killer interface { + Kill(gocontext.Context, syscall.Signal, ...containerd.KillOpts) error +} + +// ForwardAllSignals forwards signals +func ForwardAllSignals(ctx gocontext.Context, task killer) chan os.Signal { + sigc := make(chan os.Signal, 128) + signal.Notify(sigc) + go func() { + for s := range sigc { + logrus.Debug("forwarding signal ", s) + if err := task.Kill(ctx, s.(syscall.Signal)); err != nil { + logrus.WithError(err).Errorf("forward signal %s", s) + } + } + }() + return sigc +} + +// StopCatch stops and closes a channel +func StopCatch(sigc chan os.Signal) { + signal.Stop(sigc) + close(sigc) +} + +// ParseSignal parses a given string into a syscall.Signal +// it checks that the signal exists in the platform-appropriate signalMap +func ParseSignal(rawSignal string) (syscall.Signal, error) { + s, err := strconv.Atoi(rawSignal) + if err == nil { + sig := syscall.Signal(s) + for _, msig := range signalMap { + if sig == msig { + return sig, nil + } + } + return -1, fmt.Errorf("unknown signal %q", rawSignal) + } + signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] + if !ok { + return -1, fmt.Errorf("unknown signal %q", rawSignal) + } + return signal, nil +} diff --git a/cmd/ctr/signals_linux.go b/cmd/ctr/commands/signals_linux.go similarity index 98% rename from cmd/ctr/signals_linux.go rename to cmd/ctr/commands/signals_linux.go index 0cc0a5022..97a17a314 100644 --- a/cmd/ctr/signals_linux.go +++ b/cmd/ctr/commands/signals_linux.go @@ -1,4 +1,4 @@ -package main +package commands import ( "syscall" diff --git a/cmd/ctr/signals_unix.go b/cmd/ctr/commands/signals_unix.go similarity index 98% rename from cmd/ctr/signals_unix.go rename to cmd/ctr/commands/signals_unix.go index 871a8f6bf..b940c3700 100644 --- a/cmd/ctr/signals_unix.go +++ b/cmd/ctr/commands/signals_unix.go @@ -1,6 +1,6 @@ // +build darwin freebsd solaris -package main +package commands import ( "syscall" diff --git a/cmd/ctr/commands/signals_windows.go b/cmd/ctr/commands/signals_windows.go new file mode 100644 index 000000000..695d6b1a6 --- /dev/null +++ b/cmd/ctr/commands/signals_windows.go @@ -0,0 +1,23 @@ +package commands + +import ( + "syscall" + + "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), +} diff --git a/cmd/ctr/exec.go b/cmd/ctr/exec.go index ecfddf27d..65659827d 100644 --- a/cmd/ctr/exec.go +++ b/cmd/ctr/exec.go @@ -10,6 +10,7 @@ import ( "github.com/urfave/cli" ) +//TODO:(jessvalarezo) exec-id is optional here, update to required arg var taskExecCommand = cli.Command{ Name: "exec", Usage: "execute additional processes in an existing container", @@ -87,8 +88,8 @@ var taskExecCommand = cli.Command{ logrus.WithError(err).Error("console resize") } } else { - sigc := forwardAllSignals(ctx, process) - defer stopCatch(sigc) + sigc := commands.ForwardAllSignals(ctx, process) + defer commands.StopCatch(sigc) } if err := process.Start(ctx); err != nil { diff --git a/cmd/ctr/kill.go b/cmd/ctr/kill.go index 3d479ef3c..159f409ee 100644 --- a/cmd/ctr/kill.go +++ b/cmd/ctr/kill.go @@ -6,6 +6,8 @@ import ( "github.com/urfave/cli" ) +// TODO:(jessvalarezo) the pid flag is not used here +// update to be able to signal given pid var taskKillCommand = cli.Command{ Name: "kill", Usage: "signal a container (default: SIGTERM)", @@ -31,7 +33,7 @@ var taskKillCommand = cli.Command{ if id == "" { return errors.New("container id must be provided") } - signal, err := parseSignal(context.String("signal")) + signal, err := commands.ParseSignal(context.String("signal")) if err != nil { return err } diff --git a/cmd/ctr/run.go b/cmd/ctr/run.go index e0f0a82b9..88bacf2d2 100644 --- a/cmd/ctr/run.go +++ b/cmd/ctr/run.go @@ -4,7 +4,6 @@ import ( gocontext "context" "fmt" "runtime" - "syscall" "github.com/containerd/console" "github.com/containerd/containerd" @@ -20,10 +19,6 @@ type resizer interface { Resize(ctx gocontext.Context, w, h uint32) error } -type killer interface { - Kill(gocontext.Context, syscall.Signal, ...containerd.KillOpts) error -} - func withEnv(context *cli.Context) containerd.SpecOpts { return func(_ gocontext.Context, _ *containerd.Client, _ *containers.Container, s *specs.Spec) error { env := context.StringSlice("env") @@ -160,8 +155,8 @@ var runCommand = cli.Command{ logrus.WithError(err).Error("console resize") } } else { - sigc := forwardAllSignals(ctx, task) - defer stopCatch(sigc) + sigc := commands.ForwardAllSignals(ctx, task) + defer commands.StopCatch(sigc) } status := <-statusC code, _, err := status.Result() diff --git a/cmd/ctr/start.go b/cmd/ctr/start.go index 87b72ebf1..9f37af9ee 100644 --- a/cmd/ctr/start.go +++ b/cmd/ctr/start.go @@ -70,8 +70,8 @@ var taskStartCommand = cli.Command{ logrus.WithError(err).Error("console resize") } } else { - sigc := forwardAllSignals(ctx, task) - defer stopCatch(sigc) + sigc := commands.ForwardAllSignals(ctx, task) + defer commands.StopCatch(sigc) } status := <-statusC diff --git a/cmd/ctr/utils.go b/cmd/ctr/utils.go index c6fadc41a..eae6a908e 100644 --- a/cmd/ctr/utils.go +++ b/cmd/ctr/utils.go @@ -8,11 +8,7 @@ import ( "fmt" "net" "net/http" - "os" - "os/signal" - "strconv" "strings" - "syscall" "time" "github.com/containerd/console" @@ -20,7 +16,6 @@ import ( "github.com/containerd/containerd/remotes/docker" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/urfave/cli" ) @@ -95,43 +90,6 @@ func getResolver(ctx gocontext.Context, clicontext *cli.Context) (remotes.Resolv return docker.NewResolver(options), nil } -func forwardAllSignals(ctx gocontext.Context, task killer) chan os.Signal { - sigc := make(chan os.Signal, 128) - signal.Notify(sigc) - go func() { - for s := range sigc { - logrus.Debug("forwarding signal ", s) - if err := task.Kill(ctx, s.(syscall.Signal)); err != nil { - logrus.WithError(err).Errorf("forward signal %s", s) - } - } - }() - return sigc -} - -func parseSignal(rawSignal string) (syscall.Signal, error) { - s, err := strconv.Atoi(rawSignal) - if err == nil { - sig := syscall.Signal(s) - for _, msig := range signalMap { - if sig == msig { - return sig, nil - } - } - return -1, fmt.Errorf("unknown signal %q", rawSignal) - } - signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] - if !ok { - return -1, fmt.Errorf("unknown signal %q", rawSignal) - } - return signal, nil -} - -func stopCatch(sigc chan os.Signal) { - signal.Stop(sigc) - close(sigc) -} - // parseMountFlag parses a mount string in the form "type=foo,source=/path,destination=/target,options=rbind:rw" func parseMountFlag(m string) (specs.Mount, error) { mount := specs.Mount{} diff --git a/cmd/ctr/utils_windows.go b/cmd/ctr/utils_windows.go index 652478f65..ac364f792 100644 --- a/cmd/ctr/utils_windows.go +++ b/cmd/ctr/utils_windows.go @@ -5,12 +5,10 @@ import ( "net" "os" "sync" - "syscall" "github.com/Microsoft/go-winio" clog "github.com/containerd/containerd/log" "github.com/pkg/errors" - "golang.org/x/sys/windows" ) func prepareStdio(stdin, stdout, stderr string, console bool) (*sync.WaitGroup, error) { @@ -91,19 +89,3 @@ func prepareStdio(stdin, stdout, stderr string, console bool) (*sync.WaitGroup, return &wg, nil } - -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), -}