Skip to content

Commit

Permalink
Update runc for devices changes
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
  • Loading branch information
crosbymichael committed Feb 8, 2016
1 parent c2c0458 commit 3baae2d
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 491 deletions.
299 changes: 3 additions & 296 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,303 +78,10 @@ PID USER COMMAND
### OCI Container JSON Format:

OCI container JSON format is based on OCI [specs](https://github.com/opencontainers/specs).
You can generate JSON files by using `runc spec`, it'll generate `config.json`
and `runtime.json`. It assumes that the file-system is found in a directory called
You can generate JSON files by using `runc spec`.
It assumes that the file-system is found in a directory called
`rootfs` and there is a user with uid and gid of `0` defined within that file-system.

Below are sample `config.json` and `runtime.json` configuration files. Note that it
could be outdated, please always create base JSON files by `runc spec`.

`config.json`:
```json
{
"version": "0.2.0",
"platform": {
"os": "linux",
"arch": "amd64"
},
"process": {
"terminal": true,
"user": {
"uid": 0,
"gid": 0,
"additionalGids": null
},
"args": [
"sh"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": ""
},
"root": {
"path": "rootfs",
"readonly": true
},
"hostname": "shell",
"mounts": [
{
"name": "proc",
"path": "/proc"
},
{
"name": "dev",
"path": "/dev"
},
{
"name": "devpts",
"path": "/dev/pts"
},
{
"name": "shm",
"path": "/dev/shm"
},
{
"name": "mqueue",
"path": "/dev/mqueue"
},
{
"name": "sysfs",
"path": "/sys"
},
{
"name": "cgroup",
"path": "/sys/fs/cgroup"
}
],
"linux": {
"capabilities": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
]
}
}
```

`runtime.json`:
```json
{
"mounts": {
"cgroup": {
"type": "cgroup",
"source": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
},
"dev": {
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
"devpts": {
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
"mqueue": {
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
"proc": {
"type": "proc",
"source": "proc",
"options": null
},
"shm": {
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
"sysfs": {
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev"
]
}
},
"hooks": {
"prestart": null,
"poststart": null,
"poststop": null
},
"linux": {
"uidMappings": null,
"gidMappings": null,
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"sysctl": null,
"resources": {
"disableOOMKiller": false,
"memory": {
"limit": 0,
"reservation": 0,
"swap": 0,
"kernel": 0,
"swappiness": -1
},
"cpu": {
"shares": 0,
"quota": 0,
"period": 0,
"realtimeRuntime": 0,
"realtimePeriod": 0,
"cpus": "",
"mems": ""
},
"pids": {
"limit": 0
},
"blockIO": {
"blkioWeight": 0,
"blkioLeafWeight": 0,
"blkioWeightDevice": null,
"blkioThrottleReadBpsDevice": null,
"blkioThrottleWriteBpsDevice": null,
"blkioThrottleReadIOPSDevice": null,
"blkioThrottleWriteIOPSDevice": null
},
"hugepageLimits": null,
"network": {
"classId": "",
"priorities": null
}
},
"cgroupsPath": "",
"namespaces": [
{
"type": "pid",
"path": ""
},
{
"type": "network",
"path": ""
},
{
"type": "ipc",
"path": ""
},
{
"type": "uts",
"path": ""
},
{
"type": "mount",
"path": ""
}
],
"devices": [
{
"path": "/dev/null",
"type": 99,
"major": 1,
"minor": 3,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/random",
"type": 99,
"major": 1,
"minor": 8,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/full",
"type": 99,
"major": 1,
"minor": 7,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/tty",
"type": 99,
"major": 5,
"minor": 0,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/zero",
"type": 99,
"major": 1,
"minor": 5,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/urandom",
"type": 99,
"major": 1,
"minor": 9,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
}
],
"apparmorProfile": "",
"selinuxProcessLabel": "",
"seccomp": {
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": null,
"syscalls": []
},
"rootfsPropagation": ""
}
}
```

### Examples:

#### Using a Docker image (requires version 1.3 or later)
Expand All @@ -388,7 +95,7 @@ To test using Docker's `busybox` image follow these steps:
mkdir rootfs
tar -C rootfs -xf busybox.tar
```
* Create `config.json` and `runtime.json` by using `runc spec`.
* Create `config.json` by using `runc spec`.
* Execute `runc start` and you should be placed into a shell where you can run `ps`:
```
$ runc start
Expand Down
13 changes: 13 additions & 0 deletions libcontainer/cgroups/fs/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ func (s *DevicesGroup) Apply(d *cgroupData) error {
}

func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
devices := cgroup.Resources.Devices
if len(devices) > 0 {
for _, dev := range devices {
file := "devices.deny"
if dev.Allow {
file = "devices.allow"
}
if err := writeFile(path, file, dev.CgroupString()); err != nil {
return err
}
}
return nil
}
if !cgroup.Resources.AllowAllDevices {
if err := writeFile(path, "devices.deny", "a"); err != nil {
return err
Expand Down
13 changes: 8 additions & 5 deletions libcontainer/configs/cgroup_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ type Cgroup struct {

type Resources struct {
// If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list.
AllowAllDevices bool `json:"allow_all_devices"`

AllowedDevices []*Device `json:"allowed_devices"`

DeniedDevices []*Device `json:"denied_devices"`
// Deprecated
AllowAllDevices bool `json:"allow_all_devices,omitempty"`
// Deprecated
AllowedDevices []*Device `json:"allowed_devices,omitempty"`
// Deprecated
DeniedDevices []*Device `json:"denied_devices,omitempty"`

Devices []*Device `json:"devices"`

// Memory limit (in bytes)
Memory int64 `json:"memory"`
Expand Down
11 changes: 4 additions & 7 deletions libcontainer/configs/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,13 @@ type Device struct {

// Gid of the device.
Gid uint32 `json:"gid"`

// Write the file to the allowed list
Allow bool `json:"allow"`
}

func (d *Device) CgroupString() string {
var p string
if d.Permissions == "" {
p = "rwm" // empty permissions is invalid... causes a write invalid argument error upon saving to cgroups
} else {
p = d.Permissions
}
return fmt.Sprintf("%c %s:%s %s", d.Type, deviceNumberString(d.Major), deviceNumberString(d.Minor), p)
return fmt.Sprintf("%c %s:%s %s", d.Type, deviceNumberString(d.Major), deviceNumberString(d.Minor), d.Permissions)
}

func (d *Device) Mkdev() int {
Expand Down

0 comments on commit 3baae2d

Please sign in to comment.