|
@@ -10,6 +10,7 @@ import (
|
|
"github.com/dotcloud/docker/graph"
|
|
"github.com/dotcloud/docker/graph"
|
|
"github.com/dotcloud/docker/image"
|
|
"github.com/dotcloud/docker/image"
|
|
"github.com/dotcloud/docker/pkg/graphdb"
|
|
"github.com/dotcloud/docker/pkg/graphdb"
|
|
|
|
+ "github.com/dotcloud/docker/pkg/signal"
|
|
"github.com/dotcloud/docker/registry"
|
|
"github.com/dotcloud/docker/registry"
|
|
"github.com/dotcloud/docker/runconfig"
|
|
"github.com/dotcloud/docker/runconfig"
|
|
"github.com/dotcloud/docker/runtime"
|
|
"github.com/dotcloud/docker/runtime"
|
|
@@ -21,7 +22,7 @@ import (
|
|
"net/url"
|
|
"net/url"
|
|
"os"
|
|
"os"
|
|
"os/exec"
|
|
"os/exec"
|
|
- "os/signal"
|
|
|
|
|
|
+ gosignal "os/signal"
|
|
"path"
|
|
"path"
|
|
"path/filepath"
|
|
"path/filepath"
|
|
goruntime "runtime"
|
|
goruntime "runtime"
|
|
@@ -50,7 +51,7 @@ func InitServer(job *engine.Job) engine.Status {
|
|
}
|
|
}
|
|
job.Logf("Setting up signal traps")
|
|
job.Logf("Setting up signal traps")
|
|
c := make(chan os.Signal, 1)
|
|
c := make(chan os.Signal, 1)
|
|
- signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
|
|
|
|
|
+ gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
|
go func() {
|
|
go func() {
|
|
sig := <-c
|
|
sig := <-c
|
|
log.Printf("Received signal '%v', exiting\n", sig)
|
|
log.Printf("Received signal '%v', exiting\n", sig)
|
|
@@ -126,56 +127,30 @@ func (v *simpleVersionInfo) Version() string {
|
|
// for the container to exit.
|
|
// for the container to exit.
|
|
// If a signal is given, then just send it to the container and return.
|
|
// If a signal is given, then just send it to the container and return.
|
|
func (srv *Server) ContainerKill(job *engine.Job) engine.Status {
|
|
func (srv *Server) ContainerKill(job *engine.Job) engine.Status {
|
|
- signalMap := map[string]syscall.Signal{
|
|
|
|
- "HUP": syscall.SIGHUP,
|
|
|
|
- "INT": syscall.SIGINT,
|
|
|
|
- "QUIT": syscall.SIGQUIT,
|
|
|
|
- "ILL": syscall.SIGILL,
|
|
|
|
- "TRAP": syscall.SIGTRAP,
|
|
|
|
- "ABRT": syscall.SIGABRT,
|
|
|
|
- "BUS": syscall.SIGBUS,
|
|
|
|
- "FPE": syscall.SIGFPE,
|
|
|
|
- "KILL": syscall.SIGKILL,
|
|
|
|
- "USR1": syscall.SIGUSR1,
|
|
|
|
- "SEGV": syscall.SIGSEGV,
|
|
|
|
- "USR2": syscall.SIGUSR2,
|
|
|
|
- "PIPE": syscall.SIGPIPE,
|
|
|
|
- "ALRM": syscall.SIGALRM,
|
|
|
|
- "TERM": syscall.SIGTERM,
|
|
|
|
- //"STKFLT": syscall.SIGSTKFLT,
|
|
|
|
- "CHLD": syscall.SIGCHLD,
|
|
|
|
- "CONT": syscall.SIGCONT,
|
|
|
|
- "STOP": syscall.SIGSTOP,
|
|
|
|
- "TSTP": syscall.SIGTSTP,
|
|
|
|
- "TTIN": syscall.SIGTTIN,
|
|
|
|
- "TTOU": syscall.SIGTTOU,
|
|
|
|
- "URG": syscall.SIGURG,
|
|
|
|
- "XCPU": syscall.SIGXCPU,
|
|
|
|
- "XFSZ": syscall.SIGXFSZ,
|
|
|
|
- "VTALRM": syscall.SIGVTALRM,
|
|
|
|
- "PROF": syscall.SIGPROF,
|
|
|
|
- "WINCH": syscall.SIGWINCH,
|
|
|
|
- "IO": syscall.SIGIO,
|
|
|
|
- //"PWR": syscall.SIGPWR,
|
|
|
|
- "SYS": syscall.SIGSYS,
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if n := len(job.Args); n < 1 || n > 2 {
|
|
if n := len(job.Args); n < 1 || n > 2 {
|
|
return job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name)
|
|
return job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name)
|
|
}
|
|
}
|
|
- name := job.Args[0]
|
|
|
|
- var sig uint64
|
|
|
|
|
|
+ var (
|
|
|
|
+ name = job.Args[0]
|
|
|
|
+ sig uint64
|
|
|
|
+ err error
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ // If we have a signal, look at it. Otherwise, do nothing
|
|
if len(job.Args) == 2 && job.Args[1] != "" {
|
|
if len(job.Args) == 2 && job.Args[1] != "" {
|
|
- sig = uint64(signalMap[job.Args[1]])
|
|
|
|
- if sig == 0 {
|
|
|
|
- var err error
|
|
|
|
- // The largest legal signal is 31, so let's parse on 5 bits
|
|
|
|
- sig, err = strconv.ParseUint(job.Args[1], 10, 5)
|
|
|
|
- if err != nil {
|
|
|
|
|
|
+ // Check if we passed the singal as a number:
|
|
|
|
+ // The largest legal signal is 31, so let's parse on 5 bits
|
|
|
|
+ sig, err = strconv.ParseUint(job.Args[1], 10, 5)
|
|
|
|
+ if err != nil {
|
|
|
|
+ // The signal is not a number, treat it as a string
|
|
|
|
+ sig = uint64(signal.SignalMap[job.Args[1]])
|
|
|
|
+ if sig == 0 {
|
|
return job.Errorf("Invalid signal: %s", job.Args[1])
|
|
return job.Errorf("Invalid signal: %s", job.Args[1])
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
if container := srv.runtime.Get(name); container != nil {
|
|
if container := srv.runtime.Get(name); container != nil {
|
|
// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
|
|
// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
|
|
if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
|
|
if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
|