Browse code

Windows: Add default isolation exec driver option

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

John Howard authored on 2015/11/01 11:16:58
Showing 8 changed files
... ...
@@ -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
 }