Browse code

LCOW: Remove hard-coding

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2017/08/02 03:57:50
Showing 5 changed files
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"github.com/docker/docker/container"
10 10
 	"github.com/docker/docker/layer"
11 11
 	"github.com/docker/docker/libcontainerd"
12
+	"github.com/jhowardmsft/opengcs/gogcs/client"
12 13
 	"golang.org/x/sys/windows/registry"
13 14
 )
14 15
 
... ...
@@ -142,6 +143,36 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain
142 142
 		}
143 143
 	}
144 144
 
145
+	// LCOW options.
146
+	if container.Platform == "linux" {
147
+		config := &client.Config{}
148
+		if err := config.GenerateDefault(daemon.configStore.GraphOptions); err != nil {
149
+			return nil, err
150
+		}
151
+		// Override from user-supplied options.
152
+		for k, v := range container.HostConfig.StorageOpt {
153
+			switch k {
154
+			case "lcow.kirdpath":
155
+				config.KirdPath = v
156
+			case "lcow.kernel":
157
+				config.KernelFile = v
158
+			case "lcow.initrd":
159
+				config.InitrdFile = v
160
+			case "lcow.vhdx":
161
+				config.Vhdx = v
162
+			case "lcow.bootparameters":
163
+				config.BootParameters = v
164
+			}
165
+		}
166
+		if err := config.Validate(); err != nil {
167
+			return nil, err
168
+		}
169
+		lcowOpts := &libcontainerd.LCOWOption{
170
+			Config: config,
171
+		}
172
+		createOptions = append(createOptions, lcowOpts)
173
+	}
174
+
145 175
 	// Now add the remaining options.
146 176
 	createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore})
147 177
 	createOptions = append(createOptions, hvOpts)
... ...
@@ -16,6 +16,7 @@ import (
16 16
 
17 17
 	"github.com/Microsoft/hcsshim"
18 18
 	"github.com/docker/docker/pkg/sysinfo"
19
+	opengcs "github.com/jhowardmsft/opengcs/gogcs/client"
19 20
 	specs "github.com/opencontainers/runtime-spec/specs-go"
20 21
 	"github.com/sirupsen/logrus"
21 22
 )
... ...
@@ -289,8 +290,20 @@ func (clnt *client) createWindows(containerID string, checkpoint string, checkpo
289 289
 func (clnt *client) createLinux(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
290 290
 	logrus.Debugf("libcontainerd: createLinux(): containerId %s ", containerID)
291 291
 
292
-	// TODO @jhowardmsft LCOW Support: This needs to be configurable, not hard-coded.
293
-	// However, good-enough for the LCOW bring-up.
292
+	var layerOpt *LayerOption
293
+	var lcowOpt *LCOWOption
294
+	for _, option := range options {
295
+		if layer, ok := option.(*LayerOption); ok {
296
+			layerOpt = layer
297
+		}
298
+		if lcow, ok := option.(*LCOWOption); ok {
299
+			lcowOpt = lcow
300
+		}
301
+	}
302
+	if lcowOpt == nil || lcowOpt.Config == nil {
303
+		return fmt.Errorf("lcow option must be supplied to the runtime")
304
+	}
305
+
294 306
 	configuration := &hcsshim.ContainerConfig{
295 307
 		HvPartition:   true,
296 308
 		Name:          containerID,
... ...
@@ -298,17 +311,18 @@ func (clnt *client) createLinux(containerID string, checkpoint string, checkpoin
298 298
 		ContainerType: "linux",
299 299
 		Owner:         defaultOwner,
300 300
 		TerminateOnLastHandleClosed: true,
301
-		HvRuntime: &hcsshim.HvRuntime{
302
-			ImagePath:       `c:\Program Files\Linux Containers`,
303
-			LinuxKernelFile: `bootx64.efi`,
304
-			LinuxInitrdFile: `initrd.img`,
305
-		},
306 301
 	}
307 302
 
308
-	var layerOpt *LayerOption
309
-	for _, option := range options {
310
-		if l, ok := option.(*LayerOption); ok {
311
-			layerOpt = l
303
+	if lcowOpt.Config.ActualMode == opengcs.ModeActualVhdx {
304
+		configuration.HvRuntime = &hcsshim.HvRuntime{
305
+			ImagePath: lcowOpt.Config.Vhdx,
306
+		}
307
+	} else {
308
+		configuration.HvRuntime = &hcsshim.HvRuntime{
309
+			ImagePath:           lcowOpt.Config.KirdPath,
310
+			LinuxKernelFile:     lcowOpt.Config.KernelFile,
311
+			LinuxInitrdFile:     lcowOpt.Config.InitrdFile,
312
+			LinuxBootParameters: lcowOpt.Config.BootParameters,
312 313
 		}
313 314
 	}
314 315
 
... ...
@@ -9,7 +9,6 @@ import (
9 9
 	"time"
10 10
 
11 11
 	"github.com/Microsoft/hcsshim"
12
-	"github.com/docker/docker/pkg/system"
13 12
 	"github.com/opencontainers/runtime-spec/specs-go"
14 13
 	"github.com/sirupsen/logrus"
15 14
 	"golang.org/x/sys/windows"
... ...
@@ -89,8 +88,8 @@ func (ctr *container) start(attachStdio StdioCallback) error {
89 89
 	}
90 90
 	createProcessParms.User = ctr.ociSpec.Process.User.Username
91 91
 
92
-	// LCOW requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM.
93
-	if system.LCOWSupported() && ctr.ociSpec.Platform.OS == "linux" {
92
+	// Linux containers requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM.
93
+	if ctr.ociSpec.Platform.OS == "linux" {
94 94
 		ociBuf, err := json.Marshal(ctr.ociSpec)
95 95
 		if err != nil {
96 96
 			return err
... ...
@@ -2,6 +2,7 @@ package libcontainerd
2 2
 
3 3
 import (
4 4
 	"github.com/Microsoft/hcsshim"
5
+	opengcs "github.com/jhowardmsft/opengcs/gogcs/client"
5 6
 	"github.com/opencontainers/runtime-spec/specs-go"
6 7
 )
7 8
 
... ...
@@ -25,6 +26,11 @@ type Stats hcsshim.Statistics
25 25
 // Resources defines updatable container resource values.
26 26
 type Resources struct{}
27 27
 
28
+// LCOWOption is a CreateOption required for LCOW configuration
29
+type LCOWOption struct {
30
+	Config *opengcs.Config
31
+}
32
+
28 33
 // ServicingOption is a CreateOption with a no-op application that signifies
29 34
 // the container needs to be used for a Windows servicing operation.
30 35
 type ServicingOption struct {
... ...
@@ -44,3 +44,8 @@ func (s *NetworkEndpointsOption) Apply(interface{}) error {
44 44
 func (s *CredentialsOption) Apply(interface{}) error {
45 45
 	return nil
46 46
 }
47
+
48
+// Apply for the LCOW option is a no-op.
49
+func (s *LCOWOption) Apply(interface{}) error {
50
+	return nil
51
+}