diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index f480e05e73..99fca2cd6f 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -16,6 +16,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/execdriver" + "github.com/docker/docker/daemon/execdriver/native/template" "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/pools" "github.com/docker/docker/pkg/reexec" @@ -89,6 +90,7 @@ func NewDriver(root string, options []string) (*Driver, error) { case "systemd": if systemd.UseSystemd() { cgm = libcontainer.SystemdCgroups + template.SystemdCgroups = true } else { // warn them that they chose the wrong driver logrus.Warn("You cannot use systemd as native.cgroupdriver, using cgroupfs instead") diff --git a/daemon/execdriver/native/template/default_template_linux.go b/daemon/execdriver/native/template/default_template_linux.go index 1303cb545b..f37f034eae 100644 --- a/daemon/execdriver/native/template/default_template_linux.go +++ b/daemon/execdriver/native/template/default_template_linux.go @@ -9,6 +9,9 @@ import ( const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV +// SystemdCgroups indicates whether systemd cgroup implemenation is in use or not +var SystemdCgroups = false + // New returns the docker default configuration for libcontainer func New() *configs.Config { container := &configs.Config{ @@ -94,5 +97,10 @@ func New() *configs.Config { container.AppArmorProfile = "docker-default" } + if SystemdCgroups { + container.Cgroups.Parent = "system.slice" + container.Cgroups.ScopePrefix = "docker" + } + return container } diff --git a/hack/vendor.sh b/hack/vendor.sh index 34d29f2947..1164812af8 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -49,7 +49,7 @@ clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf clone git github.com/jfrazelle/go v1.5.1-1 clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c -clone git github.com/opencontainers/runc v0.0.5 # libcontainer +clone git github.com/opencontainers/runc v0.0.6 # libcontainer clone git github.com/opencontainers/specs 46d949ea81080c5f60dfb72ee91468b1e9fb2998 # specs clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json) diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go b/vendor/src/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go index 937bf915c7..d4110cf0bc 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go @@ -2,10 +2,19 @@ package apparmor +import ( + "errors" +) + +var ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported") + func IsEnabled() bool { return false } func ApplyProfile(name string) error { + if name != "" { + return ErrApparmorNotEnabled + } return nil } diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go index 7a422b3c79..41b6fbcd8a 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go @@ -167,8 +167,8 @@ func (m *Manager) Apply(pid int) error { properties []systemdDbus.Property ) - if c.Slice != "" { - slice = c.Slice + if c.Parent != "" { + slice = c.Parent } properties = append(properties, @@ -406,8 +406,8 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { } slice := "system.slice" - if c.Slice != "" { - slice = c.Slice + if c.Parent != "" { + slice = c.Parent } return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil @@ -472,7 +472,7 @@ func (m *Manager) Set(container *configs.Config) error { } func getUnitName(c *configs.Cgroup) string { - return fmt.Sprintf("%s-%s.scope", c.Parent, c.Name) + return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name) } // Atm we can't use the systemd device support because of two missing things: diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go b/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go index 24f93c1ad6..f256fa2471 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go @@ -83,8 +83,8 @@ type Cgroup struct { // Hugetlb limit (in bytes) HugetlbLimit []*HugepageLimit `json:"hugetlb_limit"` - // Parent slice to use for systemd TODO: remove in favor or parent - Slice string `json:"slice"` + // ScopePrefix decribes prefix for the scope name + ScopePrefix string `json:"scope_prefix"` // Whether to disable OOM Killer OomKillDisable bool `json:"oom_kill_disable"` diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unsupported.go b/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unsupported.go new file mode 100644 index 0000000000..95e2830a43 --- /dev/null +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/configs/cgroup_unsupported.go @@ -0,0 +1,6 @@ +// +build !windows,!linux,!freebsd + +package configs + +type Cgroup struct { +} diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/console_freebsd.go b/vendor/src/github.com/opencontainers/runc/libcontainer/console_freebsd.go index 4d20b8da40..3c89eda079 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/console_freebsd.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/console_freebsd.go @@ -6,8 +6,8 @@ import ( "errors" ) -// newConsole returns an initalized console that can be used within a container by copying bytes +// NewConsole returns an initalized console that can be used within a container by copying bytes // from the master side to the slave that is attached as the tty for the container's init process. -func newConsole(uid, gid int) (Console, error) { +func NewConsole(uid, gid int) (Console, error) { return nil, errors.New("libcontainer console is not supported on FreeBSD") } diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/console_linux.go b/vendor/src/github.com/opencontainers/runc/libcontainer/console_linux.go index f345f572b3..7af771b65e 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/console_linux.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/console_linux.go @@ -10,9 +10,9 @@ import ( "github.com/opencontainers/runc/libcontainer/label" ) -// newConsole returns an initalized console that can be used within a container by copying bytes +// NewConsole returns an initalized console that can be used within a container by copying bytes // from the master side to the slave that is attached as the tty for the container's init process. -func newConsole(uid, gid int) (Console, error) { +func NewConsole(uid, gid int) (Console, error) { master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0) if err != nil { return nil, err diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/console_windows.go b/vendor/src/github.com/opencontainers/runc/libcontainer/console_windows.go index 80c7463bc4..a68c02f66b 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/console_windows.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/console_windows.go @@ -1,7 +1,7 @@ package libcontainer -// newConsole returns an initalized console that can be used within a container -func newConsole(uid, gid int) (Console, error) { +// NewConsole returns an initalized console that can be used within a container +func NewConsole(uid, gid int) (Console, error) { return &windowsConsole{}, nil } diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/container_linux.go b/vendor/src/github.com/opencontainers/runc/libcontainer/container_linux.go index 912673a34b..82476ed99a 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/container_linux.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/container_linux.go @@ -3,8 +3,10 @@ package libcontainer import ( + "bytes" "encoding/json" "fmt" + "io" "io/ioutil" "os" "os/exec" @@ -19,6 +21,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/criurpc" + "github.com/vishvananda/netlink/nl" ) const stdioFdCount = 3 @@ -218,7 +221,7 @@ func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProces return nil, newSystemError(err) } if !doInit { - return c.newSetnsProcess(p, cmd, parentPipe, childPipe), nil + return c.newSetnsProcess(p, cmd, parentPipe, childPipe) } return c.newInitProcess(p, cmd, parentPipe, childPipe) } @@ -273,23 +276,24 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, c }, nil } -func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) *setnsProcess { - cmd.Env = append(cmd.Env, - fmt.Sprintf("_LIBCONTAINER_INITPID=%d", c.initProcess.pid()), - "_LIBCONTAINER_INITTYPE=setns", - ) - if p.consolePath != "" { - cmd.Env = append(cmd.Env, "_LIBCONTAINER_CONSOLE_PATH="+p.consolePath) +func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) (*setnsProcess, error) { + cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE=setns") + // for setns process, we dont have to set cloneflags as the process namespaces + // will only be set via setns syscall + data, err := c.bootstrapData(0, c.initProcess.pid(), p.consolePath) + if err != nil { + return nil, err } // TODO: set on container for process management return &setnsProcess{ - cmd: cmd, - cgroupPaths: c.cgroupManager.GetPaths(), - childPipe: childPipe, - parentPipe: parentPipe, - config: c.newInitConfig(p), - process: p, - } + cmd: cmd, + cgroupPaths: c.cgroupManager.GetPaths(), + childPipe: childPipe, + parentPipe: parentPipe, + config: c.newInitConfig(p), + process: p, + bootstrapData: data, + }, nil } func (c *linuxContainer) newInitConfig(process *Process) *initConfig { @@ -1021,3 +1025,25 @@ func (c *linuxContainer) currentState() (*State, error) { } return state, nil } + +// bootstrapData encodes the necessary data in netlink binary format as a io.Reader. +// Consumer can write the data to a bootstrap program such as one that uses +// nsenter package to bootstrap the container's init process correctly, i.e. with +// correct namespaces, uid/gid mapping etc. +func (c *linuxContainer) bootstrapData(cloneFlags uintptr, pid int, consolePath string) (io.Reader, error) { + // create the netlink message + r := nl.NewNetlinkRequest(int(InitMsg), 0) + // write pid + r.AddData(&Int32msg{ + Type: PidAttr, + Value: uint32(pid), + }) + // write console path + if consolePath != "" { + r.AddData(&Bytemsg{ + Type: ConsolePathAttr, + Value: []byte(consolePath), + }) + } + return bytes.NewReader(r.Serialize()), nil +} diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/error.go b/vendor/src/github.com/opencontainers/runc/libcontainer/error.go index 6c266620e7..aa59d2aecc 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/error.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/error.go @@ -22,6 +22,7 @@ const ( // Common errors ConfigInvalid + ConsoleExists SystemError ) @@ -43,6 +44,8 @@ func (c ErrorCode) String() string { return "Container is not stopped" case ContainerNotRunning: return "Container is not running" + case ConsoleExists: + return "Console exists for process" default: return "Unknown error" } diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/message_linux.go b/vendor/src/github.com/opencontainers/runc/libcontainer/message_linux.go new file mode 100644 index 0000000000..0e95e3b0ad --- /dev/null +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/message_linux.go @@ -0,0 +1,60 @@ +// +build linux + +package libcontainer + +import ( + "syscall" + + "github.com/vishvananda/netlink/nl" +) + +// list of known message types we want to send to bootstrap program +// The number is randomly chosen to not conflict with known netlink types +const ( + InitMsg uint16 = 62000 + PidAttr uint16 = 27281 + ConsolePathAttr uint16 = 27282 +) + +type Int32msg struct { + Type uint16 + Value uint32 +} + +// int32msg has the following representation +// | nlattr len | nlattr type | +// | uint32 value | +func (msg *Int32msg) Serialize() []byte { + buf := make([]byte, msg.Len()) + native := nl.NativeEndian() + native.PutUint16(buf[0:2], uint16(msg.Len())) + native.PutUint16(buf[2:4], msg.Type) + native.PutUint32(buf[4:8], msg.Value) + return buf +} + +func (msg *Int32msg) Len() int { + return syscall.NLA_HDRLEN + 4 +} + +// bytemsg has the following representation +// | nlattr len | nlattr type | +// | value | pad | +type Bytemsg struct { + Type uint16 + Value []byte +} + +func (msg *Bytemsg) Serialize() []byte { + l := msg.Len() + buf := make([]byte, (l+syscall.NLA_ALIGNTO-1) & ^(syscall.NLA_ALIGNTO-1)) + native := nl.NativeEndian() + native.PutUint16(buf[0:2], uint16(l)) + native.PutUint16(buf[2:4], msg.Type) + copy(buf[4:], msg.Value) + return buf +} + +func (msg *Bytemsg) Len() int { + return syscall.NLA_HDRLEN + len(msg.Value) + 1 // null-terminated +} diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/network_linux.go b/vendor/src/github.com/opencontainers/runc/libcontainer/network_linux.go index ce93277a52..5075bee4db 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/network_linux.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/network_linux.go @@ -93,7 +93,7 @@ func (l *loopback) create(n *network, nspid int) error { } func (l *loopback) initialize(config *network) error { - return netlink.LinkSetUp(&netlink.Device{netlink.LinkAttrs{Name: "lo"}}) + return netlink.LinkSetUp(&netlink.Device{LinkAttrs: netlink.LinkAttrs{Name: "lo"}}) } func (l *loopback) attach(n *configs.Network) (err error) { @@ -111,7 +111,7 @@ type veth struct { } func (v *veth) detach(n *configs.Network) (err error) { - return netlink.LinkSetMaster(&netlink.Device{netlink.LinkAttrs{Name: n.HostInterfaceName}}, nil) + return netlink.LinkSetMaster(&netlink.Device{LinkAttrs: netlink.LinkAttrs{Name: n.HostInterfaceName}}, nil) } // attach a container network interface to an external network diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c b/vendor/src/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c index 01450a90a6..27e6e53d4d 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c @@ -17,6 +17,11 @@ #include #include +#include +#include +#include +#include + /* All arguments should be above stack, because it grows down */ struct clone_arg { /* @@ -63,24 +68,33 @@ static int clone_parent(jmp_buf * env) return child; } +static uint32_t readint32(char *buf) +{ + return *(uint32_t *) buf; +} + +// list of known message types we want to send to bootstrap program +// These are defined in libcontainer/message_linux.go +#define INIT_MSG 62000 +#define PID_ATTR 27281 +#define CONSOLE_PATH_ATTR 27282 + void nsexec() { char *namespaces[] = { "ipc", "uts", "net", "pid", "mnt", "user" }; const int num = sizeof(namespaces) / sizeof(char *); jmp_buf env; char buf[PATH_MAX], *val; - int i, tfd, self_tfd, child, len, pipenum, consolefd = -1; - pid_t pid; - char *console; + int i, tfd, self_tfd, child, n, len, pipenum, consolefd = -1; + pid_t pid = 0; - val = getenv("_LIBCONTAINER_INITPID"); - if (val == NULL) + // if we dont have INITTYPE or this is the init process, skip the bootstrap process + val = getenv("_LIBCONTAINER_INITTYPE"); + if (val == NULL || strcmp(val, "standard") == 0) { return; - - pid = atoi(val); - snprintf(buf, sizeof(buf), "%d", pid); - if (strcmp(val, buf)) { - pr_perror("Unable to parse _LIBCONTAINER_INITPID"); + } + if (strcmp(val, "setns") != 0) { + pr_perror("Invalid inittype %s", val); exit(1); } @@ -89,7 +103,6 @@ void nsexec() pr_perror("Child pipe not found"); exit(1); } - pipenum = atoi(val); snprintf(buf, sizeof(buf), "%d", pipenum); if (strcmp(val, buf)) { @@ -97,13 +110,56 @@ void nsexec() exit(1); } - console = getenv("_LIBCONTAINER_CONSOLE_PATH"); - if (console != NULL) { - consolefd = open(console, O_RDWR); - if (consolefd < 0) { - pr_perror("Failed to open console %s", console); - exit(1); + char nlbuf[NLMSG_HDRLEN]; + struct nlmsghdr *nh; + if ((n = read(pipenum, nlbuf, NLMSG_HDRLEN)) != NLMSG_HDRLEN) { + pr_perror("Failed to read netlink header, got %d", n); + exit(1); + } + + nh = (struct nlmsghdr *)nlbuf; + if (nh->nlmsg_type == NLMSG_ERROR) { + pr_perror("Invalid netlink header message"); + exit(1); + } + if (nh->nlmsg_type != INIT_MSG) { + pr_perror("Unexpected netlink message type %d", nh->nlmsg_type); + exit(1); + } + // read the netlink payload + len = NLMSG_PAYLOAD(nh, 0); + char data[len]; + if ((n = read(pipenum, data, len)) != len) { + pr_perror("Failed to read netlink payload, got %d", n); + exit(1); + } + + int start = 0; + struct nlattr *attr; + while (start < len) { + int payload_len; + attr = (struct nlattr *)((void *)data + start); + start += NLA_HDRLEN; + payload_len = attr->nla_len - NLA_HDRLEN; + switch (attr->nla_type) { + case PID_ATTR: + pid = (pid_t) readint32(data + start); + break; + case CONSOLE_PATH_ATTR: + consolefd = open((char *)data + start, O_RDWR); + if (consolefd < 0) { + pr_perror("Failed to open console %s", (char *)data + start); + exit(1); + } + break; } + start += NLA_ALIGN(payload_len); + } + + // required pid to be passed + if (pid == 0) { + pr_perror("missing pid"); + exit(1); } /* Check that the specified process exists */ @@ -133,15 +189,13 @@ void nsexec() } /* Skip namespaces we're already part of */ - if (fstatat(self_tfd, namespaces[i], &self_st, 0) != -1 && - st.st_ino == self_st.st_ino) { + if (fstatat(self_tfd, namespaces[i], &self_st, 0) != -1 && st.st_ino == self_st.st_ino) { continue; } fd = openat(tfd, namespaces[i], O_RDONLY); if (fd == -1) { - pr_perror("Failed to open ns file %s for ns %s", buf, - namespaces[i]); + pr_perror("Failed to open ns file %s for ns %s", buf, namespaces[i]); exit(1); } // Set the namespace. diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/process.go b/vendor/src/github.com/opencontainers/runc/libcontainer/process.go index 7902d08ce4..e96dc0d360 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/process.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/process.go @@ -80,10 +80,19 @@ func (p Process) Signal(sig os.Signal) error { // NewConsole creates new console for process and returns it func (p *Process) NewConsole(rootuid int) (Console, error) { - console, err := newConsole(rootuid, rootuid) + console, err := NewConsole(rootuid, rootuid) if err != nil { return nil, err } p.consolePath = console.Path() return console, nil } + +// ConsoleFromPath sets the process's console with the path provided +func (p *Process) ConsoleFromPath(path string) error { + if p.consolePath != "" { + return newGenericError(fmt.Errorf("console path already exists for process"), ConsoleExists) + } + p.consolePath = path + return nil +} diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/process_linux.go b/vendor/src/github.com/opencontainers/runc/libcontainer/process_linux.go index 4d17cbc576..f27b6cf40c 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/process_linux.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/process_linux.go @@ -41,13 +41,14 @@ type parentProcess interface { } type setnsProcess struct { - cmd *exec.Cmd - parentPipe *os.File - childPipe *os.File - cgroupPaths map[string]string - config *initConfig - fds []string - process *Process + cmd *exec.Cmd + parentPipe *os.File + childPipe *os.File + cgroupPaths map[string]string + config *initConfig + fds []string + process *Process + bootstrapData io.Reader } func (p *setnsProcess) startTime() (string, error) { @@ -64,6 +65,16 @@ func (p *setnsProcess) signal(sig os.Signal) error { func (p *setnsProcess) start() (err error) { defer p.parentPipe.Close() + err = p.cmd.Start() + p.childPipe.Close() + if err != nil { + return newSystemError(err) + } + if p.bootstrapData != nil { + if _, err := io.Copy(p.parentPipe, p.bootstrapData); err != nil { + return newSystemError(err) + } + } if err = p.execSetns(); err != nil { return newSystemError(err) } @@ -96,11 +107,6 @@ func (p *setnsProcess) start() (err error) { // before the go runtime boots, we wait on the process to die and receive the child's pid // over the provided pipe. func (p *setnsProcess) execSetns() error { - err := p.cmd.Start() - p.childPipe.Close() - if err != nil { - return newSystemError(err) - } status, err := p.cmd.Process.Wait() if err != nil { p.cmd.Wait() diff --git a/vendor/src/github.com/opencontainers/specs/.travis.yml b/vendor/src/github.com/opencontainers/specs/.travis.yml index 222568242a..64b57bfcb7 100644 --- a/vendor/src/github.com/opencontainers/specs/.travis.yml +++ b/vendor/src/github.com/opencontainers/specs/.travis.yml @@ -17,3 +17,4 @@ script: - go vet -x ./... - $HOME/gopath/bin/golint ./... - $HOME/gopath/bin/git-validation -run DCO,short-subject -v -range ${TRAVIS_COMMIT_RANGE} + diff --git a/vendor/src/github.com/opencontainers/specs/ROADMAP.md b/vendor/src/github.com/opencontainers/specs/ROADMAP.md index 363fbbd863..89415289d9 100644 --- a/vendor/src/github.com/opencontainers/specs/ROADMAP.md +++ b/vendor/src/github.com/opencontainers/specs/ROADMAP.md @@ -10,7 +10,7 @@ Topics listed in the roadmap do not mean that they will be implemented or added ### Digest and Hashing -A bundle is designed to be moved between hosts. +A bundle is designed to be moved between hosts. Although OCI doesn't define a transport method we should have a cryptographic digest of the on-disk bundle that can be used to verify that a bundle is not corrupted and in an expected configuration. *Owner:* philips @@ -20,11 +20,11 @@ Although OCI doesn't define a transport method we should have a cryptographic di There are some discussions about having `runtime.json` being optional for containers and specifying defaults. Runtimes would use this standard set of defaults for containers and `runtime.json` would provide overrides for fine tuning of these extra host or platform specific settings. -*Owner:* +*Owner:* ### Define Container Lifecycle -Containers have a lifecycle and being able to identify and document the lifecycle of a container is very helpful for implementations of the spec. +Containers have a lifecycle and being able to identify and document the lifecycle of a container is very helpful for implementations of the spec. The lifecycle events of a container also help identify areas to implement hooks that are portable across various implementations and platforms. *Owner:* mrunalp @@ -33,27 +33,27 @@ The lifecycle events of a container also help identify areas to implement hooks Define what type of actions a runtime can perform on a container without imposing hardships on authors of platforms that do not support advanced options. -*Owner:* +*Owner:* ### Clarify rootfs requirement in base spec Is the rootfs needed or should it just be expected in the bundle without having a field in the spec? -*Owner:* +*Owner:* ### Container Definition Define what a software container is and its attributes in a cross platform way. -*Owner:* +*Owner:* ### Live Container Updates -Should we allow dynamic container updates to runtime options? +Should we allow dynamic container updates to runtime options? *Owner:* vishh -### Protobuf Config +### Protobuf Config We currently have only one language binding for the spec and that is Go. If we change the specs format in the respository to be something like protobuf then the generation for multiple language bindings become effortless. @@ -62,7 +62,7 @@ If we change the specs format in the respository to be something like protobuf t ### Validation Tooling -Provide validation tooling for compliance with OCI spec and runtime environment. +Provide validation tooling for compliance with OCI spec and runtime environment. *Owner:* mrunalp @@ -70,27 +70,27 @@ Provide validation tooling for compliance with OCI spec and runtime environment. Decide on a robust versioning schema for the spec as it evolves. -*Owner:* +*Owner:* ### Printable/Compiled Spec Reguardless of how the spec is written, ensure that it is easy to read and follow for first time users. -*Owner:* vbatts +*Owner:* vbatts ### Base Config Compatibility Ensure that the base configuration format is viable for various platforms. -Systems: +Systems: * Solaris -* Windows +* Windows * Linux -*Owner:* +*Owner:* ### Full Lifecycle Hooks Ensure that we have lifecycle hooks in the correct places with full coverage over the container lifecycle. -*Owner:* +*Owner:* diff --git a/vendor/src/github.com/opencontainers/specs/code-of-conduct.md b/vendor/src/github.com/opencontainers/specs/code-of-conduct.md index 805a62857a..06cb2b83a3 100644 --- a/vendor/src/github.com/opencontainers/specs/code-of-conduct.md +++ b/vendor/src/github.com/opencontainers/specs/code-of-conduct.md @@ -30,7 +30,7 @@ The OpenContainers team reserves the right to deny participation any individual Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. -## Thanks +## Thanks Thanks to the [Fedora Code of Conduct](https://getfedora.org/code-of-conduct) and [Contributor Covenant](http://contributor-covenant.org) for inspiration and ideas.