diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 86d37bf9..07af36bf 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -124,7 +124,7 @@ { "ImportPath": "github.com/opencontainers/runc/libcontainer", "Comment": "v0.0.7", - "Rev": "3268a1ea007f54f16e4d969c0900efb59beb3d08" + "Rev": "7ca2aa4873aea7cb4265b1726acb24b90d8726c6" }, { "ImportPath": "github.com/pborman/uuid", diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/README.md b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/README.md index 13552610..fc6b4b0b 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/README.md +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/README.md @@ -69,6 +69,7 @@ config := &configs.Config{ {Type: configs.NEWUTS}, {Type: configs.NEWIPC}, {Type: configs.NEWPID}, + {Type: configs.NEWUSER}, {Type: configs.NEWNET}, }), Cgroups: &configs.Cgroup{ @@ -129,6 +130,20 @@ config := &configs.Config{ Flags: defaultMountFlags | syscall.MS_RDONLY, }, }, + UidMappings: []configs.IDMap{ + { + ContainerID: 0, + Host: 1000, + size: 65536, + }, + }, + GidMappings: []configs.IDMap{ + { + ContainerID: 0, + Host: 1000, + size: 65536, + }, + }, Networks: []*configs.Network{ { Type: "loopback", diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go index 5b070dd0..db020a97 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go @@ -387,6 +387,28 @@ func joinPids(c *configs.Cgroup, pid int) error { return nil } +// systemd represents slice heirarchy using `-`, so we need to follow suit when +// generating the path of slice. Essentially, test-a-b.slice becomes +// test.slice/test-a.slice/test-a-b.slice. +func expandSlice(slice string) (string, error) { + suffix := ".slice" + sliceName := strings.TrimSuffix(slice, suffix) + + var path, prefix string + for _, component := range strings.Split(sliceName, "-") { + // test--a.slice isn't permitted, nor is -test.slice. + if component == "" { + return "", fmt.Errorf("invalid slice name: %s", slice) + } + + // Append the component to the path and to the prefix. + path += prefix + component + suffix + "/" + prefix += component + "-" + } + + return path, nil +} + func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { mountpoint, err := cgroups.FindCgroupMountpoint(subsystem) if err != nil { @@ -403,6 +425,11 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { slice = c.Parent } + slice, err = expandSlice(slice) + if err != nil { + return "", err + } + return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil } diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container.go index 051c8cf6..03c8c559 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container.go @@ -14,8 +14,11 @@ import ( type Status int const ( + // The container exists but has not been run yet + Created Status = iota + // The container exists and is running. - Running Status = iota + 1 + Running // The container exists, it is in the process of being paused. Pausing @@ -32,6 +35,8 @@ const ( func (s Status) String() string { switch s { + case Created: + return "created" case Running: return "running" case Pausing: @@ -43,7 +48,7 @@ func (s Status) String() string { case Destroyed: return "destroyed" default: - return "undefined" + return "unknown" } } diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container_linux.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container_linux.go index 19b8f3a7..4015c957 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container_linux.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/container_linux.go @@ -21,6 +21,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/criurpc" + "github.com/opencontainers/runc/libcontainer/utils" "github.com/vishvananda/netlink/nl" ) @@ -964,7 +965,7 @@ func (c *linuxContainer) saveState(s *State) error { return err } defer f.Close() - return json.NewEncoder(f).Encode(s) + return utils.WriteJSON(f, s) } func (c *linuxContainer) deleteState() error { diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go index eb2bb5fb..0e4e9dfd 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go @@ -18,6 +18,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs/validate" + "github.com/opencontainers/runc/libcontainer/utils" ) const ( @@ -202,7 +203,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) { cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths), root: containerRoot, } - c.state = &nullState{c: c} + c.state = &createdState{c: c, s: Created} if err := c.refreshState(); err != nil { return nil, err } @@ -235,15 +236,15 @@ func (l *LinuxFactory) StartInitialization() (err error) { if err != nil { if _, ok := i.(*linuxStandardInit); ok { // Synchronisation only necessary for standard init. - if err := json.NewEncoder(pipe).Encode(procError); err != nil { + if err := utils.WriteJSON(pipe, syncT{procError}); err != nil { panic(err) } } - if err := json.NewEncoder(pipe).Encode(newSystemError(err)); err != nil { + if err := utils.WriteJSON(pipe, newSystemError(err)); err != nil { panic(err) } } else { - if err := json.NewEncoder(pipe).Encode(procStart); err != nil { + if err := utils.WriteJSON(pipe, syncT{procStart}); err != nil { panic(err) } } diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/generic_error.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/generic_error.go index e4872e2d..924d637b 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/generic_error.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/generic_error.go @@ -18,6 +18,10 @@ const ( procRun ) +type syncT struct { + Type syncType `json:"type"` +} + var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}} Code: {{.ECode}} {{if .Message }} diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/init_linux.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/init_linux.go index 57e53782..918f1030 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/init_linux.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/init_linux.go @@ -147,17 +147,16 @@ func finalizeNamespace(config *initConfig) error { // indicate that it is cleared to Exec. func syncParentReady(pipe io.ReadWriter) error { // Tell parent. - if err := json.NewEncoder(pipe).Encode(procReady); err != nil { + if err := utils.WriteJSON(pipe, syncT{procReady}); err != nil { return err } - // Wait for parent to give the all-clear. - var procSync syncType + var procSync syncT if err := json.NewDecoder(pipe).Decode(&procSync); err != nil { if err == io.EOF { return fmt.Errorf("parent closed synchronisation channel") } - if procSync != procRun { + if procSync.Type != procRun { return fmt.Errorf("invalid synchronisation flag from parent") } } diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/process_linux.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/process_linux.go index 1a6dc124..ac457c26 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/process_linux.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/process_linux.go @@ -16,6 +16,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/system" + "github.com/opencontainers/runc/libcontainer/utils" ) type parentProcess interface { @@ -84,7 +85,7 @@ func (p *setnsProcess) start() (err error) { return newSystemError(err) } } - if err := json.NewEncoder(p.parentPipe).Encode(p.config); err != nil { + if err := utils.WriteJSON(p.parentPipe, p.config); err != nil { return newSystemError(err) } @@ -231,9 +232,8 @@ func (p *initProcess) start() (err error) { if err := p.sendConfig(); err != nil { return newSystemError(err) } - var ( - procSync syncType + procSync syncT sentRun bool ierr *genericError ) @@ -246,8 +246,7 @@ loop: } return newSystemError(err) } - - switch procSync { + switch procSync.Type { case procStart: break loop case procReady: @@ -255,7 +254,7 @@ loop: return newSystemError(err) } // Sync with child. - if err := json.NewEncoder(p.parentPipe).Encode(procRun); err != nil { + if err := utils.WriteJSON(p.parentPipe, syncT{procRun}); err != nil { return newSystemError(err) } sentRun = true @@ -317,10 +316,7 @@ func (p *initProcess) startTime() (string, error) { func (p *initProcess) sendConfig() error { // send the state to the container's init process then shutdown writes for the parent - if err := json.NewEncoder(p.parentPipe).Encode(p.config); err != nil { - return err - } - return nil + return utils.WriteJSON(p.parentPipe, p.config) } func (p *initProcess) createNetworkInterfaces() error { diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/state_linux.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/state_linux.go index fcd4e17d..fb71ef97 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/state_linux.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/state_linux.go @@ -117,7 +117,7 @@ func (r *runningState) transition(s containerState) error { } r.c.state = s return nil - case *pausedState, *nullState: + case *pausedState: r.c.state = s return nil case *runningState: @@ -202,22 +202,22 @@ func (r *restoredState) destroy() error { return destroy(r.c) } -// nullState is used whenever a container is restored, loaded, or setting additional +// createdState is used whenever a container is restored, loaded, or setting additional // processes inside and it should not be destroyed when it is exiting. -type nullState struct { +type createdState struct { c *linuxContainer s Status } -func (n *nullState) status() Status { +func (n *createdState) status() Status { return n.s } -func (n *nullState) transition(s containerState) error { +func (n *createdState) transition(s containerState) error { n.c.state = s return nil } -func (n *nullState) destroy() error { +func (n *createdState) destroy() error { return nil } diff --git a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/utils/utils.go b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/utils/utils.go index 86cf1d65..1378006b 100644 --- a/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/utils/utils.go +++ b/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "crypto/rand" "encoding/hex" + "encoding/json" "io" "path/filepath" "syscall" @@ -36,10 +37,20 @@ func ResolveRootfs(uncleanRootfs string) (string, error) { } // ExitStatus returns the correct exit status for a process based on if it -// was signaled or exited cleanly. +// was signaled or exited cleanly func ExitStatus(status syscall.WaitStatus) int { if status.Signaled() { return exitSignalOffset + int(status.Signal()) } return status.ExitStatus() } + +// WriteJSON writes the provided struct v to w using standard json marshaling +func WriteJSON(w io.Writer, v interface{}) error { + data, err := json.Marshal(v) + if err != nil { + return err + } + _, err = w.Write(data) + return err +}