Browse code

Adding postRunProcessing infrastructure for hanlding Windows Update.

Signed-off-by: Stefan J. Wernli <swernli@microsoft.com>

Stefan J. Wernli authored on 2016/04/02 09:02:38
Showing 11 changed files
... ...
@@ -40,7 +40,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
40 40
 		// FIXME: here is race condition between two RUN instructions in Dockerfile
41 41
 		// because they share same runconfig and change image. Must be fixed
42 42
 		// in builder/builder.go
43
-		return c.ToDisk()
43
+		if err := c.ToDisk(); err != nil {
44
+			return err
45
+		}
46
+		return daemon.postRunProcessing(c, e)
44 47
 	case libcontainerd.StateRestart:
45 48
 		c.Lock()
46 49
 		defer c.Unlock()
... ...
@@ -51,7 +54,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
51 51
 			"exitCode": strconv.Itoa(int(e.ExitCode)),
52 52
 		}
53 53
 		daemon.LogContainerEventWithAttributes(c, "die", attributes)
54
-		return c.ToDisk()
54
+		if err := c.ToDisk(); err != nil {
55
+			return err
56
+		}
57
+		return daemon.postRunProcessing(c, e)
55 58
 	case libcontainerd.StateExitProcess:
56 59
 		c.Lock()
57 60
 		defer c.Unlock()
... ...
@@ -12,3 +12,8 @@ func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatu
12 12
 		OOMKilled: e.OOMKilled,
13 13
 	}
14 14
 }
15
+
16
+// postRunProcessing perfoms any processing needed on the container after it has stopped.
17
+func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
18
+	return nil
19
+}
... ...
@@ -1,6 +1,8 @@
1 1
 package daemon
2 2
 
3 3
 import (
4
+	"fmt"
5
+
4 6
 	"github.com/docker/docker/container"
5 7
 	"github.com/docker/docker/libcontainerd"
6 8
 )
... ...
@@ -11,3 +13,12 @@ func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatu
11 11
 		ExitCode: int(e.ExitCode),
12 12
 	}
13 13
 }
14
+
15
+// postRunProcessing perfoms any processing needed on the container after it has stopped.
16
+func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
17
+	//TODO Windows - handle update processing here...
18
+	if e.UpdatePending {
19
+		return fmt.Errorf("Windows: Update handling not implemented.")
20
+	}
21
+	return nil
22
+}
... ...
@@ -269,9 +269,10 @@ func (clnt *client) setExited(containerID string) error {
269 269
 	}
270 270
 
271 271
 	err := clnt.backend.StateChanged(containerID, StateInfo{
272
-		State:    StateExit,
273
-		ExitCode: exitCode,
274
-	})
272
+		CommonStateInfo: CommonStateInfo{
273
+			State:    StateExit,
274
+			ExitCode: exitCode,
275
+		}})
275 276
 
276 277
 	// Unmount and delete the bundle folder
277 278
 	if mts, err := mount.GetMounts(); err == nil {
... ...
@@ -48,9 +48,10 @@ func (clnt *client) restore(cont *containerd.Container, options ...CreateOption)
48 48
 	clnt.appendContainer(container)
49 49
 
50 50
 	err = clnt.backend.StateChanged(containerID, StateInfo{
51
-		State: StateRestore,
52
-		Pid:   container.systemPid,
53
-	})
51
+		CommonStateInfo: CommonStateInfo{
52
+			State: StateRestore,
53
+			Pid:   container.systemPid,
54
+		}})
54 55
 
55 56
 	if err != nil {
56 57
 		return err
... ...
@@ -60,9 +61,10 @@ func (clnt *client) restore(cont *containerd.Container, options ...CreateOption)
60 60
 		// This should only be a pause or resume event
61 61
 		if event.Type == StatePause || event.Type == StateResume {
62 62
 			return clnt.backend.StateChanged(containerID, StateInfo{
63
-				State: event.Type,
64
-				Pid:   container.systemPid,
65
-			})
63
+				CommonStateInfo: CommonStateInfo{
64
+					State: event.Type,
65
+					Pid:   container.systemPid,
66
+				}})
66 67
 		}
67 68
 
68 69
 		logrus.Warnf("unexpected backlog event: %#v", event)
... ...
@@ -505,9 +505,10 @@ func (clnt *client) Restore(containerID string, unusedOnWindows ...CreateOption)
505 505
 	// TODO Windows: Implement this. For now, just tell the backend the container exited.
506 506
 	logrus.Debugf("lcd Restore %s", containerID)
507 507
 	return clnt.backend.StateChanged(containerID, StateInfo{
508
-		State:    StateExit,
509
-		ExitCode: 1 << 31,
510
-	})
508
+		CommonStateInfo: CommonStateInfo{
509
+			State:    StateExit,
510
+			ExitCode: 1 << 31,
511
+		}})
511 512
 }
512 513
 
513 514
 // GetPidsForContainer returns a list of process IDs running in a container.
... ...
@@ -81,9 +81,10 @@ func (ctr *container) start() error {
81 81
 	ctr.systemPid = systemPid(resp.Container)
82 82
 
83 83
 	return ctr.client.backend.StateChanged(ctr.containerID, StateInfo{
84
-		State: StateStart,
85
-		Pid:   ctr.systemPid,
86
-	})
84
+		CommonStateInfo: CommonStateInfo{
85
+			State: StateStart,
86
+			Pid:   ctr.systemPid,
87
+		}})
87 88
 }
88 89
 
89 90
 func (ctr *container) newProcess(friendlyName string) *process {
... ...
@@ -103,8 +104,10 @@ func (ctr *container) handleEvent(e *containerd.Event) error {
103 103
 	switch e.Type {
104 104
 	case StateExit, StatePause, StateResume, StateOOM:
105 105
 		st := StateInfo{
106
-			State:     e.Type,
107
-			ExitCode:  e.Status,
106
+			CommonStateInfo: CommonStateInfo{
107
+				State:    e.Type,
108
+				ExitCode: e.Status,
109
+			},
108 110
 			OOMKilled: e.Type == StateExit && ctr.oom,
109 111
 		}
110 112
 		if e.Type == StateOOM {
... ...
@@ -103,9 +103,10 @@ func (ctr *container) start() error {
103 103
 
104 104
 	// Tell the docker engine that the container has started.
105 105
 	si := StateInfo{
106
-		State: StateStart,
107
-		Pid:   ctr.systemPid, // Not sure this is needed? Double-check monitor.go in daemon BUGBUG @jhowardmsft
108
-	}
106
+		CommonStateInfo: CommonStateInfo{
107
+			State: StateStart,
108
+			Pid:   ctr.systemPid, // Not sure this is needed? Double-check monitor.go in daemon BUGBUG @jhowardmsft
109
+		}}
109 110
 	return ctr.client.backend.StateChanged(ctr.containerID, si)
110 111
 
111 112
 }
... ...
@@ -129,10 +130,13 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
129 129
 
130 130
 	// Assume the container has exited
131 131
 	si := StateInfo{
132
-		State:     StateExit,
133
-		ExitCode:  uint32(exitCode),
134
-		Pid:       pid,
135
-		ProcessID: processFriendlyName,
132
+		CommonStateInfo: CommonStateInfo{
133
+			State:     StateExit,
134
+			ExitCode:  uint32(exitCode),
135
+			Pid:       pid,
136
+			ProcessID: processFriendlyName,
137
+		},
138
+		UpdatePending: false,
136 139
 	}
137 140
 
138 141
 	// But it could have been an exec'd process which exited
... ...
@@ -143,6 +147,11 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
143 143
 	// If this is the init process, always call into vmcompute.dll to
144 144
 	// shutdown the container after we have completed.
145 145
 	if isFirstProcessToStart {
146
+
147
+		// TODO Windows - add call into hcsshim to check if an update
148
+		// is pending once that is available.
149
+		//si.UpdatePending = CHECK IF UPDATE NEEDED
150
+
146 151
 		logrus.Debugf("Shutting down container %s", ctr.containerID)
147 152
 		// Explicit timeout here rather than hcsshim.TimeoutInfinte to avoid a
148 153
 		// (remote) possibility that ShutdownComputeSystem hangs indefinitely.
... ...
@@ -16,13 +16,12 @@ const (
16 16
 	stateLive         = "live"
17 17
 )
18 18
 
19
-// StateInfo contains description about the new state container has entered.
20
-type StateInfo struct { // FIXME: event?
19
+// CommonStateInfo contains the state info common to all platforms.
20
+type CommonStateInfo struct { // FIXME: event?
21 21
 	State     string
22 22
 	Pid       uint32
23 23
 	ExitCode  uint32
24 24
 	ProcessID string
25
-	OOMKilled bool // TODO Windows containerd factor out
26 25
 }
27 26
 
28 27
 // Backend defines callbacks that the client of the library needs to implement.
... ...
@@ -33,6 +33,14 @@ type Process struct {
33 33
 	SelinuxLabel *string `json:"selinuxLabel,omitempty"`
34 34
 }
35 35
 
36
+// StateInfo contains description about the new state container has entered.
37
+type StateInfo struct {
38
+	CommonStateInfo
39
+
40
+	// Platform specific StateInfo
41
+	OOMKilled bool
42
+}
43
+
36 44
 // Stats contains a stats properties from containerd.
37 45
 type Stats containerd.StatsResponse
38 46
 
... ...
@@ -17,6 +17,14 @@ type Summary struct {
17 17
 	Command string
18 18
 }
19 19
 
20
+// StateInfo contains description about the new state container has entered.
21
+type StateInfo struct {
22
+	CommonStateInfo
23
+
24
+	// Platform specific StateInfo
25
+	UpdatePending bool
26
+}
27
+
20 28
 // Stats contains a stats properties from containerd.
21 29
 type Stats struct{}
22 30