This also removes dead code in the native driver for a past feature that
was never fully implemented.
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
| ... | ... |
@@ -195,14 +195,7 @@ func (container *Container) getRootResourcePath(path string) (string, error) {
|
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 | 197 |
func populateCommand(c *Container, env []string) error {
|
| 198 |
- var ( |
|
| 199 |
- en *execdriver.Network |
|
| 200 |
- context = make(map[string][]string) |
|
| 201 |
- ) |
|
| 202 |
- context["process_label"] = []string{c.GetProcessLabel()}
|
|
| 203 |
- context["mount_label"] = []string{c.GetMountLabel()}
|
|
| 204 |
- |
|
| 205 |
- en = &execdriver.Network{
|
|
| 198 |
+ en := &execdriver.Network{
|
|
| 206 | 199 |
Mtu: c.daemon.config.Mtu, |
| 207 | 200 |
Interface: nil, |
| 208 | 201 |
} |
| ... | ... |
@@ -247,7 +240,7 @@ func populateCommand(c *Container, env []string) error {
|
| 247 | 247 |
autoCreatedDevices := append(devices.DefaultAutoCreatedDevices, userSpecifiedDevices...) |
| 248 | 248 |
|
| 249 | 249 |
// TODO: this can be removed after lxc-conf is fully deprecated |
| 250 |
- mergeLxcConfIntoOptions(c.hostConfig, context) |
|
| 250 |
+ lxcConfig := mergeLxcConfIntoOptions(c.hostConfig) |
|
| 251 | 251 |
|
| 252 | 252 |
resources := &execdriver.Resources{
|
| 253 | 253 |
Memory: c.Config.Memory, |
| ... | ... |
@@ -263,21 +256,25 @@ func populateCommand(c *Container, env []string) error {
|
| 263 | 263 |
Tty: c.Config.Tty, |
| 264 | 264 |
User: c.Config.User, |
| 265 | 265 |
} |
| 266 |
+ |
|
| 266 | 267 |
processConfig.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
|
| 267 | 268 |
processConfig.Env = env |
| 269 |
+ |
|
| 268 | 270 |
c.command = &execdriver.Command{
|
| 269 | 271 |
ID: c.ID, |
| 270 | 272 |
Rootfs: c.RootfsPath(), |
| 271 | 273 |
InitPath: "/.dockerinit", |
| 272 | 274 |
WorkingDir: c.Config.WorkingDir, |
| 273 | 275 |
Network: en, |
| 274 |
- Config: context, |
|
| 275 | 276 |
Resources: resources, |
| 276 | 277 |
AllowedDevices: allowedDevices, |
| 277 | 278 |
AutoCreatedDevices: autoCreatedDevices, |
| 278 | 279 |
CapAdd: c.hostConfig.CapAdd, |
| 279 | 280 |
CapDrop: c.hostConfig.CapDrop, |
| 280 | 281 |
ProcessConfig: processConfig, |
| 282 |
+ ProcessLabel: c.GetProcessLabel(), |
|
| 283 |
+ MountLabel: c.GetMountLabel(), |
|
| 284 |
+ LxcConfig: lxcConfig, |
|
| 281 | 285 |
} |
| 282 | 286 |
|
| 283 | 287 |
return nil |
| ... | ... |
@@ -99,19 +99,21 @@ type ProcessConfig struct {
|
| 99 | 99 |
|
| 100 | 100 |
// Process wrapps an os/exec.Cmd to add more metadata |
| 101 | 101 |
type Command struct {
|
| 102 |
- ID string `json:"id"` |
|
| 103 |
- Rootfs string `json:"rootfs"` // root fs of the container |
|
| 104 |
- InitPath string `json:"initpath"` // dockerinit |
|
| 105 |
- WorkingDir string `json:"working_dir"` |
|
| 106 |
- ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver |
|
| 107 |
- Network *Network `json:"network"` |
|
| 108 |
- Config map[string][]string `json:"config"` // generic values that specific drivers can consume |
|
| 109 |
- Resources *Resources `json:"resources"` |
|
| 110 |
- Mounts []Mount `json:"mounts"` |
|
| 111 |
- AllowedDevices []*devices.Device `json:"allowed_devices"` |
|
| 112 |
- AutoCreatedDevices []*devices.Device `json:"autocreated_devices"` |
|
| 113 |
- CapAdd []string `json:"cap_add"` |
|
| 114 |
- CapDrop []string `json:"cap_drop"` |
|
| 115 |
- ContainerPid int `json:"container_pid"` // the pid for the process inside a container |
|
| 116 |
- ProcessConfig ProcessConfig `json:"process_config"` // Describes the init process of the container. |
|
| 102 |
+ ID string `json:"id"` |
|
| 103 |
+ Rootfs string `json:"rootfs"` // root fs of the container |
|
| 104 |
+ InitPath string `json:"initpath"` // dockerinit |
|
| 105 |
+ WorkingDir string `json:"working_dir"` |
|
| 106 |
+ ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver |
|
| 107 |
+ Network *Network `json:"network"` |
|
| 108 |
+ Resources *Resources `json:"resources"` |
|
| 109 |
+ Mounts []Mount `json:"mounts"` |
|
| 110 |
+ AllowedDevices []*devices.Device `json:"allowed_devices"` |
|
| 111 |
+ AutoCreatedDevices []*devices.Device `json:"autocreated_devices"` |
|
| 112 |
+ CapAdd []string `json:"cap_add"` |
|
| 113 |
+ CapDrop []string `json:"cap_drop"` |
|
| 114 |
+ ContainerPid int `json:"container_pid"` // the pid for the process inside a container |
|
| 115 |
+ ProcessConfig ProcessConfig `json:"process_config"` // Describes the init process of the container. |
|
| 116 |
+ ProcessLabel string `json:"process_label"` |
|
| 117 |
+ MountLabel string `json:"mount_label"` |
|
| 118 |
+ LxcConfig []string `json:"lxc_config"` |
|
| 117 | 119 |
} |
| ... | ... |
@@ -22,7 +22,6 @@ import ( |
| 22 | 22 |
"github.com/docker/docker/pkg/term" |
| 23 | 23 |
"github.com/docker/docker/utils" |
| 24 | 24 |
"github.com/docker/libcontainer/cgroups" |
| 25 |
- "github.com/docker/libcontainer/label" |
|
| 26 | 25 |
"github.com/docker/libcontainer/mount/nodes" |
| 27 | 26 |
) |
| 28 | 27 |
|
| ... | ... |
@@ -410,37 +409,24 @@ func rootIsShared() bool {
|
| 410 | 410 |
} |
| 411 | 411 |
|
| 412 | 412 |
func (d *driver) generateLXCConfig(c *execdriver.Command) (string, error) {
|
| 413 |
- var ( |
|
| 414 |
- process, mount string |
|
| 415 |
- root = path.Join(d.root, "containers", c.ID, "config.lxc") |
|
| 416 |
- labels = c.Config["label"] |
|
| 417 |
- ) |
|
| 413 |
+ root := path.Join(d.root, "containers", c.ID, "config.lxc") |
|
| 414 |
+ |
|
| 418 | 415 |
fo, err := os.Create(root) |
| 419 | 416 |
if err != nil {
|
| 420 | 417 |
return "", err |
| 421 | 418 |
} |
| 422 | 419 |
defer fo.Close() |
| 423 | 420 |
|
| 424 |
- if len(labels) > 0 {
|
|
| 425 |
- process, mount, err = label.GenLabels(labels[0]) |
|
| 426 |
- if err != nil {
|
|
| 427 |
- return "", err |
|
| 428 |
- } |
|
| 429 |
- } |
|
| 430 |
- |
|
| 431 | 421 |
if err := LxcTemplateCompiled.Execute(fo, struct {
|
| 432 | 422 |
*execdriver.Command |
| 433 |
- AppArmor bool |
|
| 434 |
- ProcessLabel string |
|
| 435 |
- MountLabel string |
|
| 423 |
+ AppArmor bool |
|
| 436 | 424 |
}{
|
| 437 |
- Command: c, |
|
| 438 |
- AppArmor: d.apparmor, |
|
| 439 |
- ProcessLabel: process, |
|
| 440 |
- MountLabel: mount, |
|
| 425 |
+ Command: c, |
|
| 426 |
+ AppArmor: d.apparmor, |
|
| 441 | 427 |
}); err != nil {
|
| 442 | 428 |
return "", err |
| 443 | 429 |
} |
| 430 |
+ |
|
| 444 | 431 |
return root, nil |
| 445 | 432 |
} |
| 446 | 433 |
|
| ... | ... |
@@ -34,10 +34,6 @@ lxc.pts = 1024 |
| 34 | 34 |
|
| 35 | 35 |
# disable the main console |
| 36 | 36 |
lxc.console = none |
| 37 |
-{{if .ProcessLabel}}
|
|
| 38 |
-lxc.se_context = {{ .ProcessLabel}}
|
|
| 39 |
-{{end}}
|
|
| 40 |
-{{$MOUNTLABEL := .MountLabel}}
|
|
| 41 | 37 |
|
| 42 | 38 |
# no controlling tty at all |
| 43 | 39 |
lxc.tty = 1 |
| ... | ... |
@@ -70,8 +66,8 @@ lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noe
|
| 70 | 70 |
lxc.mount.entry = {{.ProcessConfig.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw 0 0
|
| 71 | 71 |
{{end}}
|
| 72 | 72 |
|
| 73 |
-lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec" $MOUNTLABEL}} 0 0
|
|
| 74 |
-lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec" $MOUNTLABEL}} 0 0
|
|
| 73 |
+lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec" ""}} 0 0
|
|
| 74 |
+lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec" ""}} 0 0
|
|
| 75 | 75 |
|
| 76 | 76 |
{{range $value := .Mounts}}
|
| 77 | 77 |
{{if $value.Writable}}
|
| ... | ... |
@@ -106,8 +102,8 @@ lxc.cgroup.cpuset.cpus = {{.Resources.Cpuset}}
|
| 106 | 106 |
{{end}}
|
| 107 | 107 |
{{end}}
|
| 108 | 108 |
|
| 109 |
-{{if .Config.lxc}}
|
|
| 110 |
-{{range $value := .Config.lxc}}
|
|
| 109 |
+{{if .LxcConfig}}
|
|
| 110 |
+{{range $value := .LxcConfig}}
|
|
| 111 | 111 |
lxc.{{$value}}
|
| 112 | 112 |
{{end}}
|
| 113 | 113 |
{{end}}
|
| ... | ... |
@@ -83,11 +83,9 @@ func TestCustomLxcConfig(t *testing.T) {
|
| 83 | 83 |
} |
| 84 | 84 |
command := &execdriver.Command{
|
| 85 | 85 |
ID: "1", |
| 86 |
- Config: map[string][]string{
|
|
| 87 |
- "lxc": {
|
|
| 88 |
- "lxc.utsname = docker", |
|
| 89 |
- "lxc.cgroup.cpuset.cpus = 0,1", |
|
| 90 |
- }, |
|
| 86 |
+ LxcConfig: []string{
|
|
| 87 |
+ "lxc.utsname = docker", |
|
| 88 |
+ "lxc.cgroup.cpuset.cpus = 0,1", |
|
| 91 | 89 |
}, |
| 92 | 90 |
Network: &execdriver.Network{
|
| 93 | 91 |
Mtu: 1500, |
| 94 | 92 |
deleted file mode 100644 |
| ... | ... |
@@ -1,188 +0,0 @@ |
| 1 |
-package configuration |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "os/exec" |
|
| 6 |
- "path/filepath" |
|
| 7 |
- "strconv" |
|
| 8 |
- "strings" |
|
| 9 |
- |
|
| 10 |
- "github.com/docker/docker/pkg/units" |
|
| 11 |
- "github.com/docker/libcontainer" |
|
| 12 |
-) |
|
| 13 |
- |
|
| 14 |
-type Action func(*libcontainer.Config, interface{}, string) error
|
|
| 15 |
- |
|
| 16 |
-var actions = map[string]Action{
|
|
| 17 |
- "cap.add": addCap, // add a cap |
|
| 18 |
- "cap.drop": dropCap, // drop a cap |
|
| 19 |
- |
|
| 20 |
- "ns.add": addNamespace, // add a namespace |
|
| 21 |
- "ns.drop": dropNamespace, // drop a namespace when cloning |
|
| 22 |
- |
|
| 23 |
- "net.join": joinNetNamespace, // join another containers net namespace |
|
| 24 |
- |
|
| 25 |
- "cgroups.cpu_shares": cpuShares, // set the cpu shares |
|
| 26 |
- "cgroups.memory": memory, // set the memory limit |
|
| 27 |
- "cgroups.memory_reservation": memoryReservation, // set the memory reservation |
|
| 28 |
- "cgroups.memory_swap": memorySwap, // set the memory swap limit |
|
| 29 |
- "cgroups.cpuset.cpus": cpusetCpus, // set the cpus used |
|
| 30 |
- |
|
| 31 |
- "systemd.slice": systemdSlice, // set parent Slice used for systemd unit |
|
| 32 |
- |
|
| 33 |
- "apparmor_profile": apparmorProfile, // set the apparmor profile to apply |
|
| 34 |
- |
|
| 35 |
- "fs.readonly": readonlyFs, // make the rootfs of the container read only |
|
| 36 |
-} |
|
| 37 |
- |
|
| 38 |
-func cpusetCpus(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 39 |
- if container.Cgroups == nil {
|
|
| 40 |
- return fmt.Errorf("cannot set cgroups when they are disabled")
|
|
| 41 |
- } |
|
| 42 |
- container.Cgroups.CpusetCpus = value |
|
| 43 |
- |
|
| 44 |
- return nil |
|
| 45 |
-} |
|
| 46 |
- |
|
| 47 |
-func systemdSlice(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 48 |
- if container.Cgroups == nil {
|
|
| 49 |
- return fmt.Errorf("cannot set slice when cgroups are disabled")
|
|
| 50 |
- } |
|
| 51 |
- container.Cgroups.Slice = value |
|
| 52 |
- |
|
| 53 |
- return nil |
|
| 54 |
-} |
|
| 55 |
- |
|
| 56 |
-func apparmorProfile(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 57 |
- container.AppArmorProfile = value |
|
| 58 |
- return nil |
|
| 59 |
-} |
|
| 60 |
- |
|
| 61 |
-func cpuShares(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 62 |
- if container.Cgroups == nil {
|
|
| 63 |
- return fmt.Errorf("cannot set cgroups when they are disabled")
|
|
| 64 |
- } |
|
| 65 |
- v, err := strconv.ParseInt(value, 10, 0) |
|
| 66 |
- if err != nil {
|
|
| 67 |
- return err |
|
| 68 |
- } |
|
| 69 |
- container.Cgroups.CpuShares = v |
|
| 70 |
- return nil |
|
| 71 |
-} |
|
| 72 |
- |
|
| 73 |
-func memory(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 74 |
- if container.Cgroups == nil {
|
|
| 75 |
- return fmt.Errorf("cannot set cgroups when they are disabled")
|
|
| 76 |
- } |
|
| 77 |
- |
|
| 78 |
- v, err := units.RAMInBytes(value) |
|
| 79 |
- if err != nil {
|
|
| 80 |
- return err |
|
| 81 |
- } |
|
| 82 |
- container.Cgroups.Memory = v |
|
| 83 |
- return nil |
|
| 84 |
-} |
|
| 85 |
- |
|
| 86 |
-func memoryReservation(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 87 |
- if container.Cgroups == nil {
|
|
| 88 |
- return fmt.Errorf("cannot set cgroups when they are disabled")
|
|
| 89 |
- } |
|
| 90 |
- |
|
| 91 |
- v, err := units.RAMInBytes(value) |
|
| 92 |
- if err != nil {
|
|
| 93 |
- return err |
|
| 94 |
- } |
|
| 95 |
- container.Cgroups.MemoryReservation = v |
|
| 96 |
- return nil |
|
| 97 |
-} |
|
| 98 |
- |
|
| 99 |
-func memorySwap(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 100 |
- if container.Cgroups == nil {
|
|
| 101 |
- return fmt.Errorf("cannot set cgroups when they are disabled")
|
|
| 102 |
- } |
|
| 103 |
- v, err := strconv.ParseInt(value, 0, 64) |
|
| 104 |
- if err != nil {
|
|
| 105 |
- return err |
|
| 106 |
- } |
|
| 107 |
- container.Cgroups.MemorySwap = v |
|
| 108 |
- return nil |
|
| 109 |
-} |
|
| 110 |
- |
|
| 111 |
-func addCap(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 112 |
- container.Capabilities = append(container.Capabilities, value) |
|
| 113 |
- return nil |
|
| 114 |
-} |
|
| 115 |
- |
|
| 116 |
-func dropCap(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 117 |
- // If the capability is specified multiple times, remove all instances. |
|
| 118 |
- for i, capability := range container.Capabilities {
|
|
| 119 |
- if capability == value {
|
|
| 120 |
- container.Capabilities = append(container.Capabilities[:i], container.Capabilities[i+1:]...) |
|
| 121 |
- } |
|
| 122 |
- } |
|
| 123 |
- |
|
| 124 |
- // The capability wasn't found so we will drop it anyways. |
|
| 125 |
- return nil |
|
| 126 |
-} |
|
| 127 |
- |
|
| 128 |
-func addNamespace(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 129 |
- container.Namespaces[value] = true |
|
| 130 |
- return nil |
|
| 131 |
-} |
|
| 132 |
- |
|
| 133 |
-func dropNamespace(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 134 |
- container.Namespaces[value] = false |
|
| 135 |
- return nil |
|
| 136 |
-} |
|
| 137 |
- |
|
| 138 |
-func readonlyFs(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 139 |
- switch value {
|
|
| 140 |
- case "1", "true": |
|
| 141 |
- container.MountConfig.ReadonlyFs = true |
|
| 142 |
- default: |
|
| 143 |
- container.MountConfig.ReadonlyFs = false |
|
| 144 |
- } |
|
| 145 |
- return nil |
|
| 146 |
-} |
|
| 147 |
- |
|
| 148 |
-func joinNetNamespace(container *libcontainer.Config, context interface{}, value string) error {
|
|
| 149 |
- var ( |
|
| 150 |
- running = context.(map[string]*exec.Cmd) |
|
| 151 |
- cmd = running[value] |
|
| 152 |
- ) |
|
| 153 |
- |
|
| 154 |
- if cmd == nil || cmd.Process == nil {
|
|
| 155 |
- return fmt.Errorf("%s is not a valid running container to join", value)
|
|
| 156 |
- } |
|
| 157 |
- |
|
| 158 |
- nspath := filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net")
|
|
| 159 |
- container.Networks = append(container.Networks, &libcontainer.Network{
|
|
| 160 |
- Type: "netns", |
|
| 161 |
- NsPath: nspath, |
|
| 162 |
- }) |
|
| 163 |
- |
|
| 164 |
- return nil |
|
| 165 |
-} |
|
| 166 |
- |
|
| 167 |
-// configureCustomOptions takes string commands from the user and allows modification of the |
|
| 168 |
-// container's default configuration. |
|
| 169 |
-// |
|
| 170 |
-// TODO: this can be moved to a general utils or parser in pkg |
|
| 171 |
-func ParseConfiguration(container *libcontainer.Config, running map[string]*exec.Cmd, opts []string) error {
|
|
| 172 |
- for _, opt := range opts {
|
|
| 173 |
- kv := strings.SplitN(opt, "=", 2) |
|
| 174 |
- if len(kv) < 2 {
|
|
| 175 |
- return fmt.Errorf("invalid format for %s", opt)
|
|
| 176 |
- } |
|
| 177 |
- |
|
| 178 |
- action, exists := actions[kv[0]] |
|
| 179 |
- if !exists {
|
|
| 180 |
- return fmt.Errorf("%s is not a valid option for the native driver", kv[0])
|
|
| 181 |
- } |
|
| 182 |
- |
|
| 183 |
- if err := action(container, running, kv[1]); err != nil {
|
|
| 184 |
- return err |
|
| 185 |
- } |
|
| 186 |
- } |
|
| 187 |
- return nil |
|
| 188 |
-} |
| 189 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,193 +0,0 @@ |
| 1 |
-package configuration |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "testing" |
|
| 5 |
- |
|
| 6 |
- "github.com/docker/docker/daemon/execdriver/native/template" |
|
| 7 |
- "github.com/docker/libcontainer/security/capabilities" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-// Checks whether the expected capability is specified in the capabilities. |
|
| 11 |
-func hasCapability(expected string, capabilities []string) bool {
|
|
| 12 |
- for _, capability := range capabilities {
|
|
| 13 |
- if capability == expected {
|
|
| 14 |
- return true |
|
| 15 |
- } |
|
| 16 |
- } |
|
| 17 |
- return false |
|
| 18 |
-} |
|
| 19 |
- |
|
| 20 |
-func TestSetReadonlyRootFs(t *testing.T) {
|
|
| 21 |
- var ( |
|
| 22 |
- container = template.New() |
|
| 23 |
- opts = []string{
|
|
| 24 |
- "fs.readonly=true", |
|
| 25 |
- } |
|
| 26 |
- ) |
|
| 27 |
- |
|
| 28 |
- if container.MountConfig.ReadonlyFs {
|
|
| 29 |
- t.Fatal("container should not have a readonly rootfs by default")
|
|
| 30 |
- } |
|
| 31 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 32 |
- t.Fatal(err) |
|
| 33 |
- } |
|
| 34 |
- |
|
| 35 |
- if !container.MountConfig.ReadonlyFs {
|
|
| 36 |
- t.Fatal("container should have a readonly rootfs")
|
|
| 37 |
- } |
|
| 38 |
-} |
|
| 39 |
- |
|
| 40 |
-func TestConfigurationsDoNotConflict(t *testing.T) {
|
|
| 41 |
- var ( |
|
| 42 |
- container1 = template.New() |
|
| 43 |
- container2 = template.New() |
|
| 44 |
- opts = []string{
|
|
| 45 |
- "cap.add=NET_ADMIN", |
|
| 46 |
- } |
|
| 47 |
- ) |
|
| 48 |
- |
|
| 49 |
- if err := ParseConfiguration(container1, nil, opts); err != nil {
|
|
| 50 |
- t.Fatal(err) |
|
| 51 |
- } |
|
| 52 |
- |
|
| 53 |
- if !hasCapability("NET_ADMIN", container1.Capabilities) {
|
|
| 54 |
- t.Fatal("container one should have NET_ADMIN enabled")
|
|
| 55 |
- } |
|
| 56 |
- if hasCapability("NET_ADMIN", container2.Capabilities) {
|
|
| 57 |
- t.Fatal("container two should not have NET_ADMIN enabled")
|
|
| 58 |
- } |
|
| 59 |
-} |
|
| 60 |
- |
|
| 61 |
-func TestCpusetCpus(t *testing.T) {
|
|
| 62 |
- var ( |
|
| 63 |
- container = template.New() |
|
| 64 |
- opts = []string{
|
|
| 65 |
- "cgroups.cpuset.cpus=1,2", |
|
| 66 |
- } |
|
| 67 |
- ) |
|
| 68 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 69 |
- t.Fatal(err) |
|
| 70 |
- } |
|
| 71 |
- |
|
| 72 |
- if expected := "1,2"; container.Cgroups.CpusetCpus != expected {
|
|
| 73 |
- t.Fatalf("expected %s got %s for cpuset.cpus", expected, container.Cgroups.CpusetCpus)
|
|
| 74 |
- } |
|
| 75 |
-} |
|
| 76 |
- |
|
| 77 |
-func TestAppArmorProfile(t *testing.T) {
|
|
| 78 |
- var ( |
|
| 79 |
- container = template.New() |
|
| 80 |
- opts = []string{
|
|
| 81 |
- "apparmor_profile=koye-the-protector", |
|
| 82 |
- } |
|
| 83 |
- ) |
|
| 84 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 85 |
- t.Fatal(err) |
|
| 86 |
- } |
|
| 87 |
- |
|
| 88 |
- if expected := "koye-the-protector"; container.AppArmorProfile != expected {
|
|
| 89 |
- t.Fatalf("expected profile %s got %s", expected, container.AppArmorProfile)
|
|
| 90 |
- } |
|
| 91 |
-} |
|
| 92 |
- |
|
| 93 |
-func TestCpuShares(t *testing.T) {
|
|
| 94 |
- var ( |
|
| 95 |
- container = template.New() |
|
| 96 |
- opts = []string{
|
|
| 97 |
- "cgroups.cpu_shares=1048", |
|
| 98 |
- } |
|
| 99 |
- ) |
|
| 100 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 101 |
- t.Fatal(err) |
|
| 102 |
- } |
|
| 103 |
- |
|
| 104 |
- if expected := int64(1048); container.Cgroups.CpuShares != expected {
|
|
| 105 |
- t.Fatalf("expected cpu shares %d got %d", expected, container.Cgroups.CpuShares)
|
|
| 106 |
- } |
|
| 107 |
-} |
|
| 108 |
- |
|
| 109 |
-func TestMemory(t *testing.T) {
|
|
| 110 |
- var ( |
|
| 111 |
- container = template.New() |
|
| 112 |
- opts = []string{
|
|
| 113 |
- "cgroups.memory=500m", |
|
| 114 |
- } |
|
| 115 |
- ) |
|
| 116 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 117 |
- t.Fatal(err) |
|
| 118 |
- } |
|
| 119 |
- |
|
| 120 |
- if expected := int64(500 * 1024 * 1024); container.Cgroups.Memory != expected {
|
|
| 121 |
- t.Fatalf("expected memory %d got %d", expected, container.Cgroups.Memory)
|
|
| 122 |
- } |
|
| 123 |
-} |
|
| 124 |
- |
|
| 125 |
-func TestMemoryReservation(t *testing.T) {
|
|
| 126 |
- var ( |
|
| 127 |
- container = template.New() |
|
| 128 |
- opts = []string{
|
|
| 129 |
- "cgroups.memory_reservation=500m", |
|
| 130 |
- } |
|
| 131 |
- ) |
|
| 132 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 133 |
- t.Fatal(err) |
|
| 134 |
- } |
|
| 135 |
- |
|
| 136 |
- if expected := int64(500 * 1024 * 1024); container.Cgroups.MemoryReservation != expected {
|
|
| 137 |
- t.Fatalf("expected memory reservation %d got %d", expected, container.Cgroups.MemoryReservation)
|
|
| 138 |
- } |
|
| 139 |
-} |
|
| 140 |
- |
|
| 141 |
-func TestAddCap(t *testing.T) {
|
|
| 142 |
- var ( |
|
| 143 |
- container = template.New() |
|
| 144 |
- opts = []string{
|
|
| 145 |
- "cap.add=MKNOD", |
|
| 146 |
- "cap.add=SYS_ADMIN", |
|
| 147 |
- } |
|
| 148 |
- ) |
|
| 149 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 150 |
- t.Fatal(err) |
|
| 151 |
- } |
|
| 152 |
- |
|
| 153 |
- if !hasCapability("MKNOD", container.Capabilities) {
|
|
| 154 |
- t.Fatal("container should have MKNOD enabled")
|
|
| 155 |
- } |
|
| 156 |
- if !hasCapability("SYS_ADMIN", container.Capabilities) {
|
|
| 157 |
- t.Fatal("container should have SYS_ADMIN enabled")
|
|
| 158 |
- } |
|
| 159 |
-} |
|
| 160 |
- |
|
| 161 |
-func TestDropCap(t *testing.T) {
|
|
| 162 |
- var ( |
|
| 163 |
- container = template.New() |
|
| 164 |
- opts = []string{
|
|
| 165 |
- "cap.drop=MKNOD", |
|
| 166 |
- } |
|
| 167 |
- ) |
|
| 168 |
- // enabled all caps like in privileged mode |
|
| 169 |
- container.Capabilities = capabilities.GetAllCapabilities() |
|
| 170 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 171 |
- t.Fatal(err) |
|
| 172 |
- } |
|
| 173 |
- |
|
| 174 |
- if hasCapability("MKNOD", container.Capabilities) {
|
|
| 175 |
- t.Fatal("container should not have MKNOD enabled")
|
|
| 176 |
- } |
|
| 177 |
-} |
|
| 178 |
- |
|
| 179 |
-func TestDropNamespace(t *testing.T) {
|
|
| 180 |
- var ( |
|
| 181 |
- container = template.New() |
|
| 182 |
- opts = []string{
|
|
| 183 |
- "ns.drop=NEWNET", |
|
| 184 |
- } |
|
| 185 |
- ) |
|
| 186 |
- if err := ParseConfiguration(container, nil, opts); err != nil {
|
|
| 187 |
- t.Fatal(err) |
|
| 188 |
- } |
|
| 189 |
- |
|
| 190 |
- if container.Namespaces["NEWNET"] {
|
|
| 191 |
- t.Fatal("container should not have NEWNET enabled")
|
|
| 192 |
- } |
|
| 193 |
-} |
| ... | ... |
@@ -9,7 +9,6 @@ import ( |
| 9 | 9 |
"path/filepath" |
| 10 | 10 |
|
| 11 | 11 |
"github.com/docker/docker/daemon/execdriver" |
| 12 |
- "github.com/docker/docker/daemon/execdriver/native/configuration" |
|
| 13 | 12 |
"github.com/docker/docker/daemon/execdriver/native/template" |
| 14 | 13 |
"github.com/docker/libcontainer" |
| 15 | 14 |
"github.com/docker/libcontainer/apparmor" |
| ... | ... |
@@ -69,10 +68,6 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, e |
| 69 | 69 |
} |
| 70 | 70 |
d.Unlock() |
| 71 | 71 |
|
| 72 |
- if err := configuration.ParseConfiguration(container, cmds, c.Config["native"]); err != nil {
|
|
| 73 |
- return nil, err |
|
| 74 |
- } |
|
| 75 |
- |
|
| 76 | 72 |
return container, nil |
| 77 | 73 |
} |
| 78 | 74 |
|
| ... | ... |
@@ -175,8 +170,8 @@ func (d *driver) setupMounts(container *libcontainer.Config, c *execdriver.Comma |
| 175 | 175 |
} |
| 176 | 176 |
|
| 177 | 177 |
func (d *driver) setupLabels(container *libcontainer.Config, c *execdriver.Command) error {
|
| 178 |
- container.ProcessLabel = c.Config["process_label"][0] |
|
| 179 |
- container.MountConfig.MountLabel = c.Config["mount_label"][0] |
|
| 178 |
+ container.ProcessLabel = c.ProcessLabel |
|
| 179 |
+ container.MountConfig.MountLabel = c.MountLabel |
|
| 180 | 180 |
|
| 181 | 181 |
return nil |
| 182 | 182 |
} |
| ... | ... |
@@ -32,20 +32,22 @@ func migratePortMappings(config *runconfig.Config, hostConfig *runconfig.HostCon |
| 32 | 32 |
return nil |
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 |
-func mergeLxcConfIntoOptions(hostConfig *runconfig.HostConfig, driverConfig map[string][]string) {
|
|
| 35 |
+func mergeLxcConfIntoOptions(hostConfig *runconfig.HostConfig) []string {
|
|
| 36 | 36 |
if hostConfig == nil {
|
| 37 |
- return |
|
| 37 |
+ return nil |
|
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 |
+ out := []string{}
|
|
| 41 |
+ |
|
| 40 | 42 |
// merge in the lxc conf options into the generic config map |
| 41 | 43 |
if lxcConf := hostConfig.LxcConf; lxcConf != nil {
|
| 42 |
- lxc := driverConfig["lxc"] |
|
| 43 | 44 |
for _, pair := range lxcConf {
|
| 44 | 45 |
// because lxc conf gets the driver name lxc.XXXX we need to trim it off |
| 45 | 46 |
// and let the lxc driver add it back later if needed |
| 46 | 47 |
parts := strings.SplitN(pair.Key, ".", 2) |
| 47 |
- lxc = append(lxc, fmt.Sprintf("%s=%s", parts[1], pair.Value))
|
|
| 48 |
+ out = append(out, fmt.Sprintf("%s=%s", parts[1], pair.Value))
|
|
| 48 | 49 |
} |
| 49 |
- driverConfig["lxc"] = lxc |
|
| 50 | 50 |
} |
| 51 |
+ |
|
| 52 |
+ return out |
|
| 51 | 53 |
} |
| ... | ... |
@@ -8,21 +8,15 @@ import ( |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 | 10 |
func TestMergeLxcConfig(t *testing.T) {
|
| 11 |
- var ( |
|
| 12 |
- hostConfig = &runconfig.HostConfig{
|
|
| 13 |
- LxcConf: []utils.KeyValuePair{
|
|
| 14 |
- {Key: "lxc.cgroups.cpuset", Value: "1,2"},
|
|
| 15 |
- }, |
|
| 16 |
- } |
|
| 17 |
- driverConfig = make(map[string][]string) |
|
| 18 |
- ) |
|
| 19 |
- |
|
| 20 |
- mergeLxcConfIntoOptions(hostConfig, driverConfig) |
|
| 21 |
- if l := len(driverConfig["lxc"]); l > 1 {
|
|
| 22 |
- t.Fatalf("expected lxc options len of 1 got %d", l)
|
|
| 11 |
+ hostConfig := &runconfig.HostConfig{
|
|
| 12 |
+ LxcConf: []utils.KeyValuePair{
|
|
| 13 |
+ {Key: "lxc.cgroups.cpuset", Value: "1,2"},
|
|
| 14 |
+ }, |
|
| 23 | 15 |
} |
| 24 | 16 |
|
| 25 |
- cpuset := driverConfig["lxc"][0] |
|
| 17 |
+ out := mergeLxcConfIntoOptions(hostConfig) |
|
| 18 |
+ |
|
| 19 |
+ cpuset := out[0] |
|
| 26 | 20 |
if expected := "cgroups.cpuset=1,2"; cpuset != expected {
|
| 27 | 21 |
t.Fatalf("expected %s got %s", expected, cpuset)
|
| 28 | 22 |
} |