From 133773a4d091b830ca4bd2dc953e223ea376064f Mon Sep 17 00:00:00 2001 From: Zhang Wei Date: Thu, 7 Apr 2016 11:38:12 +0800 Subject: [PATCH] Add missing "start" event back for auto-restart container When container is automatically restarted based on restart policy, docker events can't get "start" event but only get "die" event, this is not consistent with previous behavior. This commit will add "start" event back. Signed-off-by: Zhang Wei (cherry picked from commit fdfaaeb9aa72404bde5207510bf5910893414b5d) --- daemon/monitor.go | 1 + daemon/start.go | 4 ++- integration-cli/docker_cli_events_test.go | 41 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/daemon/monitor.go b/daemon/monitor.go index 0a82c5f8fd..f9f7def98d 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -77,6 +77,7 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error { c.Reset(false) return err } + daemon.LogContainerEvent(c, "start") case libcontainerd.StatePause: c.Paused = true daemon.LogContainerEvent(c, "pause") diff --git a/daemon/start.go b/daemon/start.go index 52531f511e..1b34f42692 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -131,7 +131,6 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error) return err } - defer daemon.LogContainerEvent(container, "start") // this is logged even on error if err := daemon.containerd.Create(container.ID, *spec, libcontainerd.WithRestartManager(container.RestartManager(true))); err != nil { // if we receive an internal error from the initial start of a container then lets // return it instead of entering the restart loop @@ -149,6 +148,9 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error) } container.Reset(false) + + // start event is logged even on error + daemon.LogContainerEvent(container, "start") return err } diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index f426650c2b..f17b711cc2 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -604,3 +604,44 @@ func (s *DockerSuite) TestEventsFilterImageInContainerAction(c *check.C) { events := strings.Split(strings.TrimSpace(out), "\n") c.Assert(len(events), checker.GreaterThan, 1, check.Commentf(out)) } + +func (s *DockerSuite) TestEventsContainerRestart(c *check.C) { + dockerCmd(c, "run", "-d", "--name=testEvent", "--restart=on-failure:3", "busybox", "false") + + // wait until test2 is auto removed. + waitTime := 10 * time.Second + if daemonPlatform == "windows" { + // nslookup isn't present in Windows busybox. Is built-in. + waitTime = 90 * time.Second + } + + err := waitInspect("testEvent", "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTime) + c.Assert(err, checker.IsNil) + + var ( + createCount int + startCount int + dieCount int + ) + out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "-f", "container=testEvent") + events := strings.Split(strings.TrimSpace(out), "\n") + + nEvents := len(events) + c.Assert(nEvents, checker.GreaterOrEqualThan, 1) //Missing expected event + actions := eventActionsByIDAndType(c, events, "testEvent", "container") + + for _, a := range actions { + switch a { + case "create": + createCount++ + case "start": + startCount++ + case "die": + dieCount++ + } + } + c.Assert(createCount, checker.Equals, 1, check.Commentf("testEvent should be created 1 times: %v", actions)) + c.Assert(startCount, checker.Equals, 4, check.Commentf("testEvent should start 4 times: %v", actions)) + c.Assert(dieCount, checker.Equals, 4, check.Commentf("testEvent should die 4 times: %v", actions)) + +}