diff --git a/daemon/start_windows.go b/daemon/start_windows.go index 74129bd612..fe8fc0e5f3 100644 --- a/daemon/start_windows.go +++ b/daemon/start_windows.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/container" "github.com/docker/docker/layer" "github.com/docker/docker/libcontainerd" + "github.com/jhowardmsft/opengcs/gogcs/client" "golang.org/x/sys/windows/registry" ) @@ -142,6 +143,36 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain } } + // LCOW options. + if container.Platform == "linux" { + config := &client.Config{} + if err := config.GenerateDefault(daemon.configStore.GraphOptions); err != nil { + return nil, err + } + // Override from user-supplied options. + for k, v := range container.HostConfig.StorageOpt { + switch k { + case "lcow.kirdpath": + config.KirdPath = v + case "lcow.kernel": + config.KernelFile = v + case "lcow.initrd": + config.InitrdFile = v + case "lcow.vhdx": + config.Vhdx = v + case "lcow.bootparameters": + config.BootParameters = v + } + } + if err := config.Validate(); err != nil { + return nil, err + } + lcowOpts := &libcontainerd.LCOWOption{ + Config: config, + } + createOptions = append(createOptions, lcowOpts) + } + // Now add the remaining options. createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore}) createOptions = append(createOptions, hvOpts) diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go index d1fd2d8f91..a12948a96d 100644 --- a/libcontainerd/client_windows.go +++ b/libcontainerd/client_windows.go @@ -16,6 +16,7 @@ import ( "github.com/Microsoft/hcsshim" "github.com/docker/docker/pkg/sysinfo" + opengcs "github.com/jhowardmsft/opengcs/gogcs/client" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -289,8 +290,20 @@ func (clnt *client) createWindows(containerID string, checkpoint string, checkpo func (clnt *client) createLinux(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error { logrus.Debugf("libcontainerd: createLinux(): containerId %s ", containerID) - // TODO @jhowardmsft LCOW Support: This needs to be configurable, not hard-coded. - // However, good-enough for the LCOW bring-up. + var layerOpt *LayerOption + var lcowOpt *LCOWOption + for _, option := range options { + if layer, ok := option.(*LayerOption); ok { + layerOpt = layer + } + if lcow, ok := option.(*LCOWOption); ok { + lcowOpt = lcow + } + } + if lcowOpt == nil || lcowOpt.Config == nil { + return fmt.Errorf("lcow option must be supplied to the runtime") + } + configuration := &hcsshim.ContainerConfig{ HvPartition: true, Name: containerID, @@ -298,17 +311,18 @@ func (clnt *client) createLinux(containerID string, checkpoint string, checkpoin ContainerType: "linux", Owner: defaultOwner, TerminateOnLastHandleClosed: true, - HvRuntime: &hcsshim.HvRuntime{ - ImagePath: `c:\Program Files\Linux Containers`, - LinuxKernelFile: `bootx64.efi`, - LinuxInitrdFile: `initrd.img`, - }, } - var layerOpt *LayerOption - for _, option := range options { - if l, ok := option.(*LayerOption); ok { - layerOpt = l + if lcowOpt.Config.ActualMode == opengcs.ModeActualVhdx { + configuration.HvRuntime = &hcsshim.HvRuntime{ + ImagePath: lcowOpt.Config.Vhdx, + } + } else { + configuration.HvRuntime = &hcsshim.HvRuntime{ + ImagePath: lcowOpt.Config.KirdPath, + LinuxKernelFile: lcowOpt.Config.KernelFile, + LinuxInitrdFile: lcowOpt.Config.InitrdFile, + LinuxBootParameters: lcowOpt.Config.BootParameters, } } diff --git a/libcontainerd/container_windows.go b/libcontainerd/container_windows.go index b29ac3c5a4..33480514e5 100644 --- a/libcontainerd/container_windows.go +++ b/libcontainerd/container_windows.go @@ -9,7 +9,6 @@ import ( "time" "github.com/Microsoft/hcsshim" - "github.com/docker/docker/pkg/system" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -89,8 +88,8 @@ func (ctr *container) start(attachStdio StdioCallback) error { } createProcessParms.User = ctr.ociSpec.Process.User.Username - // LCOW requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM. - if system.LCOWSupported() && ctr.ociSpec.Platform.OS == "linux" { + // Linux containers requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM. + if ctr.ociSpec.Platform.OS == "linux" { ociBuf, err := json.Marshal(ctr.ociSpec) if err != nil { return err diff --git a/libcontainerd/types_windows.go b/libcontainerd/types_windows.go index 317bfb0209..817a332145 100644 --- a/libcontainerd/types_windows.go +++ b/libcontainerd/types_windows.go @@ -2,6 +2,7 @@ package libcontainerd import ( "github.com/Microsoft/hcsshim" + opengcs "github.com/jhowardmsft/opengcs/gogcs/client" "github.com/opencontainers/runtime-spec/specs-go" ) @@ -25,6 +26,11 @@ type Stats hcsshim.Statistics // Resources defines updatable container resource values. type Resources struct{} +// LCOWOption is a CreateOption required for LCOW configuration +type LCOWOption struct { + Config *opengcs.Config +} + // ServicingOption is a CreateOption with a no-op application that signifies // the container needs to be used for a Windows servicing operation. type ServicingOption struct { diff --git a/libcontainerd/utils_windows.go b/libcontainerd/utils_windows.go index 41ac40d2c2..e741a296f0 100644 --- a/libcontainerd/utils_windows.go +++ b/libcontainerd/utils_windows.go @@ -44,3 +44,8 @@ func (s *NetworkEndpointsOption) Apply(interface{}) error { func (s *CredentialsOption) Apply(interface{}) error { return nil } + +// Apply for the LCOW option is a no-op. +func (s *LCOWOption) Apply(interface{}) error { + return nil +}