Signed-off-by: John Howard <jhoward@microsoft.com>
| ... | ... |
@@ -136,7 +136,7 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
|
| 136 | 136 |
LayerFolder: layerFolder, |
| 137 | 137 |
LayerPaths: layerPaths, |
| 138 | 138 |
Hostname: c.Config.Hostname, |
| 139 |
- Isolated: c.hostConfig.Isolation.IsHyperV(), |
|
| 139 |
+ Isolation: c.hostConfig.Isolation, |
|
| 140 | 140 |
} |
| 141 | 141 |
|
| 142 | 142 |
return nil |
| ... | ... |
@@ -1,6 +1,9 @@ |
| 1 | 1 |
package execdriver |
| 2 | 2 |
|
| 3 |
-import "github.com/docker/docker/pkg/nat" |
|
| 3 |
+import ( |
|
| 4 |
+ "github.com/docker/docker/pkg/nat" |
|
| 5 |
+ "github.com/docker/docker/runconfig" |
|
| 6 |
+) |
|
| 4 | 7 |
|
| 5 | 8 |
// Mount contains information for a mount operation. |
| 6 | 9 |
type Mount struct {
|
| ... | ... |
@@ -40,11 +43,11 @@ type Command struct {
|
| 40 | 40 |
|
| 41 | 41 |
// Fields below here are platform specific |
| 42 | 42 |
|
| 43 |
- FirstStart bool `json:"first_start"` // Optimisation for first boot of Windows |
|
| 44 |
- Hostname string `json:"hostname"` // Windows sets the hostname in the execdriver |
|
| 45 |
- LayerFolder string `json:"layer_folder"` // Layer folder for a command |
|
| 46 |
- LayerPaths []string `json:"layer_paths"` // Layer paths for a command |
|
| 47 |
- Isolated bool `json:"isolated"` // True if a Hyper-V container |
|
| 43 |
+ FirstStart bool `json:"first_start"` // Optimisation for first boot of Windows |
|
| 44 |
+ Hostname string `json:"hostname"` // Windows sets the hostname in the execdriver |
|
| 45 |
+ LayerFolder string `json:"layer_folder"` // Layer folder for a command |
|
| 46 |
+ LayerPaths []string `json:"layer_paths"` // Layer paths for a command |
|
| 47 |
+ Isolation runconfig.IsolationLevel `json:"isolation"` // Isolation level for the container |
|
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 | 50 |
// ExitStatus provides exit reasons for a container. |
| ... | ... |
@@ -2,18 +2,23 @@ |
| 2 | 2 |
|
| 3 | 3 |
package windows |
| 4 | 4 |
|
| 5 |
-import "github.com/docker/docker/daemon/execdriver" |
|
| 5 |
+import ( |
|
| 6 |
+ "github.com/docker/docker/daemon/execdriver" |
|
| 7 |
+ "github.com/docker/docker/runconfig" |
|
| 8 |
+) |
|
| 6 | 9 |
|
| 7 | 10 |
type info struct {
|
| 8 |
- ID string |
|
| 9 |
- driver *Driver |
|
| 11 |
+ ID string |
|
| 12 |
+ driver *Driver |
|
| 13 |
+ isolation runconfig.IsolationLevel |
|
| 10 | 14 |
} |
| 11 | 15 |
|
| 12 | 16 |
// Info implements the exec driver Driver interface. |
| 13 | 17 |
func (d *Driver) Info(id string) execdriver.Info {
|
| 14 | 18 |
return &info{
|
| 15 |
- ID: id, |
|
| 16 |
- driver: d, |
|
| 19 |
+ ID: id, |
|
| 20 |
+ driver: d, |
|
| 21 |
+ isolation: defaultIsolation, |
|
| 17 | 22 |
} |
| 18 | 23 |
} |
| 19 | 24 |
|
| ... | ... |
@@ -110,10 +110,18 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd |
| 110 | 110 |
LayerFolderPath: c.LayerFolder, |
| 111 | 111 |
ProcessorWeight: c.Resources.CPUShares, |
| 112 | 112 |
HostName: c.Hostname, |
| 113 |
- HvPartition: c.Isolated, |
|
| 114 | 113 |
} |
| 115 | 114 |
|
| 116 |
- if c.Isolated {
|
|
| 115 |
+ // Work out the isolation (whether it is a hypervisor partition) |
|
| 116 |
+ if c.Isolation.IsDefault() {
|
|
| 117 |
+ // Not specified by caller. Take daemon default |
|
| 118 |
+ cu.HvPartition = defaultIsolation.IsHyperV() |
|
| 119 |
+ } else {
|
|
| 120 |
+ // Take value specified by caller |
|
| 121 |
+ cu.HvPartition = c.Isolation.IsHyperV() |
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ if cu.HvPartition {
|
|
| 117 | 125 |
cu.SandboxPath = filepath.Dir(c.LayerFolder) |
| 118 | 126 |
} else {
|
| 119 | 127 |
cu.VolumePath = c.Rootfs |
| ... | ... |
@@ -11,6 +11,7 @@ import ( |
| 11 | 11 |
"github.com/docker/docker/autogen/dockerversion" |
| 12 | 12 |
"github.com/docker/docker/daemon/execdriver" |
| 13 | 13 |
"github.com/docker/docker/pkg/parsers" |
| 14 |
+ "github.com/docker/docker/runconfig" |
|
| 14 | 15 |
) |
| 15 | 16 |
|
| 16 | 17 |
// This is a daemon development variable only and should not be |
| ... | ... |
@@ -21,6 +22,12 @@ var dummyMode bool |
| 21 | 21 |
// This allows the daemon to force kill (HCS terminate) rather than shutdown |
| 22 | 22 |
var forceKill bool |
| 23 | 23 |
|
| 24 |
+// defaultIsolation allows users to specify a default isolation mode for |
|
| 25 |
+// when running a container on Windows. For example docker daemon -D |
|
| 26 |
+// --exec-opt isolation=hyperv will cause Windows to always run containers |
|
| 27 |
+// as Hyper-V containers unless otherwise specified. |
|
| 28 |
+var defaultIsolation runconfig.IsolationLevel = "process" |
|
| 29 |
+ |
|
| 24 | 30 |
// Define name and version for windows |
| 25 | 31 |
var ( |
| 26 | 32 |
DriverName = "Windows 1854" |
| ... | ... |
@@ -42,7 +49,7 @@ type Driver struct {
|
| 42 | 42 |
|
| 43 | 43 |
// Name implements the exec driver Driver interface. |
| 44 | 44 |
func (d *Driver) Name() string {
|
| 45 |
- return fmt.Sprintf("%s %s", DriverName, Version)
|
|
| 45 |
+ return fmt.Sprintf("\n Name: %s\n Build: %s \n Default Isolation: %s", DriverName, Version, defaultIsolation)
|
|
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 | 48 |
// NewDriver returns a new windows driver, called from NewDriver of execdriver. |
| ... | ... |
@@ -70,6 +77,14 @@ func NewDriver(root, initPath string, options []string) (*Driver, error) {
|
| 70 | 70 |
logrus.Warn("Using force kill mode in Windows exec driver. This is for testing purposes only.")
|
| 71 | 71 |
} |
| 72 | 72 |
|
| 73 |
+ case "isolation": |
|
| 74 |
+ if !runconfig.IsolationLevel(val).IsValid() {
|
|
| 75 |
+ return nil, fmt.Errorf("Unrecognised exec driver option 'isolation':'%s'", val)
|
|
| 76 |
+ } |
|
| 77 |
+ if runconfig.IsolationLevel(val).IsHyperV() {
|
|
| 78 |
+ defaultIsolation = "hyperv" |
|
| 79 |
+ } |
|
| 80 |
+ logrus.Infof("Windows default isolation level: '%s'", val)
|
|
| 73 | 81 |
default: |
| 74 | 82 |
return nil, fmt.Errorf("Unrecognised exec driver option %s\n", key)
|
| 75 | 83 |
} |
| ... | ... |
@@ -117,7 +117,7 @@ Query Parameters: |
| 117 | 117 |
- `exited=<int>`; -- containers with exit code of `<int>` ; |
| 118 | 118 |
- `status=`(`created`|`restarting`|`running`|`paused`|`exited`) |
| 119 | 119 |
- `label=key` or `label="key=value"` of a container label |
| 120 |
- - `isolation=`(`default`|`hyperv`) (Windows daemon only) |
|
| 120 |
+ - `isolation=`(`default`|`process`|`hyperv`) (Windows daemon only) |
|
| 121 | 121 |
|
| 122 | 122 |
Status Codes: |
| 123 | 123 |
|
| ... | ... |
@@ -51,7 +51,7 @@ The currently supported filters are: |
| 51 | 51 |
* exited (int - the code of exited containers. Only useful with `--all`) |
| 52 | 52 |
* status (created|restarting|running|paused|exited) |
| 53 | 53 |
* ancestor (`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`) - filters containers that were created from the given image or a descendant. |
| 54 |
-* isolation (default|hyperv) (Windows daemon only) |
|
| 54 |
+* isolation (default|process|hyperv) (Windows daemon only) |
|
| 55 | 55 |
|
| 56 | 56 |
|
| 57 | 57 |
#### Label |
| ... | ... |
@@ -10,15 +10,19 @@ func (n NetworkMode) IsDefault() bool {
|
| 10 | 10 |
return n == "default" |
| 11 | 11 |
} |
| 12 | 12 |
|
| 13 |
-// IsHyperV indicates the use of Hyper-V Containers for isolation (as opposed |
|
| 14 |
-// to Windows Server Containers |
|
| 13 |
+// IsHyperV indicates the use of a Hyper-V partition for isolation |
|
| 15 | 14 |
func (i IsolationLevel) IsHyperV() bool {
|
| 16 | 15 |
return strings.ToLower(string(i)) == "hyperv" |
| 17 | 16 |
} |
| 18 | 17 |
|
| 18 |
+// IsProcess indicates the use of process isolation |
|
| 19 |
+func (i IsolationLevel) IsProcess() bool {
|
|
| 20 |
+ return strings.ToLower(string(i)) == "process" |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 19 | 23 |
// IsValid indicates is an isolation level is valid |
| 20 | 24 |
func (i IsolationLevel) IsValid() bool {
|
| 21 |
- return i.IsDefault() || i.IsHyperV() |
|
| 25 |
+ return i.IsDefault() || i.IsHyperV() || i.IsProcess() |
|
| 22 | 26 |
} |
| 23 | 27 |
|
| 24 | 28 |
// DefaultDaemonNetworkMode returns the default network stack the daemon should |
| ... | ... |
@@ -67,15 +71,14 @@ func ValidateNetMode(c *Config, hc *HostConfig) error {
|
| 67 | 67 |
|
| 68 | 68 |
// ValidateIsolationLevel performs platform specific validation of the |
| 69 | 69 |
// isolation level in the hostconfig structure. Windows supports 'default' (or |
| 70 |
-// blank), and 'hyperv'. These refer to Windows Server Containers and |
|
| 71 |
-// Hyper-V Containers respectively. |
|
| 70 |
+// blank), 'process', or 'hyperv'. |
|
| 72 | 71 |
func ValidateIsolationLevel(hc *HostConfig) error {
|
| 73 | 72 |
// We may not be passed a host config, such as in the case of docker commit |
| 74 | 73 |
if hc == nil {
|
| 75 | 74 |
return nil |
| 76 | 75 |
} |
| 77 | 76 |
if !hc.Isolation.IsValid() {
|
| 78 |
- return fmt.Errorf("invalid --isolation: %q. Windows supports 'default' (Windows Server Container) or 'hyperv' (Hyper-V Container)", hc.Isolation)
|
|
| 77 |
+ return fmt.Errorf("invalid --isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation)
|
|
| 79 | 78 |
} |
| 80 | 79 |
return nil |
| 81 | 80 |
} |