From 78540d0d181d581342b0a2750786ae91e6ed9f91 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 4 Oct 2016 12:30:07 -0700 Subject: [PATCH] Fixing servicing bug by always specifying LayerFolderPath During the recent OCI changes, I mistakenly thought LayerFolderPath is only needed for Windows Server containers (isolation=process) and not for Hyper-V Containers, but it turns out it is also required for servicing containers used to finish installing updates. Since the servicing containers need to reuse the container's create options, this change makes it so that LayerFolderPath is always filled in for all containers as part of constructing the create options. Signed-off-by: Stefan J. Wernli --- daemon/monitor_windows.go | 13 +++++++++++-- daemon/start_windows.go | 4 ++-- libcontainerd/client_windows.go | 21 +++++++++++---------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/daemon/monitor_windows.go b/daemon/monitor_windows.go index 0d4a818229..f4857d7f8a 100644 --- a/daemon/monitor_windows.go +++ b/daemon/monitor_windows.go @@ -22,13 +22,22 @@ func (daemon *Daemon) postRunProcessing(container *container.Container, e libcon return err } - servicingOption := &libcontainerd.ServicingOption{ + newOpts := []libcontainerd.CreateOption{&libcontainerd.ServicingOption{ IsServicing: true, + }} + + copts, err := daemon.getLibcontainerdCreateOptions(container) + if err != nil { + return err + } + + if copts != nil { + newOpts = append(newOpts, *copts...) } // Create a new servicing container, which will start, complete the update, and merge back the // results if it succeeded, all as part of the below function call. - if err := daemon.containerd.Create((container.ID + "_servicing"), "", "", *spec, servicingOption); err != nil { + if err := daemon.containerd.Create((container.ID + "_servicing"), "", "", *spec, newOpts...); err != nil { container.SetExitCode(-1) return fmt.Errorf("Post-run update servicing failed: %s", err) } diff --git a/daemon/start_windows.go b/daemon/start_windows.go index 160a57e860..8b9cae7629 100644 --- a/daemon/start_windows.go +++ b/daemon/start_windows.go @@ -30,10 +30,10 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain } if hvOpts.IsHyperV { hvOpts.SandboxPath = filepath.Dir(m["dir"]) - } else { - layerOpts.LayerFolderPath = m["dir"] } + layerOpts.LayerFolderPath = m["dir"] + // Generate the layer paths of the layer options img, err := daemon.imageStore.Get(container.ImageID) if err != nil { diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go index 1e833ce862..938d81e543 100644 --- a/libcontainerd/client_windows.go +++ b/libcontainerd/client_windows.go @@ -40,15 +40,15 @@ const defaultOwner = "docker" // Create is the entrypoint to create a container from a spec, and if successfully // created, start it too. Table below shows the fields required for HCS JSON calling parameters, // where if not populated, is omitted. -// +-----------------+--------------------------------------------+--------------------------------------------+ -// | | Isolation=Process | Isolation=Hyper-V | -// +-----------------+--------------------------------------------+--------------------------------------------+ -// | VolumePath | \\?\\Volume{GUIDa} | | -// | LayerFolderPath | %root%\windowsfilter\containerID | | -// | Layers[] | ID=GUIDb;Path=%root%\windowsfilter\layerID | ID=GUIDb;Path=%root%\windowsfilter\layerID | -// | SandboxPath | | %root%\windowsfilter | -// | HvRuntime | | ImagePath=%root%\BaseLayerID\UtilityVM | -// +-----------------+--------------------------------------------+--------------------------------------------+ +// +-----------------+--------------------------------------------+---------------------------------------------------+ +// | | Isolation=Process | Isolation=Hyper-V | +// +-----------------+--------------------------------------------+---------------------------------------------------+ +// | VolumePath | \\?\\Volume{GUIDa} | | +// | LayerFolderPath | %root%\windowsfilter\containerID | %root%\windowsfilter\containerID (servicing only) | +// | Layers[] | ID=GUIDb;Path=%root%\windowsfilter\layerID | ID=GUIDb;Path=%root%\windowsfilter\layerID | +// | SandboxPath | | %root%\windowsfilter | +// | HvRuntime | | ImagePath=%root%\BaseLayerID\UtilityVM | +// +-----------------+--------------------------------------------+---------------------------------------------------+ // // Isolation=Process example: // @@ -170,9 +170,10 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir } } else { configuration.VolumePath = spec.Root.Path - configuration.LayerFolderPath = layerOpt.LayerFolderPath } + configuration.LayerFolderPath = layerOpt.LayerFolderPath + for _, layerPath := range layerOpt.LayerPaths { _, filename := filepath.Split(layerPath) g, err := hcsshim.NameToGuid(filename)