| ... | ... |
@@ -2,12 +2,13 @@ package configuration |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "github.com/dotcloud/docker/pkg/libcontainer" |
|
| 6 |
- "github.com/dotcloud/docker/utils" |
|
| 7 | 5 |
"os/exec" |
| 8 | 6 |
"path/filepath" |
| 9 | 7 |
"strconv" |
| 10 | 8 |
"strings" |
| 9 |
+ |
|
| 10 |
+ "github.com/dotcloud/docker/pkg/libcontainer" |
|
| 11 |
+ "github.com/dotcloud/docker/utils" |
|
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
type Action func(*libcontainer.Container, interface{}, string) error
|
| ... | ... |
@@ -97,38 +98,22 @@ func memorySwap(container *libcontainer.Container, context interface{}, value st
|
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 | 99 |
func addCap(container *libcontainer.Container, context interface{}, value string) error {
|
| 100 |
- c := container.CapabilitiesMask.Get(value) |
|
| 101 |
- if c == nil {
|
|
| 102 |
- return fmt.Errorf("%s is not a valid capability", value)
|
|
| 103 |
- } |
|
| 104 |
- c.Enabled = true |
|
| 100 |
+ container.CapabilitiesMask[value] = true |
|
| 105 | 101 |
return nil |
| 106 | 102 |
} |
| 107 | 103 |
|
| 108 | 104 |
func dropCap(container *libcontainer.Container, context interface{}, value string) error {
|
| 109 |
- c := container.CapabilitiesMask.Get(value) |
|
| 110 |
- if c == nil {
|
|
| 111 |
- return fmt.Errorf("%s is not a valid capability", value)
|
|
| 112 |
- } |
|
| 113 |
- c.Enabled = false |
|
| 105 |
+ container.CapabilitiesMask[value] = false |
|
| 114 | 106 |
return nil |
| 115 | 107 |
} |
| 116 | 108 |
|
| 117 | 109 |
func addNamespace(container *libcontainer.Container, context interface{}, value string) error {
|
| 118 |
- ns := container.Namespaces.Get(value) |
|
| 119 |
- if ns == nil {
|
|
| 120 |
- return fmt.Errorf("%s is not a valid namespace", value[1:])
|
|
| 121 |
- } |
|
| 122 |
- ns.Enabled = true |
|
| 110 |
+ container.Namespaces[value] = true |
|
| 123 | 111 |
return nil |
| 124 | 112 |
} |
| 125 | 113 |
|
| 126 | 114 |
func dropNamespace(container *libcontainer.Container, context interface{}, value string) error {
|
| 127 |
- ns := container.Namespaces.Get(value) |
|
| 128 |
- if ns == nil {
|
|
| 129 |
- return fmt.Errorf("%s is not a valid namespace", value[1:])
|
|
| 130 |
- } |
|
| 131 |
- ns.Enabled = false |
|
| 115 |
+ container.Namespaces[value] = false |
|
| 132 | 116 |
return nil |
| 133 | 117 |
} |
| 134 | 118 |
|
| ... | ... |
@@ -1,8 +1,9 @@ |
| 1 | 1 |
package configuration |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "github.com/dotcloud/docker/daemon/execdriver/native/template" |
|
| 5 | 4 |
"testing" |
| 5 |
+ |
|
| 6 |
+ "github.com/dotcloud/docker/daemon/execdriver/native/template" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
func TestSetReadonlyRootFs(t *testing.T) {
|
| ... | ... |
@@ -38,10 +39,10 @@ func TestConfigurationsDoNotConflict(t *testing.T) {
|
| 38 | 38 |
t.Fatal(err) |
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 |
- if !container1.CapabilitiesMask.Get("NET_ADMIN").Enabled {
|
|
| 41 |
+ if !container1.CapabilitiesMask["NET_ADMIN"] {
|
|
| 42 | 42 |
t.Fatal("container one should have NET_ADMIN enabled")
|
| 43 | 43 |
} |
| 44 |
- if container2.CapabilitiesMask.Get("NET_ADMIN").Enabled {
|
|
| 44 |
+ if container2.CapabilitiesMask["NET_ADMIN"] {
|
|
| 45 | 45 |
t.Fatal("container two should not have NET_ADMIN enabled")
|
| 46 | 46 |
} |
| 47 | 47 |
} |
| ... | ... |
@@ -137,10 +138,10 @@ func TestAddCap(t *testing.T) {
|
| 137 | 137 |
t.Fatal(err) |
| 138 | 138 |
} |
| 139 | 139 |
|
| 140 |
- if !container.CapabilitiesMask.Get("MKNOD").Enabled {
|
|
| 140 |
+ if !container.CapabilitiesMask["MKNOD"] {
|
|
| 141 | 141 |
t.Fatal("container should have MKNOD enabled")
|
| 142 | 142 |
} |
| 143 |
- if !container.CapabilitiesMask.Get("SYS_ADMIN").Enabled {
|
|
| 143 |
+ if !container.CapabilitiesMask["SYS_ADMIN"] {
|
|
| 144 | 144 |
t.Fatal("container should have SYS_ADMIN enabled")
|
| 145 | 145 |
} |
| 146 | 146 |
} |
| ... | ... |
@@ -153,14 +154,14 @@ func TestDropCap(t *testing.T) {
|
| 153 | 153 |
} |
| 154 | 154 |
) |
| 155 | 155 |
// enabled all caps like in privileged mode |
| 156 |
- for _, c := range container.CapabilitiesMask {
|
|
| 157 |
- c.Enabled = true |
|
| 156 |
+ for key := range container.CapabilitiesMask {
|
|
| 157 |
+ container.CapabilitiesMask[key] = true |
|
| 158 | 158 |
} |
| 159 | 159 |
if err := ParseConfiguration(container, nil, opts); err != nil {
|
| 160 | 160 |
t.Fatal(err) |
| 161 | 161 |
} |
| 162 | 162 |
|
| 163 |
- if container.CapabilitiesMask.Get("MKNOD").Enabled {
|
|
| 163 |
+ if container.CapabilitiesMask["MKNOD"] {
|
|
| 164 | 164 |
t.Fatal("container should not have MKNOD enabled")
|
| 165 | 165 |
} |
| 166 | 166 |
} |
| ... | ... |
@@ -176,7 +177,7 @@ func TestDropNamespace(t *testing.T) {
|
| 176 | 176 |
t.Fatal(err) |
| 177 | 177 |
} |
| 178 | 178 |
|
| 179 |
- if container.Namespaces.Get("NEWNET").Enabled {
|
|
| 179 |
+ if container.Namespaces["NEWNET"] {
|
|
| 180 | 180 |
t.Fatal("container should not have NEWNET enabled")
|
| 181 | 181 |
} |
| 182 | 182 |
} |
| ... | ... |
@@ -79,8 +79,8 @@ func (d *driver) createNetwork(container *libcontainer.Container, c *execdriver. |
| 79 | 79 |
} |
| 80 | 80 |
|
| 81 | 81 |
func (d *driver) setPrivileged(container *libcontainer.Container) error {
|
| 82 |
- for _, c := range container.CapabilitiesMask {
|
|
| 83 |
- c.Enabled = true |
|
| 82 |
+ for key := range container.CapabilitiesMask {
|
|
| 83 |
+ container.CapabilitiesMask[key] = true |
|
| 84 | 84 |
} |
| 85 | 85 |
container.Cgroups.DeviceAccess = true |
| 86 | 86 |
|
| ... | ... |
@@ -9,30 +9,30 @@ import ( |
| 9 | 9 |
// New returns the docker default configuration for libcontainer |
| 10 | 10 |
func New() *libcontainer.Container {
|
| 11 | 11 |
container := &libcontainer.Container{
|
| 12 |
- CapabilitiesMask: libcontainer.Capabilities{
|
|
| 13 |
- libcontainer.GetCapability("SETPCAP"),
|
|
| 14 |
- libcontainer.GetCapability("SYS_MODULE"),
|
|
| 15 |
- libcontainer.GetCapability("SYS_RAWIO"),
|
|
| 16 |
- libcontainer.GetCapability("SYS_PACCT"),
|
|
| 17 |
- libcontainer.GetCapability("SYS_ADMIN"),
|
|
| 18 |
- libcontainer.GetCapability("SYS_NICE"),
|
|
| 19 |
- libcontainer.GetCapability("SYS_RESOURCE"),
|
|
| 20 |
- libcontainer.GetCapability("SYS_TIME"),
|
|
| 21 |
- libcontainer.GetCapability("SYS_TTY_CONFIG"),
|
|
| 22 |
- libcontainer.GetCapability("AUDIT_WRITE"),
|
|
| 23 |
- libcontainer.GetCapability("AUDIT_CONTROL"),
|
|
| 24 |
- libcontainer.GetCapability("MAC_OVERRIDE"),
|
|
| 25 |
- libcontainer.GetCapability("MAC_ADMIN"),
|
|
| 26 |
- libcontainer.GetCapability("NET_ADMIN"),
|
|
| 27 |
- libcontainer.GetCapability("MKNOD"),
|
|
| 28 |
- libcontainer.GetCapability("SYSLOG"),
|
|
| 12 |
+ CapabilitiesMask: map[string]bool{
|
|
| 13 |
+ "SETPCAP": false, |
|
| 14 |
+ "SYS_MODULE": false, |
|
| 15 |
+ "SYS_RAWIO": false, |
|
| 16 |
+ "SYS_PACCT": false, |
|
| 17 |
+ "SYS_ADMIN": false, |
|
| 18 |
+ "SYS_NICE": false, |
|
| 19 |
+ "SYS_RESOURCE": false, |
|
| 20 |
+ "SYS_TIME": false, |
|
| 21 |
+ "SYS_TTY_CONFIG": false, |
|
| 22 |
+ "AUDIT_WRITE": false, |
|
| 23 |
+ "AUDIT_CONTROL": false, |
|
| 24 |
+ "MAC_OVERRIDE": false, |
|
| 25 |
+ "MAC_ADMIN": false, |
|
| 26 |
+ "NET_ADMIN": false, |
|
| 27 |
+ "MKNOD": true, |
|
| 28 |
+ "SYSLOG": false, |
|
| 29 | 29 |
}, |
| 30 |
- Namespaces: libcontainer.Namespaces{
|
|
| 31 |
- libcontainer.GetNamespace("NEWNS"),
|
|
| 32 |
- libcontainer.GetNamespace("NEWUTS"),
|
|
| 33 |
- libcontainer.GetNamespace("NEWIPC"),
|
|
| 34 |
- libcontainer.GetNamespace("NEWPID"),
|
|
| 35 |
- libcontainer.GetNamespace("NEWNET"),
|
|
| 30 |
+ Namespaces: map[string]bool{
|
|
| 31 |
+ "NEWNS": true, |
|
| 32 |
+ "NEWUTS": true, |
|
| 33 |
+ "NEWIPC": true, |
|
| 34 |
+ "NEWPID": true, |
|
| 35 |
+ "NEWNET": true, |
|
| 36 | 36 |
}, |
| 37 | 37 |
Cgroups: &cgroups.Cgroup{
|
| 38 | 38 |
Parent: "docker", |
| ... | ... |
@@ -40,7 +40,6 @@ func New() *libcontainer.Container {
|
| 40 | 40 |
}, |
| 41 | 41 |
Context: libcontainer.Context{},
|
| 42 | 42 |
} |
| 43 |
- container.CapabilitiesMask.Get("MKNOD").Enabled = true
|
|
| 44 | 43 |
if apparmor.IsEnabled() {
|
| 45 | 44 |
container.Context["apparmor_profile"] = "docker-default" |
| 46 | 45 |
} |
| ... | ... |
@@ -18,8 +18,8 @@ type Container struct {
|
| 18 | 18 |
WorkingDir string `json:"working_dir,omitempty"` // current working directory |
| 19 | 19 |
Env []string `json:"environment,omitempty"` // environment to set |
| 20 | 20 |
Tty bool `json:"tty,omitempty"` // setup a proper tty or not |
| 21 |
- Namespaces Namespaces `json:"namespaces,omitempty"` // namespaces to apply |
|
| 22 |
- CapabilitiesMask Capabilities `json:"capabilities_mask,omitempty"` // capabilities to drop |
|
| 21 |
+ Namespaces map[string]bool `json:"namespaces,omitempty"` // namespaces to apply |
|
| 22 |
+ CapabilitiesMask map[string]bool `json:"capabilities_mask,omitempty"` // capabilities to drop |
|
| 23 | 23 |
Networks []*Network `json:"networks,omitempty"` // nil for host's network stack |
| 24 | 24 |
Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"` // cgroups |
| 25 | 25 |
Context Context `json:"context,omitempty"` // generic context for specific options (apparmor, selinux) |
| ... | ... |
@@ -1,151 +1,62 @@ |
| 1 | 1 |
{
|
| 2 |
- "mounts" : [ |
|
| 3 |
- {
|
|
| 4 |
- "type" : "devtmpfs" |
|
| 5 |
- } |
|
| 6 |
- ], |
|
| 7 |
- "tty" : true, |
|
| 8 |
- "environment" : [ |
|
| 9 |
- "HOME=/", |
|
| 10 |
- "PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin", |
|
| 11 |
- "container=docker", |
|
| 12 |
- "TERM=xterm-256color" |
|
| 13 |
- ], |
|
| 14 |
- "hostname" : "koye", |
|
| 15 |
- "cgroups" : {
|
|
| 16 |
- "parent" : "docker", |
|
| 17 |
- "name" : "docker-koye" |
|
| 18 |
- }, |
|
| 19 |
- "capabilities_mask" : [ |
|
| 20 |
- {
|
|
| 21 |
- "value" : 8, |
|
| 22 |
- "key" : "SETPCAP", |
|
| 23 |
- "enabled" : false |
|
| 24 |
- }, |
|
| 25 |
- {
|
|
| 26 |
- "enabled" : false, |
|
| 27 |
- "value" : 16, |
|
| 28 |
- "key" : "SYS_MODULE" |
|
| 29 |
- }, |
|
| 30 |
- {
|
|
| 31 |
- "value" : 17, |
|
| 32 |
- "key" : "SYS_RAWIO", |
|
| 33 |
- "enabled" : false |
|
| 34 |
- }, |
|
| 35 |
- {
|
|
| 36 |
- "key" : "SYS_PACCT", |
|
| 37 |
- "value" : 20, |
|
| 38 |
- "enabled" : false |
|
| 39 |
- }, |
|
| 40 |
- {
|
|
| 41 |
- "value" : 21, |
|
| 42 |
- "key" : "SYS_ADMIN", |
|
| 43 |
- "enabled" : false |
|
| 44 |
- }, |
|
| 45 |
- {
|
|
| 46 |
- "value" : 23, |
|
| 47 |
- "key" : "SYS_NICE", |
|
| 48 |
- "enabled" : false |
|
| 49 |
- }, |
|
| 50 |
- {
|
|
| 51 |
- "value" : 24, |
|
| 52 |
- "key" : "SYS_RESOURCE", |
|
| 53 |
- "enabled" : false |
|
| 54 |
- }, |
|
| 55 |
- {
|
|
| 56 |
- "key" : "SYS_TIME", |
|
| 57 |
- "value" : 25, |
|
| 58 |
- "enabled" : false |
|
| 59 |
- }, |
|
| 60 |
- {
|
|
| 61 |
- "enabled" : false, |
|
| 62 |
- "value" : 26, |
|
| 63 |
- "key" : "SYS_TTY_CONFIG" |
|
| 64 |
- }, |
|
| 65 |
- {
|
|
| 66 |
- "key" : "AUDIT_WRITE", |
|
| 67 |
- "value" : 29, |
|
| 68 |
- "enabled" : false |
|
| 69 |
- }, |
|
| 70 |
- {
|
|
| 71 |
- "value" : 30, |
|
| 72 |
- "key" : "AUDIT_CONTROL", |
|
| 73 |
- "enabled" : false |
|
| 74 |
- }, |
|
| 75 |
- {
|
|
| 76 |
- "enabled" : false, |
|
| 77 |
- "key" : "MAC_OVERRIDE", |
|
| 78 |
- "value" : 32 |
|
| 79 |
- }, |
|
| 80 |
- {
|
|
| 81 |
- "enabled" : false, |
|
| 82 |
- "key" : "MAC_ADMIN", |
|
| 83 |
- "value" : 33 |
|
| 84 |
- }, |
|
| 85 |
- {
|
|
| 86 |
- "key" : "NET_ADMIN", |
|
| 87 |
- "value" : 12, |
|
| 88 |
- "enabled" : false |
|
| 89 |
- }, |
|
| 90 |
- {
|
|
| 91 |
- "value" : 27, |
|
| 92 |
- "key" : "MKNOD", |
|
| 93 |
- "enabled" : true |
|
| 94 |
- }, |
|
| 95 |
- {
|
|
| 96 |
- "value" : 34, |
|
| 97 |
- "key" : "SYSLOG", |
|
| 98 |
- "enabled" : false |
|
| 99 |
- } |
|
| 100 |
- ], |
|
| 101 |
- "networks" : [ |
|
| 102 |
- {
|
|
| 103 |
- "mtu" : 1500, |
|
| 104 |
- "address" : "127.0.0.1/0", |
|
| 105 |
- "type" : "loopback", |
|
| 106 |
- "gateway" : "localhost" |
|
| 107 |
- }, |
|
| 108 |
- {
|
|
| 109 |
- "mtu" : 1500, |
|
| 110 |
- "address" : "172.17.42.2/16", |
|
| 111 |
- "type" : "veth", |
|
| 112 |
- "context" : {
|
|
| 113 |
- "bridge" : "docker0", |
|
| 114 |
- "prefix" : "veth" |
|
| 115 |
- }, |
|
| 116 |
- "gateway" : "172.17.42.1" |
|
| 117 |
- } |
|
| 118 |
- ], |
|
| 119 |
- "namespaces" : [ |
|
| 120 |
- {
|
|
| 121 |
- "key" : "NEWNS", |
|
| 122 |
- "value" : 131072, |
|
| 123 |
- "enabled" : true, |
|
| 124 |
- "file" : "mnt" |
|
| 125 |
- }, |
|
| 126 |
- {
|
|
| 127 |
- "key" : "NEWUTS", |
|
| 128 |
- "value" : 67108864, |
|
| 129 |
- "enabled" : true, |
|
| 130 |
- "file" : "uts" |
|
| 131 |
- }, |
|
| 132 |
- {
|
|
| 133 |
- "enabled" : true, |
|
| 134 |
- "file" : "ipc", |
|
| 135 |
- "key" : "NEWIPC", |
|
| 136 |
- "value" : 134217728 |
|
| 137 |
- }, |
|
| 138 |
- {
|
|
| 139 |
- "file" : "pid", |
|
| 140 |
- "enabled" : true, |
|
| 141 |
- "value" : 536870912, |
|
| 142 |
- "key" : "NEWPID" |
|
| 143 |
- }, |
|
| 144 |
- {
|
|
| 145 |
- "enabled" : true, |
|
| 146 |
- "file" : "net", |
|
| 147 |
- "key" : "NEWNET", |
|
| 148 |
- "value" : 1073741824 |
|
| 149 |
- } |
|
| 150 |
- ] |
|
| 2 |
+ "namespaces": {
|
|
| 3 |
+ "NEWNET": true, |
|
| 4 |
+ "NEWPID": true, |
|
| 5 |
+ "NEWIPC": true, |
|
| 6 |
+ "NEWUTS": true, |
|
| 7 |
+ "NEWNS": true |
|
| 8 |
+ }, |
|
| 9 |
+ "networks": [ |
|
| 10 |
+ {
|
|
| 11 |
+ "gateway": "localhost", |
|
| 12 |
+ "type": "loopback", |
|
| 13 |
+ "address": "127.0.0.1/0", |
|
| 14 |
+ "mtu": 1500 |
|
| 15 |
+ }, |
|
| 16 |
+ {
|
|
| 17 |
+ "gateway": "172.17.42.1", |
|
| 18 |
+ "context": {
|
|
| 19 |
+ "prefix": "veth", |
|
| 20 |
+ "bridge": "docker0" |
|
| 21 |
+ }, |
|
| 22 |
+ "type": "veth", |
|
| 23 |
+ "address": "172.17.42.2/16", |
|
| 24 |
+ "mtu": 1500 |
|
| 25 |
+ } |
|
| 26 |
+ ], |
|
| 27 |
+ "capabilities_mask": {
|
|
| 28 |
+ "SYSLOG": false, |
|
| 29 |
+ "MKNOD": true, |
|
| 30 |
+ "NET_ADMIN": false, |
|
| 31 |
+ "MAC_ADMIN": false, |
|
| 32 |
+ "MAC_OVERRIDE": false, |
|
| 33 |
+ "AUDIT_CONTROL": false, |
|
| 34 |
+ "AUDIT_WRITE": false, |
|
| 35 |
+ "SYS_TTY_CONFIG": false, |
|
| 36 |
+ "SETPCAP": false, |
|
| 37 |
+ "SYS_MODULE": false, |
|
| 38 |
+ "SYS_RAWIO": false, |
|
| 39 |
+ "SYS_PACCT": false, |
|
| 40 |
+ "SYS_ADMIN": false, |
|
| 41 |
+ "SYS_NICE": false, |
|
| 42 |
+ "SYS_RESOURCE": false, |
|
| 43 |
+ "SYS_TIME": false |
|
| 44 |
+ }, |
|
| 45 |
+ "cgroups": {
|
|
| 46 |
+ "name": "docker-koye", |
|
| 47 |
+ "parent": "docker" |
|
| 48 |
+ }, |
|
| 49 |
+ "hostname": "koye", |
|
| 50 |
+ "environment": [ |
|
| 51 |
+ "HOME=/", |
|
| 52 |
+ "PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin", |
|
| 53 |
+ "container=docker", |
|
| 54 |
+ "TERM=xterm-256color" |
|
| 55 |
+ ], |
|
| 56 |
+ "tty": true, |
|
| 57 |
+ "mounts": [ |
|
| 58 |
+ {
|
|
| 59 |
+ "type": "devtmpfs" |
|
| 60 |
+ } |
|
| 61 |
+ ] |
|
| 151 | 62 |
} |
| ... | ... |
@@ -15,7 +15,7 @@ func TestContainerJsonFormat(t *testing.T) {
|
| 15 | 15 |
|
| 16 | 16 |
var container *Container |
| 17 | 17 |
if err := json.NewDecoder(f).Decode(&container); err != nil {
|
| 18 |
- t.Fatal("failed to decode container config")
|
|
| 18 |
+ t.Fatalf("failed to decode container config: %s", err)
|
|
| 19 | 19 |
} |
| 20 | 20 |
if container.Hostname != "koye" {
|
| 21 | 21 |
t.Log("hostname is not set")
|
| ... | ... |
@@ -27,32 +27,32 @@ func TestContainerJsonFormat(t *testing.T) {
|
| 27 | 27 |
t.Fail() |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
- if !container.Namespaces.Contains("NEWNET") {
|
|
| 30 |
+ if !container.Namespaces["NEWNET"] {
|
|
| 31 | 31 |
t.Log("namespaces should contain NEWNET")
|
| 32 | 32 |
t.Fail() |
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 |
- if container.Namespaces.Contains("NEWUSER") {
|
|
| 35 |
+ if container.Namespaces["NEWUSER"] {
|
|
| 36 | 36 |
t.Log("namespaces should not contain NEWUSER")
|
| 37 | 37 |
t.Fail() |
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 |
- if !container.CapabilitiesMask.Contains("SYS_ADMIN") {
|
|
| 40 |
+ if _, exists := container.CapabilitiesMask["SYS_ADMIN"]; !exists {
|
|
| 41 | 41 |
t.Log("capabilities mask should contain SYS_ADMIN")
|
| 42 | 42 |
t.Fail() |
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 |
- if container.CapabilitiesMask.Get("SYS_ADMIN").Enabled {
|
|
| 45 |
+ if container.CapabilitiesMask["SYS_ADMIN"] {
|
|
| 46 | 46 |
t.Log("SYS_ADMIN should not be enabled in capabilities mask")
|
| 47 | 47 |
t.Fail() |
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 |
- if !container.CapabilitiesMask.Get("MKNOD").Enabled {
|
|
| 50 |
+ if !container.CapabilitiesMask["MKNOD"] {
|
|
| 51 | 51 |
t.Log("MKNOD should be enabled in capabilities mask")
|
| 52 | 52 |
t.Fail() |
| 53 | 53 |
} |
| 54 | 54 |
|
| 55 |
- if container.CapabilitiesMask.Contains("SYS_CHROOT") {
|
|
| 55 |
+ if container.CapabilitiesMask["SYS_CHROOT"] {
|
|
| 56 | 56 |
t.Log("capabilities mask should not contain SYS_CHROOT")
|
| 57 | 57 |
t.Fail() |
| 58 | 58 |
} |
| ... | ... |
@@ -159,10 +159,12 @@ func InitializeNetworking(container *libcontainer.Container, nspid int, pipe *Sy |
| 159 | 159 |
|
| 160 | 160 |
// GetNamespaceFlags parses the container's Namespaces options to set the correct |
| 161 | 161 |
// flags on clone, unshare, and setns |
| 162 |
-func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
|
|
| 163 |
- for _, ns := range namespaces {
|
|
| 164 |
- if ns.Enabled {
|
|
| 165 |
- flag |= ns.Value |
|
| 162 |
+func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
|
|
| 163 |
+ for key, enabled := range namespaces {
|
|
| 164 |
+ if enabled {
|
|
| 165 |
+ if ns := libcontainer.GetNamespace(key); ns != nil {
|
|
| 166 |
+ flag |= ns.Value |
|
| 167 |
+ } |
|
| 166 | 168 |
} |
| 167 | 169 |
} |
| 168 | 170 |
return flag |
| ... | ... |
@@ -23,11 +23,13 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) (int, e |
| 23 | 23 |
return -1, err |
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
- for _, nsv := range container.Namespaces {
|
|
| 26 |
+ for key, enabled := range container.Namespaces {
|
|
| 27 | 27 |
// skip the PID namespace on unshare because it it not supported |
| 28 |
- if nsv.Enabled && nsv.Key != "NEWPID" {
|
|
| 29 |
- if err := system.Unshare(nsv.Value); err != nil {
|
|
| 30 |
- return -1, err |
|
| 28 |
+ if enabled && key != "NEWPID" {
|
|
| 29 |
+ if ns := libcontainer.GetNamespace(key); ns != nil {
|
|
| 30 |
+ if err := system.Unshare(ns.Value); err != nil {
|
|
| 31 |
+ return -1, err |
|
| 32 |
+ } |
|
| 31 | 33 |
} |
| 32 | 34 |
} |
| 33 | 35 |
} |
| ... | ... |
@@ -59,7 +61,7 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) (int, e |
| 59 | 59 |
|
| 60 | 60 |
// if the container has a new pid and mount namespace we need to |
| 61 | 61 |
// remount proc and sys to pick up the changes |
| 62 |
- if container.Namespaces.Contains("NEWNS") && container.Namespaces.Contains("NEWPID") {
|
|
| 62 |
+ if container.Namespaces["NEWNS"] && container.Namespaces["NEWPID"] {
|
|
| 63 | 63 |
pid, err := system.Fork() |
| 64 | 64 |
if err != nil {
|
| 65 | 65 |
return -1, err |
| ... | ... |
@@ -102,13 +104,18 @@ dropAndExec: |
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 | 104 |
func getNsFds(pid int, container *libcontainer.Container) ([]uintptr, error) {
|
| 105 |
- fds := make([]uintptr, len(container.Namespaces)) |
|
| 106 |
- for i, ns := range container.Namespaces {
|
|
| 107 |
- f, err := os.OpenFile(filepath.Join("/proc/", strconv.Itoa(pid), "ns", ns.File), os.O_RDONLY, 0)
|
|
| 108 |
- if err != nil {
|
|
| 109 |
- return fds, err |
|
| 105 |
+ fds := []uintptr{}
|
|
| 106 |
+ |
|
| 107 |
+ for key, enabled := range container.Namespaces {
|
|
| 108 |
+ if enabled {
|
|
| 109 |
+ if ns := libcontainer.GetNamespace(key); ns != nil {
|
|
| 110 |
+ f, err := os.OpenFile(filepath.Join("/proc/", strconv.Itoa(pid), "ns", ns.File), os.O_RDONLY, 0)
|
|
| 111 |
+ if err != nil {
|
|
| 112 |
+ return fds, err |
|
| 113 |
+ } |
|
| 114 |
+ fds = append(fds, f.Fd()) |
|
| 115 |
+ } |
|
| 110 | 116 |
} |
| 111 |
- fds[i] = f.Fd() |
|
| 112 | 117 |
} |
| 113 | 118 |
return fds, nil |
| 114 | 119 |
} |
| ... | ... |
@@ -23,6 +23,6 @@ func SetupCgroups(container *libcontainer.Container, nspid int) (cgroups.ActiveC |
| 23 | 23 |
return nil, libcontainer.ErrUnsupported |
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
-func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
|
|
| 26 |
+func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
|
|
| 27 | 27 |
return 0 |
| 28 | 28 |
} |
| ... | ... |
@@ -1,9 +1,10 @@ |
| 1 | 1 |
package capabilities |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "os" |
|
| 5 |
+ |
|
| 4 | 6 |
"github.com/dotcloud/docker/pkg/libcontainer" |
| 5 | 7 |
"github.com/syndtr/gocapability/capability" |
| 6 |
- "os" |
|
| 7 | 8 |
) |
| 8 | 9 |
|
| 9 | 10 |
// DropCapabilities drops capabilities for the current process based |
| ... | ... |
@@ -26,9 +27,11 @@ func DropCapabilities(container *libcontainer.Container) error {
|
| 26 | 26 |
// getCapabilitiesMask returns the specific cap mask values for the libcontainer types |
| 27 | 27 |
func getCapabilitiesMask(container *libcontainer.Container) []capability.Cap {
|
| 28 | 28 |
drop := []capability.Cap{}
|
| 29 |
- for _, c := range container.CapabilitiesMask {
|
|
| 30 |
- if !c.Enabled {
|
|
| 31 |
- drop = append(drop, c.Value) |
|
| 29 |
+ for key, enabled := range container.CapabilitiesMask {
|
|
| 30 |
+ if !enabled {
|
|
| 31 |
+ if c := libcontainer.GetCapability(key); c != nil {
|
|
| 32 |
+ drop = append(drop, c.Value) |
|
| 33 |
+ } |
|
| 32 | 34 |
} |
| 33 | 35 |
} |
| 34 | 36 |
return drop |
| ... | ... |
@@ -2,6 +2,7 @@ package libcontainer |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"errors" |
| 5 |
+ |
|
| 5 | 6 |
"github.com/syndtr/gocapability/capability" |
| 6 | 7 |
) |
| 7 | 8 |
|
| ... | ... |
@@ -38,31 +39,30 @@ var ( |
| 38 | 38 |
namespaceList = Namespaces{}
|
| 39 | 39 |
|
| 40 | 40 |
capabilityList = Capabilities{
|
| 41 |
- {Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: false},
|
|
| 42 |
- {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: false},
|
|
| 43 |
- {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: false},
|
|
| 44 |
- {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: false},
|
|
| 45 |
- {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: false},
|
|
| 46 |
- {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: false},
|
|
| 47 |
- {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: false},
|
|
| 48 |
- {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: false},
|
|
| 49 |
- {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: false},
|
|
| 50 |
- {Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: false},
|
|
| 51 |
- {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: false},
|
|
| 52 |
- {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: false},
|
|
| 53 |
- {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: false},
|
|
| 54 |
- {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: false},
|
|
| 55 |
- {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: false},
|
|
| 56 |
- {Key: "SYSLOG", Value: capability.CAP_SYSLOG, Enabled: false},
|
|
| 41 |
+ {Key: "SETPCAP", Value: capability.CAP_SETPCAP},
|
|
| 42 |
+ {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE},
|
|
| 43 |
+ {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO},
|
|
| 44 |
+ {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT},
|
|
| 45 |
+ {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN},
|
|
| 46 |
+ {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE},
|
|
| 47 |
+ {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE},
|
|
| 48 |
+ {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME},
|
|
| 49 |
+ {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG},
|
|
| 50 |
+ {Key: "MKNOD", Value: capability.CAP_MKNOD},
|
|
| 51 |
+ {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE},
|
|
| 52 |
+ {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL},
|
|
| 53 |
+ {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE},
|
|
| 54 |
+ {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN},
|
|
| 55 |
+ {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN},
|
|
| 56 |
+ {Key: "SYSLOG", Value: capability.CAP_SYSLOG},
|
|
| 57 | 57 |
} |
| 58 | 58 |
) |
| 59 | 59 |
|
| 60 | 60 |
type ( |
| 61 | 61 |
Namespace struct {
|
| 62 |
- Key string `json:"key,omitempty"` |
|
| 63 |
- Enabled bool `json:"enabled,omitempty"` |
|
| 64 |
- Value int `json:"value,omitempty"` |
|
| 65 |
- File string `json:"file,omitempty"` |
|
| 62 |
+ Key string `json:"key,omitempty"` |
|
| 63 |
+ Value int `json:"value,omitempty"` |
|
| 64 |
+ File string `json:"file,omitempty"` |
|
| 66 | 65 |
} |
| 67 | 66 |
Namespaces []*Namespace |
| 68 | 67 |
) |
| ... | ... |
@@ -98,9 +98,8 @@ func (n Namespaces) Get(ns string) *Namespace {
|
| 98 | 98 |
|
| 99 | 99 |
type ( |
| 100 | 100 |
Capability struct {
|
| 101 |
- Key string `json:"key,omitempty"` |
|
| 102 |
- Enabled bool `json:"enabled"` |
|
| 103 |
- Value capability.Cap `json:"value,omitempty"` |
|
| 101 |
+ Key string `json:"key,omitempty"` |
|
| 102 |
+ Value capability.Cap `json:"value,omitempty"` |
|
| 104 | 103 |
} |
| 105 | 104 |
Capabilities []*Capability |
| 106 | 105 |
) |
| ... | ... |
@@ -6,11 +6,11 @@ import ( |
| 6 | 6 |
|
| 7 | 7 |
func init() {
|
| 8 | 8 |
namespaceList = Namespaces{
|
| 9 |
- {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt", Enabled: true},
|
|
| 10 |
- {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts", Enabled: true},
|
|
| 11 |
- {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc", Enabled: true},
|
|
| 12 |
- {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user", Enabled: true},
|
|
| 13 |
- {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid", Enabled: true},
|
|
| 14 |
- {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net", Enabled: true},
|
|
| 9 |
+ {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"},
|
|
| 10 |
+ {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"},
|
|
| 11 |
+ {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"},
|
|
| 12 |
+ {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"},
|
|
| 13 |
+ {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"},
|
|
| 14 |
+ {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"},
|
|
| 15 | 15 |
} |
| 16 | 16 |
} |