浏览代码

ensure heath monitor status updates are propagated

initHealthMonitor and updateHealthMonitor can cause container state to
be changed (State.Health).

Signed-off-by: Fabio Kung <fabio.kung@gmail.com>
Fabio Kung 8 年之前
父节点
当前提交
04bd768a88
共有 2 个文件被更改,包括 10 次插入6 次删除
  1. 4 3
      container/health.go
  2. 6 3
      daemon/monitor.go

+ 4 - 3
container/health.go

@@ -13,9 +13,8 @@ type Health struct {
 
 // String returns a human-readable description of the health-check state
 func (s *Health) String() string {
-	// This happens when the container is being shutdown and the monitor has stopped
-	// or the monitor has yet to be setup.
-	if s.stop == nil {
+	// This happens when the monitor has yet to be setup.
+	if s.Status == "" {
 		return types.Unhealthy
 	}
 
@@ -44,6 +43,8 @@ func (s *Health) CloseMonitorChannel() {
 		logrus.Debug("CloseMonitorChannel: waiting for probe to stop")
 		close(s.stop)
 		s.stop = nil
+		// unhealthy when the monitor has stopped for compatibility reasons
+		s.Status = types.Unhealthy
 		logrus.Debug("CloseMonitorChannel done")
 	}
 }

+ 6 - 3
daemon/monitor.go

@@ -39,6 +39,9 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
 			return errors.New("Received StateOOM from libcontainerd on Windows. This should never happen.")
 		}
 		daemon.updateHealthMonitor(c)
+		if err := c.CheckpointTo(daemon.containersReplica); err != nil {
+			return err
+		}
 		daemon.LogContainerEvent(c, "oom")
 	case libcontainerd.StateExit:
 
@@ -119,30 +122,30 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
 		c.HasBeenStartedBefore = true
 		daemon.setStateCounter(c)
 
+		daemon.initHealthMonitor(c)
 		if err := c.CheckpointTo(daemon.containersReplica); err != nil {
 			c.Reset(false)
 			return err
 		}
-		daemon.initHealthMonitor(c)
 
 		daemon.LogContainerEvent(c, "start")
 	case libcontainerd.StatePause:
 		// Container is already locked in this case
 		c.Paused = true
 		daemon.setStateCounter(c)
+		daemon.updateHealthMonitor(c)
 		if err := c.CheckpointTo(daemon.containersReplica); err != nil {
 			return err
 		}
-		daemon.updateHealthMonitor(c)
 		daemon.LogContainerEvent(c, "pause")
 	case libcontainerd.StateResume:
 		// Container is already locked in this case
 		c.Paused = false
 		daemon.setStateCounter(c)
+		daemon.updateHealthMonitor(c)
 		if err := c.CheckpointTo(daemon.containersReplica); err != nil {
 			return err
 		}
-		daemon.updateHealthMonitor(c)
 		daemon.LogContainerEvent(c, "unpause")
 	}
 	return nil