| ... | ... |
@@ -27,7 +27,9 @@ func DropCapabilities(container *libcontainer.Container) error {
|
| 27 | 27 |
func getCapabilitiesMask(container *libcontainer.Container) []capability.Cap {
|
| 28 | 28 |
drop := []capability.Cap{}
|
| 29 | 29 |
for _, c := range container.CapabilitiesMask {
|
| 30 |
- drop = append(drop, c.Value) |
|
| 30 |
+ if !c.Enabled {
|
|
| 31 |
+ drop = append(drop, c.Value) |
|
| 32 |
+ } |
|
| 31 | 33 |
} |
| 32 | 34 |
return drop |
| 33 | 35 |
} |
| ... | ... |
@@ -18,21 +18,21 @@ var ( |
| 18 | 18 |
namespaceList = Namespaces{}
|
| 19 | 19 |
|
| 20 | 20 |
capabilityList = Capabilities{
|
| 21 |
- {Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: true},
|
|
| 22 |
- {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: true},
|
|
| 23 |
- {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: true},
|
|
| 24 |
- {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: true},
|
|
| 25 |
- {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: true},
|
|
| 26 |
- {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: true},
|
|
| 27 |
- {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: true},
|
|
| 28 |
- {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: true},
|
|
| 29 |
- {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: true},
|
|
| 30 |
- {Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: true},
|
|
| 31 |
- {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: true},
|
|
| 32 |
- {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: true},
|
|
| 33 |
- {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: true},
|
|
| 34 |
- {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: true},
|
|
| 35 |
- {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: true},
|
|
| 21 |
+ {Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: false},
|
|
| 22 |
+ {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: false},
|
|
| 23 |
+ {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: false},
|
|
| 24 |
+ {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: false},
|
|
| 25 |
+ {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: false},
|
|
| 26 |
+ {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: false},
|
|
| 27 |
+ {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: false},
|
|
| 28 |
+ {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: false},
|
|
| 29 |
+ {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: false},
|
|
| 30 |
+ {Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: false},
|
|
| 31 |
+ {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: false},
|
|
| 32 |
+ {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: false},
|
|
| 33 |
+ {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: false},
|
|
| 34 |
+ {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: false},
|
|
| 35 |
+ {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: false},
|
|
| 36 | 36 |
} |
| 37 | 37 |
) |
| 38 | 38 |
|
| ... | ... |
@@ -86,7 +86,8 @@ func (c *Capability) String() string {
|
| 86 | 86 |
func GetCapability(key string) *Capability {
|
| 87 | 87 |
for _, capp := range capabilityList {
|
| 88 | 88 |
if capp.Key == key {
|
| 89 |
- return capp |
|
| 89 |
+ cpy := *capp |
|
| 90 |
+ return &cpy |
|
| 90 | 91 |
} |
| 91 | 92 |
} |
| 92 | 93 |
return nil |
| ... | ... |
@@ -95,10 +96,14 @@ func GetCapability(key string) *Capability {
|
| 95 | 95 |
// Contains returns true if the specified Capability is |
| 96 | 96 |
// in the slice |
| 97 | 97 |
func (c Capabilities) Contains(capp string) bool {
|
| 98 |
+ return c.Get(capp) != nil |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 101 |
+func (c Capabilities) Get(capp string) *Capability {
|
|
| 98 | 102 |
for _, cap := range c {
|
| 99 | 103 |
if cap.Key == capp {
|
| 100 |
- return true |
|
| 104 |
+ return cap |
|
| 101 | 105 |
} |
| 102 | 106 |
} |
| 103 |
- return false |
|
| 107 |
+ return nil |
|
| 104 | 108 |
} |
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"github.com/dotcloud/docker/pkg/libcontainer" |
| 7 | 7 |
"github.com/dotcloud/docker/runtime/execdriver" |
| 8 | 8 |
"os" |
| 9 |
+ "strings" |
|
| 9 | 10 |
) |
| 10 | 11 |
|
| 11 | 12 |
// createContainer populates and configures the container type with the |
| ... | ... |
@@ -63,9 +64,39 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
|
| 63 | 63 |
container.Mounts = append(container.Mounts, libcontainer.Mount{m.Source, m.Destination, m.Writable, m.Private})
|
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 |
+ configureCustomOptions(container, c.Config["native"]) |
|
| 67 |
+ |
|
| 66 | 68 |
return container |
| 67 | 69 |
} |
| 68 | 70 |
|
| 71 |
+// configureCustomOptions takes string commands from the user and allows modification of the |
|
| 72 |
+// container's default configuration. |
|
| 73 |
+// |
|
| 74 |
+// format: <key> <value> |
|
| 75 |
+// i.e: cap +MKNOD cap -NET_ADMIN |
|
| 76 |
+// i.e: cgroup devices.allow *:* |
|
| 77 |
+func configureCustomOptions(container *libcontainer.Container, opts []string) {
|
|
| 78 |
+ for _, opt := range opts {
|
|
| 79 |
+ parts := strings.Split(strings.TrimSpace(opt), " ") |
|
| 80 |
+ switch parts[0] {
|
|
| 81 |
+ case "cap": |
|
| 82 |
+ value := strings.TrimSpace(parts[1]) |
|
| 83 |
+ c := container.CapabilitiesMask.Get(value[1:]) |
|
| 84 |
+ if c == nil {
|
|
| 85 |
+ continue |
|
| 86 |
+ } |
|
| 87 |
+ switch value[0] {
|
|
| 88 |
+ case '-': |
|
| 89 |
+ c.Enabled = false |
|
| 90 |
+ case '+': |
|
| 91 |
+ c.Enabled = true |
|
| 92 |
+ default: |
|
| 93 |
+ // do error here |
|
| 94 |
+ } |
|
| 95 |
+ } |
|
| 96 |
+ } |
|
| 97 |
+} |
|
| 98 |
+ |
|
| 69 | 99 |
// getDefaultTemplate returns the docker default for |
| 70 | 100 |
// the libcontainer configuration file |
| 71 | 101 |
func getDefaultTemplate() *libcontainer.Container {
|
| ... | ... |
@@ -75,9 +75,6 @@ func NewDriver(root, initPath string) (*driver, error) {
|
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 | 77 |
func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
|
| 78 |
- if err := d.validateCommand(c); err != nil {
|
|
| 79 |
- return -1, err |
|
| 80 |
- } |
|
| 81 | 78 |
var ( |
| 82 | 79 |
term nsinit.Terminal |
| 83 | 80 |
container = createContainer(c) |
| ... | ... |
@@ -181,15 +178,6 @@ func (d *driver) removeContainerRoot(id string) error {
|
| 181 | 181 |
return os.RemoveAll(filepath.Join(d.root, id)) |
| 182 | 182 |
} |
| 183 | 183 |
|
| 184 |
-func (d *driver) validateCommand(c *execdriver.Command) error {
|
|
| 185 |
- // we need to check the Config of the command to make sure that we |
|
| 186 |
- // do not have any of the lxc-conf variables |
|
| 187 |
- for _, conf := range c.Config["native"] {
|
|
| 188 |
- log.Println(conf) |
|
| 189 |
- } |
|
| 190 |
- return nil |
|
| 191 |
-} |
|
| 192 |
- |
|
| 193 | 184 |
func getEnv(key string, env []string) string {
|
| 194 | 185 |
for _, pair := range env {
|
| 195 | 186 |
parts := strings.Split(pair, "=") |