From 443a75d5f66e986e9d7740d3f2aaef080aef8ea0 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 21 Mar 2014 00:10:24 +0000 Subject: [PATCH] Allow caps to be toggled in native driver with plugin flag Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- pkg/libcontainer/capabilities/capabilities.go | 4 +- pkg/libcontainer/types.go | 41 +++++++++++-------- runtime/execdriver/native/default_template.go | 31 ++++++++++++++ runtime/execdriver/native/driver.go | 12 ------ 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/pkg/libcontainer/capabilities/capabilities.go b/pkg/libcontainer/capabilities/capabilities.go index fbf73538e0..4b81e708c7 100644 --- a/pkg/libcontainer/capabilities/capabilities.go +++ b/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 } diff --git a/pkg/libcontainer/types.go b/pkg/libcontainer/types.go index 87346348bc..7751e850b6 100644 --- a/pkg/libcontainer/types.go +++ b/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 } diff --git a/runtime/execdriver/native/default_template.go b/runtime/execdriver/native/default_template.go index d744ab382f..d47a5eb8cd 100644 --- a/runtime/execdriver/native/default_template.go +++ b/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: +// 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 { diff --git a/runtime/execdriver/native/driver.go b/runtime/execdriver/native/driver.go index 0a09d324db..0d9297191c 100644 --- a/runtime/execdriver/native/driver.go +++ b/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, "=")