Merge pull request #1079 from jimmidyson/libcontainer-bump

bump(github.com/opencontainers/runc/libcontainer)
This commit is contained in:
Jimmi Dyson 2016-01-27 10:11:08 +00:00
commit c2eaabd58b
11 changed files with 88 additions and 29 deletions

2
Godeps/Godeps.json generated
View File

@ -124,7 +124,7 @@
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer", "ImportPath": "github.com/opencontainers/runc/libcontainer",
"Comment": "v0.0.7", "Comment": "v0.0.7",
"Rev": "3268a1ea007f54f16e4d969c0900efb59beb3d08" "Rev": "7ca2aa4873aea7cb4265b1726acb24b90d8726c6"
}, },
{ {
"ImportPath": "github.com/pborman/uuid", "ImportPath": "github.com/pborman/uuid",

View File

@ -69,6 +69,7 @@ config := &configs.Config{
{Type: configs.NEWUTS}, {Type: configs.NEWUTS},
{Type: configs.NEWIPC}, {Type: configs.NEWIPC},
{Type: configs.NEWPID}, {Type: configs.NEWPID},
{Type: configs.NEWUSER},
{Type: configs.NEWNET}, {Type: configs.NEWNET},
}), }),
Cgroups: &configs.Cgroup{ Cgroups: &configs.Cgroup{
@ -129,6 +130,20 @@ config := &configs.Config{
Flags: defaultMountFlags | syscall.MS_RDONLY, 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{ Networks: []*configs.Network{
{ {
Type: "loopback", Type: "loopback",

View File

@ -387,6 +387,28 @@ func joinPids(c *configs.Cgroup, pid int) error {
return nil 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) { func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
mountpoint, err := cgroups.FindCgroupMountpoint(subsystem) mountpoint, err := cgroups.FindCgroupMountpoint(subsystem)
if err != nil { if err != nil {
@ -403,6 +425,11 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
slice = c.Parent slice = c.Parent
} }
slice, err = expandSlice(slice)
if err != nil {
return "", err
}
return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil
} }

View File

@ -14,8 +14,11 @@ import (
type Status int type Status int
const ( const (
// The container exists but has not been run yet
Created Status = iota
// The container exists and is running. // The container exists and is running.
Running Status = iota + 1 Running
// The container exists, it is in the process of being paused. // The container exists, it is in the process of being paused.
Pausing Pausing
@ -32,6 +35,8 @@ const (
func (s Status) String() string { func (s Status) String() string {
switch s { switch s {
case Created:
return "created"
case Running: case Running:
return "running" return "running"
case Pausing: case Pausing:
@ -43,7 +48,7 @@ func (s Status) String() string {
case Destroyed: case Destroyed:
return "destroyed" return "destroyed"
default: default:
return "undefined" return "unknown"
} }
} }

View File

@ -21,6 +21,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/criurpc" "github.com/opencontainers/runc/libcontainer/criurpc"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/vishvananda/netlink/nl" "github.com/vishvananda/netlink/nl"
) )
@ -964,7 +965,7 @@ func (c *linuxContainer) saveState(s *State) error {
return err return err
} }
defer f.Close() defer f.Close()
return json.NewEncoder(f).Encode(s) return utils.WriteJSON(f, s)
} }
func (c *linuxContainer) deleteState() error { func (c *linuxContainer) deleteState() error {

View File

@ -18,6 +18,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs/validate" "github.com/opencontainers/runc/libcontainer/configs/validate"
"github.com/opencontainers/runc/libcontainer/utils"
) )
const ( const (
@ -202,7 +203,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths), cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
root: containerRoot, root: containerRoot,
} }
c.state = &nullState{c: c} c.state = &createdState{c: c, s: Created}
if err := c.refreshState(); err != nil { if err := c.refreshState(); err != nil {
return nil, err return nil, err
} }
@ -235,15 +236,15 @@ func (l *LinuxFactory) StartInitialization() (err error) {
if err != nil { if err != nil {
if _, ok := i.(*linuxStandardInit); ok { if _, ok := i.(*linuxStandardInit); ok {
// Synchronisation only necessary for standard init. // 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) panic(err)
} }
} }
if err := json.NewEncoder(pipe).Encode(newSystemError(err)); err != nil { if err := utils.WriteJSON(pipe, newSystemError(err)); err != nil {
panic(err) panic(err)
} }
} else { } else {
if err := json.NewEncoder(pipe).Encode(procStart); err != nil { if err := utils.WriteJSON(pipe, syncT{procStart}); err != nil {
panic(err) panic(err)
} }
} }

View File

@ -18,6 +18,10 @@ const (
procRun procRun
) )
type syncT struct {
Type syncType `json:"type"`
}
var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}} var errorTemplate = template.Must(template.New("error").Parse(`Timestamp: {{.Timestamp}}
Code: {{.ECode}} Code: {{.ECode}}
{{if .Message }} {{if .Message }}

View File

@ -147,17 +147,16 @@ func finalizeNamespace(config *initConfig) error {
// indicate that it is cleared to Exec. // indicate that it is cleared to Exec.
func syncParentReady(pipe io.ReadWriter) error { func syncParentReady(pipe io.ReadWriter) error {
// Tell parent. // Tell parent.
if err := json.NewEncoder(pipe).Encode(procReady); err != nil { if err := utils.WriteJSON(pipe, syncT{procReady}); err != nil {
return err return err
} }
// Wait for parent to give the all-clear. // 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 := json.NewDecoder(pipe).Decode(&procSync); err != nil {
if err == io.EOF { if err == io.EOF {
return fmt.Errorf("parent closed synchronisation channel") return fmt.Errorf("parent closed synchronisation channel")
} }
if procSync != procRun { if procSync.Type != procRun {
return fmt.Errorf("invalid synchronisation flag from parent") return fmt.Errorf("invalid synchronisation flag from parent")
} }
} }

View File

@ -16,6 +16,7 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils"
) )
type parentProcess interface { type parentProcess interface {
@ -84,7 +85,7 @@ func (p *setnsProcess) start() (err error) {
return newSystemError(err) 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) return newSystemError(err)
} }
@ -231,9 +232,8 @@ func (p *initProcess) start() (err error) {
if err := p.sendConfig(); err != nil { if err := p.sendConfig(); err != nil {
return newSystemError(err) return newSystemError(err)
} }
var ( var (
procSync syncType procSync syncT
sentRun bool sentRun bool
ierr *genericError ierr *genericError
) )
@ -246,8 +246,7 @@ loop:
} }
return newSystemError(err) return newSystemError(err)
} }
switch procSync.Type {
switch procSync {
case procStart: case procStart:
break loop break loop
case procReady: case procReady:
@ -255,7 +254,7 @@ loop:
return newSystemError(err) return newSystemError(err)
} }
// Sync with child. // 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) return newSystemError(err)
} }
sentRun = true sentRun = true
@ -317,10 +316,7 @@ func (p *initProcess) startTime() (string, error) {
func (p *initProcess) sendConfig() error { func (p *initProcess) sendConfig() error {
// send the state to the container's init process then shutdown writes for the parent // 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 utils.WriteJSON(p.parentPipe, p.config)
return err
}
return nil
} }
func (p *initProcess) createNetworkInterfaces() error { func (p *initProcess) createNetworkInterfaces() error {

View File

@ -117,7 +117,7 @@ func (r *runningState) transition(s containerState) error {
} }
r.c.state = s r.c.state = s
return nil return nil
case *pausedState, *nullState: case *pausedState:
r.c.state = s r.c.state = s
return nil return nil
case *runningState: case *runningState:
@ -202,22 +202,22 @@ func (r *restoredState) destroy() error {
return destroy(r.c) 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. // processes inside and it should not be destroyed when it is exiting.
type nullState struct { type createdState struct {
c *linuxContainer c *linuxContainer
s Status s Status
} }
func (n *nullState) status() Status { func (n *createdState) status() Status {
return n.s return n.s
} }
func (n *nullState) transition(s containerState) error { func (n *createdState) transition(s containerState) error {
n.c.state = s n.c.state = s
return nil return nil
} }
func (n *nullState) destroy() error { func (n *createdState) destroy() error {
return nil return nil
} }

View File

@ -3,6 +3,7 @@ package utils
import ( import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"encoding/json"
"io" "io"
"path/filepath" "path/filepath"
"syscall" "syscall"
@ -36,10 +37,20 @@ func ResolveRootfs(uncleanRootfs string) (string, error) {
} }
// ExitStatus returns the correct exit status for a process based on if it // 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 { func ExitStatus(status syscall.WaitStatus) int {
if status.Signaled() { if status.Signaled() {
return exitSignalOffset + int(status.Signal()) return exitSignalOffset + int(status.Signal())
} }
return status.ExitStatus() 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
}