diff --git a/daemon/daemon.go b/daemon/daemon.go index e4304b2a48..3876027ca6 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -117,6 +117,9 @@ func (daemon *Daemon) Install(eng *engine.Engine) error { if err := eng.Register("unpause", daemon.ContainerUnpause); err != nil { return err } + if err := eng.Register("kill", daemon.ContainerKill); err != nil { + return err + } return nil } diff --git a/daemon/kill.go b/daemon/kill.go new file mode 100644 index 0000000000..f883495cef --- /dev/null +++ b/daemon/kill.go @@ -0,0 +1,59 @@ +package daemon + +import ( + "strconv" + "strings" + "syscall" + + "github.com/docker/docker/engine" + "github.com/docker/docker/pkg/signal" +) + +// ContainerKill send signal to the container +// If no signal is given (sig 0), then Kill with SIGKILL and wait +// for the container to exit. +// If a signal is given, then just send it to the container and return. +func (daemon *Daemon) ContainerKill(job *engine.Job) engine.Status { + if n := len(job.Args); n < 1 || n > 2 { + return job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name) + } + 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] != "" { + // Check if we passed the signal 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 (either like "KILL" or like "SIGKILL") + sig = uint64(signal.SignalMap[strings.TrimPrefix(job.Args[1], "SIG")]) + } + + if sig == 0 { + return job.Errorf("Invalid signal: %s", job.Args[1]) + } + } + + if container := daemon.Get(name); container != nil { + // If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait()) + if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL { + if err := container.Kill(); err != nil { + return job.Errorf("Cannot kill container %s: %s", name, err) + } + job.Eng.Job("log", "kill", container.ID, daemon.Repositories().ImageName(container.Image)).Run() + } else { + // Otherwise, just send the requested signal + if err := container.KillSig(int(sig)); err != nil { + return job.Errorf("Cannot kill container %s: %s", name, err) + } + // FIXME: Add event for signals + } + } else { + return job.Errorf("No such container: %s", name) + } + return engine.StatusOK +} diff --git a/server/container.go b/server/container.go index b37fa521f5..a5ab85b2a7 100644 --- a/server/container.go +++ b/server/container.go @@ -17,7 +17,6 @@ import ( "path/filepath" "strconv" "strings" - "syscall" "time" "github.com/docker/docker/daemon" @@ -25,61 +24,11 @@ import ( "github.com/docker/docker/graph" "github.com/docker/docker/pkg/graphdb" "github.com/docker/docker/pkg/parsers" - "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/tailfile" "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" ) -// ContainerKill send signal to the container -// If no signal is given (sig 0), then Kill with SIGKILL and wait -// for the container to exit. -// If a signal is given, then just send it to the container and return. -func (srv *Server) ContainerKill(job *engine.Job) engine.Status { - if n := len(job.Args); n < 1 || n > 2 { - return job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name) - } - 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] != "" { - // Check if we passed the signal 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 (either like "KILL" or like "SIGKILL") - sig = uint64(signal.SignalMap[strings.TrimPrefix(job.Args[1], "SIG")]) - } - - if sig == 0 { - return job.Errorf("Invalid signal: %s", job.Args[1]) - } - } - - if container := srv.daemon.Get(name); container != nil { - // If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait()) - if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL { - if err := container.Kill(); err != nil { - return job.Errorf("Cannot kill container %s: %s", name, err) - } - srv.LogEvent("kill", container.ID, srv.daemon.Repositories().ImageName(container.Image)) - } else { - // Otherwise, just send the requested signal - if err := container.KillSig(int(sig)); err != nil { - return job.Errorf("Cannot kill container %s: %s", name, err) - } - // FIXME: Add event for signals - } - } else { - return job.Errorf("No such container: %s", name) - } - return engine.StatusOK -} - func (srv *Server) ContainerExport(job *engine.Job) engine.Status { if len(job.Args) != 1 { return job.Errorf("Usage: %s container_id", job.Name) diff --git a/server/init.go b/server/init.go index 9b6033b6c0..5fdc542fe6 100644 --- a/server/init.go +++ b/server/init.go @@ -91,7 +91,6 @@ func InitServer(job *engine.Job) engine.Status { "stop": srv.ContainerStop, "restart": srv.ContainerRestart, "start": srv.ContainerStart, - "kill": srv.ContainerKill, "wait": srv.ContainerWait, "tag": srv.ImageTag, // FIXME merge with "image_tag" "resize": srv.ContainerResize,