Browse code

Add --device support for Windows

Implements the --device forwarding for Windows daemons. This maps the physical
device into the container at runtime.

Ex:

docker run --device="class/<clsid>" <image> <cmd>

Signed-off-by: Justin Terry (VM) <juterry@microsoft.com>

Justin Terry (VM) authored on 2018/07/17 07:19:11
Showing 4 changed files
... ...
@@ -332,6 +332,30 @@ func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.S
332 332
 		s.Windows.CredentialSpec = cs
333 333
 	}
334 334
 
335
+	// Do we have any assigned devices?
336
+	if len(c.HostConfig.Devices) > 0 {
337
+		if isHyperV {
338
+			return errors.New("device assignment is not supported for HyperV containers")
339
+		}
340
+		if system.GetOSVersion().Build < 17763 {
341
+			return errors.New("device assignment requires Windows builds RS5 (17763+) or later")
342
+		}
343
+		for _, deviceMapping := range c.HostConfig.Devices {
344
+			srcParts := strings.SplitN(deviceMapping.PathOnHost, "/", 2)
345
+			if len(srcParts) != 2 {
346
+				return errors.New("invalid device assignment path")
347
+			}
348
+			if srcParts[0] != "class" {
349
+				return errors.Errorf("invalid device assignment type: '%s' should be 'class'", srcParts[0])
350
+			}
351
+			wd := specs.WindowsDevice{
352
+				ID:     srcParts[1],
353
+				IDType: srcParts[0],
354
+			}
355
+			s.Windows.Devices = append(s.Windows.Devices, wd)
356
+		}
357
+	}
358
+
335 359
 	return nil
336 360
 }
337 361
 
... ...
@@ -326,6 +326,19 @@ func (c *client) createWindows(id string, spec *specs.Spec, runtimeOptions inter
326 326
 	}
327 327
 	configuration.MappedPipes = mps
328 328
 
329
+	if len(spec.Windows.Devices) > 0 {
330
+		// Add any device assignments
331
+		if configuration.HvPartition {
332
+			return errors.New("device assignment is not supported for HyperV containers")
333
+		}
334
+		if system.GetOSVersion().Build < 17763 { // RS5
335
+			return errors.New("device assignment requires Windows builds RS5 (17763+) or later")
336
+		}
337
+		for _, d := range spec.Windows.Devices {
338
+			configuration.AssignedDevices = append(configuration.AssignedDevices, hcsshim.AssignedDevice{InterfaceClassGUID: d.ID})
339
+		}
340
+	}
341
+
329 342
 	hcsContainer, err := hcsshim.CreateContainer(id, configuration)
330 343
 	if err != nil {
331 344
 		return err
... ...
@@ -1,6 +1,6 @@
1 1
 # the following lines are in sorted order, FYI
2 2
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
3
-github.com/Microsoft/hcsshim v0.7.12
3
+github.com/Microsoft/hcsshim v0.7.12-1
4 4
 github.com/Microsoft/go-winio v0.4.11
5 5
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
6 6
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
... ...
@@ -17,6 +17,11 @@ type MappedPipe = schema1.MappedPipe
17 17
 type HvRuntime = schema1.HvRuntime
18 18
 type MappedVirtualDisk = schema1.MappedVirtualDisk
19 19
 
20
+// AssignedDevice represents a device that has been directly assigned to a container
21
+//
22
+// NOTE: Support added in RS5
23
+type AssignedDevice = schema1.AssignedDevice
24
+
20 25
 // ContainerConfig is used as both the input of CreateContainer
21 26
 // and to convert the parameters to JSON for passing onto the HCS
22 27
 type ContainerConfig = schema1.ContainerConfig