Adding postRunProcessing infrastructure for hanlding Windows Update.

Signed-off-by: Stefan J. Wernli <swernli@microsoft.com>
This commit is contained in:
Stefan J. Wernli 2016-04-01 17:02:38 -07:00
parent 8eb8a1d6b8
commit 818a5198e4
11 changed files with 82 additions and 29 deletions

View File

@ -40,7 +40,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
// FIXME: here is race condition between two RUN instructions in Dockerfile
// because they share same runconfig and change image. Must be fixed
// in builder/builder.go
return c.ToDisk()
if err := c.ToDisk(); err != nil {
return err
}
return daemon.postRunProcessing(c, e)
case libcontainerd.StateRestart:
c.Lock()
defer c.Unlock()
@ -51,7 +54,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
"exitCode": strconv.Itoa(int(e.ExitCode)),
}
daemon.LogContainerEventWithAttributes(c, "die", attributes)
return c.ToDisk()
if err := c.ToDisk(); err != nil {
return err
}
return daemon.postRunProcessing(c, e)
case libcontainerd.StateExitProcess:
c.Lock()
defer c.Unlock()

View File

@ -12,3 +12,8 @@ func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatu
OOMKilled: e.OOMKilled,
}
}
// postRunProcessing perfoms any processing needed on the container after it has stopped.
func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
return nil
}

View File

@ -1,6 +1,8 @@
package daemon
import (
"fmt"
"github.com/docker/docker/container"
"github.com/docker/docker/libcontainerd"
)
@ -11,3 +13,12 @@ func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatu
ExitCode: int(e.ExitCode),
}
}
// postRunProcessing perfoms any processing needed on the container after it has stopped.
func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
//TODO Windows - handle update processing here...
if e.UpdatePending {
return fmt.Errorf("Windows: Update handling not implemented.")
}
return nil
}

View File

@ -269,9 +269,10 @@ func (clnt *client) setExited(containerID string) error {
}
err := clnt.backend.StateChanged(containerID, StateInfo{
State: StateExit,
ExitCode: exitCode,
})
CommonStateInfo: CommonStateInfo{
State: StateExit,
ExitCode: exitCode,
}})
// Unmount and delete the bundle folder
if mts, err := mount.GetMounts(); err == nil {

View File

@ -48,9 +48,10 @@ func (clnt *client) restore(cont *containerd.Container, options ...CreateOption)
clnt.appendContainer(container)
err = clnt.backend.StateChanged(containerID, StateInfo{
State: StateRestore,
Pid: container.systemPid,
})
CommonStateInfo: CommonStateInfo{
State: StateRestore,
Pid: container.systemPid,
}})
if err != nil {
return err
@ -60,9 +61,10 @@ func (clnt *client) restore(cont *containerd.Container, options ...CreateOption)
// This should only be a pause or resume event
if event.Type == StatePause || event.Type == StateResume {
return clnt.backend.StateChanged(containerID, StateInfo{
State: event.Type,
Pid: container.systemPid,
})
CommonStateInfo: CommonStateInfo{
State: event.Type,
Pid: container.systemPid,
}})
}
logrus.Warnf("unexpected backlog event: %#v", event)

View File

@ -505,9 +505,10 @@ func (clnt *client) Restore(containerID string, unusedOnWindows ...CreateOption)
// TODO Windows: Implement this. For now, just tell the backend the container exited.
logrus.Debugf("lcd Restore %s", containerID)
return clnt.backend.StateChanged(containerID, StateInfo{
State: StateExit,
ExitCode: 1 << 31,
})
CommonStateInfo: CommonStateInfo{
State: StateExit,
ExitCode: 1 << 31,
}})
}
// GetPidsForContainer returns a list of process IDs running in a container.

View File

@ -81,9 +81,10 @@ func (ctr *container) start() error {
ctr.systemPid = systemPid(resp.Container)
return ctr.client.backend.StateChanged(ctr.containerID, StateInfo{
State: StateStart,
Pid: ctr.systemPid,
})
CommonStateInfo: CommonStateInfo{
State: StateStart,
Pid: ctr.systemPid,
}})
}
func (ctr *container) newProcess(friendlyName string) *process {
@ -103,8 +104,10 @@ func (ctr *container) handleEvent(e *containerd.Event) error {
switch e.Type {
case StateExit, StatePause, StateResume, StateOOM:
st := StateInfo{
State: e.Type,
ExitCode: e.Status,
CommonStateInfo: CommonStateInfo{
State: e.Type,
ExitCode: e.Status,
},
OOMKilled: e.Type == StateExit && ctr.oom,
}
if e.Type == StateOOM {

View File

@ -103,9 +103,10 @@ func (ctr *container) start() error {
// Tell the docker engine that the container has started.
si := StateInfo{
State: StateStart,
Pid: ctr.systemPid, // Not sure this is needed? Double-check monitor.go in daemon BUGBUG @jhowardmsft
}
CommonStateInfo: CommonStateInfo{
State: StateStart,
Pid: ctr.systemPid, // Not sure this is needed? Double-check monitor.go in daemon BUGBUG @jhowardmsft
}}
return ctr.client.backend.StateChanged(ctr.containerID, si)
}
@ -129,10 +130,13 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
// Assume the container has exited
si := StateInfo{
State: StateExit,
ExitCode: uint32(exitCode),
Pid: pid,
ProcessID: processFriendlyName,
CommonStateInfo: CommonStateInfo{
State: StateExit,
ExitCode: uint32(exitCode),
Pid: pid,
ProcessID: processFriendlyName,
},
UpdatePending: false,
}
// But it could have been an exec'd process which exited
@ -143,6 +147,11 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
// If this is the init process, always call into vmcompute.dll to
// shutdown the container after we have completed.
if isFirstProcessToStart {
// TODO Windows - add call into hcsshim to check if an update
// is pending once that is available.
//si.UpdatePending = CHECK IF UPDATE NEEDED
logrus.Debugf("Shutting down container %s", ctr.containerID)
// Explicit timeout here rather than hcsshim.TimeoutInfinte to avoid a
// (remote) possibility that ShutdownComputeSystem hangs indefinitely.

View File

@ -16,13 +16,12 @@ const (
stateLive = "live"
)
// StateInfo contains description about the new state container has entered.
type StateInfo struct { // FIXME: event?
// CommonStateInfo contains the state info common to all platforms.
type CommonStateInfo struct { // FIXME: event?
State string
Pid uint32
ExitCode uint32
ProcessID string
OOMKilled bool // TODO Windows containerd factor out
}
// Backend defines callbacks that the client of the library needs to implement.

View File

@ -33,6 +33,14 @@ type Process struct {
SelinuxLabel *string `json:"selinuxLabel,omitempty"`
}
// StateInfo contains description about the new state container has entered.
type StateInfo struct {
CommonStateInfo
// Platform specific StateInfo
OOMKilled bool
}
// Stats contains a stats properties from containerd.
type Stats containerd.StatsResponse

View File

@ -17,6 +17,14 @@ type Summary struct {
Command string
}
// StateInfo contains description about the new state container has entered.
type StateInfo struct {
CommonStateInfo
// Platform specific StateInfo
UpdatePending bool
}
// Stats contains a stats properties from containerd.
type Stats struct{}