From 818a5198e4a76cd63ff84a7796ff3b0b91302552 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Fri, 1 Apr 2016 17:02:38 -0700 Subject: [PATCH] Adding postRunProcessing infrastructure for hanlding Windows Update. Signed-off-by: Stefan J. Wernli --- daemon/monitor.go | 10 ++++++++-- daemon/monitor_linux.go | 5 +++++ daemon/monitor_windows.go | 11 +++++++++++ libcontainerd/client_linux.go | 7 ++++--- libcontainerd/client_liverestore_linux.go | 14 ++++++++------ libcontainerd/client_windows.go | 7 ++++--- libcontainerd/container_linux.go | 13 ++++++++----- libcontainerd/container_windows.go | 23 ++++++++++++++++------- libcontainerd/types.go | 5 ++--- libcontainerd/types_linux.go | 8 ++++++++ libcontainerd/types_windows.go | 8 ++++++++ 11 files changed, 82 insertions(+), 29 deletions(-) diff --git a/daemon/monitor.go b/daemon/monitor.go index 0a82c5f8fd..94ca267cb8 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -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() diff --git a/daemon/monitor_linux.go b/daemon/monitor_linux.go index df8b6c5dba..09f5af50c6 100644 --- a/daemon/monitor_linux.go +++ b/daemon/monitor_linux.go @@ -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 +} diff --git a/daemon/monitor_windows.go b/daemon/monitor_windows.go index b808ed3d03..4a6339467b 100644 --- a/daemon/monitor_windows.go +++ b/daemon/monitor_windows.go @@ -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 +} diff --git a/libcontainerd/client_linux.go b/libcontainerd/client_linux.go index f747b2fe2e..a6c70e3e7d 100644 --- a/libcontainerd/client_linux.go +++ b/libcontainerd/client_linux.go @@ -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 { diff --git a/libcontainerd/client_liverestore_linux.go b/libcontainerd/client_liverestore_linux.go index 1a1f7fe73c..b190550838 100644 --- a/libcontainerd/client_liverestore_linux.go +++ b/libcontainerd/client_liverestore_linux.go @@ -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) diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go index 50cb4168f7..5668974244 100644 --- a/libcontainerd/client_windows.go +++ b/libcontainerd/client_windows.go @@ -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. diff --git a/libcontainerd/container_linux.go b/libcontainerd/container_linux.go index 506a1770dd..a2a67af2ff 100644 --- a/libcontainerd/container_linux.go +++ b/libcontainerd/container_linux.go @@ -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 { diff --git a/libcontainerd/container_windows.go b/libcontainerd/container_windows.go index f1df64aa4f..7cab47e6b3 100644 --- a/libcontainerd/container_windows.go +++ b/libcontainerd/container_windows.go @@ -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. diff --git a/libcontainerd/types.go b/libcontainerd/types.go index bb82fe407c..15d0fc33f8 100644 --- a/libcontainerd/types.go +++ b/libcontainerd/types.go @@ -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. diff --git a/libcontainerd/types_linux.go b/libcontainerd/types_linux.go index bee12d9122..4f714a2329 100644 --- a/libcontainerd/types_linux.go +++ b/libcontainerd/types_linux.go @@ -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 diff --git a/libcontainerd/types_windows.go b/libcontainerd/types_windows.go index 2a915ff1e2..0f8bdd678c 100644 --- a/libcontainerd/types_windows.go +++ b/libcontainerd/types_windows.go @@ -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{}