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>

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
 
... ...
@@ -608,3 +608,44 @@ func (s *DockerSuite) TestEventsFilterImageInContainerAction(c *check.C) {
608 608
 	events := strings.Split(strings.TrimSpace(out), "\n")
609 609
 	c.Assert(len(events), checker.GreaterThan, 1, check.Commentf(out))
610 610
 }
611
+
612
+func (s *DockerSuite) TestEventsContainerRestart(c *check.C) {
613
+	dockerCmd(c, "run", "-d", "--name=testEvent", "--restart=on-failure:3", "busybox", "false")
614
+
615
+	// wait until test2 is auto removed.
616
+	waitTime := 10 * time.Second
617
+	if daemonPlatform == "windows" {
618
+		// nslookup isn't present in Windows busybox. Is built-in.
619
+		waitTime = 90 * time.Second
620
+	}
621
+
622
+	err := waitInspect("testEvent", "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTime)
623
+	c.Assert(err, checker.IsNil)
624
+
625
+	var (
626
+		createCount int
627
+		startCount  int
628
+		dieCount    int
629
+	)
630
+	out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "-f", "container=testEvent")
631
+	events := strings.Split(strings.TrimSpace(out), "\n")
632
+
633
+	nEvents := len(events)
634
+	c.Assert(nEvents, checker.GreaterOrEqualThan, 1) //Missing expected event
635
+	actions := eventActionsByIDAndType(c, events, "testEvent", "container")
636
+
637
+	for _, a := range actions {
638
+		switch a {
639
+		case "create":
640
+			createCount++
641
+		case "start":
642
+			startCount++
643
+		case "die":
644
+			dieCount++
645
+		}
646
+	}
647
+	c.Assert(createCount, checker.Equals, 1, check.Commentf("testEvent should be created 1 times: %v", actions))
648
+	c.Assert(startCount, checker.Equals, 4, check.Commentf("testEvent should start 4 times: %v", actions))
649
+	c.Assert(dieCount, checker.Equals, 4, check.Commentf("testEvent should die 4 times: %v", actions))
650
+
651
+}