Browse code

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 <swernli@microsoft.com>

Stefan J. Wernli authored on 2016/10/05 04:30:07
Showing 3 changed files
... ...
@@ -22,13 +22,22 @@ func (daemon *Daemon) postRunProcessing(container *container.Container, e libcon
22 22
 			return err
23 23
 		}
24 24
 
25
-		servicingOption := &libcontainerd.ServicingOption{
25
+		newOpts := []libcontainerd.CreateOption{&libcontainerd.ServicingOption{
26 26
 			IsServicing: true,
27
+		}}
28
+
29
+		copts, err := daemon.getLibcontainerdCreateOptions(container)
30
+		if err != nil {
31
+			return err
32
+		}
33
+
34
+		if copts != nil {
35
+			newOpts = append(newOpts, *copts...)
27 36
 		}
28 37
 
29 38
 		// Create a new servicing container, which will start, complete the update, and merge back the
30 39
 		// results if it succeeded, all as part of the below function call.
31
-		if err := daemon.containerd.Create((container.ID + "_servicing"), "", "", *spec, servicingOption); err != nil {
40
+		if err := daemon.containerd.Create((container.ID + "_servicing"), "", "", *spec, newOpts...); err != nil {
32 41
 			container.SetExitCode(-1)
33 42
 			return fmt.Errorf("Post-run update servicing failed: %s", err)
34 43
 		}
... ...
@@ -30,10 +30,10 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain
30 30
 	}
31 31
 	if hvOpts.IsHyperV {
32 32
 		hvOpts.SandboxPath = filepath.Dir(m["dir"])
33
-	} else {
34
-		layerOpts.LayerFolderPath = m["dir"]
35 33
 	}
36 34
 
35
+	layerOpts.LayerFolderPath = m["dir"]
36
+
37 37
 	// Generate the layer paths of the layer options
38 38
 	img, err := daemon.imageStore.Get(container.ImageID)
39 39
 	if err != nil {
... ...
@@ -40,15 +40,15 @@ const defaultOwner = "docker"
40 40
 // Create is the entrypoint to create a container from a spec, and if successfully
41 41
 // created, start it too. Table below shows the fields required for HCS JSON calling parameters,
42 42
 // where if not populated, is omitted.
43
-// +-----------------+--------------------------------------------+--------------------------------------------+
44
-// |                 | Isolation=Process                          | Isolation=Hyper-V                          |
45
-// +-----------------+--------------------------------------------+--------------------------------------------+
46
-// | VolumePath      | \\?\\Volume{GUIDa}                         |                                            |
47
-// | LayerFolderPath | %root%\windowsfilter\containerID           |                                            |
48
-// | Layers[]        | ID=GUIDb;Path=%root%\windowsfilter\layerID | ID=GUIDb;Path=%root%\windowsfilter\layerID |
49
-// | SandboxPath     |                                            | %root%\windowsfilter                       |
50
-// | HvRuntime       |                                            | ImagePath=%root%\BaseLayerID\UtilityVM     |
51
-// +-----------------+--------------------------------------------+--------------------------------------------+
43
+// +-----------------+--------------------------------------------+---------------------------------------------------+
44
+// |                 | Isolation=Process                          | Isolation=Hyper-V                                 |
45
+// +-----------------+--------------------------------------------+---------------------------------------------------+
46
+// | VolumePath      | \\?\\Volume{GUIDa}                         |                                                   |
47
+// | LayerFolderPath | %root%\windowsfilter\containerID           | %root%\windowsfilter\containerID (servicing only) |
48
+// | Layers[]        | ID=GUIDb;Path=%root%\windowsfilter\layerID | ID=GUIDb;Path=%root%\windowsfilter\layerID        |
49
+// | SandboxPath     |                                            | %root%\windowsfilter                              |
50
+// | HvRuntime       |                                            | ImagePath=%root%\BaseLayerID\UtilityVM            |
51
+// +-----------------+--------------------------------------------+---------------------------------------------------+
52 52
 //
53 53
 // Isolation=Process example:
54 54
 //
... ...
@@ -170,9 +170,10 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir
170 170
 		}
171 171
 	} else {
172 172
 		configuration.VolumePath = spec.Root.Path
173
-		configuration.LayerFolderPath = layerOpt.LayerFolderPath
174 173
 	}
175 174
 
175
+	configuration.LayerFolderPath = layerOpt.LayerFolderPath
176
+
176 177
 	for _, layerPath := range layerOpt.LayerPaths {
177 178
 		_, filename := filepath.Split(layerPath)
178 179
 		g, err := hcsshim.NameToGuid(filename)