Просмотр исходного кода

lcow: Allow the client to add device cgroup rules

Signed-off-by: John Starks <jostarks@microsoft.com>
John Starks 7 лет назад
Родитель
Сommit
e9268d9642
3 измененных файлов с 56 добавлено и 39 удалено
  1. 47 0
      daemon/oci.go
  2. 4 39
      daemon/oci_linux.go
  3. 5 0
      daemon/oci_windows.go

+ 47 - 0
daemon/oci.go

@@ -1,11 +1,20 @@
 package daemon // import "github.com/docker/docker/daemon"
 
 import (
+	"fmt"
+	"regexp"
+	"strconv"
+
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/caps"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 )
 
+// nolint: gosimple
+var (
+	deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$")
+)
+
 func setCapabilities(s *specs.Spec, c *container.Container) error {
 	var caplist []string
 	var err error
@@ -29,3 +38,41 @@ func setCapabilities(s *specs.Spec, c *container.Container) error {
 	}
 	return nil
 }
+
+func appendDevicePermissionsFromCgroupRules(devPermissions []specs.LinuxDeviceCgroup, rules []string) ([]specs.LinuxDeviceCgroup, error) {
+	for _, deviceCgroupRule := range rules {
+		ss := deviceCgroupRuleRegex.FindAllStringSubmatch(deviceCgroupRule, -1)
+		if len(ss[0]) != 5 {
+			return nil, fmt.Errorf("invalid device cgroup rule format: '%s'", deviceCgroupRule)
+		}
+		matches := ss[0]
+
+		dPermissions := specs.LinuxDeviceCgroup{
+			Allow:  true,
+			Type:   matches[1],
+			Access: matches[4],
+		}
+		if matches[2] == "*" {
+			major := int64(-1)
+			dPermissions.Major = &major
+		} else {
+			major, err := strconv.ParseInt(matches[2], 10, 64)
+			if err != nil {
+				return nil, fmt.Errorf("invalid major value in device cgroup rule format: '%s'", deviceCgroupRule)
+			}
+			dPermissions.Major = &major
+		}
+		if matches[3] == "*" {
+			minor := int64(-1)
+			dPermissions.Minor = &minor
+		} else {
+			minor, err := strconv.ParseInt(matches[3], 10, 64)
+			if err != nil {
+				return nil, fmt.Errorf("invalid minor value in device cgroup rule format: '%s'", deviceCgroupRule)
+			}
+			dPermissions.Minor = &minor
+		}
+		devPermissions = append(devPermissions, dPermissions)
+	}
+	return devPermissions, nil
+}

+ 4 - 39
daemon/oci_linux.go

@@ -6,7 +6,6 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
-	"regexp"
 	"sort"
 	"strconv"
 	"strings"
@@ -28,11 +27,6 @@ import (
 	"golang.org/x/sys/unix"
 )
 
-// nolint: gosimple
-var (
-	deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$")
-)
-
 func setResources(s *specs.Spec, r containertypes.Resources) error {
 	weightDevices, err := getBlkioWeightDevices(r)
 	if err != nil {
@@ -114,39 +108,10 @@ func setDevices(s *specs.Spec, c *container.Container) error {
 			devPermissions = append(devPermissions, dPermissions...)
 		}
 
-		for _, deviceCgroupRule := range c.HostConfig.DeviceCgroupRules {
-			ss := deviceCgroupRuleRegex.FindAllStringSubmatch(deviceCgroupRule, -1)
-			if len(ss[0]) != 5 {
-				return fmt.Errorf("invalid device cgroup rule format: '%s'", deviceCgroupRule)
-			}
-			matches := ss[0]
-
-			dPermissions := specs.LinuxDeviceCgroup{
-				Allow:  true,
-				Type:   matches[1],
-				Access: matches[4],
-			}
-			if matches[2] == "*" {
-				major := int64(-1)
-				dPermissions.Major = &major
-			} else {
-				major, err := strconv.ParseInt(matches[2], 10, 64)
-				if err != nil {
-					return fmt.Errorf("invalid major value in device cgroup rule format: '%s'", deviceCgroupRule)
-				}
-				dPermissions.Major = &major
-			}
-			if matches[3] == "*" {
-				minor := int64(-1)
-				dPermissions.Minor = &minor
-			} else {
-				minor, err := strconv.ParseInt(matches[3], 10, 64)
-				if err != nil {
-					return fmt.Errorf("invalid minor value in device cgroup rule format: '%s'", deviceCgroupRule)
-				}
-				dPermissions.Minor = &minor
-			}
-			devPermissions = append(devPermissions, dPermissions)
+		var err error
+		devPermissions, err = appendDevicePermissionsFromCgroupRules(devPermissions, c.HostConfig.DeviceCgroupRules)
+		if err != nil {
+			return err
 		}
 	}
 

+ 5 - 0
daemon/oci_windows.go

@@ -347,6 +347,11 @@ func (daemon *Daemon) createSpecLinuxFields(c *container.Container, s *specs.Spe
 	if err := setCapabilities(s, c); err != nil {
 		return fmt.Errorf("linux spec capabilities: %v", err)
 	}
+	devPermissions, err := appendDevicePermissionsFromCgroupRules(nil, c.HostConfig.DeviceCgroupRules)
+	if err != nil {
+		return fmt.Errorf("linux runtime spec devices: %v", err)
+	}
+	s.Linux.Resources.Devices = devPermissions
 	return nil
 }