summaryrefslogtreecommitdiff
path: root/oci
diff options
context:
space:
mode:
authorhwajeong.son <hwajeong.son@samsung.com>2018-08-20 13:30:55 +0900
committerhwajeong.son <hwajeong.son@samsung.com>2018-08-20 13:30:55 +0900
commit0b51891e5977b87f986f4db2cbbe09295cfdbedc (patch)
treec35ac732cb1dffccee5a32131431f753481077c2 /oci
parenteea0e89806b2cf59af3dccabc67014bd19b91b82 (diff)
downloaddocker-engine-0b51891e5977b87f986f4db2cbbe09295cfdbedc.tar.gz
docker-engine-0b51891e5977b87f986f4db2cbbe09295cfdbedc.tar.bz2
docker-engine-0b51891e5977b87f986f4db2cbbe09295cfdbedc.zip
Signed-off-by: hwajeong.son <hwajeong.son@samsung.com>
Diffstat (limited to 'oci')
-rw-r--r--oci/defaults.go221
-rw-r--r--oci/devices_linux.go86
-rw-r--r--oci/devices_unsupported.go20
-rw-r--r--oci/namespaces.go13
4 files changed, 340 insertions, 0 deletions
diff --git a/oci/defaults.go b/oci/defaults.go
new file mode 100644
index 0000000..4376faf
--- /dev/null
+++ b/oci/defaults.go
@@ -0,0 +1,221 @@
+package oci
+
+import (
+ "os"
+ "runtime"
+
+ "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+func iPtr(i int64) *int64 { return &i }
+func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
+func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
+
+func defaultCapabilities() []string {
+ return []string{
+ "CAP_CHOWN",
+ "CAP_DAC_OVERRIDE",
+ "CAP_FSETID",
+ "CAP_FOWNER",
+ "CAP_MKNOD",
+ "CAP_NET_RAW",
+ "CAP_SETGID",
+ "CAP_SETUID",
+ "CAP_SETFCAP",
+ "CAP_SETPCAP",
+ "CAP_NET_BIND_SERVICE",
+ "CAP_SYS_CHROOT",
+ "CAP_KILL",
+ "CAP_AUDIT_WRITE",
+ }
+}
+
+// DefaultSpec returns the default spec used by docker for the current Platform
+func DefaultSpec() specs.Spec {
+ return DefaultOSSpec(runtime.GOOS)
+}
+
+// DefaultOSSpec returns the spec for a given OS
+func DefaultOSSpec(osName string) specs.Spec {
+ if osName == "windows" {
+ return DefaultWindowsSpec()
+ } else if osName == "solaris" {
+ return DefaultSolarisSpec()
+ } else {
+ return DefaultLinuxSpec()
+ }
+}
+
+// DefaultWindowsSpec create a default spec for running Windows containers
+func DefaultWindowsSpec() specs.Spec {
+ return specs.Spec{
+ Version: specs.Version,
+ Platform: specs.Platform{
+ OS: runtime.GOOS,
+ Arch: runtime.GOARCH,
+ },
+ Windows: &specs.Windows{},
+ }
+}
+
+// DefaultSolarisSpec create a default spec for running Solaris containers
+func DefaultSolarisSpec() specs.Spec {
+ s := specs.Spec{
+ Version: "0.6.0",
+ Platform: specs.Platform{
+ OS: "SunOS",
+ Arch: runtime.GOARCH,
+ },
+ }
+ s.Solaris = &specs.Solaris{}
+ return s
+}
+
+// DefaultLinuxSpec create a default spec for running Linux containers
+func DefaultLinuxSpec() specs.Spec {
+ s := specs.Spec{
+ Version: specs.Version,
+ Platform: specs.Platform{
+ OS: "linux",
+ Arch: runtime.GOARCH,
+ },
+ }
+ s.Mounts = []specs.Mount{
+ {
+ Destination: "/proc",
+ Type: "proc",
+ Source: "proc",
+ Options: []string{"nosuid", "noexec", "nodev"},
+ },
+ {
+ Destination: "/dev",
+ Type: "tmpfs",
+ Source: "tmpfs",
+ Options: []string{"nosuid", "strictatime", "mode=755"},
+ },
+ {
+ Destination: "/dev/pts",
+ Type: "devpts",
+ Source: "devpts",
+ Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
+ },
+ {
+ Destination: "/sys",
+ Type: "sysfs",
+ Source: "sysfs",
+ Options: []string{"nosuid", "noexec", "nodev", "ro"},
+ },
+ {
+ Destination: "/sys/fs/cgroup",
+ Type: "cgroup",
+ Source: "cgroup",
+ Options: []string{"ro", "nosuid", "noexec", "nodev"},
+ },
+ {
+ Destination: "/dev/mqueue",
+ Type: "mqueue",
+ Source: "mqueue",
+ Options: []string{"nosuid", "noexec", "nodev"},
+ },
+ }
+ s.Process.Capabilities = &specs.LinuxCapabilities{
+ Bounding: defaultCapabilities(),
+ Permitted: defaultCapabilities(),
+ Inheritable: defaultCapabilities(),
+ Effective: defaultCapabilities(),
+ }
+
+ s.Linux = &specs.Linux{
+ MaskedPaths: []string{
+ "/proc/kcore",
+ "/proc/latency_stats",
+ "/proc/timer_list",
+ "/proc/timer_stats",
+ "/proc/sched_debug",
+ },
+ ReadonlyPaths: []string{
+ "/proc/asound",
+ "/proc/bus",
+ "/proc/fs",
+ "/proc/irq",
+ "/proc/sys",
+ "/proc/sysrq-trigger",
+ },
+ Namespaces: []specs.LinuxNamespace{
+ {Type: "mount"},
+ {Type: "network"},
+ {Type: "uts"},
+ {Type: "pid"},
+ {Type: "ipc"},
+ },
+ // Devices implicitly contains the following devices:
+ // null, zero, full, random, urandom, tty, console, and ptmx.
+ // ptmx is a bind-mount or symlink of the container's ptmx.
+ // See also: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices
+ Devices: []specs.LinuxDevice{},
+ Resources: &specs.LinuxResources{
+ Devices: []specs.LinuxDeviceCgroup{
+ {
+ Allow: false,
+ Access: "rwm",
+ },
+ {
+ Allow: true,
+ Type: "c",
+ Major: iPtr(1),
+ Minor: iPtr(5),
+ Access: "rwm",
+ },
+ {
+ Allow: true,
+ Type: "c",
+ Major: iPtr(1),
+ Minor: iPtr(3),
+ Access: "rwm",
+ },
+ {
+ Allow: true,
+ Type: "c",
+ Major: iPtr(1),
+ Minor: iPtr(9),
+ Access: "rwm",
+ },
+ {
+ Allow: true,
+ Type: "c",
+ Major: iPtr(1),
+ Minor: iPtr(8),
+ Access: "rwm",
+ },
+ {
+ Allow: true,
+ Type: "c",
+ Major: iPtr(5),
+ Minor: iPtr(0),
+ Access: "rwm",
+ },
+ {
+ Allow: true,
+ Type: "c",
+ Major: iPtr(5),
+ Minor: iPtr(1),
+ Access: "rwm",
+ },
+ {
+ Allow: false,
+ Type: "c",
+ Major: iPtr(10),
+ Minor: iPtr(229),
+ Access: "rwm",
+ },
+ },
+ },
+ }
+
+ // For LCOW support, don't mask /sys/firmware
+ if runtime.GOOS != "windows" {
+ s.Linux.MaskedPaths = append(s.Linux.MaskedPaths, "/sys/firmware")
+ }
+
+ return s
+}
diff --git a/oci/devices_linux.go b/oci/devices_linux.go
new file mode 100644
index 0000000..fa9c726
--- /dev/null
+++ b/oci/devices_linux.go
@@ -0,0 +1,86 @@
+package oci
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/opencontainers/runc/libcontainer/configs"
+ "github.com/opencontainers/runc/libcontainer/devices"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
+func Device(d *configs.Device) specs.LinuxDevice {
+ return specs.LinuxDevice{
+ Type: string(d.Type),
+ Path: d.Path,
+ Major: d.Major,
+ Minor: d.Minor,
+ FileMode: fmPtr(int64(d.FileMode)),
+ UID: u32Ptr(int64(d.Uid)),
+ GID: u32Ptr(int64(d.Gid)),
+ }
+}
+
+func deviceCgroup(d *configs.Device) specs.LinuxDeviceCgroup {
+ t := string(d.Type)
+ return specs.LinuxDeviceCgroup{
+ Allow: true,
+ Type: t,
+ Major: &d.Major,
+ Minor: &d.Minor,
+ Access: d.Permissions,
+ }
+}
+
+// DevicesFromPath computes a list of devices and device permissions from paths (pathOnHost and pathInContainer) and cgroup permissions.
+func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.LinuxDevice, devPermissions []specs.LinuxDeviceCgroup, err error) {
+ resolvedPathOnHost := pathOnHost
+
+ // check if it is a symbolic link
+ if src, e := os.Lstat(pathOnHost); e == nil && src.Mode()&os.ModeSymlink == os.ModeSymlink {
+ if linkedPathOnHost, e := filepath.EvalSymlinks(pathOnHost); e == nil {
+ resolvedPathOnHost = linkedPathOnHost
+ }
+ }
+
+ device, err := devices.DeviceFromPath(resolvedPathOnHost, cgroupPermissions)
+ // if there was no error, return the device
+ if err == nil {
+ device.Path = pathInContainer
+ return append(devs, Device(device)), append(devPermissions, deviceCgroup(device)), nil
+ }
+
+ // if the device is not a device node
+ // try to see if it's a directory holding many devices
+ if err == devices.ErrNotADevice {
+
+ // check if it is a directory
+ if src, e := os.Stat(resolvedPathOnHost); e == nil && src.IsDir() {
+
+ // mount the internal devices recursively
+ filepath.Walk(resolvedPathOnHost, func(dpath string, f os.FileInfo, e error) error {
+ childDevice, e := devices.DeviceFromPath(dpath, cgroupPermissions)
+ if e != nil {
+ // ignore the device
+ return nil
+ }
+
+ // add the device to userSpecified devices
+ childDevice.Path = strings.Replace(dpath, resolvedPathOnHost, pathInContainer, 1)
+ devs = append(devs, Device(childDevice))
+ devPermissions = append(devPermissions, deviceCgroup(childDevice))
+
+ return nil
+ })
+ }
+ }
+
+ if len(devs) > 0 {
+ return devs, devPermissions, nil
+ }
+
+ return devs, devPermissions, fmt.Errorf("error gathering device information while adding custom device %q: %s", pathOnHost, err)
+}
diff --git a/oci/devices_unsupported.go b/oci/devices_unsupported.go
new file mode 100644
index 0000000..b5d3fab
--- /dev/null
+++ b/oci/devices_unsupported.go
@@ -0,0 +1,20 @@
+// +build !linux
+
+package oci
+
+import (
+ "errors"
+
+ "github.com/opencontainers/runc/libcontainer/configs"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// Device transforms a libcontainer configs.Device to a specs.Device object.
+// Not implemented
+func Device(d *configs.Device) specs.LinuxDevice { return specs.LinuxDevice{} }
+
+// DevicesFromPath computes a list of devices and device permissions from paths (pathOnHost and pathInContainer) and cgroup permissions.
+// Not implemented
+func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.LinuxDevice, devPermissions []specs.LinuxDeviceCgroup, err error) {
+ return nil, nil, errors.New("oci/devices: unsupported platform")
+}
diff --git a/oci/namespaces.go b/oci/namespaces.go
new file mode 100644
index 0000000..cb222dc
--- /dev/null
+++ b/oci/namespaces.go
@@ -0,0 +1,13 @@
+package oci
+
+import specs "github.com/opencontainers/runtime-spec/specs-go"
+
+// RemoveNamespace removes the `nsType` namespace from OCI spec `s`
+func RemoveNamespace(s *specs.Spec, nsType specs.LinuxNamespaceType) {
+ for i, n := range s.Linux.Namespaces {
+ if n.Type == nsType {
+ s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)
+ return
+ }
+ }
+}