Update runc for devices changes
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
c2c0458598
commit
3baae2d525
299
README.md
299
README.md
|
@ -78,303 +78,10 @@ PID USER COMMAND
|
||||||
### OCI Container JSON Format:
|
### OCI Container JSON Format:
|
||||||
|
|
||||||
OCI container JSON format is based on OCI [specs](https://github.com/opencontainers/specs).
|
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`
|
You can generate JSON files by using `runc spec`.
|
||||||
and `runtime.json`. It assumes that the file-system is found in a directory called
|
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.
|
`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:
|
### Examples:
|
||||||
|
|
||||||
#### Using a Docker image (requires version 1.3 or later)
|
#### Using a Docker image (requires version 1.3 or later)
|
||||||
|
@ -388,7 +95,7 @@ To test using Docker's `busybox` image follow these steps:
|
||||||
mkdir rootfs
|
mkdir rootfs
|
||||||
tar -C rootfs -xf busybox.tar
|
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`:
|
* Execute `runc start` and you should be placed into a shell where you can run `ps`:
|
||||||
```
|
```
|
||||||
$ runc start
|
$ runc start
|
||||||
|
|
|
@ -25,6 +25,19 @@ func (s *DevicesGroup) Apply(d *cgroupData) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) 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 !cgroup.Resources.AllowAllDevices {
|
||||||
if err := writeFile(path, "devices.deny", "a"); err != nil {
|
if err := writeFile(path, "devices.deny", "a"); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -28,11 +28,14 @@ type Cgroup struct {
|
||||||
|
|
||||||
type Resources 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.
|
// 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"`
|
// Deprecated
|
||||||
|
AllowAllDevices bool `json:"allow_all_devices,omitempty"`
|
||||||
|
// Deprecated
|
||||||
|
AllowedDevices []*Device `json:"allowed_devices,omitempty"`
|
||||||
|
// Deprecated
|
||||||
|
DeniedDevices []*Device `json:"denied_devices,omitempty"`
|
||||||
|
|
||||||
AllowedDevices []*Device `json:"allowed_devices"`
|
Devices []*Device `json:"devices"`
|
||||||
|
|
||||||
DeniedDevices []*Device `json:"denied_devices"`
|
|
||||||
|
|
||||||
// Memory limit (in bytes)
|
// Memory limit (in bytes)
|
||||||
Memory int64 `json:"memory"`
|
Memory int64 `json:"memory"`
|
||||||
|
|
|
@ -35,16 +35,13 @@ type Device struct {
|
||||||
|
|
||||||
// Gid of the device.
|
// Gid of the device.
|
||||||
Gid uint32 `json:"gid"`
|
Gid uint32 `json:"gid"`
|
||||||
|
|
||||||
|
// Write the file to the allowed list
|
||||||
|
Allow bool `json:"allow"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) CgroupString() string {
|
func (d *Device) CgroupString() string {
|
||||||
var p string
|
return fmt.Sprintf("%c %s:%s %s", d.Type, deviceNumberString(d.Major), deviceNumberString(d.Minor), d.Permissions)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) Mkdev() int {
|
func (d *Device) Mkdev() int {
|
||||||
|
|
388
spec.go
388
spec.go
|
@ -107,7 +107,14 @@ var specCommand = cli.Command{
|
||||||
"CAP_KILL",
|
"CAP_KILL",
|
||||||
"CAP_NET_BIND_SERVICE",
|
"CAP_NET_BIND_SERVICE",
|
||||||
},
|
},
|
||||||
|
Resources: &specs.Resources{
|
||||||
|
Devices: []specs.DeviceCgroup{
|
||||||
|
{
|
||||||
|
Allow: false,
|
||||||
|
Access: sPtr("rwm"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
Namespaces: []specs.Namespace{
|
Namespaces: []specs.Namespace{
|
||||||
{
|
{
|
||||||
Type: "pid",
|
Type: "pid",
|
||||||
|
@ -125,7 +132,6 @@ var specCommand = cli.Command{
|
||||||
Type: "mount",
|
Type: "mount",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Rlimits: []specs.Rlimit{
|
Rlimits: []specs.Rlimit{
|
||||||
{
|
{
|
||||||
Type: "RLIMIT_NOFILE",
|
Type: "RLIMIT_NOFILE",
|
||||||
|
@ -133,90 +139,6 @@ var specCommand = cli.Command{
|
||||||
Soft: uint64(1024),
|
Soft: uint64(1024),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Resources: &specs.Resources{
|
|
||||||
Devices: []specs.DeviceCgroup{
|
|
||||||
{
|
|
||||||
Allow: false,
|
|
||||||
Access: sPtr("rwm"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Allow: true,
|
|
||||||
Type: rPtr('c'),
|
|
||||||
Major: iPtr(8),
|
|
||||||
Minor: iPtr(229),
|
|
||||||
Access: sPtr("rw"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Allow: true,
|
|
||||||
Type: rPtr('b'),
|
|
||||||
Major: iPtr(8),
|
|
||||||
Minor: iPtr(0),
|
|
||||||
Access: sPtr("r"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Memory: &specs.Memory{},
|
|
||||||
},
|
|
||||||
Devices: []specs.Device{
|
|
||||||
{
|
|
||||||
Type: 'c',
|
|
||||||
Path: "/dev/null",
|
|
||||||
Major: 1,
|
|
||||||
Minor: 3,
|
|
||||||
FileMode: fmPtr(0666),
|
|
||||||
UID: u32Ptr(0),
|
|
||||||
GID: u32Ptr(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: 'c',
|
|
||||||
Path: "/dev/random",
|
|
||||||
Major: 1,
|
|
||||||
Minor: 8,
|
|
||||||
FileMode: fmPtr(0666),
|
|
||||||
UID: u32Ptr(0),
|
|
||||||
GID: u32Ptr(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: 'c',
|
|
||||||
Path: "/dev/full",
|
|
||||||
Major: 1,
|
|
||||||
Minor: 7,
|
|
||||||
FileMode: fmPtr(0666),
|
|
||||||
UID: u32Ptr(0),
|
|
||||||
GID: u32Ptr(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: 'c',
|
|
||||||
Path: "/dev/tty",
|
|
||||||
Major: 5,
|
|
||||||
Minor: 0,
|
|
||||||
FileMode: fmPtr(0666),
|
|
||||||
UID: u32Ptr(0),
|
|
||||||
GID: u32Ptr(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: 'c',
|
|
||||||
Path: "/dev/zero",
|
|
||||||
Major: 1,
|
|
||||||
Minor: 5,
|
|
||||||
FileMode: fmPtr(0666),
|
|
||||||
UID: u32Ptr(0),
|
|
||||||
GID: u32Ptr(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: 'c',
|
|
||||||
Path: "/dev/urandom",
|
|
||||||
Major: 1,
|
|
||||||
Minor: 9,
|
|
||||||
FileMode: fmPtr(0666),
|
|
||||||
UID: u32Ptr(0),
|
|
||||||
GID: u32Ptr(0),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
Seccomp: specs.Seccomp{
|
|
||||||
DefaultAction: "SCMP_ACT_ALLOW",
|
|
||||||
Syscalls: []specs.Syscall{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +277,7 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*config
|
||||||
}
|
}
|
||||||
config.Rlimits = append(config.Rlimits, rl)
|
config.Rlimits = append(config.Rlimits, rl)
|
||||||
}
|
}
|
||||||
c, err := createCgroupConfig(cgroupName, spec, config.Devices)
|
c, err := createCgroupConfig(cgroupName, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -403,7 +325,7 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createCgroupConfig(name string, spec *specs.LinuxSpec, devices []*configs.Device) (*configs.Cgroup, error) {
|
func createCgroupConfig(name string, spec *specs.LinuxSpec) (*configs.Cgroup, error) {
|
||||||
myCgroupPath, err := cgroups.GetThisCgroupDir("devices")
|
myCgroupPath, err := cgroups.GetThisCgroupDir("devices")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -413,125 +335,219 @@ func createCgroupConfig(name string, spec *specs.LinuxSpec, devices []*configs.D
|
||||||
Parent: myCgroupPath,
|
Parent: myCgroupPath,
|
||||||
Resources: &configs.Resources{},
|
Resources: &configs.Resources{},
|
||||||
}
|
}
|
||||||
c.Resources.AllowedDevices = append(devices, allowedDevices...)
|
c.Resources.AllowedDevices = allowedDevices
|
||||||
r := spec.Linux.Resources
|
r := spec.Linux.Resources
|
||||||
if r != nil {
|
if r == nil {
|
||||||
if r.Memory != nil {
|
return c, nil
|
||||||
if r.Memory.Limit != nil {
|
}
|
||||||
c.Resources.Memory = int64(*r.Memory.Limit)
|
for i, d := range spec.Linux.Resources.Devices {
|
||||||
}
|
var (
|
||||||
if r.Memory.Reservation != nil {
|
t = 'a'
|
||||||
c.Resources.MemoryReservation = int64(*r.Memory.Reservation)
|
major = int64(-1)
|
||||||
}
|
minor = int64(-1)
|
||||||
if r.Memory.Swap != nil {
|
)
|
||||||
c.Resources.MemorySwap = int64(*r.Memory.Swap)
|
if d.Type != nil {
|
||||||
}
|
t = *d.Type
|
||||||
if r.Memory.Kernel != nil {
|
}
|
||||||
c.Resources.KernelMemory = int64(*r.Memory.Kernel)
|
if d.Major != nil {
|
||||||
}
|
major = *d.Major
|
||||||
if r.Memory.Swappiness != nil {
|
}
|
||||||
c.Resources.MemorySwappiness = int64(*r.Memory.Swappiness)
|
if d.Minor != nil {
|
||||||
|
minor = *d.Minor
|
||||||
|
}
|
||||||
|
if d.Access == nil || *d.Access == "" {
|
||||||
|
return nil, fmt.Errorf("device access at %d field canot be empty", i)
|
||||||
|
}
|
||||||
|
dd := &configs.Device{
|
||||||
|
Type: t,
|
||||||
|
Major: major,
|
||||||
|
Minor: minor,
|
||||||
|
Permissions: *d.Access,
|
||||||
|
Allow: d.Allow,
|
||||||
|
}
|
||||||
|
c.Resources.Devices = append(c.Resources.Devices, dd)
|
||||||
|
}
|
||||||
|
// append the default allowed devices to the end of the list
|
||||||
|
c.Resources.Devices = append(c.Resources.Devices, allowedDevices...)
|
||||||
|
if r.Memory != nil {
|
||||||
|
if r.Memory.Limit != nil {
|
||||||
|
c.Resources.Memory = int64(*r.Memory.Limit)
|
||||||
|
}
|
||||||
|
if r.Memory.Reservation != nil {
|
||||||
|
c.Resources.MemoryReservation = int64(*r.Memory.Reservation)
|
||||||
|
}
|
||||||
|
if r.Memory.Swap != nil {
|
||||||
|
c.Resources.MemorySwap = int64(*r.Memory.Swap)
|
||||||
|
}
|
||||||
|
if r.Memory.Kernel != nil {
|
||||||
|
c.Resources.KernelMemory = int64(*r.Memory.Kernel)
|
||||||
|
}
|
||||||
|
if r.Memory.Swappiness != nil {
|
||||||
|
c.Resources.MemorySwappiness = int64(*r.Memory.Swappiness)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.CPU != nil {
|
||||||
|
if r.CPU.Shares != nil {
|
||||||
|
c.Resources.CpuShares = int64(*r.CPU.Shares)
|
||||||
|
}
|
||||||
|
if r.CPU.Quota != nil {
|
||||||
|
c.Resources.CpuQuota = int64(*r.CPU.Quota)
|
||||||
|
}
|
||||||
|
if r.CPU.Period != nil {
|
||||||
|
c.Resources.CpuPeriod = int64(*r.CPU.Period)
|
||||||
|
}
|
||||||
|
if r.CPU.RealtimeRuntime != nil {
|
||||||
|
c.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
|
||||||
|
}
|
||||||
|
if r.CPU.RealtimePeriod != nil {
|
||||||
|
c.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
|
||||||
|
}
|
||||||
|
if r.CPU.Cpus != nil {
|
||||||
|
c.Resources.CpusetCpus = *r.CPU.Cpus
|
||||||
|
}
|
||||||
|
if r.CPU.Mems != nil {
|
||||||
|
c.Resources.CpusetMems = *r.CPU.Mems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.Pids != nil {
|
||||||
|
c.Resources.PidsLimit = *r.Pids.Limit
|
||||||
|
}
|
||||||
|
if r.BlockIO != nil {
|
||||||
|
if r.BlockIO.Weight != nil {
|
||||||
|
c.Resources.BlkioWeight = *r.BlockIO.Weight
|
||||||
|
}
|
||||||
|
if r.BlockIO.LeafWeight != nil {
|
||||||
|
c.Resources.BlkioLeafWeight = *r.BlockIO.LeafWeight
|
||||||
|
}
|
||||||
|
if r.BlockIO.WeightDevice != nil {
|
||||||
|
for _, wd := range r.BlockIO.WeightDevice {
|
||||||
|
weightDevice := configs.NewWeightDevice(wd.Major, wd.Minor, *wd.Weight, *wd.LeafWeight)
|
||||||
|
c.Resources.BlkioWeightDevice = append(c.Resources.BlkioWeightDevice, weightDevice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if r.BlockIO.ThrottleReadBpsDevice != nil {
|
||||||
if r.CPU != nil {
|
for _, td := range r.BlockIO.ThrottleReadBpsDevice {
|
||||||
if r.CPU.Shares != nil {
|
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
||||||
c.Resources.CpuShares = int64(*r.CPU.Shares)
|
c.Resources.BlkioThrottleReadBpsDevice = append(c.Resources.BlkioThrottleReadBpsDevice, throttleDevice)
|
||||||
}
|
|
||||||
if r.CPU.Quota != nil {
|
|
||||||
c.Resources.CpuQuota = int64(*r.CPU.Quota)
|
|
||||||
}
|
|
||||||
if r.CPU.Period != nil {
|
|
||||||
c.Resources.CpuPeriod = int64(*r.CPU.Period)
|
|
||||||
}
|
|
||||||
if r.CPU.RealtimeRuntime != nil {
|
|
||||||
c.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
|
|
||||||
}
|
|
||||||
if r.CPU.RealtimePeriod != nil {
|
|
||||||
c.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
|
|
||||||
}
|
|
||||||
if r.CPU.Cpus != nil {
|
|
||||||
c.Resources.CpusetCpus = *r.CPU.Cpus
|
|
||||||
}
|
|
||||||
if r.CPU.Mems != nil {
|
|
||||||
c.Resources.CpusetMems = *r.CPU.Mems
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if r.Pids != nil {
|
if r.BlockIO.ThrottleWriteBpsDevice != nil {
|
||||||
c.Resources.PidsLimit = *r.Pids.Limit
|
for _, td := range r.BlockIO.ThrottleWriteBpsDevice {
|
||||||
}
|
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
||||||
if r.BlockIO != nil {
|
c.Resources.BlkioThrottleWriteBpsDevice = append(c.Resources.BlkioThrottleWriteBpsDevice, throttleDevice)
|
||||||
if r.BlockIO.Weight != nil {
|
|
||||||
c.Resources.BlkioWeight = *r.BlockIO.Weight
|
|
||||||
}
|
|
||||||
if r.BlockIO.LeafWeight != nil {
|
|
||||||
c.Resources.BlkioLeafWeight = *r.BlockIO.LeafWeight
|
|
||||||
}
|
|
||||||
if r.BlockIO.WeightDevice != nil {
|
|
||||||
for _, wd := range r.BlockIO.WeightDevice {
|
|
||||||
weightDevice := configs.NewWeightDevice(wd.Major, wd.Minor, *wd.Weight, *wd.LeafWeight)
|
|
||||||
c.Resources.BlkioWeightDevice = append(c.Resources.BlkioWeightDevice, weightDevice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.BlockIO.ThrottleReadBpsDevice != nil {
|
|
||||||
for _, td := range r.BlockIO.ThrottleReadBpsDevice {
|
|
||||||
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
|
||||||
c.Resources.BlkioThrottleReadBpsDevice = append(c.Resources.BlkioThrottleReadBpsDevice, throttleDevice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.BlockIO.ThrottleWriteBpsDevice != nil {
|
|
||||||
for _, td := range r.BlockIO.ThrottleWriteBpsDevice {
|
|
||||||
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
|
||||||
c.Resources.BlkioThrottleWriteBpsDevice = append(c.Resources.BlkioThrottleWriteBpsDevice, throttleDevice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.BlockIO.ThrottleReadIOPSDevice != nil {
|
|
||||||
for _, td := range r.BlockIO.ThrottleReadIOPSDevice {
|
|
||||||
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
|
||||||
c.Resources.BlkioThrottleReadIOPSDevice = append(c.Resources.BlkioThrottleReadIOPSDevice, throttleDevice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.BlockIO.ThrottleWriteIOPSDevice != nil {
|
|
||||||
for _, td := range r.BlockIO.ThrottleWriteIOPSDevice {
|
|
||||||
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
|
||||||
c.Resources.BlkioThrottleWriteIOPSDevice = append(c.Resources.BlkioThrottleWriteIOPSDevice, throttleDevice)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, l := range r.HugepageLimits {
|
if r.BlockIO.ThrottleReadIOPSDevice != nil {
|
||||||
c.Resources.HugetlbLimit = append(c.Resources.HugetlbLimit, &configs.HugepageLimit{
|
for _, td := range r.BlockIO.ThrottleReadIOPSDevice {
|
||||||
Pagesize: *l.Pagesize,
|
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
||||||
Limit: *l.Limit,
|
c.Resources.BlkioThrottleReadIOPSDevice = append(c.Resources.BlkioThrottleReadIOPSDevice, throttleDevice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.BlockIO.ThrottleWriteIOPSDevice != nil {
|
||||||
|
for _, td := range r.BlockIO.ThrottleWriteIOPSDevice {
|
||||||
|
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
|
||||||
|
c.Resources.BlkioThrottleWriteIOPSDevice = append(c.Resources.BlkioThrottleWriteIOPSDevice, throttleDevice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, l := range r.HugepageLimits {
|
||||||
|
c.Resources.HugetlbLimit = append(c.Resources.HugetlbLimit, &configs.HugepageLimit{
|
||||||
|
Pagesize: *l.Pagesize,
|
||||||
|
Limit: *l.Limit,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if r.DisableOOMKiller != nil {
|
||||||
|
c.Resources.OomKillDisable = *r.DisableOOMKiller
|
||||||
|
}
|
||||||
|
if r.Network != nil {
|
||||||
|
if r.Network.ClassID != nil {
|
||||||
|
c.Resources.NetClsClassid = string(*r.Network.ClassID)
|
||||||
|
}
|
||||||
|
for _, m := range r.Network.Priorities {
|
||||||
|
c.Resources.NetPrioIfpriomap = append(c.Resources.NetPrioIfpriomap, &configs.IfPrioMap{
|
||||||
|
Interface: m.Name,
|
||||||
|
Priority: int64(m.Priority),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if r.DisableOOMKiller != nil {
|
|
||||||
c.Resources.OomKillDisable = *r.DisableOOMKiller
|
|
||||||
}
|
|
||||||
if r.Network != nil {
|
|
||||||
if r.Network.ClassID != nil {
|
|
||||||
c.Resources.NetClsClassid = string(*r.Network.ClassID)
|
|
||||||
}
|
|
||||||
for _, m := range r.Network.Priorities {
|
|
||||||
c.Resources.NetPrioIfpriomap = append(c.Resources.NetPrioIfpriomap, &configs.IfPrioMap{
|
|
||||||
Interface: m.Name,
|
|
||||||
Priority: int64(m.Priority),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDevices(spec *specs.LinuxSpec, config *configs.Config) error {
|
func createDevices(spec *specs.LinuxSpec, config *configs.Config) error {
|
||||||
|
// add whitelisted devices
|
||||||
|
config.Devices = []*configs.Device{
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/null",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 3,
|
||||||
|
FileMode: 0666,
|
||||||
|
Uid: 0,
|
||||||
|
Gid: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/random",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 8,
|
||||||
|
FileMode: 0666,
|
||||||
|
Uid: 0,
|
||||||
|
Gid: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/full",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 7,
|
||||||
|
FileMode: 0666,
|
||||||
|
Uid: 0,
|
||||||
|
Gid: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/tty",
|
||||||
|
Major: 5,
|
||||||
|
Minor: 0,
|
||||||
|
FileMode: 0666,
|
||||||
|
Uid: 0,
|
||||||
|
Gid: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/zero",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 5,
|
||||||
|
FileMode: 0666,
|
||||||
|
Uid: 0,
|
||||||
|
Gid: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/urandom",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 9,
|
||||||
|
FileMode: 0666,
|
||||||
|
Uid: 0,
|
||||||
|
Gid: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// merge in additional devices from the spec
|
||||||
for _, d := range spec.Linux.Devices {
|
for _, d := range spec.Linux.Devices {
|
||||||
|
var uid, gid uint32
|
||||||
|
if d.UID != nil {
|
||||||
|
uid = *d.UID
|
||||||
|
}
|
||||||
|
if d.GID != nil {
|
||||||
|
gid = *d.GID
|
||||||
|
}
|
||||||
device := &configs.Device{
|
device := &configs.Device{
|
||||||
Type: d.Type,
|
Type: d.Type,
|
||||||
Path: d.Path,
|
Path: d.Path,
|
||||||
Major: d.Major,
|
Major: d.Major,
|
||||||
Minor: d.Minor,
|
Minor: d.Minor,
|
||||||
FileMode: *d.FileMode,
|
FileMode: *d.FileMode,
|
||||||
Uid: *d.UID,
|
Uid: uid,
|
||||||
Gid: *d.GID,
|
Gid: gid,
|
||||||
}
|
}
|
||||||
config.Devices = append(config.Devices, device)
|
config.Devices = append(config.Devices, device)
|
||||||
}
|
}
|
||||||
|
|
56
utils.go
56
utils.go
|
@ -24,12 +24,62 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: wildcard,
|
Major: wildcard,
|
||||||
Minor: wildcard,
|
Minor: wildcard,
|
||||||
Permissions: "m",
|
Permissions: "m",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: 'b',
|
Type: 'b',
|
||||||
Major: wildcard,
|
Major: wildcard,
|
||||||
Minor: wildcard,
|
Minor: wildcard,
|
||||||
Permissions: "m",
|
Permissions: "m",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/null",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 3,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/random",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 8,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/full",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 7,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/tty",
|
||||||
|
Major: 5,
|
||||||
|
Minor: 0,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/zero",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 5,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: 'c',
|
||||||
|
Path: "/dev/urandom",
|
||||||
|
Major: 1,
|
||||||
|
Minor: 9,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Path: "/dev/console",
|
Path: "/dev/console",
|
||||||
|
@ -37,6 +87,7 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: 5,
|
Major: 5,
|
||||||
Minor: 1,
|
Minor: 1,
|
||||||
Permissions: "rwm",
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Path: "/dev/tty0",
|
Path: "/dev/tty0",
|
||||||
|
@ -44,6 +95,7 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: 4,
|
Major: 4,
|
||||||
Minor: 0,
|
Minor: 0,
|
||||||
Permissions: "rwm",
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Path: "/dev/tty1",
|
Path: "/dev/tty1",
|
||||||
|
@ -51,6 +103,7 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: 4,
|
Major: 4,
|
||||||
Minor: 1,
|
Minor: 1,
|
||||||
Permissions: "rwm",
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
// /dev/pts/ - pts namespaces are "coming soon"
|
// /dev/pts/ - pts namespaces are "coming soon"
|
||||||
{
|
{
|
||||||
|
@ -59,6 +112,7 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: 136,
|
Major: 136,
|
||||||
Minor: wildcard,
|
Minor: wildcard,
|
||||||
Permissions: "rwm",
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Path: "",
|
Path: "",
|
||||||
|
@ -66,6 +120,7 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: 5,
|
Major: 5,
|
||||||
Minor: 2,
|
Minor: 2,
|
||||||
Permissions: "rwm",
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
// tuntap
|
// tuntap
|
||||||
{
|
{
|
||||||
|
@ -74,6 +129,7 @@ var allowedDevices = []*configs.Device{
|
||||||
Major: 10,
|
Major: 10,
|
||||||
Minor: 200,
|
Minor: 200,
|
||||||
Permissions: "rwm",
|
Permissions: "rwm",
|
||||||
|
Allow: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue