From e03485acda2db3679d7247d240fedc4c8417777e Mon Sep 17 00:00:00 2001 From: Krasi Georgiev Date: Fri, 14 Apr 2017 14:06:00 +0300 Subject: [PATCH] forward all signals to the container Signed-off-by: Krasi Georgiev --- cmd/ctr/kill_unix.go | 66 ---------------------------------------- cmd/ctr/kill_windows.go | 7 ----- cmd/ctr/run.go | 3 ++ cmd/ctr/utils.go | 50 ++++++++++++++++++++++++++++++ cmd/ctr/utils_unix.go | 42 +++++++++++++++++++++++-- cmd/ctr/utils_windows.go | 18 +++++++++++ 6 files changed, 111 insertions(+), 75 deletions(-) delete mode 100644 cmd/ctr/kill_unix.go delete mode 100644 cmd/ctr/kill_windows.go diff --git a/cmd/ctr/kill_unix.go b/cmd/ctr/kill_unix.go deleted file mode 100644 index 3dee6e283..000000000 --- a/cmd/ctr/kill_unix.go +++ /dev/null @@ -1,66 +0,0 @@ -// +build !windows - -package main - -import ( - "fmt" - "strconv" - "strings" - "syscall" -) - -var signalMap = map[string]syscall.Signal{ - "ABRT": syscall.SIGABRT, - "ALRM": syscall.SIGALRM, - "BUS": syscall.SIGBUS, - "CHLD": syscall.SIGCHLD, - "CLD": syscall.SIGCLD, - "CONT": syscall.SIGCONT, - "FPE": syscall.SIGFPE, - "HUP": syscall.SIGHUP, - "ILL": syscall.SIGILL, - "INT": syscall.SIGINT, - "IO": syscall.SIGIO, - "IOT": syscall.SIGIOT, - "KILL": syscall.SIGKILL, - "PIPE": syscall.SIGPIPE, - "POLL": syscall.SIGPOLL, - "PROF": syscall.SIGPROF, - "PWR": syscall.SIGPWR, - "QUIT": syscall.SIGQUIT, - "SEGV": syscall.SIGSEGV, - "STKFLT": syscall.SIGSTKFLT, - "STOP": syscall.SIGSTOP, - "SYS": syscall.SIGSYS, - "TERM": syscall.SIGTERM, - "TRAP": syscall.SIGTRAP, - "TSTP": syscall.SIGTSTP, - "TTIN": syscall.SIGTTIN, - "TTOU": syscall.SIGTTOU, - "UNUSED": syscall.SIGUNUSED, - "URG": syscall.SIGURG, - "USR1": syscall.SIGUSR1, - "USR2": syscall.SIGUSR2, - "VTALRM": syscall.SIGVTALRM, - "WINCH": syscall.SIGWINCH, - "XCPU": syscall.SIGXCPU, - "XFSZ": syscall.SIGXFSZ, -} - -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/kill_windows.go b/cmd/ctr/kill_windows.go deleted file mode 100644 index a59618d5f..000000000 --- a/cmd/ctr/kill_windows.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "syscall" - -func parseSignal(rawSignal string) (syscall.Signal, error) { - return syscall.SIGKILL, nil -} diff --git a/cmd/ctr/run.go b/cmd/ctr/run.go index 77be2ca4d..6e3974eda 100644 --- a/cmd/ctr/run.go +++ b/cmd/ctr/run.go @@ -169,6 +169,9 @@ var runCommand = cli.Command{ if err := handleConsoleResize(ctx, containers, response.ID, response.Pid, con); err != nil { logrus.WithError(err).Error("console resize") } + } else { + sigc := forwardAllSignals(containers, id) + defer stopCatch(sigc) } if _, err := containers.Start(ctx, &execution.StartRequest{ ID: response.ID, diff --git a/cmd/ctr/utils.go b/cmd/ctr/utils.go index 74bebdb7e..e244c1199 100644 --- a/cmd/ctr/utils.go +++ b/cmd/ctr/utils.go @@ -1,11 +1,17 @@ package main import ( + gocontext "context" "fmt" "io/ioutil" "os" + "os/signal" "path/filepath" + "strconv" + "strings" + "syscall" + "github.com/Sirupsen/logrus" contentapi "github.com/containerd/containerd/api/services/content" "github.com/containerd/containerd/api/services/execution" imagesapi "github.com/containerd/containerd/api/services/images" @@ -79,3 +85,47 @@ func waitContainer(events execution.ContainerService_EventsClient, id string, pi } } } + +func forwardAllSignals(containers execution.ContainerServiceClient, id string) chan os.Signal { + sigc := make(chan os.Signal, 128) + signal.Notify(sigc) + + go func() { + for s := range sigc { + logrus.Debug("Forwarding signal ", s) + killRequest := &execution.KillRequest{ + ID: id, + Signal: uint32(s.(syscall.Signal)), + All: false, + } + _, err := containers.Kill(gocontext.Background(), killRequest) + if err != nil { + logrus.WithError(err).Error("grpc event from kill") + } + } + }() + 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) +} diff --git a/cmd/ctr/utils_unix.go b/cmd/ctr/utils_unix.go index 0bc62b677..6d07f25b9 100644 --- a/cmd/ctr/utils_unix.go +++ b/cmd/ctr/utils_unix.go @@ -3,6 +3,7 @@ package main import ( + gocontext "context" "fmt" "io" "io/ioutil" @@ -13,11 +14,10 @@ import ( "syscall" "time" - gocontext "context" - "github.com/pkg/errors" "github.com/tonistiigi/fifo" "github.com/urfave/cli" + "golang.org/x/sys/unix" "google.golang.org/grpc" "google.golang.org/grpc/grpclog" ) @@ -100,3 +100,41 @@ func getGRPCConnection(context *cli.Context) (*grpc.ClientConn, error) { grpcConn = conn return grpcConn, nil } + +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, + "UNUSED": unix.SIGUNUSED, + "URG": unix.SIGURG, + "USR1": unix.SIGUSR1, + "USR2": unix.SIGUSR2, + "VTALRM": unix.SIGVTALRM, + "WINCH": unix.SIGWINCH, + "XCPU": unix.SIGXCPU, + "XFSZ": unix.SIGXFSZ, +} diff --git a/cmd/ctr/utils_windows.go b/cmd/ctr/utils_windows.go index d456bf9a9..cc1e3c55a 100644 --- a/cmd/ctr/utils_windows.go +++ b/cmd/ctr/utils_windows.go @@ -7,12 +7,14 @@ import ( "net" "os" "sync" + "syscall" "time" "github.com/Microsoft/go-winio" clog "github.com/containerd/containerd/log" "github.com/pkg/errors" "github.com/urfave/cli" + "golang.org/x/sys/windows" "google.golang.org/grpc" "google.golang.org/grpc/grpclog" ) @@ -119,3 +121,19 @@ 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), +}