From a429ad1e35691fb01f3f80461964030d2197a0eb Mon Sep 17 00:00:00 2001 From: John Howard Date: Sat, 31 Oct 2015 19:16:58 -0700 Subject: [PATCH] Windows: Add default isolation exec driver option Signed-off-by: John Howard --- daemon/container_windows.go | 2 +- daemon/execdriver/driver_windows.go | 15 +++++++++------ daemon/execdriver/windows/info.go | 15 ++++++++++----- daemon/execdriver/windows/run.go | 12 ++++++++++-- daemon/execdriver/windows/windows.go | 17 ++++++++++++++++- docs/reference/api/docker_remote_api_v1.22.md | 2 +- docs/reference/commandline/ps.md | 2 +- runconfig/hostconfig_windows.go | 15 +++++++++------ 8 files changed, 57 insertions(+), 23 deletions(-) diff --git a/daemon/container_windows.go b/daemon/container_windows.go index fd2dcb9bdf..5a73d2f6b4 100644 --- a/daemon/container_windows.go +++ b/daemon/container_windows.go @@ -136,7 +136,7 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error { LayerFolder: layerFolder, LayerPaths: layerPaths, Hostname: c.Config.Hostname, - Isolated: c.hostConfig.Isolation.IsHyperV(), + Isolation: c.hostConfig.Isolation, } return nil diff --git a/daemon/execdriver/driver_windows.go b/daemon/execdriver/driver_windows.go index 1336ba97f0..033051328b 100644 --- a/daemon/execdriver/driver_windows.go +++ b/daemon/execdriver/driver_windows.go @@ -1,6 +1,9 @@ package execdriver -import "github.com/docker/docker/pkg/nat" +import ( + "github.com/docker/docker/pkg/nat" + "github.com/docker/docker/runconfig" +) // Mount contains information for a mount operation. type Mount struct { @@ -40,11 +43,11 @@ type Command struct { // Fields below here are platform specific - FirstStart bool `json:"first_start"` // Optimisation for first boot of Windows - Hostname string `json:"hostname"` // Windows sets the hostname in the execdriver - LayerFolder string `json:"layer_folder"` // Layer folder for a command - LayerPaths []string `json:"layer_paths"` // Layer paths for a command - Isolated bool `json:"isolated"` // True if a Hyper-V container + FirstStart bool `json:"first_start"` // Optimisation for first boot of Windows + Hostname string `json:"hostname"` // Windows sets the hostname in the execdriver + LayerFolder string `json:"layer_folder"` // Layer folder for a command + LayerPaths []string `json:"layer_paths"` // Layer paths for a command + Isolation runconfig.IsolationLevel `json:"isolation"` // Isolation level for the container } // ExitStatus provides exit reasons for a container. diff --git a/daemon/execdriver/windows/info.go b/daemon/execdriver/windows/info.go index 2a16d5607d..c85cd8a299 100644 --- a/daemon/execdriver/windows/info.go +++ b/daemon/execdriver/windows/info.go @@ -2,18 +2,23 @@ package windows -import "github.com/docker/docker/daemon/execdriver" +import ( + "github.com/docker/docker/daemon/execdriver" + "github.com/docker/docker/runconfig" +) type info struct { - ID string - driver *Driver + ID string + driver *Driver + isolation runconfig.IsolationLevel } // Info implements the exec driver Driver interface. func (d *Driver) Info(id string) execdriver.Info { return &info{ - ID: id, - driver: d, + ID: id, + driver: d, + isolation: defaultIsolation, } } diff --git a/daemon/execdriver/windows/run.go b/daemon/execdriver/windows/run.go index 058109f2ef..44ab82258f 100644 --- a/daemon/execdriver/windows/run.go +++ b/daemon/execdriver/windows/run.go @@ -110,10 +110,18 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd LayerFolderPath: c.LayerFolder, ProcessorWeight: c.Resources.CPUShares, HostName: c.Hostname, - HvPartition: c.Isolated, } - if c.Isolated { + // Work out the isolation (whether it is a hypervisor partition) + if c.Isolation.IsDefault() { + // Not specified by caller. Take daemon default + cu.HvPartition = defaultIsolation.IsHyperV() + } else { + // Take value specified by caller + cu.HvPartition = c.Isolation.IsHyperV() + } + + if cu.HvPartition { cu.SandboxPath = filepath.Dir(c.LayerFolder) } else { cu.VolumePath = c.Rootfs diff --git a/daemon/execdriver/windows/windows.go b/daemon/execdriver/windows/windows.go index a1f4f48ae3..cce3e390b1 100644 --- a/daemon/execdriver/windows/windows.go +++ b/daemon/execdriver/windows/windows.go @@ -11,6 +11,7 @@ import ( "github.com/docker/docker/autogen/dockerversion" "github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/pkg/parsers" + "github.com/docker/docker/runconfig" ) // This is a daemon development variable only and should not be @@ -21,6 +22,12 @@ var dummyMode bool // This allows the daemon to force kill (HCS terminate) rather than shutdown var forceKill bool +// defaultIsolation allows users to specify a default isolation mode for +// when running a container on Windows. For example docker daemon -D +// --exec-opt isolation=hyperv will cause Windows to always run containers +// as Hyper-V containers unless otherwise specified. +var defaultIsolation runconfig.IsolationLevel = "process" + // Define name and version for windows var ( DriverName = "Windows 1854" @@ -42,7 +49,7 @@ type Driver struct { // Name implements the exec driver Driver interface. func (d *Driver) Name() string { - return fmt.Sprintf("%s %s", DriverName, Version) + return fmt.Sprintf("\n Name: %s\n Build: %s \n Default Isolation: %s", DriverName, Version, defaultIsolation) } // NewDriver returns a new windows driver, called from NewDriver of execdriver. @@ -70,6 +77,14 @@ func NewDriver(root, initPath string, options []string) (*Driver, error) { logrus.Warn("Using force kill mode in Windows exec driver. This is for testing purposes only.") } + case "isolation": + if !runconfig.IsolationLevel(val).IsValid() { + return nil, fmt.Errorf("Unrecognised exec driver option 'isolation':'%s'", val) + } + if runconfig.IsolationLevel(val).IsHyperV() { + defaultIsolation = "hyperv" + } + logrus.Infof("Windows default isolation level: '%s'", val) default: return nil, fmt.Errorf("Unrecognised exec driver option %s\n", key) } diff --git a/docs/reference/api/docker_remote_api_v1.22.md b/docs/reference/api/docker_remote_api_v1.22.md index 938a3dd4a7..f52d929720 100644 --- a/docs/reference/api/docker_remote_api_v1.22.md +++ b/docs/reference/api/docker_remote_api_v1.22.md @@ -117,7 +117,7 @@ Query Parameters: - `exited=`; -- containers with exit code of `` ; - `status=`(`created`|`restarting`|`running`|`paused`|`exited`) - `label=key` or `label="key=value"` of a container label - - `isolation=`(`default`|`hyperv`) (Windows daemon only) + - `isolation=`(`default`|`process`|`hyperv`) (Windows daemon only) Status Codes: diff --git a/docs/reference/commandline/ps.md b/docs/reference/commandline/ps.md index 9298bf4cf4..b10ad49c9e 100644 --- a/docs/reference/commandline/ps.md +++ b/docs/reference/commandline/ps.md @@ -51,7 +51,7 @@ The currently supported filters are: * exited (int - the code of exited containers. Only useful with `--all`) * status (created|restarting|running|paused|exited) * ancestor (`[:]`, `` or ``) - filters containers that were created from the given image or a descendant. -* isolation (default|hyperv) (Windows daemon only) +* isolation (default|process|hyperv) (Windows daemon only) #### Label diff --git a/runconfig/hostconfig_windows.go b/runconfig/hostconfig_windows.go index dbdb1683a0..211c93b281 100644 --- a/runconfig/hostconfig_windows.go +++ b/runconfig/hostconfig_windows.go @@ -10,15 +10,19 @@ func (n NetworkMode) IsDefault() bool { return n == "default" } -// IsHyperV indicates the use of Hyper-V Containers for isolation (as opposed -// to Windows Server Containers +// IsHyperV indicates the use of a Hyper-V partition for isolation func (i IsolationLevel) IsHyperV() bool { return strings.ToLower(string(i)) == "hyperv" } +// IsProcess indicates the use of process isolation +func (i IsolationLevel) IsProcess() bool { + return strings.ToLower(string(i)) == "process" +} + // IsValid indicates is an isolation level is valid func (i IsolationLevel) IsValid() bool { - return i.IsDefault() || i.IsHyperV() + return i.IsDefault() || i.IsHyperV() || i.IsProcess() } // DefaultDaemonNetworkMode returns the default network stack the daemon should @@ -67,15 +71,14 @@ func ValidateNetMode(c *Config, hc *HostConfig) error { // ValidateIsolationLevel performs platform specific validation of the // isolation level in the hostconfig structure. Windows supports 'default' (or -// blank), and 'hyperv'. These refer to Windows Server Containers and -// Hyper-V Containers respectively. +// blank), 'process', or 'hyperv'. func ValidateIsolationLevel(hc *HostConfig) error { // We may not be passed a host config, such as in the case of docker commit if hc == nil { return nil } if !hc.Isolation.IsValid() { - return fmt.Errorf("invalid --isolation: %q. Windows supports 'default' (Windows Server Container) or 'hyperv' (Hyper-V Container)", hc.Isolation) + return fmt.Errorf("invalid --isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation) } return nil }