Browse code

Taking stop-signal into account when docker kill

If a container sets a stop-signal, taking it into account to disable or
not the restart policy.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/10/25 03:10:14
Showing 2 changed files
... ...
@@ -68,7 +68,17 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er
68 68
 		return errNotRunning{container.ID}
69 69
 	}
70 70
 
71
-	container.ExitOnNext()
71
+	if container.Config.StopSignal != "" {
72
+		containerStopSignal, err := signal.ParseSignal(container.Config.StopSignal)
73
+		if err != nil {
74
+			return err
75
+		}
76
+		if containerStopSignal == syscall.Signal(sig) {
77
+			container.ExitOnNext()
78
+		}
79
+	} else {
80
+		container.ExitOnNext()
81
+	}
72 82
 
73 83
 	if !daemon.IsShuttingDown() {
74 84
 		container.HasBeenManuallyStopped = true
... ...
@@ -47,7 +47,7 @@ func (s *DockerSuite) TestKillDifferentUserContainer(c *check.C) {
47 47
 
48 48
 // regression test about correct signal parsing see #13665
49 49
 func (s *DockerSuite) TestKillWithSignal(c *check.C) {
50
-	// Cannot port to Windows - does not support signals in the same was a Linux does
50
+	// Cannot port to Windows - does not support signals in the same way Linux does
51 51
 	testRequires(c, DaemonIsLinux)
52 52
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
53 53
 	cid := strings.TrimSpace(out)
... ...
@@ -60,6 +60,36 @@ func (s *DockerSuite) TestKillWithSignal(c *check.C) {
60 60
 	c.Assert(running, checker.Equals, "true", check.Commentf("Container should be in running state after SIGWINCH"))
61 61
 }
62 62
 
63
+func (s *DockerSuite) TestKillWithStopSignalWithSameSignalShouldDisableRestartPolicy(c *check.C) {
64
+	// Cannot port to Windows - does not support signals int the same way as Linux does
65
+	testRequires(c, DaemonIsLinux)
66
+	out, _ := dockerCmd(c, "run", "-d", "--stop-signal=TERM", "busybox", "top")
67
+	cid := strings.TrimSpace(out)
68
+	c.Assert(waitRun(cid), check.IsNil)
69
+
70
+	// Let's docker send a CONT signal to the container
71
+	dockerCmd(c, "kill", "-s", "TERM", cid)
72
+
73
+	out, _ = dockerCmd(c, "ps", "-q")
74
+	c.Assert(out, checker.Not(checker.Contains), cid, check.Commentf("killed container is still running"))
75
+}
76
+
77
+func (s *DockerSuite) TestKillWithStopSignalWithDifferentSignalShouldKeepRestartPolicy(c *check.C) {
78
+	// Cannot port to Windows - does not support signals int the same way as Linux does
79
+	testRequires(c, DaemonIsLinux)
80
+	out, _ := dockerCmd(c, "run", "-d", "--stop-signal=CONT", "busybox", "top")
81
+	cid := strings.TrimSpace(out)
82
+	c.Assert(waitRun(cid), check.IsNil)
83
+
84
+	// Let's docker send a TERM signal to the container
85
+	// It will kill the process, but not disable the restart policy
86
+	dockerCmd(c, "kill", "-s", "TERM", cid)
87
+
88
+	// Restart policy should still be in place, so it should be still running
89
+	c.Assert(waitRun(cid), check.IsNil)
90
+}
91
+
92
+// FIXME(vdemeester) should be a unit test
63 93
 func (s *DockerSuite) TestKillWithInvalidSignal(c *check.C) {
64 94
 	out, _ := runSleepingContainer(c, "-d")
65 95
 	cid := strings.TrimSpace(out)