Signed-off-by: Doug Davis <dug@us.ibm.com>
| ... | ... |
@@ -28,6 +28,7 @@ import ( |
| 28 | 28 |
"github.com/docker/docker/pkg/jsonmessage" |
| 29 | 29 |
"github.com/docker/docker/pkg/parsers" |
| 30 | 30 |
"github.com/docker/docker/pkg/parsers/filters" |
| 31 |
+ "github.com/docker/docker/pkg/signal" |
|
| 31 | 32 |
"github.com/docker/docker/pkg/stdcopy" |
| 32 | 33 |
"github.com/docker/docker/pkg/streamformatter" |
| 33 | 34 |
"github.com/docker/docker/pkg/version" |
| ... | ... |
@@ -193,16 +194,34 @@ func postContainersKill(eng *engine.Engine, version version.Version, w http.Resp |
| 193 | 193 |
if vars == nil {
|
| 194 | 194 |
return fmt.Errorf("Missing parameter")
|
| 195 | 195 |
} |
| 196 |
- if err := parseForm(r); err != nil {
|
|
| 196 |
+ err := parseForm(r) |
|
| 197 |
+ if err != nil {
|
|
| 197 | 198 |
return err |
| 198 | 199 |
} |
| 199 |
- job := eng.Job("kill", vars["name"])
|
|
| 200 |
- if sig := r.Form.Get("signal"); sig != "" {
|
|
| 201 |
- job.Args = append(job.Args, sig) |
|
| 200 |
+ |
|
| 201 |
+ var sig uint64 |
|
| 202 |
+ name := vars["name"] |
|
| 203 |
+ |
|
| 204 |
+ // If we have a signal, look at it. Otherwise, do nothing |
|
| 205 |
+ if sigStr := vars["signal"]; sigStr != "" {
|
|
| 206 |
+ // Check if we passed the signal as a number: |
|
| 207 |
+ // The largest legal signal is 31, so let's parse on 5 bits |
|
| 208 |
+ sig, err = strconv.ParseUint(sigStr, 10, 5) |
|
| 209 |
+ if err != nil {
|
|
| 210 |
+ // The signal is not a number, treat it as a string (either like |
|
| 211 |
+ // "KILL" or like "SIGKILL") |
|
| 212 |
+ sig = uint64(signal.SignalMap[strings.TrimPrefix(sigStr, "SIG")]) |
|
| 213 |
+ } |
|
| 214 |
+ |
|
| 215 |
+ if sig == 0 {
|
|
| 216 |
+ return fmt.Errorf("Invalid signal: %s", sigStr)
|
|
| 217 |
+ } |
|
| 202 | 218 |
} |
| 203 |
- if err := job.Run(); err != nil {
|
|
| 219 |
+ |
|
| 220 |
+ if err = getDaemon(eng).ContainerKill(name, sig); err != nil {
|
|
| 204 | 221 |
return err |
| 205 | 222 |
} |
| 223 |
+ |
|
| 206 | 224 |
w.WriteHeader(http.StatusNoContent) |
| 207 | 225 |
return nil |
| 208 | 226 |
} |
| ... | ... |
@@ -123,7 +123,6 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
|
| 123 | 123 |
"create": daemon.ContainerCreate, |
| 124 | 124 |
"export": daemon.ContainerExport, |
| 125 | 125 |
"info": daemon.CmdInfo, |
| 126 |
- "kill": daemon.ContainerKill, |
|
| 127 | 126 |
"logs": daemon.ContainerLogs, |
| 128 | 127 |
"pause": daemon.ContainerPause, |
| 129 | 128 |
"resize": daemon.ContainerResize, |
| ... | ... |
@@ -2,43 +2,14 @@ package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "strconv" |
|
| 6 |
- "strings" |
|
| 7 | 5 |
"syscall" |
| 8 |
- |
|
| 9 |
- "github.com/docker/docker/engine" |
|
| 10 |
- "github.com/docker/docker/pkg/signal" |
|
| 11 | 6 |
) |
| 12 | 7 |
|
| 13 | 8 |
// ContainerKill send signal to the container |
| 14 | 9 |
// If no signal is given (sig 0), then Kill with SIGKILL and wait |
| 15 | 10 |
// for the container to exit. |
| 16 | 11 |
// If a signal is given, then just send it to the container and return. |
| 17 |
-func (daemon *Daemon) ContainerKill(job *engine.Job) error {
|
|
| 18 |
- if n := len(job.Args); n < 1 || n > 2 {
|
|
| 19 |
- return fmt.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name)
|
|
| 20 |
- } |
|
| 21 |
- var ( |
|
| 22 |
- name = job.Args[0] |
|
| 23 |
- sig uint64 |
|
| 24 |
- err error |
|
| 25 |
- ) |
|
| 26 |
- |
|
| 27 |
- // If we have a signal, look at it. Otherwise, do nothing |
|
| 28 |
- if len(job.Args) == 2 && job.Args[1] != "" {
|
|
| 29 |
- // Check if we passed the signal as a number: |
|
| 30 |
- // The largest legal signal is 31, so let's parse on 5 bits |
|
| 31 |
- sig, err = strconv.ParseUint(job.Args[1], 10, 5) |
|
| 32 |
- if err != nil {
|
|
| 33 |
- // The signal is not a number, treat it as a string (either like "KILL" or like "SIGKILL") |
|
| 34 |
- sig = uint64(signal.SignalMap[strings.TrimPrefix(job.Args[1], "SIG")]) |
|
| 35 |
- } |
|
| 36 |
- |
|
| 37 |
- if sig == 0 {
|
|
| 38 |
- return fmt.Errorf("Invalid signal: %s", job.Args[1])
|
|
| 39 |
- } |
|
| 40 |
- } |
|
| 41 |
- |
|
| 12 |
+func (daemon *Daemon) ContainerKill(name string, sig uint64) error {
|
|
| 42 | 13 |
container, err := daemon.Get(name) |
| 43 | 14 |
if err != nil {
|
| 44 | 15 |
return err |
| ... | ... |
@@ -49,13 +20,12 @@ func (daemon *Daemon) ContainerKill(job *engine.Job) error {
|
| 49 | 49 |
if err := container.Kill(); err != nil {
|
| 50 | 50 |
return fmt.Errorf("Cannot kill container %s: %s", name, err)
|
| 51 | 51 |
} |
| 52 |
- container.LogEvent("kill")
|
|
| 53 | 52 |
} else {
|
| 54 | 53 |
// Otherwise, just send the requested signal |
| 55 | 54 |
if err := container.KillSig(int(sig)); err != nil {
|
| 56 | 55 |
return fmt.Errorf("Cannot kill container %s: %s", name, err)
|
| 57 | 56 |
} |
| 58 |
- // FIXME: Add event for signals |
|
| 59 | 57 |
} |
| 58 |
+ container.LogEvent("kill")
|
|
| 60 | 59 |
return nil |
| 61 | 60 |
} |
| ... | ... |
@@ -132,8 +132,8 @@ func TestRestartKillWait(t *testing.T) {
|
| 132 | 132 |
if err := job.Run(); err != nil {
|
| 133 | 133 |
t.Fatal(err) |
| 134 | 134 |
} |
| 135 |
- job = eng.Job("kill", id)
|
|
| 136 |
- if err := job.Run(); err != nil {
|
|
| 135 |
+ |
|
| 136 |
+ if err := runtime.ContainerKill(id, 0); err != nil {
|
|
| 137 | 137 |
t.Fatal(err) |
| 138 | 138 |
} |
| 139 | 139 |
|
| ... | ... |
@@ -104,7 +104,7 @@ func containerWaitTimeout(eng *engine.Engine, id string, t Fataler) error {
|
| 104 | 104 |
} |
| 105 | 105 |
|
| 106 | 106 |
func containerKill(eng *engine.Engine, id string, t Fataler) {
|
| 107 |
- if err := eng.Job("kill", id).Run(); err != nil {
|
|
| 107 |
+ if err := getDaemon(eng).ContainerKill(id, 0); err != nil {
|
|
| 108 | 108 |
t.Fatal(err) |
| 109 | 109 |
} |
| 110 | 110 |
} |