Browse code

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 <zhangwei555@huawei.com>
(cherry picked from commit fdfaaeb9aa72404bde5207510bf5910893414b5d)

Zhang Wei authored on 2016/04/07 12:38:12
Showing 3 changed files
... ...
@@ -77,6 +77,7 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
77 77
 			c.Reset(false)
78 78
 			return err
79 79
 		}
80
+		daemon.LogContainerEvent(c, "start")
80 81
 	case libcontainerd.StatePause:
81 82
 		c.Paused = true
82 83
 		daemon.LogContainerEvent(c, "pause")
... ...
@@ -131,7 +131,6 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
131 131
 		return err
132 132
 	}
133 133
 
134
-	defer daemon.LogContainerEvent(container, "start") // this is logged even on error
135 134
 	if err := daemon.containerd.Create(container.ID, *spec, libcontainerd.WithRestartManager(container.RestartManager(true))); err != nil {
136 135
 		// if we receive an internal error from the initial start of a container then lets
137 136
 		// return it instead of entering the restart loop
... ...
@@ -149,6 +148,9 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error)
149 149
 		}
150 150
 
151 151
 		container.Reset(false)
152
+
153
+		// start event is logged even on error
154
+		daemon.LogContainerEvent(container, "start")
152 155
 		return err
153 156
 	}
154 157
 
... ...
@@ -604,3 +604,44 @@ func (s *DockerSuite) TestEventsFilterImageInContainerAction(c *check.C) {
604 604
 	events := strings.Split(strings.TrimSpace(out), "\n")
605 605
 	c.Assert(len(events), checker.GreaterThan, 1, check.Commentf(out))
606 606
 }
607
+
608
+func (s *DockerSuite) TestEventsContainerRestart(c *check.C) {
609
+	dockerCmd(c, "run", "-d", "--name=testEvent", "--restart=on-failure:3", "busybox", "false")
610
+
611
+	// wait until test2 is auto removed.
612
+	waitTime := 10 * time.Second
613
+	if daemonPlatform == "windows" {
614
+		// nslookup isn't present in Windows busybox. Is built-in.
615
+		waitTime = 90 * time.Second
616
+	}
617
+
618
+	err := waitInspect("testEvent", "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTime)
619
+	c.Assert(err, checker.IsNil)
620
+
621
+	var (
622
+		createCount int
623
+		startCount  int
624
+		dieCount    int
625
+	)
626
+	out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "-f", "container=testEvent")
627
+	events := strings.Split(strings.TrimSpace(out), "\n")
628
+
629
+	nEvents := len(events)
630
+	c.Assert(nEvents, checker.GreaterOrEqualThan, 1) //Missing expected event
631
+	actions := eventActionsByIDAndType(c, events, "testEvent", "container")
632
+
633
+	for _, a := range actions {
634
+		switch a {
635
+		case "create":
636
+			createCount++
637
+		case "start":
638
+			startCount++
639
+		case "die":
640
+			dieCount++
641
+		}
642
+	}
643
+	c.Assert(createCount, checker.Equals, 1, check.Commentf("testEvent should be created 1 times: %v", actions))
644
+	c.Assert(startCount, checker.Equals, 4, check.Commentf("testEvent should start 4 times: %v", actions))
645
+	c.Assert(dieCount, checker.Equals, 4, check.Commentf("testEvent should die 4 times: %v", actions))
646
+
647
+}