Browse Source

Allow caps to be toggled in native driver with plugin flag
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby 11 years ago
parent
commit
443a75d5f6

+ 3 - 1
pkg/libcontainer/capabilities/capabilities.go

@@ -27,7 +27,9 @@ func DropCapabilities(container *libcontainer.Container) error {
 func getCapabilitiesMask(container *libcontainer.Container) []capability.Cap {
 	drop := []capability.Cap{}
 	for _, c := range container.CapabilitiesMask {
-		drop = append(drop, c.Value)
+		if !c.Enabled {
+			drop = append(drop, c.Value)
+		}
 	}
 	return drop
 }

+ 23 - 18
pkg/libcontainer/types.go

@@ -18,21 +18,21 @@ var (
 	namespaceList = Namespaces{}
 
 	capabilityList = Capabilities{
-		{Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: true},
-		{Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: true},
-		{Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: true},
-		{Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: true},
-		{Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: true},
-		{Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: true},
-		{Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: true},
-		{Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: true},
-		{Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: true},
-		{Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: true},
-		{Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: true},
-		{Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: true},
-		{Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: true},
-		{Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: true},
-		{Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: true},
+		{Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: false},
+		{Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: false},
+		{Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: false},
+		{Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: false},
+		{Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: false},
+		{Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: false},
+		{Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: false},
+		{Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: false},
+		{Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: false},
+		{Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: false},
+		{Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: false},
+		{Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: false},
+		{Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: false},
+		{Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: false},
+		{Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: false},
 	}
 )
 
@@ -86,7 +86,8 @@ func (c *Capability) String() string {
 func GetCapability(key string) *Capability {
 	for _, capp := range capabilityList {
 		if capp.Key == key {
-			return capp
+			cpy := *capp
+			return &cpy
 		}
 	}
 	return nil
@@ -95,10 +96,14 @@ func GetCapability(key string) *Capability {
 // Contains returns true if the specified Capability is
 // in the slice
 func (c Capabilities) Contains(capp string) bool {
+	return c.Get(capp) != nil
+}
+
+func (c Capabilities) Get(capp string) *Capability {
 	for _, cap := range c {
 		if cap.Key == capp {
-			return true
+			return cap
 		}
 	}
-	return false
+	return nil
 }

+ 31 - 0
runtime/execdriver/native/default_template.go

@@ -6,6 +6,7 @@ import (
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/runtime/execdriver"
 	"os"
+	"strings"
 )
 
 // createContainer populates and configures the container type with the
@@ -63,9 +64,39 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
 		container.Mounts = append(container.Mounts, libcontainer.Mount{m.Source, m.Destination, m.Writable, m.Private})
 	}
 
+	configureCustomOptions(container, c.Config["native"])
+
 	return container
 }
 
+// configureCustomOptions takes string commands from the user and allows modification of the
+// container's default configuration.
+//
+// format: <key> <value>
+// i.e: cap +MKNOD cap -NET_ADMIN
+// i.e: cgroup devices.allow *:*
+func configureCustomOptions(container *libcontainer.Container, opts []string) {
+	for _, opt := range opts {
+		parts := strings.Split(strings.TrimSpace(opt), " ")
+		switch parts[0] {
+		case "cap":
+			value := strings.TrimSpace(parts[1])
+			c := container.CapabilitiesMask.Get(value[1:])
+			if c == nil {
+				continue
+			}
+			switch value[0] {
+			case '-':
+				c.Enabled = false
+			case '+':
+				c.Enabled = true
+			default:
+				// do error here
+			}
+		}
+	}
+}
+
 // getDefaultTemplate returns the docker default for
 // the libcontainer configuration file
 func getDefaultTemplate() *libcontainer.Container {

+ 0 - 12
runtime/execdriver/native/driver.go

@@ -75,9 +75,6 @@ func NewDriver(root, initPath string) (*driver, error) {
 }
 
 func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
-	if err := d.validateCommand(c); err != nil {
-		return -1, err
-	}
 	var (
 		term        nsinit.Terminal
 		container   = createContainer(c)
@@ -181,15 +178,6 @@ func (d *driver) removeContainerRoot(id string) error {
 	return os.RemoveAll(filepath.Join(d.root, id))
 }
 
-func (d *driver) validateCommand(c *execdriver.Command) error {
-	// we need to check the Config of the command to make sure that we
-	// do not have any of the lxc-conf variables
-	for _, conf := range c.Config["native"] {
-		log.Println(conf)
-	}
-	return nil
-}
-
 func getEnv(key string, env []string) string {
 	for _, pair := range env {
 		parts := strings.Split(pair, "=")