Refactor device handling code

We now have one place that keeps track of (most) devices that are allowed and created within the container.  That place is pkg/libcontainer/devices/devices.go

This fixes several inconsistencies between which devices were created in the lxc backend and the native backend.  It also fixes inconsistencies between wich devices were created and which were allowed.  For example, /dev/full was being created but it was not allowed within the cgroup.  It also declares the file modes and permissions of the default devices, rather than copying them from the host.  This is in line with docker's philosphy of not being host dependent.

Docker-DCO-1.1-Signed-off-by: Timothy Hobbs <timothyhobbs@seznam.cz> (github: https://github.com/timthelion)
This commit is contained in:
Timothy Hobbs
2014-05-30 19:21:29 +00:00
committed by Timothy
parent f00c2e5007
commit 608702b980
19 changed files with 466 additions and 214 deletions
+18 -14
View File
@@ -5,6 +5,8 @@ import (
"io"
"os"
"os/exec"
"github.com/dotcloud/docker/pkg/libcontainer/devices"
)
// Context is a generic key value pair that allows
@@ -120,20 +122,22 @@ type Mount struct {
type Command struct {
exec.Cmd `json:"-"`
ID string `json:"id"`
Privileged bool `json:"privileged"`
User string `json:"user"`
Rootfs string `json:"rootfs"` // root fs of the container
InitPath string `json:"initpath"` // dockerinit
Entrypoint string `json:"entrypoint"`
Arguments []string `json:"arguments"`
WorkingDir string `json:"working_dir"`
ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver
Tty bool `json:"tty"`
Network *Network `json:"network"`
Config map[string][]string `json:"config"` // generic values that specific drivers can consume
Resources *Resources `json:"resources"`
Mounts []Mount `json:"mounts"`
ID string `json:"id"`
Privileged bool `json:"privileged"`
User string `json:"user"`
Rootfs string `json:"rootfs"` // root fs of the container
InitPath string `json:"initpath"` // dockerinit
Entrypoint string `json:"entrypoint"`
Arguments []string `json:"arguments"`
WorkingDir string `json:"working_dir"`
ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver
Tty bool `json:"tty"`
Network *Network `json:"network"`
Config map[string][]string `json:"config"` // generic values that specific drivers can consume
Resources *Resources `json:"resources"`
Mounts []Mount `json:"mounts"`
AllowedDevices []devices.Device `json:"allowed_devices"`
AutoCreatedDevices []devices.Device `json:"autocreated_devices"`
Terminal Terminal `json:"-"` // standard or tty terminal
Console string `json:"-"` // dev/console path
+5
View File
@@ -17,6 +17,7 @@ import (
"github.com/dotcloud/docker/daemon/execdriver"
"github.com/dotcloud/docker/pkg/label"
"github.com/dotcloud/docker/pkg/libcontainer/cgroups"
"github.com/dotcloud/docker/pkg/libcontainer/mount/nodes"
"github.com/dotcloud/docker/pkg/system"
"github.com/dotcloud/docker/utils"
)
@@ -159,6 +160,10 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
c.Path = aname
c.Args = append([]string{name}, arg...)
if err := nodes.CreateDeviceNodes(c.Rootfs, c.AutoCreatedDevices); err != nil {
return -1, err
}
if err := c.Start(); err != nil {
return -1, err
}
+4 -31
View File
@@ -47,37 +47,10 @@ lxc.cgroup.devices.allow = a
{{else}}
# no implicit access to devices
lxc.cgroup.devices.deny = a
# but allow mknod for any device
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/urandom,/dev/random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
# /dev/pts/ - pts namespaces are "coming soon"
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# tuntap
lxc.cgroup.devices.allow = c 10:200 rwm
# fuse
#lxc.cgroup.devices.allow = c 10:229 rwm
# rtc
#lxc.cgroup.devices.allow = c 254:0 rwm
#Allow the devices passed to us in the AllowedDevices list.
{{range $allowedDevice := .AllowedDevices}}
lxc.cgroup.devices.allow = {{$allowedDevice.GetCgroupAllowString}}
{{end}}
{{end}}
# standard mount point
@@ -11,6 +11,8 @@ import (
"strings"
"testing"
"time"
"github.com/dotcloud/docker/pkg/libcontainer/devices"
)
func TestLXCConfig(t *testing.T) {
@@ -47,6 +49,7 @@ func TestLXCConfig(t *testing.T) {
Mtu: 1500,
Interface: nil,
},
AllowedDevices: make([]devices.Device, 0),
}
p, err := driver.generateLXCConfig(command)
if err != nil {
+3 -7
View File
@@ -11,7 +11,6 @@ import (
"github.com/dotcloud/docker/daemon/execdriver/native/template"
"github.com/dotcloud/docker/pkg/apparmor"
"github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/mount/nodes"
)
// createContainer populates and configures the container type with the
@@ -25,6 +24,8 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Container
container.WorkingDir = c.WorkingDir
container.Env = c.Env
container.Cgroups.Name = c.ID
container.Cgroups.AllowedDevices = c.AllowedDevices
container.DeviceNodes = c.AutoCreatedDevices
// check to see if we are running in ramdisk to disable pivot root
container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
container.Context["restrictions"] = "true"
@@ -105,15 +106,10 @@ func (d *driver) createNetwork(container *libcontainer.Container, c *execdriver.
func (d *driver) setPrivileged(container *libcontainer.Container) (err error) {
container.Capabilities = libcontainer.GetAllCapabilities()
container.Cgroups.DeviceAccess = true
container.Cgroups.AllowAllDevices = true
delete(container.Context, "restrictions")
container.OptionalDeviceNodes = nil
if container.RequiredDeviceNodes, err = nodes.GetHostDeviceNodes(); err != nil {
return err
}
if apparmor.IsEnabled() {
container.Context["apparmor_profile"] = "unconfined"
}
@@ -4,7 +4,6 @@ import (
"github.com/dotcloud/docker/pkg/apparmor"
"github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/cgroups"
"github.com/dotcloud/docker/pkg/libcontainer/mount/nodes"
)
// New returns the docker default configuration for libcontainer
@@ -30,12 +29,10 @@ func New() *libcontainer.Container {
"NEWNET": true,
},
Cgroups: &cgroups.Cgroup{
Parent: "docker",
DeviceAccess: false,
Parent: "docker",
AllowAllDevices: false,
},
Context: libcontainer.Context{},
RequiredDeviceNodes: nodes.DefaultNodes,
OptionalDeviceNodes: []string{"/dev/fuse"},
Context: libcontainer.Context{},
}
if apparmor.IsEnabled() {
container.Context["apparmor_profile"] = "docker-default"