diff --git a/README.md b/README.md index 86ccb7d0254..6c12554935d 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,6 @@ On the [Amazon Linux AMI](https://aws.amazon.com/amazon-linux-ami/), we provide The Amazon ECS Container Agent may also be run in a Docker container on an EC2 Instance with a recent Docker version installed. A Docker image is available in our [Docker Hub Repository](https://registry.hub.docker.com/u/amazon/amazon-ecs-agent/). -*Note: The below command should work on most AMIs, but the cgroup and execdriver path may differ in some cases* - ```bash $ mkdir -p /var/log/ecs /etc/ecs /var/lib/ecs/data $ touch /etc/ecs/ecs.config @@ -30,8 +28,6 @@ $ docker run --name ecs-agent \ -v /var/log/ecs:/log \ -v /var/lib/ecs/data:/data \ -v /var/lib/docker:/var/lib/docker \ - -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ - -v /var/run/docker/execdriver/native:/var/lib/docker/execdriver/native:ro \ -p 127.0.0.1:51678:51678 \ --env-file /etc/ecs/ecs.config \ -e ECS_LOGFILE=/log/ecs-agent.log \ @@ -108,7 +104,6 @@ configure them as something other than the defaults. | `ECS_UPDATES_ENABLED` | <true | false> | Whether to exit for an updater to apply updates when requested | false | | `ECS_UPDATE_DOWNLOAD_DIR` | /cache | Where to place update tarballs within the container | | | `ECS_DISABLE_METRICS` | <true | false> | Whether to disable metrics gathering for tasks. | false | -| `ECS_DOCKER_GRAPHPATH` | /var/lib/docker | Used to create the path to the state file of containers launched. The state file is used to read utilization metrics of containers. | /var/lib/docker | | `AWS_SESSION_TOKEN` | | The [Session Token](http://docs.aws.amazon.com/STS/latest/UsingSTS/Welcome.html) used for temporary credentials. | Taken from EC2 Instance Metadata | | `ECS_RESERVED_MEMORY` | 32 | Memory, in MB, to reserve for use by things other than containers managed by ECS. | 0 | | `ECS_AVAILABLE_LOGGING_DRIVERS` | `["json-file","syslog"]` | Which logging drivers are available on the Container Instance. | `["json-file"]` | diff --git a/agent/Godeps/Godeps.json b/agent/Godeps/Godeps.json index 39fba9880b5..8bbb05cead1 100644 --- a/agent/Godeps/Godeps.json +++ b/agent/Godeps/Godeps.json @@ -146,21 +146,11 @@ "Comment": "go1.1-57-g0fa7e41", "Rev": "0fa7e41d2b9600ca6b7e1592478124e4f800f724" }, - { - "ImportPath": "github.com/docker/docker/pkg/mount", - "Comment": "v1.6.2", - "Rev": "7c8fca2ddb58c8d2c4fb4df31c242886df7dd257" - }, { "ImportPath": "github.com/docker/docker/pkg/parsers", "Comment": "v1.6.2", "Rev": "7c8fca2ddb58c8d2c4fb4df31c242886df7dd257" }, - { - "ImportPath": "github.com/docker/docker/pkg/symlink", - "Comment": "v1.6.2", - "Rev": "7c8fca2ddb58c8d2c4fb4df31c242886df7dd257" - }, { "ImportPath": "github.com/docker/docker/pkg/system", "Comment": "v1.6.2", @@ -171,71 +161,6 @@ "Comment": "v1.6.2", "Rev": "7c8fca2ddb58c8d2c4fb4df31c242886df7dd257" }, - { - "ImportPath": "github.com/docker/libcontainer", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/cgroups", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/cgroups/fs", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/console", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/devices", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/label", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/mount", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/mount/nodes", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/netlink", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/network", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/selinux", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/system", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, - { - "ImportPath": "github.com/docker/libcontainer/utils", - "Comment": "v1.4.0-121-g21ed476", - "Rev": "21ed4766b1523373b0463af497ef1c6b3b98c2ca" - }, { "ImportPath": "github.com/fsouza/go-dockerclient", "Rev": "7c07ffce0f7e14a4da49ce92a2842d4e87be1c1e" @@ -308,66 +233,6 @@ "ImportPath": "github.com/fsouza/go-dockerclient/external/golang.org/x/sys/unix", "Rev": "7c07ffce0f7e14a4da49ce92a2842d4e87be1c1e" }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/Sirupsen/logrus", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/fileutils", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/homedir", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ioutils", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/parsers", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/pools", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/promise", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/stdcopy", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ulimit", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/units", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/volume", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, - { - "ImportPath": "github.com/fsouza/go-dockerclient/external/github.com/opencontainers/runc/libcontainer/user", - "Rev": "134c9ac46b51ace9135c81efe9aa9895d346c1cf" - }, { "ImportPath": "github.com/go-ini/ini", "Comment": "v0-48-g060d7da", diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go deleted file mode 100644 index 17dbd7a64cf..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go +++ /dev/null @@ -1,69 +0,0 @@ -package mount - -import ( - "strings" -) - -// Parse fstab type mount options into mount() flags -// and device specific data -func parseOptions(options string) (int, string) { - var ( - flag int - data []string - ) - - flags := map[string]struct { - clear bool - flag int - }{ - "defaults": {false, 0}, - "ro": {false, RDONLY}, - "rw": {true, RDONLY}, - "suid": {true, NOSUID}, - "nosuid": {false, NOSUID}, - "dev": {true, NODEV}, - "nodev": {false, NODEV}, - "exec": {true, NOEXEC}, - "noexec": {false, NOEXEC}, - "sync": {false, SYNCHRONOUS}, - "async": {true, SYNCHRONOUS}, - "dirsync": {false, DIRSYNC}, - "remount": {false, REMOUNT}, - "mand": {false, MANDLOCK}, - "nomand": {true, MANDLOCK}, - "atime": {true, NOATIME}, - "noatime": {false, NOATIME}, - "diratime": {true, NODIRATIME}, - "nodiratime": {false, NODIRATIME}, - "bind": {false, BIND}, - "rbind": {false, RBIND}, - "unbindable": {false, UNBINDABLE}, - "runbindable": {false, RUNBINDABLE}, - "private": {false, PRIVATE}, - "rprivate": {false, RPRIVATE}, - "shared": {false, SHARED}, - "rshared": {false, RSHARED}, - "slave": {false, SLAVE}, - "rslave": {false, RSLAVE}, - "relatime": {false, RELATIME}, - "norelatime": {true, RELATIME}, - "strictatime": {false, STRICTATIME}, - "nostrictatime": {true, STRICTATIME}, - } - - for _, o := range strings.Split(options, ",") { - // If the option does not exist in the flags table or the flag - // is not supported on the platform, - // then it is a data value for a specific fs type - if f, exists := flags[o]; exists && f.flag != 0 { - if f.clear { - flag &= ^f.flag - } else { - flag |= f.flag - } - } else { - data = append(data, o) - } - } - return flag, strings.Join(data, ",") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_freebsd.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_freebsd.go deleted file mode 100644 index a59b58960bd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_freebsd.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build freebsd,cgo - -package mount - -/* -#include -*/ -import "C" - -const ( - RDONLY = C.MNT_RDONLY - NOSUID = C.MNT_NOSUID - NOEXEC = C.MNT_NOEXEC - SYNCHRONOUS = C.MNT_SYNCHRONOUS - NOATIME = C.MNT_NOATIME - - BIND = 0 - DIRSYNC = 0 - MANDLOCK = 0 - NODEV = 0 - NODIRATIME = 0 - UNBINDABLE = 0 - RUNBINDABLE = 0 - PRIVATE = 0 - RPRIVATE = 0 - SHARED = 0 - RSHARED = 0 - SLAVE = 0 - RSLAVE = 0 - RBIND = 0 - RELATIVE = 0 - RELATIME = 0 - REMOUNT = 0 - STRICTATIME = 0 -) diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go deleted file mode 100644 index 9986621c8f6..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go +++ /dev/null @@ -1,30 +0,0 @@ -package mount - -import ( - "syscall" -) - -const ( - RDONLY = syscall.MS_RDONLY - NOSUID = syscall.MS_NOSUID - NODEV = syscall.MS_NODEV - NOEXEC = syscall.MS_NOEXEC - SYNCHRONOUS = syscall.MS_SYNCHRONOUS - DIRSYNC = syscall.MS_DIRSYNC - REMOUNT = syscall.MS_REMOUNT - MANDLOCK = syscall.MS_MANDLOCK - NOATIME = syscall.MS_NOATIME - NODIRATIME = syscall.MS_NODIRATIME - BIND = syscall.MS_BIND - RBIND = syscall.MS_BIND | syscall.MS_REC - UNBINDABLE = syscall.MS_UNBINDABLE - RUNBINDABLE = syscall.MS_UNBINDABLE | syscall.MS_REC - PRIVATE = syscall.MS_PRIVATE - RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC - SLAVE = syscall.MS_SLAVE - RSLAVE = syscall.MS_SLAVE | syscall.MS_REC - SHARED = syscall.MS_SHARED - RSHARED = syscall.MS_SHARED | syscall.MS_REC - RELATIME = syscall.MS_RELATIME - STRICTATIME = syscall.MS_STRICTATIME -) diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_unsupported.go deleted file mode 100644 index c4f82176b81..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_unsupported.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build !linux,!freebsd freebsd,!cgo - -package mount - -const ( - BIND = 0 - DIRSYNC = 0 - MANDLOCK = 0 - NOATIME = 0 - NODEV = 0 - NODIRATIME = 0 - NOEXEC = 0 - NOSUID = 0 - UNBINDABLE = 0 - RUNBINDABLE = 0 - PRIVATE = 0 - RPRIVATE = 0 - SHARED = 0 - RSHARED = 0 - SLAVE = 0 - RSLAVE = 0 - RBIND = 0 - RELATIME = 0 - RELATIVE = 0 - REMOUNT = 0 - STRICTATIME = 0 - SYNCHRONOUS = 0 - RDONLY = 0 -) diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount.go deleted file mode 100644 index 5ca731601f2..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount.go +++ /dev/null @@ -1,70 +0,0 @@ -package mount - -import ( - "time" -) - -func GetMounts() ([]*MountInfo, error) { - return parseMountTable() -} - -// Looks at /proc/self/mountinfo to determine of the specified -// mountpoint has been mounted -func Mounted(mountpoint string) (bool, error) { - entries, err := parseMountTable() - if err != nil { - return false, err - } - - // Search the table for the mountpoint - for _, e := range entries { - if e.Mountpoint == mountpoint { - return true, nil - } - } - return false, nil -} - -// Mount the specified options at the target path only if -// the target is not mounted -// Options must be specified as fstab style -func Mount(device, target, mType, options string) error { - flag, _ := parseOptions(options) - if flag&REMOUNT != REMOUNT { - if mounted, err := Mounted(target); err != nil || mounted { - return err - } - } - return ForceMount(device, target, mType, options) -} - -// Mount the specified options at the target path -// reguardless if the target is mounted or not -// Options must be specified as fstab style -func ForceMount(device, target, mType, options string) error { - flag, data := parseOptions(options) - if err := mount(device, target, mType, uintptr(flag), data); err != nil { - return err - } - return nil -} - -// Unmount the target only if it is mounted -func Unmount(target string) error { - if mounted, err := Mounted(target); err != nil || !mounted { - return err - } - return ForceUnmount(target) -} - -// Unmount the target reguardless if it is mounted or not -func ForceUnmount(target string) (err error) { - // Simple retry logic for unmount - for i := 0; i < 10; i++ { - if err = unmount(target, 0); err == nil { - return nil - } - time.Sleep(100 * time.Millisecond) - } - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount_test.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount_test.go deleted file mode 100644 index 5c7f1b86a0a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mount_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package mount - -import ( - "os" - "path" - "testing" -) - -func TestMountOptionsParsing(t *testing.T) { - options := "noatime,ro,size=10k" - - flag, data := parseOptions(options) - - if data != "size=10k" { - t.Fatalf("Expected size=10 got %s", data) - } - - expectedFlag := NOATIME | RDONLY - - if flag != expectedFlag { - t.Fatalf("Expected %d got %d", expectedFlag, flag) - } -} - -func TestMounted(t *testing.T) { - tmp := path.Join(os.TempDir(), "mount-tests") - if err := os.MkdirAll(tmp, 0777); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmp) - - var ( - sourceDir = path.Join(tmp, "source") - targetDir = path.Join(tmp, "target") - sourcePath = path.Join(sourceDir, "file.txt") - targetPath = path.Join(targetDir, "file.txt") - ) - - os.Mkdir(sourceDir, 0777) - os.Mkdir(targetDir, 0777) - - f, err := os.Create(sourcePath) - if err != nil { - t.Fatal(err) - } - f.WriteString("hello") - f.Close() - - f, err = os.Create(targetPath) - if err != nil { - t.Fatal(err) - } - f.Close() - - if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - mounted, err := Mounted(targetDir) - if err != nil { - t.Fatal(err) - } - if !mounted { - t.Fatalf("Expected %s to be mounted", targetDir) - } - if _, err := os.Stat(targetDir); err != nil { - t.Fatal(err) - } -} - -func TestMountReadonly(t *testing.T) { - tmp := path.Join(os.TempDir(), "mount-tests") - if err := os.MkdirAll(tmp, 0777); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmp) - - var ( - sourceDir = path.Join(tmp, "source") - targetDir = path.Join(tmp, "target") - sourcePath = path.Join(sourceDir, "file.txt") - targetPath = path.Join(targetDir, "file.txt") - ) - - os.Mkdir(sourceDir, 0777) - os.Mkdir(targetDir, 0777) - - f, err := os.Create(sourcePath) - if err != nil { - t.Fatal(err) - } - f.WriteString("hello") - f.Close() - - f, err = os.Create(targetPath) - if err != nil { - t.Fatal(err) - } - f.Close() - - if err := Mount(sourceDir, targetDir, "none", "bind,ro"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - f, err = os.OpenFile(targetPath, os.O_RDWR, 0777) - if err == nil { - t.Fatal("Should not be able to open a ro file as rw") - } -} - -func TestGetMounts(t *testing.T) { - mounts, err := GetMounts() - if err != nil { - t.Fatal(err) - } - - root := false - for _, entry := range mounts { - if entry.Mountpoint == "/" { - root = true - } - } - - if !root { - t.Fatal("/ should be mounted at least") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_freebsd.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_freebsd.go deleted file mode 100644 index bb870e6f59b..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_freebsd.go +++ /dev/null @@ -1,59 +0,0 @@ -package mount - -/* -#include -#include -#include -#include -#include -#include -*/ -import "C" - -import ( - "fmt" - "strings" - "syscall" - "unsafe" -) - -func allocateIOVecs(options []string) []C.struct_iovec { - out := make([]C.struct_iovec, len(options)) - for i, option := range options { - out[i].iov_base = unsafe.Pointer(C.CString(option)) - out[i].iov_len = C.size_t(len(option) + 1) - } - return out -} - -func mount(device, target, mType string, flag uintptr, data string) error { - isNullFS := false - - xs := strings.Split(data, ",") - for _, x := range xs { - if x == "bind" { - isNullFS = true - } - } - - options := []string{"fspath", target} - if isNullFS { - options = append(options, "fstype", "nullfs", "target", device) - } else { - options = append(options, "fstype", mType, "from", device) - } - rawOptions := allocateIOVecs(options) - for _, rawOption := range rawOptions { - defer C.free(rawOption.iov_base) - } - - if errno := C.nmount(&rawOptions[0], C.uint(len(options)), C.int(flag)); errno != 0 { - reason := C.GoString(C.strerror(*C.__error())) - return fmt.Errorf("Failed to call nmount: %s", reason) - } - return nil -} - -func unmount(target string, flag int) error { - return syscall.Unmount(target, flag) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_linux.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_linux.go deleted file mode 100644 index dd4280c7778..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_linux.go +++ /dev/null @@ -1,21 +0,0 @@ -package mount - -import ( - "syscall" -) - -func mount(device, target, mType string, flag uintptr, data string) error { - if err := syscall.Mount(device, target, mType, flag, data); err != nil { - return err - } - - // If we have a bind mount or remount, remount... - if flag&syscall.MS_BIND == syscall.MS_BIND && flag&syscall.MS_RDONLY == syscall.MS_RDONLY { - return syscall.Mount(device, target, mType, flag|syscall.MS_REMOUNT, data) - } - return nil -} - -func unmount(target string, flag int) error { - return syscall.Unmount(target, flag) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_unsupported.go deleted file mode 100644 index eb93365eb74..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mounter_unsupported.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !linux,!freebsd freebsd,!cgo - -package mount - -func mount(device, target, mType string, flag uintptr, data string) error { - panic("Not implemented") -} - -func unmount(target string, flag int) error { - panic("Not implemented") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo.go deleted file mode 100644 index ec8e8bca2a1..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo.go +++ /dev/null @@ -1,7 +0,0 @@ -package mount - -type MountInfo struct { - Id, Parent, Major, Minor int - Root, Mountpoint, Opts, Optional string - Fstype, Source, VfsOpts string -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go deleted file mode 100644 index 2fe91862d84..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go +++ /dev/null @@ -1,40 +0,0 @@ -package mount - -/* -#include -#include -#include -*/ -import "C" - -import ( - "fmt" - "reflect" - "unsafe" -) - -// Parse /proc/self/mountinfo because comparing Dev and ino does not work from bind mounts -func parseMountTable() ([]*MountInfo, error) { - var rawEntries *C.struct_statfs - - count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT)) - if count == 0 { - return nil, fmt.Errorf("Failed to call getmntinfo") - } - - var entries []C.struct_statfs - header := (*reflect.SliceHeader)(unsafe.Pointer(&entries)) - header.Cap = count - header.Len = count - header.Data = uintptr(unsafe.Pointer(rawEntries)) - - var out []*MountInfo - for _, entry := range entries { - var mountinfo MountInfo - mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0]) - mountinfo.Source = C.GoString(&entry.f_mntfromname[0]) - mountinfo.Fstype = C.GoString(&entry.f_fstypename[0]) - out = append(out, &mountinfo) - } - return out, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux.go deleted file mode 100644 index 0eb018e231a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux.go +++ /dev/null @@ -1,92 +0,0 @@ -// +build linux - -package mount - -import ( - "bufio" - "fmt" - "io" - "os" - "strings" -) - -const ( - /* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue - (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) - - (1) mount ID: unique identifier of the mount (may be reused after umount) - (2) parent ID: ID of parent (or of self for the top of the mount tree) - (3) major:minor: value of st_dev for files on filesystem - (4) root: root of the mount within the filesystem - (5) mount point: mount point relative to the process's root - (6) mount options: per mount options - (7) optional fields: zero or more fields of the form "tag[:value]" - (8) separator: marks the end of the optional fields - (9) filesystem type: name of filesystem of the form "type[.subtype]" - (10) mount source: filesystem specific information or "none" - (11) super options: per super block options*/ - mountinfoFormat = "%d %d %d:%d %s %s %s %s" -) - -// Parse /proc/self/mountinfo because comparing Dev and ino does not work from bind mounts -func parseMountTable() ([]*MountInfo, error) { - f, err := os.Open("/proc/self/mountinfo") - if err != nil { - return nil, err - } - defer f.Close() - - return parseInfoFile(f) -} - -func parseInfoFile(r io.Reader) ([]*MountInfo, error) { - var ( - s = bufio.NewScanner(r) - out = []*MountInfo{} - ) - - for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - var ( - p = &MountInfo{} - text = s.Text() - optionalFields string - ) - - if _, err := fmt.Sscanf(text, mountinfoFormat, - &p.Id, &p.Parent, &p.Major, &p.Minor, - &p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil { - return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err) - } - // Safe as mountinfo encodes mountpoints with spaces as \040. - index := strings.Index(text, " - ") - postSeparatorFields := strings.Fields(text[index+3:]) - if len(postSeparatorFields) < 3 { - return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text) - } - - if optionalFields != "-" { - p.Optional = optionalFields - } - - p.Fstype = postSeparatorFields[0] - p.Source = postSeparatorFields[1] - p.VfsOpts = strings.Join(postSeparatorFields[2:], " ") - out = append(out, p) - } - return out, nil -} - -// PidMountInfo collects the mounts for a specific Pid -func PidMountInfo(pid int) ([]*MountInfo, error) { - f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid)) - if err != nil { - return nil, err - } - defer f.Close() - - return parseInfoFile(f) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux_test.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux_test.go deleted file mode 100644 index e92b7e2c741..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_linux_test.go +++ /dev/null @@ -1,477 +0,0 @@ -// +build linux - -package mount - -import ( - "bytes" - "testing" -) - -const ( - fedoraMountinfo = `15 35 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw - 16 35 0:14 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw,seclabel - 17 35 0:5 / /dev rw,nosuid shared:2 - devtmpfs devtmpfs rw,seclabel,size=8056484k,nr_inodes=2014121,mode=755 - 18 16 0:15 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:7 - securityfs securityfs rw - 19 16 0:13 / /sys/fs/selinux rw,relatime shared:8 - selinuxfs selinuxfs rw - 20 17 0:16 / /dev/shm rw,nosuid,nodev shared:3 - tmpfs tmpfs rw,seclabel - 21 17 0:10 / /dev/pts rw,nosuid,noexec,relatime shared:4 - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=000 - 22 35 0:17 / /run rw,nosuid,nodev shared:21 - tmpfs tmpfs rw,seclabel,mode=755 - 23 16 0:18 / /sys/fs/cgroup rw,nosuid,nodev,noexec shared:9 - tmpfs tmpfs rw,seclabel,mode=755 - 24 23 0:19 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd - 25 16 0:20 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:20 - pstore pstore rw - 26 23 0:21 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:11 - cgroup cgroup rw,cpuset,clone_children - 27 23 0:22 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:12 - cgroup cgroup rw,cpuacct,cpu,clone_children - 28 23 0:23 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,memory,clone_children - 29 23 0:24 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,devices,clone_children - 30 23 0:25 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,freezer,clone_children - 31 23 0:26 / /sys/fs/cgroup/net_cls rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,net_cls,clone_children - 32 23 0:27 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,blkio,clone_children - 33 23 0:28 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,perf_event,clone_children - 34 23 0:29 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,hugetlb,clone_children - 35 1 253:2 / / rw,relatime shared:1 - ext4 /dev/mapper/ssd-root--f20 rw,seclabel,data=ordered - 36 15 0:30 / /proc/sys/fs/binfmt_misc rw,relatime shared:22 - autofs systemd-1 rw,fd=38,pgrp=1,timeout=300,minproto=5,maxproto=5,direct - 37 17 0:12 / /dev/mqueue rw,relatime shared:23 - mqueue mqueue rw,seclabel - 38 35 0:31 / /tmp rw shared:24 - tmpfs tmpfs rw,seclabel - 39 17 0:32 / /dev/hugepages rw,relatime shared:25 - hugetlbfs hugetlbfs rw,seclabel - 40 16 0:7 / /sys/kernel/debug rw,relatime shared:26 - debugfs debugfs rw - 41 16 0:33 / /sys/kernel/config rw,relatime shared:27 - configfs configfs rw - 42 35 0:34 / /var/lib/nfs/rpc_pipefs rw,relatime shared:28 - rpc_pipefs sunrpc rw - 43 15 0:35 / /proc/fs/nfsd rw,relatime shared:29 - nfsd sunrpc rw - 45 35 8:17 / /boot rw,relatime shared:30 - ext4 /dev/sdb1 rw,seclabel,data=ordered - 46 35 253:4 / /home rw,relatime shared:31 - ext4 /dev/mapper/ssd-home rw,seclabel,data=ordered - 47 35 253:5 / /var/lib/libvirt/images rw,noatime,nodiratime shared:32 - ext4 /dev/mapper/ssd-virt rw,seclabel,discard,data=ordered - 48 35 253:12 / /mnt/old rw,relatime shared:33 - ext4 /dev/mapper/HelpDeskRHEL6-FedoraRoot rw,seclabel,data=ordered - 121 22 0:36 / /run/user/1000/gvfs rw,nosuid,nodev,relatime shared:104 - fuse.gvfsd-fuse gvfsd-fuse rw,user_id=1000,group_id=1000 - 124 16 0:37 / /sys/fs/fuse/connections rw,relatime shared:107 - fusectl fusectl rw - 165 38 253:3 / /tmp/mnt rw,relatime shared:147 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered - 167 35 253:15 / /var/lib/docker/devicemapper/mnt/aae4076022f0e2b80a2afbf8fc6df450c52080191fcef7fb679a73e6f073e5c2 rw,relatime shared:149 - ext4 /dev/mapper/docker-253:2-425882-aae4076022f0e2b80a2afbf8fc6df450c52080191fcef7fb679a73e6f073e5c2 rw,seclabel,discard,stripe=16,data=ordered - 171 35 253:16 / /var/lib/docker/devicemapper/mnt/c71be651f114db95180e472f7871b74fa597ee70a58ccc35cb87139ddea15373 rw,relatime shared:153 - ext4 /dev/mapper/docker-253:2-425882-c71be651f114db95180e472f7871b74fa597ee70a58ccc35cb87139ddea15373 rw,seclabel,discard,stripe=16,data=ordered - 175 35 253:17 / /var/lib/docker/devicemapper/mnt/1bac6ab72862d2d5626560df6197cf12036b82e258c53d981fa29adce6f06c3c rw,relatime shared:157 - ext4 /dev/mapper/docker-253:2-425882-1bac6ab72862d2d5626560df6197cf12036b82e258c53d981fa29adce6f06c3c rw,seclabel,discard,stripe=16,data=ordered - 179 35 253:18 / /var/lib/docker/devicemapper/mnt/d710a357d77158e80d5b2c55710ae07c94e76d34d21ee7bae65ce5418f739b09 rw,relatime shared:161 - ext4 /dev/mapper/docker-253:2-425882-d710a357d77158e80d5b2c55710ae07c94e76d34d21ee7bae65ce5418f739b09 rw,seclabel,discard,stripe=16,data=ordered - 183 35 253:19 / /var/lib/docker/devicemapper/mnt/6479f52366114d5f518db6837254baab48fab39f2ac38d5099250e9a6ceae6c7 rw,relatime shared:165 - ext4 /dev/mapper/docker-253:2-425882-6479f52366114d5f518db6837254baab48fab39f2ac38d5099250e9a6ceae6c7 rw,seclabel,discard,stripe=16,data=ordered - 187 35 253:20 / /var/lib/docker/devicemapper/mnt/8d9df91c4cca5aef49eeb2725292aab324646f723a7feab56be34c2ad08268e1 rw,relatime shared:169 - ext4 /dev/mapper/docker-253:2-425882-8d9df91c4cca5aef49eeb2725292aab324646f723a7feab56be34c2ad08268e1 rw,seclabel,discard,stripe=16,data=ordered - 191 35 253:21 / /var/lib/docker/devicemapper/mnt/c8240b768603d32e920d365dc9d1dc2a6af46cd23e7ae819947f969e1b4ec661 rw,relatime shared:173 - ext4 /dev/mapper/docker-253:2-425882-c8240b768603d32e920d365dc9d1dc2a6af46cd23e7ae819947f969e1b4ec661 rw,seclabel,discard,stripe=16,data=ordered - 195 35 253:22 / /var/lib/docker/devicemapper/mnt/2eb3a01278380bbf3ed12d86ac629eaa70a4351301ee307a5cabe7b5f3b1615f rw,relatime shared:177 - ext4 /dev/mapper/docker-253:2-425882-2eb3a01278380bbf3ed12d86ac629eaa70a4351301ee307a5cabe7b5f3b1615f rw,seclabel,discard,stripe=16,data=ordered - 199 35 253:23 / /var/lib/docker/devicemapper/mnt/37a17fb7c9d9b80821235d5f2662879bd3483915f245f9b49cdaa0e38779b70b rw,relatime shared:181 - ext4 /dev/mapper/docker-253:2-425882-37a17fb7c9d9b80821235d5f2662879bd3483915f245f9b49cdaa0e38779b70b rw,seclabel,discard,stripe=16,data=ordered - 203 35 253:24 / /var/lib/docker/devicemapper/mnt/aea459ae930bf1de913e2f29428fd80ee678a1e962d4080019d9f9774331ee2b rw,relatime shared:185 - ext4 /dev/mapper/docker-253:2-425882-aea459ae930bf1de913e2f29428fd80ee678a1e962d4080019d9f9774331ee2b rw,seclabel,discard,stripe=16,data=ordered - 207 35 253:25 / /var/lib/docker/devicemapper/mnt/928ead0bc06c454bd9f269e8585aeae0a6bd697f46dc8754c2a91309bc810882 rw,relatime shared:189 - ext4 /dev/mapper/docker-253:2-425882-928ead0bc06c454bd9f269e8585aeae0a6bd697f46dc8754c2a91309bc810882 rw,seclabel,discard,stripe=16,data=ordered - 211 35 253:26 / /var/lib/docker/devicemapper/mnt/0f284d18481d671644706e7a7244cbcf63d590d634cc882cb8721821929d0420 rw,relatime shared:193 - ext4 /dev/mapper/docker-253:2-425882-0f284d18481d671644706e7a7244cbcf63d590d634cc882cb8721821929d0420 rw,seclabel,discard,stripe=16,data=ordered - 215 35 253:27 / /var/lib/docker/devicemapper/mnt/d9dd16722ab34c38db2733e23f69e8f4803ce59658250dd63e98adff95d04919 rw,relatime shared:197 - ext4 /dev/mapper/docker-253:2-425882-d9dd16722ab34c38db2733e23f69e8f4803ce59658250dd63e98adff95d04919 rw,seclabel,discard,stripe=16,data=ordered - 219 35 253:28 / /var/lib/docker/devicemapper/mnt/bc4500479f18c2c08c21ad5282e5f826a016a386177d9874c2764751c031d634 rw,relatime shared:201 - ext4 /dev/mapper/docker-253:2-425882-bc4500479f18c2c08c21ad5282e5f826a016a386177d9874c2764751c031d634 rw,seclabel,discard,stripe=16,data=ordered - 223 35 253:29 / /var/lib/docker/devicemapper/mnt/7770c8b24eb3d5cc159a065910076938910d307ab2f5d94e1dc3b24c06ee2c8a rw,relatime shared:205 - ext4 /dev/mapper/docker-253:2-425882-7770c8b24eb3d5cc159a065910076938910d307ab2f5d94e1dc3b24c06ee2c8a rw,seclabel,discard,stripe=16,data=ordered - 227 35 253:30 / /var/lib/docker/devicemapper/mnt/c280cd3d0bf0aa36b478b292279671624cceafc1a67eaa920fa1082601297adf rw,relatime shared:209 - ext4 /dev/mapper/docker-253:2-425882-c280cd3d0bf0aa36b478b292279671624cceafc1a67eaa920fa1082601297adf rw,seclabel,discard,stripe=16,data=ordered - 231 35 253:31 / /var/lib/docker/devicemapper/mnt/8b59a7d9340279f09fea67fd6ad89ddef711e9e7050eb647984f8b5ef006335f rw,relatime shared:213 - ext4 /dev/mapper/docker-253:2-425882-8b59a7d9340279f09fea67fd6ad89ddef711e9e7050eb647984f8b5ef006335f rw,seclabel,discard,stripe=16,data=ordered - 235 35 253:32 / /var/lib/docker/devicemapper/mnt/1a28059f29eda821578b1bb27a60cc71f76f846a551abefabce6efd0146dce9f rw,relatime shared:217 - ext4 /dev/mapper/docker-253:2-425882-1a28059f29eda821578b1bb27a60cc71f76f846a551abefabce6efd0146dce9f rw,seclabel,discard,stripe=16,data=ordered - 239 35 253:33 / /var/lib/docker/devicemapper/mnt/e9aa60c60128cad1 rw,relatime shared:221 - ext4 /dev/mapper/docker-253:2-425882-e9aa60c60128cad1 rw,seclabel,discard,stripe=16,data=ordered - 243 35 253:34 / /var/lib/docker/devicemapper/mnt/5fec11304b6f4713fea7b6ccdcc1adc0a1966187f590fe25a8227428a8df275d-init rw,relatime shared:225 - ext4 /dev/mapper/docker-253:2-425882-5fec11304b6f4713fea7b6ccdcc1adc0a1966187f590fe25a8227428a8df275d-init rw,seclabel,discard,stripe=16,data=ordered - 247 35 253:35 / /var/lib/docker/devicemapper/mnt/5fec11304b6f4713fea7b6ccdcc1adc0a1966187f590fe25a8227428a8df275d rw,relatime shared:229 - ext4 /dev/mapper/docker-253:2-425882-5fec11304b6f4713fea7b6ccdcc1adc0a1966187f590fe25a8227428a8df275d rw,seclabel,discard,stripe=16,data=ordered - 31 21 0:23 / /DATA/foo_bla_bla rw,relatime - cifs //foo/BLA\040BLA\040BLA/ rw,sec=ntlm,cache=loose,unc=\\foo\BLA BLA BLA,username=my_login,domain=mydomain.com,uid=12345678,forceuid,gid=12345678,forcegid,addr=10.1.30.10,file_mode=0755,dir_mode=0755,nounix,rsize=61440,wsize=65536,actimeo=1` - - ubuntuMountInfo = `15 20 0:14 / /sys rw,nosuid,nodev,noexec,relatime - sysfs sysfs rw -16 20 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw -17 20 0:5 / /dev rw,relatime - devtmpfs udev rw,size=1015140k,nr_inodes=253785,mode=755 -18 17 0:11 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000 -19 20 0:15 / /run rw,nosuid,noexec,relatime - tmpfs tmpfs rw,size=205044k,mode=755 -20 1 253:0 / / rw,relatime - ext4 /dev/disk/by-label/DOROOT rw,errors=remount-ro,data=ordered -21 15 0:16 / /sys/fs/cgroup rw,relatime - tmpfs none rw,size=4k,mode=755 -22 15 0:17 / /sys/fs/fuse/connections rw,relatime - fusectl none rw -23 15 0:6 / /sys/kernel/debug rw,relatime - debugfs none rw -24 15 0:10 / /sys/kernel/security rw,relatime - securityfs none rw -25 19 0:18 / /run/lock rw,nosuid,nodev,noexec,relatime - tmpfs none rw,size=5120k -26 21 0:19 / /sys/fs/cgroup/cpuset rw,relatime - cgroup cgroup rw,cpuset,clone_children -27 19 0:20 / /run/shm rw,nosuid,nodev,relatime - tmpfs none rw -28 21 0:21 / /sys/fs/cgroup/cpu rw,relatime - cgroup cgroup rw,cpu -29 19 0:22 / /run/user rw,nosuid,nodev,noexec,relatime - tmpfs none rw,size=102400k,mode=755 -30 15 0:23 / /sys/fs/pstore rw,relatime - pstore none rw -31 21 0:24 / /sys/fs/cgroup/cpuacct rw,relatime - cgroup cgroup rw,cpuacct -32 21 0:25 / /sys/fs/cgroup/memory rw,relatime - cgroup cgroup rw,memory -33 21 0:26 / /sys/fs/cgroup/devices rw,relatime - cgroup cgroup rw,devices -34 21 0:27 / /sys/fs/cgroup/freezer rw,relatime - cgroup cgroup rw,freezer -35 21 0:28 / /sys/fs/cgroup/blkio rw,relatime - cgroup cgroup rw,blkio -36 21 0:29 / /sys/fs/cgroup/perf_event rw,relatime - cgroup cgroup rw,perf_event -37 21 0:30 / /sys/fs/cgroup/hugetlb rw,relatime - cgroup cgroup rw,hugetlb -38 21 0:31 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup systemd rw,name=systemd -39 20 0:32 / /var/lib/docker/aufs/mnt/b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc rw,relatime - aufs none rw,si=caafa54fdc06525 -40 20 0:33 / /var/lib/docker/aufs/mnt/2eed44ac7ce7c75af04f088ed6cb4ce9d164801e91d78c6db65d7ef6d572bba8-init rw,relatime - aufs none rw,si=caafa54f882b525 -41 20 0:34 / /var/lib/docker/aufs/mnt/2eed44ac7ce7c75af04f088ed6cb4ce9d164801e91d78c6db65d7ef6d572bba8 rw,relatime - aufs none rw,si=caafa54f8829525 -42 20 0:35 / /var/lib/docker/aufs/mnt/16f4d7e96dd612903f425bfe856762f291ff2e36a8ecd55a2209b7d7cd81c30b rw,relatime - aufs none rw,si=caafa54f882d525 -43 20 0:36 / /var/lib/docker/aufs/mnt/63ca08b75d7438a9469a5954e003f48ffede73541f6286ce1cb4d7dd4811da7e-init rw,relatime - aufs none rw,si=caafa54f882f525 -44 20 0:37 / /var/lib/docker/aufs/mnt/63ca08b75d7438a9469a5954e003f48ffede73541f6286ce1cb4d7dd4811da7e rw,relatime - aufs none rw,si=caafa54f88ba525 -45 20 0:38 / /var/lib/docker/aufs/mnt/283f35a910233c756409313be71ecd8fcfef0df57108b8d740b61b3e88860452 rw,relatime - aufs none rw,si=caafa54f88b8525 -46 20 0:39 / /var/lib/docker/aufs/mnt/2c6c7253d4090faa3886871fb21bd660609daeb0206588c0602007f7d0f254b1-init rw,relatime - aufs none rw,si=caafa54f88be525 -47 20 0:40 / /var/lib/docker/aufs/mnt/2c6c7253d4090faa3886871fb21bd660609daeb0206588c0602007f7d0f254b1 rw,relatime - aufs none rw,si=caafa54f882c525 -48 20 0:41 / /var/lib/docker/aufs/mnt/de2b538c97d6366cc80e8658547c923ea1d042f85580df379846f36a4df7049d rw,relatime - aufs none rw,si=caafa54f85bb525 -49 20 0:42 / /var/lib/docker/aufs/mnt/94a3d8ed7c27e5b0aa71eba46c736bfb2742afda038e74f2dd6035fb28415b49-init rw,relatime - aufs none rw,si=caafa54fdc00525 -50 20 0:43 / /var/lib/docker/aufs/mnt/94a3d8ed7c27e5b0aa71eba46c736bfb2742afda038e74f2dd6035fb28415b49 rw,relatime - aufs none rw,si=caafa54fbaec525 -51 20 0:44 / /var/lib/docker/aufs/mnt/6ac1cace985c9fc9bea32234de8b36dba49bdd5e29a2972b327ff939d78a6274 rw,relatime - aufs none rw,si=caafa54f8e1a525 -52 20 0:45 / /var/lib/docker/aufs/mnt/dff147033e3a0ef061e1de1ad34256b523d4a8c1fa6bba71a0ab538e8628ff0b-init rw,relatime - aufs none rw,si=caafa54f8e1d525 -53 20 0:46 / /var/lib/docker/aufs/mnt/dff147033e3a0ef061e1de1ad34256b523d4a8c1fa6bba71a0ab538e8628ff0b rw,relatime - aufs none rw,si=caafa54f8e1b525 -54 20 0:47 / /var/lib/docker/aufs/mnt/cabb117d997f0f93519185aea58389a9762770b7496ed0b74a3e4a083fa45902 rw,relatime - aufs none rw,si=caafa54f810a525 -55 20 0:48 / /var/lib/docker/aufs/mnt/e1c8a94ffaa9d532bbbdc6ef771ce8a6c2c06757806ecaf8b68e9108fec65f33-init rw,relatime - aufs none rw,si=caafa54f8529525 -56 20 0:49 / /var/lib/docker/aufs/mnt/e1c8a94ffaa9d532bbbdc6ef771ce8a6c2c06757806ecaf8b68e9108fec65f33 rw,relatime - aufs none rw,si=caafa54f852f525 -57 20 0:50 / /var/lib/docker/aufs/mnt/16a1526fa445b84ce84f89506d219e87fa488a814063baf045d88b02f21166b3 rw,relatime - aufs none rw,si=caafa54f9e1d525 -58 20 0:51 / /var/lib/docker/aufs/mnt/57b9c92e1e368fa7dbe5079f7462e917777829caae732828b003c355fe49da9f-init rw,relatime - aufs none rw,si=caafa54f854d525 -59 20 0:52 / /var/lib/docker/aufs/mnt/57b9c92e1e368fa7dbe5079f7462e917777829caae732828b003c355fe49da9f rw,relatime - aufs none rw,si=caafa54f854e525 -60 20 0:53 / /var/lib/docker/aufs/mnt/e370c3e286bea027917baa0e4d251262681a472a87056e880dfd0513516dffd9 rw,relatime - aufs none rw,si=caafa54f840a525 -61 20 0:54 / /var/lib/docker/aufs/mnt/6b00d3b4f32b41997ec07412b5e18204f82fbe643e7122251cdeb3582abd424e-init rw,relatime - aufs none rw,si=caafa54f8408525 -62 20 0:55 / /var/lib/docker/aufs/mnt/6b00d3b4f32b41997ec07412b5e18204f82fbe643e7122251cdeb3582abd424e rw,relatime - aufs none rw,si=caafa54f8409525 -63 20 0:56 / /var/lib/docker/aufs/mnt/abd0b5ea5d355a67f911475e271924a5388ee60c27185fcd60d095afc4a09dc7 rw,relatime - aufs none rw,si=caafa54f9eb1525 -64 20 0:57 / /var/lib/docker/aufs/mnt/336222effc3f7b89867bb39ff7792ae5412c35c749f127c29159d046b6feedd2-init rw,relatime - aufs none rw,si=caafa54f85bf525 -65 20 0:58 / /var/lib/docker/aufs/mnt/336222effc3f7b89867bb39ff7792ae5412c35c749f127c29159d046b6feedd2 rw,relatime - aufs none rw,si=caafa54f85b8525 -66 20 0:59 / /var/lib/docker/aufs/mnt/912e1bf28b80a09644503924a8a1a4fb8ed10b808ca847bda27a369919aa52fa rw,relatime - aufs none rw,si=caafa54fbaea525 -67 20 0:60 / /var/lib/docker/aufs/mnt/386f722875013b4a875118367abc783fc6617a3cb7cf08b2b4dcf550b4b9c576-init rw,relatime - aufs none rw,si=caafa54f8472525 -68 20 0:61 / /var/lib/docker/aufs/mnt/386f722875013b4a875118367abc783fc6617a3cb7cf08b2b4dcf550b4b9c576 rw,relatime - aufs none rw,si=caafa54f8474525 -69 20 0:62 / /var/lib/docker/aufs/mnt/5aaebb79ef3097dfca377889aeb61a0c9d5e3795117d2b08d0751473c671dfb2 rw,relatime - aufs none rw,si=caafa54f8c5e525 -70 20 0:63 / /var/lib/docker/aufs/mnt/5ba3e493279d01277d583600b81c7c079e691b73c3a2bdea8e4b12a35a418be2-init rw,relatime - aufs none rw,si=caafa54f8c3b525 -71 20 0:64 / /var/lib/docker/aufs/mnt/5ba3e493279d01277d583600b81c7c079e691b73c3a2bdea8e4b12a35a418be2 rw,relatime - aufs none rw,si=caafa54f8c3d525 -72 20 0:65 / /var/lib/docker/aufs/mnt/2777f0763da4de93f8bebbe1595cc77f739806a158657b033eca06f827b6028a rw,relatime - aufs none rw,si=caafa54f8c3e525 -73 20 0:66 / /var/lib/docker/aufs/mnt/5d7445562acf73c6f0ae34c3dd0921d7457de1ba92a587d9e06a44fa209eeb3e-init rw,relatime - aufs none rw,si=caafa54f8c39525 -74 20 0:67 / /var/lib/docker/aufs/mnt/5d7445562acf73c6f0ae34c3dd0921d7457de1ba92a587d9e06a44fa209eeb3e rw,relatime - aufs none rw,si=caafa54f854f525 -75 20 0:68 / /var/lib/docker/aufs/mnt/06400b526ec18b66639c96efc41a84f4ae0b117cb28dafd56be420651b4084a0 rw,relatime - aufs none rw,si=caafa54f840b525 -76 20 0:69 / /var/lib/docker/aufs/mnt/e051d45ec42d8e3e1cc57bb39871a40de486dc123522e9c067fbf2ca6a357785-init rw,relatime - aufs none rw,si=caafa54fdddf525 -77 20 0:70 / /var/lib/docker/aufs/mnt/e051d45ec42d8e3e1cc57bb39871a40de486dc123522e9c067fbf2ca6a357785 rw,relatime - aufs none rw,si=caafa54f854b525 -78 20 0:71 / /var/lib/docker/aufs/mnt/1ff414fa93fd61ec81b0ab7b365a841ff6545accae03cceac702833aaeaf718f rw,relatime - aufs none rw,si=caafa54f8d85525 -79 20 0:72 / /var/lib/docker/aufs/mnt/c661b2f871dd5360e46a2aebf8f970f6d39a2ff64e06979aa0361227c88128b8-init rw,relatime - aufs none rw,si=caafa54f8da3525 -80 20 0:73 / /var/lib/docker/aufs/mnt/c661b2f871dd5360e46a2aebf8f970f6d39a2ff64e06979aa0361227c88128b8 rw,relatime - aufs none rw,si=caafa54f8da2525 -81 20 0:74 / /var/lib/docker/aufs/mnt/b68b1d4fe4d30016c552398e78b379a39f651661d8e1fa5f2460c24a5e723420 rw,relatime - aufs none rw,si=caafa54f8d81525 -82 20 0:75 / /var/lib/docker/aufs/mnt/c5c5979c936cd0153a4c626fa9d69ce4fce7d924cc74fa68b025d2f585031739-init rw,relatime - aufs none rw,si=caafa54f8da1525 -83 20 0:76 / /var/lib/docker/aufs/mnt/c5c5979c936cd0153a4c626fa9d69ce4fce7d924cc74fa68b025d2f585031739 rw,relatime - aufs none rw,si=caafa54f8da0525 -84 20 0:77 / /var/lib/docker/aufs/mnt/53e10b0329afc0e0d3322d31efaed4064139dc7027fe6ae445cffd7104bcc94f rw,relatime - aufs none rw,si=caafa54f8c35525 -85 20 0:78 / /var/lib/docker/aufs/mnt/3bfafd09ff2603e2165efacc2215c1f51afabba6c42d04a68cc2df0e8cc31494-init rw,relatime - aufs none rw,si=caafa54f8db8525 -86 20 0:79 / /var/lib/docker/aufs/mnt/3bfafd09ff2603e2165efacc2215c1f51afabba6c42d04a68cc2df0e8cc31494 rw,relatime - aufs none rw,si=caafa54f8dba525 -87 20 0:80 / /var/lib/docker/aufs/mnt/90fdd2c03eeaf65311f88f4200e18aef6d2772482712d9aea01cd793c64781b5 rw,relatime - aufs none rw,si=caafa54f8315525 -88 20 0:81 / /var/lib/docker/aufs/mnt/7bdf2591c06c154ceb23f5e74b1d03b18fbf6fe96e35fbf539b82d446922442f-init rw,relatime - aufs none rw,si=caafa54f8fc6525 -89 20 0:82 / /var/lib/docker/aufs/mnt/7bdf2591c06c154ceb23f5e74b1d03b18fbf6fe96e35fbf539b82d446922442f rw,relatime - aufs none rw,si=caafa54f8468525 -90 20 0:83 / /var/lib/docker/aufs/mnt/8cf9a993f50f3305abad3da268c0fc44ff78a1e7bba595ef9de963497496c3f9 rw,relatime - aufs none rw,si=caafa54f8c59525 -91 20 0:84 / /var/lib/docker/aufs/mnt/ecc896fd74b21840a8d35e8316b92a08b1b9c83d722a12acff847e9f0ff17173-init rw,relatime - aufs none rw,si=caafa54f846a525 -92 20 0:85 / /var/lib/docker/aufs/mnt/ecc896fd74b21840a8d35e8316b92a08b1b9c83d722a12acff847e9f0ff17173 rw,relatime - aufs none rw,si=caafa54f846b525 -93 20 0:86 / /var/lib/docker/aufs/mnt/d8c8288ec920439a48b5796bab5883ee47a019240da65e8d8f33400c31bac5df rw,relatime - aufs none rw,si=caafa54f8dbf525 -94 20 0:87 / /var/lib/docker/aufs/mnt/ecba66710bcd03199b9398e46c005cd6b68d0266ec81dc8b722a29cc417997c6-init rw,relatime - aufs none rw,si=caafa54f810f525 -95 20 0:88 / /var/lib/docker/aufs/mnt/ecba66710bcd03199b9398e46c005cd6b68d0266ec81dc8b722a29cc417997c6 rw,relatime - aufs none rw,si=caafa54fbae9525 -96 20 0:89 / /var/lib/docker/aufs/mnt/befc1c67600df449dddbe796c0d06da7caff1d2bbff64cde1f0ba82d224996b5 rw,relatime - aufs none rw,si=caafa54f8dab525 -97 20 0:90 / /var/lib/docker/aufs/mnt/c9f470e73d2742629cdc4084a1b2c1a8302914f2aa0d0ec4542371df9a050562-init rw,relatime - aufs none rw,si=caafa54fdc02525 -98 20 0:91 / /var/lib/docker/aufs/mnt/c9f470e73d2742629cdc4084a1b2c1a8302914f2aa0d0ec4542371df9a050562 rw,relatime - aufs none rw,si=caafa54f9eb0525 -99 20 0:92 / /var/lib/docker/aufs/mnt/2a31f10029f04ff9d4381167a9b739609853d7220d55a56cb654779a700ee246 rw,relatime - aufs none rw,si=caafa54f8c37525 -100 20 0:93 / /var/lib/docker/aufs/mnt/8c4261b8e3e4b21ebba60389bd64b6261217e7e6b9fd09e201d5a7f6760f6927-init rw,relatime - aufs none rw,si=caafa54fd173525 -101 20 0:94 / /var/lib/docker/aufs/mnt/8c4261b8e3e4b21ebba60389bd64b6261217e7e6b9fd09e201d5a7f6760f6927 rw,relatime - aufs none rw,si=caafa54f8108525 -102 20 0:95 / /var/lib/docker/aufs/mnt/eaa0f57403a3dc685268f91df3fbcd7a8423cee50e1a9ee5c3e1688d9d676bb4 rw,relatime - aufs none rw,si=caafa54f852d525 -103 20 0:96 / /var/lib/docker/aufs/mnt/9cfe69a2cbffd9bfc7f396d4754f6fe5cc457ef417b277797be3762dfe955a6b-init rw,relatime - aufs none rw,si=caafa54f8d80525 -104 20 0:97 / /var/lib/docker/aufs/mnt/9cfe69a2cbffd9bfc7f396d4754f6fe5cc457ef417b277797be3762dfe955a6b rw,relatime - aufs none rw,si=caafa54f8fc3525 -105 20 0:98 / /var/lib/docker/aufs/mnt/d1b322ae17613c6adee84e709641a9244ac56675244a89a64dc0075075fcbb83 rw,relatime - aufs none rw,si=caafa54f8c58525 -106 20 0:99 / /var/lib/docker/aufs/mnt/d46c2a8e9da7e91ab34fd9c192851c246a4e770a46720bda09e55c7554b9dbbd-init rw,relatime - aufs none rw,si=caafa54f8c63525 -107 20 0:100 / /var/lib/docker/aufs/mnt/d46c2a8e9da7e91ab34fd9c192851c246a4e770a46720bda09e55c7554b9dbbd rw,relatime - aufs none rw,si=caafa54f8c67525 -108 20 0:101 / /var/lib/docker/aufs/mnt/bc9d2a264158f83a617a069bf17cbbf2a2ba453db7d3951d9dc63cc1558b1c2b rw,relatime - aufs none rw,si=caafa54f8dbe525 -109 20 0:102 / /var/lib/docker/aufs/mnt/9e6abb8d72bbeb4d5cf24b96018528015ba830ce42b4859965bd482cbd034e99-init rw,relatime - aufs none rw,si=caafa54f9e0d525 -110 20 0:103 / /var/lib/docker/aufs/mnt/9e6abb8d72bbeb4d5cf24b96018528015ba830ce42b4859965bd482cbd034e99 rw,relatime - aufs none rw,si=caafa54f9e1b525 -111 20 0:104 / /var/lib/docker/aufs/mnt/d4dca7b02569c732e740071e1c654d4ad282de5c41edb619af1f0aafa618be26 rw,relatime - aufs none rw,si=caafa54f8dae525 -112 20 0:105 / /var/lib/docker/aufs/mnt/fea63da40fa1c5ffbad430dde0bc64a8fc2edab09a051fff55b673c40a08f6b7-init rw,relatime - aufs none rw,si=caafa54f8c5c525 -113 20 0:106 / /var/lib/docker/aufs/mnt/fea63da40fa1c5ffbad430dde0bc64a8fc2edab09a051fff55b673c40a08f6b7 rw,relatime - aufs none rw,si=caafa54fd172525 -114 20 0:107 / /var/lib/docker/aufs/mnt/e60c57499c0b198a6734f77f660cdbbd950a5b78aa23f470ca4f0cfcc376abef rw,relatime - aufs none rw,si=caafa54909c4525 -115 20 0:108 / /var/lib/docker/aufs/mnt/099c78e7ccd9c8717471bb1bbfff838c0a9913321ba2f214fbeaf92c678e5b35-init rw,relatime - aufs none rw,si=caafa54909c3525 -116 20 0:109 / /var/lib/docker/aufs/mnt/099c78e7ccd9c8717471bb1bbfff838c0a9913321ba2f214fbeaf92c678e5b35 rw,relatime - aufs none rw,si=caafa54909c7525 -117 20 0:110 / /var/lib/docker/aufs/mnt/2997be666d58b9e71469759bcb8bd9608dad0e533a1a7570a896919ba3388825 rw,relatime - aufs none rw,si=caafa54f8557525 -118 20 0:111 / /var/lib/docker/aufs/mnt/730694eff438ef20569df38dfb38a920969d7ff2170cc9aa7cb32a7ed8147a93-init rw,relatime - aufs none rw,si=caafa54c6e88525 -119 20 0:112 / /var/lib/docker/aufs/mnt/730694eff438ef20569df38dfb38a920969d7ff2170cc9aa7cb32a7ed8147a93 rw,relatime - aufs none rw,si=caafa54c6e8e525 -120 20 0:113 / /var/lib/docker/aufs/mnt/a672a1e2f2f051f6e19ed1dfbe80860a2d774174c49f7c476695f5dd1d5b2f67 rw,relatime - aufs none rw,si=caafa54c6e15525 -121 20 0:114 / /var/lib/docker/aufs/mnt/aba3570e17859f76cf29d282d0d150659c6bd80780fdc52a465ba05245c2a420-init rw,relatime - aufs none rw,si=caafa54f8dad525 -122 20 0:115 / /var/lib/docker/aufs/mnt/aba3570e17859f76cf29d282d0d150659c6bd80780fdc52a465ba05245c2a420 rw,relatime - aufs none rw,si=caafa54f8d84525 -123 20 0:116 / /var/lib/docker/aufs/mnt/2abc86007aca46fb4a817a033e2a05ccacae40b78ea4b03f8ea616b9ada40e2e rw,relatime - aufs none rw,si=caafa54c6e8b525 -124 20 0:117 / /var/lib/docker/aufs/mnt/36352f27f7878e648367a135bd1ec3ed497adcb8ac13577ee892a0bd921d2374-init rw,relatime - aufs none rw,si=caafa54c6e8d525 -125 20 0:118 / /var/lib/docker/aufs/mnt/36352f27f7878e648367a135bd1ec3ed497adcb8ac13577ee892a0bd921d2374 rw,relatime - aufs none rw,si=caafa54f8c34525 -126 20 0:119 / /var/lib/docker/aufs/mnt/2f95ca1a629cea8363b829faa727dd52896d5561f2c96ddee4f697ea2fc872c2 rw,relatime - aufs none rw,si=caafa54c6e8a525 -127 20 0:120 / /var/lib/docker/aufs/mnt/f108c8291654f179ef143a3e07de2b5a34adbc0b28194a0ab17742b6db9a7fb2-init rw,relatime - aufs none rw,si=caafa54f8e19525 -128 20 0:121 / /var/lib/docker/aufs/mnt/f108c8291654f179ef143a3e07de2b5a34adbc0b28194a0ab17742b6db9a7fb2 rw,relatime - aufs none rw,si=caafa54fa8c6525 -129 20 0:122 / /var/lib/docker/aufs/mnt/c1d04dfdf8cccb3676d5a91e84e9b0781ce40623d127d038bcfbe4c761b27401 rw,relatime - aufs none rw,si=caafa54f8c30525 -130 20 0:123 / /var/lib/docker/aufs/mnt/3f4898ffd0e1239aeebf1d1412590cdb7254207fa3883663e2c40cf772e5f05a-init rw,relatime - aufs none rw,si=caafa54c6e1a525 -131 20 0:124 / /var/lib/docker/aufs/mnt/3f4898ffd0e1239aeebf1d1412590cdb7254207fa3883663e2c40cf772e5f05a rw,relatime - aufs none rw,si=caafa54c6e1c525 -132 20 0:125 / /var/lib/docker/aufs/mnt/5ae3b6fccb1539fc02d420e86f3e9637bef5b711fed2ca31a2f426c8f5deddbf rw,relatime - aufs none rw,si=caafa54c4fea525 -133 20 0:126 / /var/lib/docker/aufs/mnt/310bfaf80d57020f2e73b06aeffb0b9b0ca2f54895f88bf5e4d1529ccac58fe0-init rw,relatime - aufs none rw,si=caafa54c6e1e525 -134 20 0:127 / /var/lib/docker/aufs/mnt/310bfaf80d57020f2e73b06aeffb0b9b0ca2f54895f88bf5e4d1529ccac58fe0 rw,relatime - aufs none rw,si=caafa54fa8c0525 -135 20 0:128 / /var/lib/docker/aufs/mnt/f382bd5aaccaf2d04a59089ac7cb12ec87efd769fd0c14d623358fbfd2a3f896 rw,relatime - aufs none rw,si=caafa54c4fec525 -136 20 0:129 / /var/lib/docker/aufs/mnt/50d45e9bb2d779bc6362824085564c7578c231af5ae3b3da116acf7e17d00735-init rw,relatime - aufs none rw,si=caafa54c4fef525 -137 20 0:130 / /var/lib/docker/aufs/mnt/50d45e9bb2d779bc6362824085564c7578c231af5ae3b3da116acf7e17d00735 rw,relatime - aufs none rw,si=caafa54c4feb525 -138 20 0:131 / /var/lib/docker/aufs/mnt/a9c5ee0854dc083b6bf62b7eb1e5291aefbb10702289a446471ce73aba0d5d7d rw,relatime - aufs none rw,si=caafa54909c6525 -139 20 0:134 / /var/lib/docker/aufs/mnt/03a613e7bd5078819d1fd92df4e671c0127559a5e0b5a885cc8d5616875162f0-init rw,relatime - aufs none rw,si=caafa54804fe525 -140 20 0:135 / /var/lib/docker/aufs/mnt/03a613e7bd5078819d1fd92df4e671c0127559a5e0b5a885cc8d5616875162f0 rw,relatime - aufs none rw,si=caafa54804fa525 -141 20 0:136 / /var/lib/docker/aufs/mnt/7ec3277e5c04c907051caf9c9c35889f5fcd6463e5485971b25404566830bb70 rw,relatime - aufs none rw,si=caafa54804f9525 -142 20 0:139 / /var/lib/docker/aufs/mnt/26b5b5d71d79a5b2bfcf8bc4b2280ee829f261eb886745dd90997ed410f7e8b8-init rw,relatime - aufs none rw,si=caafa54c6ef6525 -143 20 0:140 / /var/lib/docker/aufs/mnt/26b5b5d71d79a5b2bfcf8bc4b2280ee829f261eb886745dd90997ed410f7e8b8 rw,relatime - aufs none rw,si=caafa54c6ef5525 -144 20 0:356 / /var/lib/docker/aufs/mnt/e6ecde9e2c18cd3c75f424c67b6d89685cfee0fc67abf2cb6bdc0867eb998026 rw,relatime - aufs none rw,si=caafa548068e525` - - gentooMountinfo = `15 1 8:6 / / rw,noatime,nodiratime - ext4 /dev/sda6 rw,data=ordered -16 15 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw -17 15 0:14 / /run rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=3292172k,mode=755 -18 15 0:5 / /dev rw,nosuid,relatime - devtmpfs udev rw,size=10240k,nr_inodes=4106451,mode=755 -19 18 0:12 / /dev/mqueue rw,nosuid,nodev,noexec,relatime - mqueue mqueue rw -20 18 0:10 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000 -21 18 0:15 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw -22 15 0:16 / /sys rw,nosuid,nodev,noexec,relatime - sysfs sysfs rw -23 22 0:7 / /sys/kernel/debug rw,nosuid,nodev,noexec,relatime - debugfs debugfs rw -24 22 0:17 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs cgroup_root rw,size=10240k,mode=755 -25 24 0:18 / /sys/fs/cgroup/openrc rw,nosuid,nodev,noexec,relatime - cgroup openrc rw,release_agent=/lib64/rc/sh/cgroup-release-agent.sh,name=openrc -26 24 0:19 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime - cgroup cpuset rw,cpuset,clone_children -27 24 0:20 / /sys/fs/cgroup/cpu rw,nosuid,nodev,noexec,relatime - cgroup cpu rw,cpu,clone_children -28 24 0:21 / /sys/fs/cgroup/cpuacct rw,nosuid,nodev,noexec,relatime - cgroup cpuacct rw,cpuacct,clone_children -29 24 0:22 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime - cgroup memory rw,memory,clone_children -30 24 0:23 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime - cgroup devices rw,devices,clone_children -31 24 0:24 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime - cgroup freezer rw,freezer,clone_children -32 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime - cgroup blkio rw,blkio,clone_children -33 15 8:1 / /boot rw,noatime,nodiratime - vfat /dev/sda1 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro -34 15 8:18 / /mnt/xfs rw,noatime,nodiratime - xfs /dev/sdb2 rw,attr2,inode64,noquota -35 15 0:26 / /tmp rw,relatime - tmpfs tmpfs rw -36 16 0:27 / /proc/sys/fs/binfmt_misc rw,nosuid,nodev,noexec,relatime - binfmt_misc binfmt_misc rw -42 15 0:33 / /var/lib/nfs/rpc_pipefs rw,relatime - rpc_pipefs rpc_pipefs rw -43 16 0:34 / /proc/fs/nfsd rw,nosuid,nodev,noexec,relatime - nfsd nfsd rw -44 15 0:35 / /home/tianon/.gvfs rw,nosuid,nodev,relatime - fuse.gvfs-fuse-daemon gvfs-fuse-daemon rw,user_id=1000,group_id=1000 -68 15 0:3336 / /var/lib/docker/aufs/mnt/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd rw,relatime - aufs none rw,si=9b4a7640128db39c -85 68 8:6 /var/lib/docker/init/dockerinit-0.7.2-dev//deleted /var/lib/docker/aufs/mnt/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/.dockerinit rw,noatime,nodiratime - ext4 /dev/sda6 rw,data=ordered -86 68 8:6 /var/lib/docker/containers/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/config.env /var/lib/docker/aufs/mnt/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/.dockerenv rw,noatime,nodiratime - ext4 /dev/sda6 rw,data=ordered -87 68 8:6 /etc/resolv.conf /var/lib/docker/aufs/mnt/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/etc/resolv.conf rw,noatime,nodiratime - ext4 /dev/sda6 rw,data=ordered -88 68 8:6 /var/lib/docker/containers/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/hostname /var/lib/docker/aufs/mnt/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/etc/hostname rw,noatime,nodiratime - ext4 /dev/sda6 rw,data=ordered -89 68 8:6 /var/lib/docker/containers/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/hosts /var/lib/docker/aufs/mnt/3597a1a6d6298c1decc339ebb90aad6f7d6ba2e15af3131b1f85e7ee4787a0cd/etc/hosts rw,noatime,nodiratime - ext4 /dev/sda6 rw,data=ordered -38 15 0:3384 / /var/lib/docker/aufs/mnt/0292005a9292401bb5197657f2b682d97d8edcb3b72b5e390d2a680139985b55 rw,relatime - aufs none rw,si=9b4a7642b584939c -39 15 0:3385 / /var/lib/docker/aufs/mnt/59db98c889de5f71b70cfb82c40cbe47b64332f0f56042a2987a9e5df6e5e3aa rw,relatime - aufs none rw,si=9b4a7642b584e39c -40 15 0:3386 / /var/lib/docker/aufs/mnt/0545f0f2b6548eb9601d08f35a08f5a0a385407d36027a28f58e06e9f61e0278 rw,relatime - aufs none rw,si=9b4a7642b584b39c -41 15 0:3387 / /var/lib/docker/aufs/mnt/d882cfa16d1aa8fe0331a36e79be3d80b151e49f24fc39a39c3fed1735d5feb5 rw,relatime - aufs none rw,si=9b4a76453040039c -45 15 0:3388 / /var/lib/docker/aufs/mnt/055ca3befcb1626e74f5344b3398724ff05c0de0e20021683d04305c9e70a3f6 rw,relatime - aufs none rw,si=9b4a76453040739c -46 15 0:3389 / /var/lib/docker/aufs/mnt/b899e4567a351745d4285e7f1c18fdece75d877deb3041981cd290be348b7aa6 rw,relatime - aufs none rw,si=9b4a7647def4039c -47 15 0:3390 / /var/lib/docker/aufs/mnt/067ca040292c58954c5129f953219accfae0d40faca26b4d05e76ca76a998f16 rw,relatime - aufs none rw,si=9b4a7647def4239c -48 15 0:3391 / /var/lib/docker/aufs/mnt/8c995e7cb6e5082742daeea720e340b021d288d25d92e0412c03d200df308a11 rw,relatime - aufs none rw,si=9b4a764479c1639c -49 15 0:3392 / /var/lib/docker/aufs/mnt/07cc54dfae5b45300efdacdd53cc72c01b9044956a86ce7bff42d087e426096d rw,relatime - aufs none rw,si=9b4a764479c1739c -50 15 0:3393 / /var/lib/docker/aufs/mnt/0a9c95cf4c589c05b06baa79150b0cc1d8e7102759fe3ce4afaabb8247ca4f85 rw,relatime - aufs none rw,si=9b4a7644059c839c -51 15 0:3394 / /var/lib/docker/aufs/mnt/468fa98cececcf4e226e8370f18f4f848d63faf287fb8321a07f73086441a3a0 rw,relatime - aufs none rw,si=9b4a7644059ca39c -52 15 0:3395 / /var/lib/docker/aufs/mnt/0b826192231c5ce066fffb5beff4397337b5fc19a377aa7c6282c7c0ce7f111f rw,relatime - aufs none rw,si=9b4a764479c1339c -53 15 0:3396 / /var/lib/docker/aufs/mnt/93b8ba1b772fbe79709b909c43ea4b2c30d712e53548f467db1ffdc7a384f196 rw,relatime - aufs none rw,si=9b4a7640798a739c -54 15 0:3397 / /var/lib/docker/aufs/mnt/0c0d0acfb506859b12ef18cdfef9ebed0b43a611482403564224bde9149d373c rw,relatime - aufs none rw,si=9b4a7640798a039c -55 15 0:3398 / /var/lib/docker/aufs/mnt/33648c39ab6c7c74af0243d6d6a81b052e9e25ad1e04b19892eb2dde013e358b rw,relatime - aufs none rw,si=9b4a7644b439b39c -56 15 0:3399 / /var/lib/docker/aufs/mnt/0c12bea97a1c958a3c739fb148536c1c89351d48e885ecda8f0499b5cc44407e rw,relatime - aufs none rw,si=9b4a7640798a239c -57 15 0:3400 / /var/lib/docker/aufs/mnt/ed443988ce125f172d7512e84a4de2627405990fd767a16adefa8ce700c19ce8 rw,relatime - aufs none rw,si=9b4a7644c8ed339c -59 15 0:3402 / /var/lib/docker/aufs/mnt/f61612c324ff3c924d3f7a82fb00a0f8d8f73c248c41897061949e9f5ab7e3b1 rw,relatime - aufs none rw,si=9b4a76442810c39c -60 15 0:3403 / /var/lib/docker/aufs/mnt/0f1ee55c6c4e25027b80de8e64b8b6fb542b3b41aa0caab9261da75752e22bfd rw,relatime - aufs none rw,si=9b4a76442810e39c -61 15 0:3404 / /var/lib/docker/aufs/mnt/956f6cc4af5785cb3ee6963dcbca668219437d9b28f513290b1453ac64a34f97 rw,relatime - aufs none rw,si=9b4a7644303ec39c -62 15 0:3405 / /var/lib/docker/aufs/mnt/1099769158c4b4773e2569e38024e8717e400f87a002c41d8cf47cb81b051ba6 rw,relatime - aufs none rw,si=9b4a7644303ee39c -63 15 0:3406 / /var/lib/docker/aufs/mnt/11890ceb98d4442595b676085cd7b21550ab85c5df841e0fba997ff54e3d522d rw,relatime - aufs none rw,si=9b4a7644303ed39c -64 15 0:3407 / /var/lib/docker/aufs/mnt/acdb90dc378e8ed2420b43a6d291f1c789a081cd1904018780cc038fcd7aae53 rw,relatime - aufs none rw,si=9b4a76434be2139c -65 15 0:3408 / /var/lib/docker/aufs/mnt/120e716f19d4714fbe63cc1ed246204f2c1106eefebc6537ba2587d7e7711959 rw,relatime - aufs none rw,si=9b4a76434be2339c -66 15 0:3409 / /var/lib/docker/aufs/mnt/b197b7fffb61d89e0ba1c40de9a9fc0d912e778b3c1bd828cf981ff37c1963bc rw,relatime - aufs none rw,si=9b4a76434be2039c -70 15 0:3412 / /var/lib/docker/aufs/mnt/1434b69d2e1bb18a9f0b96b9cdac30132b2688f5d1379f68a39a5e120c2f93eb rw,relatime - aufs none rw,si=9b4a76434be2639c -71 15 0:3413 / /var/lib/docker/aufs/mnt/16006e83caf33ab5eb0cd6afc92ea2ee8edeff897496b0bb3ec3a75b767374b3 rw,relatime - aufs none rw,si=9b4a7644d790439c -72 15 0:3414 / /var/lib/docker/aufs/mnt/55bfa5f44e94d27f91f79ba901b118b15098449165c87abf1b53ffff147ff164 rw,relatime - aufs none rw,si=9b4a7644d790239c -73 15 0:3415 / /var/lib/docker/aufs/mnt/1912b97a07ab21ccd98a2a27bc779bf3cf364a3138afa3c3e6f7f169a3c3eab5 rw,relatime - aufs none rw,si=9b4a76441822739c -76 15 0:3418 / /var/lib/docker/aufs/mnt/1a7c3292e8879bd91ffd9282e954f643b1db5683093574c248ff14a9609f2f56 rw,relatime - aufs none rw,si=9b4a76438cb7239c -77 15 0:3419 / /var/lib/docker/aufs/mnt/bb1faaf0d076ddba82c2318305a85f490dafa4e8a8640a8db8ed657c439120cc rw,relatime - aufs none rw,si=9b4a76438cb7339c -78 15 0:3420 / /var/lib/docker/aufs/mnt/1ab869f21d2241a73ac840c7f988490313f909ac642eba71d092204fec66dd7c rw,relatime - aufs none rw,si=9b4a76438cb7639c -79 15 0:3421 / /var/lib/docker/aufs/mnt/fd7245b2cfe3890fa5f5b452260e4edf9e7fb7746532ed9d83f7a0d7dbaa610e rw,relatime - aufs none rw,si=9b4a7644bdc0139c -80 15 0:3422 / /var/lib/docker/aufs/mnt/1e5686c5301f26b9b3cd24e322c608913465cc6c5d0dcd7c5e498d1314747d61 rw,relatime - aufs none rw,si=9b4a7644bdc0639c -81 15 0:3423 / /var/lib/docker/aufs/mnt/52edf6ee6e40bfec1e9301a4d4a92ab83d144e2ae4ce5099e99df6138cb844bf rw,relatime - aufs none rw,si=9b4a7644bdc0239c -82 15 0:3424 / /var/lib/docker/aufs/mnt/1ea10fb7085d28cda4904657dff0454e52598d28e1d77e4f2965bbc3666e808f rw,relatime - aufs none rw,si=9b4a76438cb7139c -83 15 0:3425 / /var/lib/docker/aufs/mnt/9c03e98c3593946dbd4087f8d83f9ca262f4a2efdc952ce60690838b9ba6c526 rw,relatime - aufs none rw,si=9b4a76443020639c -84 15 0:3426 / /var/lib/docker/aufs/mnt/220a2344d67437602c6d2cee9a98c46be13f82c2a8063919dd2fad52bf2fb7dd rw,relatime - aufs none rw,si=9b4a76434bff339c -94 15 0:3427 / /var/lib/docker/aufs/mnt/3b32876c5b200312c50baa476ff342248e88c8ea96e6a1032cd53a88738a1cf2 rw,relatime - aufs none rw,si=9b4a76434bff139c -95 15 0:3428 / /var/lib/docker/aufs/mnt/23ee2b8b0d4ae8db6f6d1e168e2c6f79f8a18f953b09f65e0d22cc1e67a3a6fa rw,relatime - aufs none rw,si=9b4a7646c305c39c -96 15 0:3429 / /var/lib/docker/aufs/mnt/e86e6daa70b61b57945fa178222615f3c3d6bcef12c9f28e9f8623d44dc2d429 rw,relatime - aufs none rw,si=9b4a7646c305f39c -97 15 0:3430 / /var/lib/docker/aufs/mnt/2413d07623e80860bb2e9e306fbdee699afd07525785c025c591231e864aa162 rw,relatime - aufs none rw,si=9b4a76434bff039c -98 15 0:3431 / /var/lib/docker/aufs/mnt/adfd622eb22340fc80b429e5564b125668e260bf9068096c46dd59f1386a4b7d rw,relatime - aufs none rw,si=9b4a7646a7a1039c -102 15 0:3435 / /var/lib/docker/aufs/mnt/27cd92e7a91d02e2d6b44d16679a00fb6d169b19b88822891084e7fd1a84882d rw,relatime - aufs none rw,si=9b4a7646f25ec39c -103 15 0:3436 / /var/lib/docker/aufs/mnt/27dfdaf94cfbf45055c748293c37dd68d9140240bff4c646cb09216015914a88 rw,relatime - aufs none rw,si=9b4a7646732f939c -104 15 0:3437 / /var/lib/docker/aufs/mnt/5ed7524aff68dfbf0fc601cbaeac01bab14391850a973dabf3653282a627920f rw,relatime - aufs none rw,si=9b4a7646732f839c -105 15 0:3438 / /var/lib/docker/aufs/mnt/2a0d4767e536beb5785b60e071e3ac8e5e812613ab143a9627bee77d0c9ab062 rw,relatime - aufs none rw,si=9b4a7646732fe39c -106 15 0:3439 / /var/lib/docker/aufs/mnt/dea3fc045d9f4ae51ba952450b948a822cf85c39411489ca5224f6d9a8d02bad rw,relatime - aufs none rw,si=9b4a764012ad839c -107 15 0:3440 / /var/lib/docker/aufs/mnt/2d140a787160798da60cb67c21b1210054ad4dafecdcf832f015995b9aa99cfd rw,relatime - aufs none rw,si=9b4a764012add39c -108 15 0:3441 / /var/lib/docker/aufs/mnt/cb190b2a8e984475914430fbad2382e0d20b9b659f8ef83ae8d170cc672e519c rw,relatime - aufs none rw,si=9b4a76454d9c239c -109 15 0:3442 / /var/lib/docker/aufs/mnt/2f4a012d5a7ffd90256a6e9aa479054b3dddbc3c6a343f26dafbf3196890223b rw,relatime - aufs none rw,si=9b4a76454d9c439c -110 15 0:3443 / /var/lib/docker/aufs/mnt/63cc77904b80c4ffbf49cb974c5d8733dc52ad7640d3ae87554b325d7312d87f rw,relatime - aufs none rw,si=9b4a76454d9c339c -111 15 0:3444 / /var/lib/docker/aufs/mnt/30333e872c451482ea2d235ff2192e875bd234006b238ae2bdde3b91a86d7522 rw,relatime - aufs none rw,si=9b4a76422cebf39c -112 15 0:3445 / /var/lib/docker/aufs/mnt/6c54fc1125da3925cae65b5c9a98f3be55b0a2c2666082e5094a4ba71beb5bff rw,relatime - aufs none rw,si=9b4a7646dd5a439c -113 15 0:3446 / /var/lib/docker/aufs/mnt/3087d48cb01cda9d0a83a9ca301e6ea40e8593d18c4921be4794c91a420ab9a3 rw,relatime - aufs none rw,si=9b4a7646dd5a739c -114 15 0:3447 / /var/lib/docker/aufs/mnt/cc2607462a8f55b179a749b144c3fdbb50678e1a4f3065ea04e283e9b1f1d8e2 rw,relatime - aufs none rw,si=9b4a7646dd5a239c -117 15 0:3450 / /var/lib/docker/aufs/mnt/310c5e8392b29e8658a22e08d96d63936633b7e2c38e8d220047928b00a03d24 rw,relatime - aufs none rw,si=9b4a7647932d739c -118 15 0:3451 / /var/lib/docker/aufs/mnt/38a1f0029406ba9c3b6058f2f406d8a1d23c855046cf355c91d87d446fcc1460 rw,relatime - aufs none rw,si=9b4a76445abc939c -119 15 0:3452 / /var/lib/docker/aufs/mnt/42e109ab7914ae997a11ccd860fd18e4d488c50c044c3240423ce15774b8b62e rw,relatime - aufs none rw,si=9b4a76445abca39c -120 15 0:3453 / /var/lib/docker/aufs/mnt/365d832af0402d052b389c1e9c0d353b48487533d20cd4351df8e24ec4e4f9d8 rw,relatime - aufs none rw,si=9b4a7644066aa39c -121 15 0:3454 / /var/lib/docker/aufs/mnt/d3fa8a24d695b6cda9b64f96188f701963d28bef0473343f8b212df1a2cf1d2b rw,relatime - aufs none rw,si=9b4a7644066af39c -122 15 0:3455 / /var/lib/docker/aufs/mnt/37d4f491919abc49a15d0c7a7cc8383f087573525d7d288accd14f0b4af9eae0 rw,relatime - aufs none rw,si=9b4a7644066ad39c -123 15 0:3456 / /var/lib/docker/aufs/mnt/93902707fe12cbdd0068ce73f2baad4b3a299189b1b19cb5f8a2025e106ae3f5 rw,relatime - aufs none rw,si=9b4a76444445f39c -126 15 0:3459 / /var/lib/docker/aufs/mnt/3b49291670a625b9bbb329ffba99bf7fa7abff80cefef040f8b89e2b3aad4f9f rw,relatime - aufs none rw,si=9b4a7640798a339c -127 15 0:3460 / /var/lib/docker/aufs/mnt/8d9c7b943cc8f854f4d0d4ec19f7c16c13b0cc4f67a41472a072648610cecb59 rw,relatime - aufs none rw,si=9b4a76427383039c -128 15 0:3461 / /var/lib/docker/aufs/mnt/3b6c90036526c376307df71d49c9f5fce334c01b926faa6a78186842de74beac rw,relatime - aufs none rw,si=9b4a7644badd439c -130 15 0:3463 / /var/lib/docker/aufs/mnt/7b24158eeddfb5d31b7e932e406ea4899fd728344335ff8e0765e89ddeb351dd rw,relatime - aufs none rw,si=9b4a7644badd539c -131 15 0:3464 / /var/lib/docker/aufs/mnt/3ead6dd5773765c74850cf6c769f21fe65c29d622ffa712664f9f5b80364ce27 rw,relatime - aufs none rw,si=9b4a7642f469939c -132 15 0:3465 / /var/lib/docker/aufs/mnt/3f825573b29547744a37b65597a9d6d15a8350be4429b7038d126a4c9a8e178f rw,relatime - aufs none rw,si=9b4a7642f469c39c -133 15 0:3466 / /var/lib/docker/aufs/mnt/f67aaaeb3681e5dcb99a41f847087370bd1c206680cb8c7b6a9819fd6c97a331 rw,relatime - aufs none rw,si=9b4a7647cc25939c -134 15 0:3467 / /var/lib/docker/aufs/mnt/41afe6cfb3c1fc2280b869db07699da88552786e28793f0bc048a265c01bd942 rw,relatime - aufs none rw,si=9b4a7647cc25c39c -135 15 0:3468 / /var/lib/docker/aufs/mnt/b8092ea59da34a40b120e8718c3ae9fa8436996edc4fc50e4b99c72dfd81e1af rw,relatime - aufs none rw,si=9b4a76445abc439c -136 15 0:3469 / /var/lib/docker/aufs/mnt/42c69d2cc179e2684458bb8596a9da6dad182c08eae9b74d5f0e615b399f75a5 rw,relatime - aufs none rw,si=9b4a76455ddbe39c -137 15 0:3470 / /var/lib/docker/aufs/mnt/ea0871954acd2d62a211ac60e05969622044d4c74597870c4f818fbb0c56b09b rw,relatime - aufs none rw,si=9b4a76455ddbf39c -138 15 0:3471 / /var/lib/docker/aufs/mnt/4307906b275ab3fc971786b3841ae3217ac85b6756ddeb7ad4ba09cd044c2597 rw,relatime - aufs none rw,si=9b4a76455ddb839c -139 15 0:3472 / /var/lib/docker/aufs/mnt/4390b872928c53500a5035634f3421622ed6299dc1472b631fc45de9f56dc180 rw,relatime - aufs none rw,si=9b4a76402f2fd39c -140 15 0:3473 / /var/lib/docker/aufs/mnt/6bb41e78863b85e4aa7da89455314855c8c3bda64e52a583bab15dc1fa2e80c2 rw,relatime - aufs none rw,si=9b4a76402f2fa39c -141 15 0:3474 / /var/lib/docker/aufs/mnt/4444f583c2a79c66608f4673a32c9c812154f027045fbd558c2d69920c53f835 rw,relatime - aufs none rw,si=9b4a764479dbd39c -142 15 0:3475 / /var/lib/docker/aufs/mnt/6f11883af4a05ea362e0c54df89058da4859f977efd07b6f539e1f55c1d2a668 rw,relatime - aufs none rw,si=9b4a76402f30b39c -143 15 0:3476 / /var/lib/docker/aufs/mnt/453490dd32e7c2e9ef906f995d8fb3c2753923d1a5e0ba3fd3296e2e4dc238e7 rw,relatime - aufs none rw,si=9b4a76402f30c39c -144 15 0:3477 / /var/lib/docker/aufs/mnt/45e5945735ee102b5e891c91650c57ec4b52bb53017d68f02d50ea8a6e230610 rw,relatime - aufs none rw,si=9b4a76423260739c -147 15 0:3480 / /var/lib/docker/aufs/mnt/4727a64a5553a1125f315b96bed10d3073d6988225a292cce732617c925b56ab rw,relatime - aufs none rw,si=9b4a76443030339c -150 15 0:3483 / /var/lib/docker/aufs/mnt/4e348b5187b9a567059306afc72d42e0ec5c893b0d4abd547526d5f9b6fb4590 rw,relatime - aufs none rw,si=9b4a7644f5d8c39c -151 15 0:3484 / /var/lib/docker/aufs/mnt/4efc616bfbc3f906718b052da22e4335f8e9f91ee9b15866ed3a8029645189ef rw,relatime - aufs none rw,si=9b4a7644f5d8939c -152 15 0:3485 / /var/lib/docker/aufs/mnt/83e730ae9754d5adb853b64735472d98dfa17136b8812ac9cfcd1eba7f4e7d2d rw,relatime - aufs none rw,si=9b4a76469aa7139c -153 15 0:3486 / /var/lib/docker/aufs/mnt/4fc5ba8a5b333be2b7eefacccb626772eeec0ae8a6975112b56c9fb36c0d342f rw,relatime - aufs none rw,si=9b4a7640128dc39c -154 15 0:3487 / /var/lib/docker/aufs/mnt/50200d5edff5dfe8d1ef3c78b0bbd709793ac6e936aa16d74ff66f7ea577b6f9 rw,relatime - aufs none rw,si=9b4a7640128da39c -155 15 0:3488 / /var/lib/docker/aufs/mnt/51e5e51604361448f0b9777f38329f414bc5ba9cf238f26d465ff479bd574b61 rw,relatime - aufs none rw,si=9b4a76444f68939c -156 15 0:3489 / /var/lib/docker/aufs/mnt/52a142149aa98bba83df8766bbb1c629a97b9799944ead90dd206c4bdf0b8385 rw,relatime - aufs none rw,si=9b4a76444f68b39c -157 15 0:3490 / /var/lib/docker/aufs/mnt/52dd21a94a00f58a1ed489312fcfffb91578089c76c5650364476f1d5de031bc rw,relatime - aufs none rw,si=9b4a76444f68f39c -158 15 0:3491 / /var/lib/docker/aufs/mnt/ee562415ddaad353ed22c88d0ca768a0c74bfba6333b6e25c46849ee22d990da rw,relatime - aufs none rw,si=9b4a7640128d839c -159 15 0:3492 / /var/lib/docker/aufs/mnt/db47a9e87173f7554f550c8a01891de79cf12acdd32e01f95c1a527a08bdfb2c rw,relatime - aufs none rw,si=9b4a764405a1d39c -160 15 0:3493 / /var/lib/docker/aufs/mnt/55e827bf6d44d930ec0b827c98356eb8b68c3301e2d60d1429aa72e05b4c17df rw,relatime - aufs none rw,si=9b4a764405a1a39c -162 15 0:3495 / /var/lib/docker/aufs/mnt/578dc4e0a87fc37ec081ca098430499a59639c09f6f12a8f48de29828a091aa6 rw,relatime - aufs none rw,si=9b4a76406d7d439c -163 15 0:3496 / /var/lib/docker/aufs/mnt/728cc1cb04fa4bc6f7bf7a90980beda6d8fc0beb71630874c0747b994efb0798 rw,relatime - aufs none rw,si=9b4a76444f20e39c -164 15 0:3497 / /var/lib/docker/aufs/mnt/5850cc4bd9b55aea46c7ad598f1785117607974084ea643580f58ce3222e683a rw,relatime - aufs none rw,si=9b4a7644a824239c -165 15 0:3498 / /var/lib/docker/aufs/mnt/89443b3f766d5a37bc8b84e29da8b84e6a3ea8486d3cf154e2aae1816516e4a8 rw,relatime - aufs none rw,si=9b4a7644a824139c -166 15 0:3499 / /var/lib/docker/aufs/mnt/f5ae8fd5a41a337907d16515bc3162525154b59c32314c695ecd092c3b47943d rw,relatime - aufs none rw,si=9b4a7644a824439c -167 15 0:3500 / /var/lib/docker/aufs/mnt/5a430854f2a03a9e5f7cbc9f3fb46a8ebca526a5b3f435236d8295e5998798f5 rw,relatime - aufs none rw,si=9b4a7647fc82439c -168 15 0:3501 / /var/lib/docker/aufs/mnt/eda16901ae4cead35070c39845cbf1e10bd6b8cb0ffa7879ae2d8a186e460f91 rw,relatime - aufs none rw,si=9b4a76441e0df39c -169 15 0:3502 / /var/lib/docker/aufs/mnt/5a593721430c2a51b119ff86a7e06ea2b37e3b4131f8f1344d402b61b0c8d868 rw,relatime - aufs none rw,si=9b4a764248bad39c -170 15 0:3503 / /var/lib/docker/aufs/mnt/d662ad0a30fbfa902e0962108685b9330597e1ee2abb16dc9462eb5a67fdd23f rw,relatime - aufs none rw,si=9b4a764248bae39c -171 15 0:3504 / /var/lib/docker/aufs/mnt/5bc9de5c79812843fb36eee96bef1ddba812407861f572e33242f4ee10da2c15 rw,relatime - aufs none rw,si=9b4a764248ba839c -172 15 0:3505 / /var/lib/docker/aufs/mnt/5e763de8e9b0f7d58d2e12a341e029ab4efb3b99788b175090d8209e971156c1 rw,relatime - aufs none rw,si=9b4a764248baa39c -173 15 0:3506 / /var/lib/docker/aufs/mnt/b4431dc2739936f1df6387e337f5a0c99cf051900c896bd7fd46a870ce61c873 rw,relatime - aufs none rw,si=9b4a76401263539c -174 15 0:3507 / /var/lib/docker/aufs/mnt/5f37830e5a02561ab8c67ea3113137ba69f67a60e41c05cb0e7a0edaa1925b24 rw,relatime - aufs none rw,si=9b4a76401263639c -184 15 0:3508 / /var/lib/docker/aufs/mnt/62ea10b957e6533538a4633a1e1d678502f50ddcdd354b2ca275c54dd7a7793a rw,relatime - aufs none rw,si=9b4a76401263039c -187 15 0:3509 / /var/lib/docker/aufs/mnt/d56ee9d44195fe390e042fda75ec15af5132adb6d5c69468fa8792f4e54a6953 rw,relatime - aufs none rw,si=9b4a76401263239c -188 15 0:3510 / /var/lib/docker/aufs/mnt/6a300930673174549c2b62f36c933f0332a20735978c007c805a301f897146c5 rw,relatime - aufs none rw,si=9b4a76455d4c539c -189 15 0:3511 / /var/lib/docker/aufs/mnt/64496c45c84d348c24d410015456d101601c30cab4d1998c395591caf7e57a70 rw,relatime - aufs none rw,si=9b4a76455d4c639c -190 15 0:3512 / /var/lib/docker/aufs/mnt/65a6a645883fe97a7422cd5e71ebe0bc17c8e6302a5361edf52e89747387e908 rw,relatime - aufs none rw,si=9b4a76455d4c039c -191 15 0:3513 / /var/lib/docker/aufs/mnt/672be40695f7b6e13b0a3ed9fc996c73727dede3481f58155950fcfad57ed616 rw,relatime - aufs none rw,si=9b4a76455d4c239c -192 15 0:3514 / /var/lib/docker/aufs/mnt/d42438acb2bfb2169e1c0d8e917fc824f7c85d336dadb0b0af36dfe0f001b3ba rw,relatime - aufs none rw,si=9b4a7642bfded39c -193 15 0:3515 / /var/lib/docker/aufs/mnt/b48a54abf26d01cb2ddd908b1ed6034d17397c1341bf0eb2b251a3e5b79be854 rw,relatime - aufs none rw,si=9b4a7642bfdee39c -194 15 0:3516 / /var/lib/docker/aufs/mnt/76f27134491f052bfb87f59092126e53ef875d6851990e59195a9da16a9412f8 rw,relatime - aufs none rw,si=9b4a7642bfde839c -195 15 0:3517 / /var/lib/docker/aufs/mnt/6bd626a5462b4f8a8e1cc7d10351326dca97a59b2758e5ea549a4f6350ce8a90 rw,relatime - aufs none rw,si=9b4a7642bfdea39c -196 15 0:3518 / /var/lib/docker/aufs/mnt/f1fe3549dbd6f5ca615e9139d9b53f0c83a3b825565df37628eacc13e70cbd6d rw,relatime - aufs none rw,si=9b4a7642bfdf539c -197 15 0:3519 / /var/lib/docker/aufs/mnt/6d0458c8426a9e93d58d0625737e6122e725c9408488ed9e3e649a9984e15c34 rw,relatime - aufs none rw,si=9b4a7642bfdf639c -198 15 0:3520 / /var/lib/docker/aufs/mnt/6e4c97db83aa82145c9cf2bafc20d500c0b5389643b689e3ae84188c270a48c5 rw,relatime - aufs none rw,si=9b4a7642bfdf039c -199 15 0:3521 / /var/lib/docker/aufs/mnt/eb94d6498f2c5969eaa9fa11ac2934f1ab90ef88e2d002258dca08e5ba74ea27 rw,relatime - aufs none rw,si=9b4a7642bfdf239c -200 15 0:3522 / /var/lib/docker/aufs/mnt/fe3f88f0c511608a2eec5f13a98703aa16e55dbf930309723d8a37101f539fe1 rw,relatime - aufs none rw,si=9b4a7642bfc3539c -201 15 0:3523 / /var/lib/docker/aufs/mnt/6f40c229fb9cad85fabf4b64a2640a5403ec03fe5ac1a57d0609fb8b606b9c83 rw,relatime - aufs none rw,si=9b4a7642bfc3639c -202 15 0:3524 / /var/lib/docker/aufs/mnt/7513e9131f7a8acf58ff15248237feb767c78732ca46e159f4d791e6ef031dbc rw,relatime - aufs none rw,si=9b4a7642bfc3039c -203 15 0:3525 / /var/lib/docker/aufs/mnt/79f48b00aa713cdf809c6bb7c7cb911b66e9a8076c81d6c9d2504139984ea2da rw,relatime - aufs none rw,si=9b4a7642bfc3239c -204 15 0:3526 / /var/lib/docker/aufs/mnt/c3680418350d11358f0a96c676bc5aa74fa00a7c89e629ef5909d3557b060300 rw,relatime - aufs none rw,si=9b4a7642f47cd39c -205 15 0:3527 / /var/lib/docker/aufs/mnt/7a1744dd350d7fcc0cccb6f1757ca4cbe5453f203a5888b0f1014d96ad5a5ef9 rw,relatime - aufs none rw,si=9b4a7642f47ce39c -206 15 0:3528 / /var/lib/docker/aufs/mnt/7fa99662db046be9f03c33c35251afda9ccdc0085636bbba1d90592cec3ff68d rw,relatime - aufs none rw,si=9b4a7642f47c839c -207 15 0:3529 / /var/lib/docker/aufs/mnt/f815021ef20da9c9b056bd1d52d8aaf6e2c0c19f11122fc793eb2b04eb995e35 rw,relatime - aufs none rw,si=9b4a7642f47ca39c -208 15 0:3530 / /var/lib/docker/aufs/mnt/801086ae3110192d601dfcebdba2db92e86ce6b6a9dba6678ea04488e4513669 rw,relatime - aufs none rw,si=9b4a7642dc6dd39c -209 15 0:3531 / /var/lib/docker/aufs/mnt/822ba7db69f21daddda87c01cfbfbf73013fc03a879daf96d16cdde6f9b1fbd6 rw,relatime - aufs none rw,si=9b4a7642dc6de39c -210 15 0:3532 / /var/lib/docker/aufs/mnt/834227c1a950fef8cae3827489129d0dd220541e60c6b731caaa765bf2e6a199 rw,relatime - aufs none rw,si=9b4a7642dc6d839c -211 15 0:3533 / /var/lib/docker/aufs/mnt/83dccbc385299bd1c7cf19326e791b33a544eea7b4cdfb6db70ea94eed4389fb rw,relatime - aufs none rw,si=9b4a7642dc6da39c -212 15 0:3534 / /var/lib/docker/aufs/mnt/f1b8e6f0e7c8928b5dcdab944db89306ebcae3e0b32f9ff40d2daa8329f21600 rw,relatime - aufs none rw,si=9b4a7645a126039c -213 15 0:3535 / /var/lib/docker/aufs/mnt/970efb262c7a020c2404cbcc5b3259efba0d110a786079faeef05bc2952abf3a rw,relatime - aufs none rw,si=9b4a7644c8ed139c -214 15 0:3536 / /var/lib/docker/aufs/mnt/84b6d73af7450f3117a77e15a5ca1255871fea6182cd8e8a7be6bc744be18c2c rw,relatime - aufs none rw,si=9b4a76406559139c -215 15 0:3537 / /var/lib/docker/aufs/mnt/88be2716e026bc681b5e63fe7942068773efbd0b6e901ca7ba441412006a96b6 rw,relatime - aufs none rw,si=9b4a76406559339c -216 15 0:3538 / /var/lib/docker/aufs/mnt/c81939aa166ce50cd8bca5cfbbcc420a78e0318dd5cd7c755209b9166a00a752 rw,relatime - aufs none rw,si=9b4a76406559239c -217 15 0:3539 / /var/lib/docker/aufs/mnt/e0f241645d64b7dc5ff6a8414087cca226be08fb54ce987d1d1f6350c57083aa rw,relatime - aufs none rw,si=9b4a7647cfc0f39c -218 15 0:3540 / /var/lib/docker/aufs/mnt/e10e2bf75234ed51d8a6a4bb39e465404fecbe318e54400d3879cdb2b0679c78 rw,relatime - aufs none rw,si=9b4a7647cfc0939c -219 15 0:3541 / /var/lib/docker/aufs/mnt/8f71d74c8cfc3228b82564aa9f09b2e576cff0083ddfb6aa5cb350346063f080 rw,relatime - aufs none rw,si=9b4a7647cfc0a39c -220 15 0:3542 / /var/lib/docker/aufs/mnt/9159f1eba2aef7f5205cc18d015cda7f5933cd29bba3b1b8aed5ccb5824c69ee rw,relatime - aufs none rw,si=9b4a76468cedd39c -221 15 0:3543 / /var/lib/docker/aufs/mnt/932cad71e652e048e500d9fbb5b8ea4fc9a269d42a3134ce527ceef42a2be56b rw,relatime - aufs none rw,si=9b4a76468cede39c -222 15 0:3544 / /var/lib/docker/aufs/mnt/bf1e1b5f529e8943cc0144ee86dbaaa37885c1ddffcef29537e0078ee7dd316a rw,relatime - aufs none rw,si=9b4a76468ced839c -223 15 0:3545 / /var/lib/docker/aufs/mnt/949d93ecf3322e09f858ce81d5f4b434068ec44ff84c375de03104f7b45ee955 rw,relatime - aufs none rw,si=9b4a76468ceda39c -224 15 0:3546 / /var/lib/docker/aufs/mnt/d65c6087f92dc2a3841b5251d2fe9ca07d4c6e5b021597692479740816e4e2a1 rw,relatime - aufs none rw,si=9b4a7645a126239c -225 15 0:3547 / /var/lib/docker/aufs/mnt/98a0153119d0651c193d053d254f6e16a68345a141baa80c87ae487e9d33f290 rw,relatime - aufs none rw,si=9b4a7640787cf39c -226 15 0:3548 / /var/lib/docker/aufs/mnt/99daf7fe5847c017392f6e59aa9706b3dfdd9e6d1ba11dae0f7fffde0a60b5e5 rw,relatime - aufs none rw,si=9b4a7640787c839c -227 15 0:3549 / /var/lib/docker/aufs/mnt/9ad1f2fe8a5599d4e10c5a6effa7f03d932d4e92ee13149031a372087a359079 rw,relatime - aufs none rw,si=9b4a7640787ca39c -228 15 0:3550 / /var/lib/docker/aufs/mnt/c26d64494da782ddac26f8370d86ac93e7c1666d88a7b99110fc86b35ea6a85d rw,relatime - aufs none rw,si=9b4a7642fc6b539c -229 15 0:3551 / /var/lib/docker/aufs/mnt/a49e4a8275133c230ec640997f35f172312eb0ea5bd2bbe10abf34aae98f30eb rw,relatime - aufs none rw,si=9b4a7642fc6b639c -230 15 0:3552 / /var/lib/docker/aufs/mnt/b5e2740c867ed843025f49d84e8d769de9e8e6039b3c8cb0735b5bf358994bc7 rw,relatime - aufs none rw,si=9b4a7642fc6b039c -231 15 0:3553 / /var/lib/docker/aufs/mnt/a826fdcf3a7039b30570054579b65763db605a314275d7aef31b872c13311b4b rw,relatime - aufs none rw,si=9b4a7642fc6b239c -232 15 0:3554 / /var/lib/docker/aufs/mnt/addf3025babf5e43b5a3f4a0da7ad863dda3c01fb8365c58fd8d28bb61dc11bc rw,relatime - aufs none rw,si=9b4a76407871d39c -233 15 0:3555 / /var/lib/docker/aufs/mnt/c5b6c6813ab3e5ebdc6d22cb2a3d3106a62095f2c298be52b07a3b0fa20ff690 rw,relatime - aufs none rw,si=9b4a76407871e39c -234 15 0:3556 / /var/lib/docker/aufs/mnt/af0609eaaf64e2392060cb46f5a9f3d681a219bb4c651d4f015bf573fbe6c4cf rw,relatime - aufs none rw,si=9b4a76407871839c -235 15 0:3557 / /var/lib/docker/aufs/mnt/e7f20e3c37ecad39cd90a97cd3549466d0d106ce4f0a930b8495442634fa4a1f rw,relatime - aufs none rw,si=9b4a76407871a39c -237 15 0:3559 / /var/lib/docker/aufs/mnt/b57a53d440ffd0c1295804fa68cdde35d2fed5409484627e71b9c37e4249fd5c rw,relatime - aufs none rw,si=9b4a76444445a39c -238 15 0:3560 / /var/lib/docker/aufs/mnt/b5e7d7b8f35e47efbba3d80c5d722f5e7bd43e54c824e54b4a4b351714d36d42 rw,relatime - aufs none rw,si=9b4a7647932d439c -239 15 0:3561 / /var/lib/docker/aufs/mnt/f1b136def157e9465640658f277f3347de593c6ae76412a2e79f7002f091cae2 rw,relatime - aufs none rw,si=9b4a76445abcd39c -240 15 0:3562 / /var/lib/docker/aufs/mnt/b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc rw,relatime - aufs none rw,si=9b4a7644403b339c -241 15 0:3563 / /var/lib/docker/aufs/mnt/b89b140cdbc95063761864e0a23346207fa27ee4c5c63a1ae85c9069a9d9cf1d rw,relatime - aufs none rw,si=9b4a7644aa19739c -242 15 0:3564 / /var/lib/docker/aufs/mnt/bc6a69ed51c07f5228f6b4f161c892e6a949c0e7e86a9c3432049d4c0e5cd298 rw,relatime - aufs none rw,si=9b4a7644aa19139c -243 15 0:3565 / /var/lib/docker/aufs/mnt/be4e2ba3f136933e239f7cf3d136f484fb9004f1fbdfee24a62a2c7b0ab30670 rw,relatime - aufs none rw,si=9b4a7644aa19339c -244 15 0:3566 / /var/lib/docker/aufs/mnt/e04ca1a4a5171e30d20f0c92f90a50b8b6f8600af5459c4b4fb25e42e864dfe1 rw,relatime - aufs none rw,si=9b4a7647932d139c -245 15 0:3567 / /var/lib/docker/aufs/mnt/be61576b31db893129aaffcd3dcb5ce35e49c4b71b30c392a78609a45c7323d8 rw,relatime - aufs none rw,si=9b4a7642d85f739c -246 15 0:3568 / /var/lib/docker/aufs/mnt/dda42c191e56becf672327658ab84fcb563322db3764b91c2fefe4aaef04c624 rw,relatime - aufs none rw,si=9b4a7642d85f139c -247 15 0:3569 / /var/lib/docker/aufs/mnt/c0a7995053330f3d88969247a2e72b07e2dd692133f5668a4a35ea3905561072 rw,relatime - aufs none rw,si=9b4a7642d85f339c -249 15 0:3571 / /var/lib/docker/aufs/mnt/c3594b2e5f08c59ff5ed338a1ba1eceeeb1f7fc5d180068338110c00b1eb8502 rw,relatime - aufs none rw,si=9b4a7642738c739c -250 15 0:3572 / /var/lib/docker/aufs/mnt/c58dce03a0ab0a7588393880379dc3bce9f96ec08ed3f99cf1555260ff0031e8 rw,relatime - aufs none rw,si=9b4a7642738c139c -251 15 0:3573 / /var/lib/docker/aufs/mnt/c73e9f1d109c9d14cb36e1c7489df85649be3911116d76c2fd3648ec8fd94e23 rw,relatime - aufs none rw,si=9b4a7642738c339c -252 15 0:3574 / /var/lib/docker/aufs/mnt/c9eef28c344877cd68aa09e543c0710ab2b305a0ff96dbb859bfa7808c3e8d01 rw,relatime - aufs none rw,si=9b4a7642d85f439c -253 15 0:3575 / /var/lib/docker/aufs/mnt/feb67148f548d70cb7484f2aaad2a86051cd6867a561741a2f13b552457d666e rw,relatime - aufs none rw,si=9b4a76468c55739c -254 15 0:3576 / /var/lib/docker/aufs/mnt/cdf1f96c36d35a96041a896bf398ec0f7dc3b0fb0643612a0f4b6ff96e04e1bb rw,relatime - aufs none rw,si=9b4a76468c55139c -255 15 0:3577 / /var/lib/docker/aufs/mnt/ec6e505872353268451ac4bc034c1df00f3bae4a3ea2261c6e48f7bd5417c1b3 rw,relatime - aufs none rw,si=9b4a76468c55339c -256 15 0:3578 / /var/lib/docker/aufs/mnt/d6dc8aca64efd90e0bc10274001882d0efb310d42ccbf5712b99b169053b8b1a rw,relatime - aufs none rw,si=9b4a7642738c439c -257 15 0:3579 / /var/lib/docker/aufs/mnt/d712594e2ff6eaeb895bfd150d694bd1305fb927e7a186b2dab7df2ea95f8f81 rw,relatime - aufs none rw,si=9b4a76401268f39c -259 15 0:3581 / /var/lib/docker/aufs/mnt/dbfa1174cd78cde2d7410eae442af0b416c4a0e6f87ed4ff1e9f169a0029abc0 rw,relatime - aufs none rw,si=9b4a76401268b39c -260 15 0:3582 / /var/lib/docker/aufs/mnt/e883f5a82316d7856fbe93ee8c0af5a920b7079619dd95c4ffd88bbd309d28dd rw,relatime - aufs none rw,si=9b4a76468c55439c -261 15 0:3583 / /var/lib/docker/aufs/mnt/fdec3eff581c4fc2b09f87befa2fa021f3f2d373bea636a87f1fb5b367d6347a rw,relatime - aufs none rw,si=9b4a7644aa1af39c -262 15 0:3584 / /var/lib/docker/aufs/mnt/ef764e26712184653067ecf7afea18a80854c41331ca0f0ef03e1bacf90a6ffc rw,relatime - aufs none rw,si=9b4a7644aa1a939c -263 15 0:3585 / /var/lib/docker/aufs/mnt/f3176b40c41fce8ce6942936359a2001a6f1b5c1bb40ee224186db0789ec2f76 rw,relatime - aufs none rw,si=9b4a7644aa1ab39c -264 15 0:3586 / /var/lib/docker/aufs/mnt/f5daf06785d3565c6dd18ea7d953d9a8b9606107781e63270fe0514508736e6a rw,relatime - aufs none rw,si=9b4a76401268c39c -58 15 0:3587 / /var/lib/docker/aufs/mnt/cde8c40f6524b7361af4f5ad05bb857dc9ee247c20852ba666195c0739e3a2b8-init rw,relatime - aufs none rw,si=9b4a76444445839c -67 15 0:3588 / /var/lib/docker/aufs/mnt/cde8c40f6524b7361af4f5ad05bb857dc9ee247c20852ba666195c0739e3a2b8 rw,relatime - aufs none rw,si=9b4a7644badd339c -265 15 0:3610 / /var/lib/docker/aufs/mnt/e812472cd2c8c4748d1ef71fac4e77e50d661b9349abe66ce3e23511ed44f414 rw,relatime - aufs none rw,si=9b4a76427937d39c -270 15 0:3615 / /var/lib/docker/aufs/mnt/997636e7c5c9d0d1376a217e295c14c205350b62bc12052804fb5f90abe6f183 rw,relatime - aufs none rw,si=9b4a76406540739c -273 15 0:3618 / /var/lib/docker/aufs/mnt/d5794d080417b6e52e69227c3873e0e4c1ff0d5a845ebe3860ec2f89a47a2a1e rw,relatime - aufs none rw,si=9b4a76454814039c -278 15 0:3623 / /var/lib/docker/aufs/mnt/586bdd48baced671bb19bc4d294ec325f26c55545ae267db426424f157d59c48 rw,relatime - aufs none rw,si=9b4a7644b439f39c -281 15 0:3626 / /var/lib/docker/aufs/mnt/69739d022f89f8586908bbd5edbbdd95ea5256356f177f9ffcc6ef9c0ea752d2 rw,relatime - aufs none rw,si=9b4a7644a0f1b39c -286 15 0:3631 / /var/lib/docker/aufs/mnt/ff28c27d5f894363993622de26d5dd352dba072f219e4691d6498c19bbbc15a9 rw,relatime - aufs none rw,si=9b4a7642265b339c -289 15 0:3634 / /var/lib/docker/aufs/mnt/aa128fe0e64fdede333aa48fd9de39530c91a9244a0f0649a3c411c61e372daa rw,relatime - aufs none rw,si=9b4a764012ada39c -99 15 8:33 / /media/REMOVE\040ME rw,nosuid,nodev,relatime - fuseblk /dev/sdc1 rw,user_id=0,group_id=0,allow_other,blksize=4096` -) - -func TestParseFedoraMountinfo(t *testing.T) { - r := bytes.NewBuffer([]byte(fedoraMountinfo)) - _, err := parseInfoFile(r) - if err != nil { - t.Fatal(err) - } -} - -func TestParseUbuntuMountinfo(t *testing.T) { - r := bytes.NewBuffer([]byte(ubuntuMountInfo)) - _, err := parseInfoFile(r) - if err != nil { - t.Fatal(err) - } -} - -func TestParseGentooMountinfo(t *testing.T) { - r := bytes.NewBuffer([]byte(gentooMountinfo)) - _, err := parseInfoFile(r) - if err != nil { - t.Fatal(err) - } -} - -func TestParseFedoraMountinfoFields(t *testing.T) { - r := bytes.NewBuffer([]byte(fedoraMountinfo)) - infos, err := parseInfoFile(r) - if err != nil { - t.Fatal(err) - } - expectedLength := 58 - if len(infos) != expectedLength { - t.Fatalf("Expected %d entries, got %d", expectedLength, len(infos)) - } - mi := MountInfo{ - Id: 15, - Parent: 35, - Major: 0, - Minor: 3, - Root: "/", - Mountpoint: "/proc", - Opts: "rw,nosuid,nodev,noexec,relatime", - Optional: "shared:5", - Fstype: "proc", - Source: "proc", - VfsOpts: "rw", - } - - if *infos[0] != mi { - t.Fatalf("expected %#v, got %#v", mi, infos[0]) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go deleted file mode 100644 index 352336b9a34..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !linux,!freebsd freebsd,!cgo - -package mount - -import ( - "fmt" - "runtime" -) - -func parseMountTable() ([]*MountInfo, error) { - return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go deleted file mode 100644 index cd9b86cefac..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build linux - -package mount - -func MakeShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "shared") -} - -func MakeRShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "rshared") -} - -func MakePrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "private") -} - -func MakeRPrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "rprivate") -} - -func MakeSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "slave") -} - -func MakeRSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "rslave") -} - -func MakeUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "unbindable") -} - -func MakeRUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "runbindable") -} - -func ensureMountedAs(mountPoint, options string) error { - mounted, err := Mounted(mountPoint) - if err != nil { - return err - } - - if !mounted { - if err := Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil { - return err - } - } - mounted, err = Mounted(mountPoint) - if err != nil { - return err - } - - return ForceMount("", mountPoint, "none", options) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux_test.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux_test.go deleted file mode 100644 index da9aa15015a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux_test.go +++ /dev/null @@ -1,331 +0,0 @@ -// +build linux - -package mount - -import ( - "os" - "path" - "syscall" - "testing" -) - -// nothing is propagated in or out -func TestSubtreePrivate(t *testing.T) { - tmp := path.Join(os.TempDir(), "mount-tests") - if err := os.MkdirAll(tmp, 0777); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmp) - - var ( - sourceDir = path.Join(tmp, "source") - targetDir = path.Join(tmp, "target") - outside1Dir = path.Join(tmp, "outside1") - outside2Dir = path.Join(tmp, "outside2") - - outside1Path = path.Join(outside1Dir, "file.txt") - outside2Path = path.Join(outside2Dir, "file.txt") - outside1CheckPath = path.Join(targetDir, "a", "file.txt") - outside2CheckPath = path.Join(sourceDir, "b", "file.txt") - ) - if err := os.MkdirAll(path.Join(sourceDir, "a"), 0777); err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(path.Join(sourceDir, "b"), 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(targetDir, 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(outside1Dir, 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(outside2Dir, 0777); err != nil { - t.Fatal(err) - } - - if err := createFile(outside1Path); err != nil { - t.Fatal(err) - } - if err := createFile(outside2Path); err != nil { - t.Fatal(err) - } - - // mount the shared directory to a target - if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - // next, make the target private - if err := MakePrivate(targetDir); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - // mount in an outside path to a mounted path inside the _source_ - if err := Mount(outside1Dir, path.Join(sourceDir, "a"), "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(path.Join(sourceDir, "a")); err != nil { - t.Fatal(err) - } - }() - - // check that this file _does_not_ show in the _target_ - if _, err := os.Stat(outside1CheckPath); err != nil && !os.IsNotExist(err) { - t.Fatal(err) - } else if err == nil { - t.Fatalf("%q should not be visible, but is", outside1CheckPath) - } - - // next mount outside2Dir into the _target_ - if err := Mount(outside2Dir, path.Join(targetDir, "b"), "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(path.Join(targetDir, "b")); err != nil { - t.Fatal(err) - } - }() - - // check that this file _does_not_ show in the _source_ - if _, err := os.Stat(outside2CheckPath); err != nil && !os.IsNotExist(err) { - t.Fatal(err) - } else if err == nil { - t.Fatalf("%q should not be visible, but is", outside2CheckPath) - } -} - -// Testing that when a target is a shared mount, -// then child mounts propogate to the source -func TestSubtreeShared(t *testing.T) { - tmp := path.Join(os.TempDir(), "mount-tests") - if err := os.MkdirAll(tmp, 0777); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmp) - - var ( - sourceDir = path.Join(tmp, "source") - targetDir = path.Join(tmp, "target") - outsideDir = path.Join(tmp, "outside") - - outsidePath = path.Join(outsideDir, "file.txt") - sourceCheckPath = path.Join(sourceDir, "a", "file.txt") - ) - - if err := os.MkdirAll(path.Join(sourceDir, "a"), 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(targetDir, 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(outsideDir, 0777); err != nil { - t.Fatal(err) - } - - if err := createFile(outsidePath); err != nil { - t.Fatal(err) - } - - // mount the source as shared - if err := MakeShared(sourceDir); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(sourceDir); err != nil { - t.Fatal(err) - } - }() - - // mount the shared directory to a target - if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - // mount in an outside path to a mounted path inside the target - if err := Mount(outsideDir, path.Join(targetDir, "a"), "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(path.Join(targetDir, "a")); err != nil { - t.Fatal(err) - } - }() - - // NOW, check that the file from the outside directory is avaible in the source directory - if _, err := os.Stat(sourceCheckPath); err != nil { - t.Fatal(err) - } -} - -// testing that mounts to a shared source show up in the slave target, -// and that mounts into a slave target do _not_ show up in the shared source -func TestSubtreeSharedSlave(t *testing.T) { - tmp := path.Join(os.TempDir(), "mount-tests") - if err := os.MkdirAll(tmp, 0777); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmp) - - var ( - sourceDir = path.Join(tmp, "source") - targetDir = path.Join(tmp, "target") - outside1Dir = path.Join(tmp, "outside1") - outside2Dir = path.Join(tmp, "outside2") - - outside1Path = path.Join(outside1Dir, "file.txt") - outside2Path = path.Join(outside2Dir, "file.txt") - outside1CheckPath = path.Join(targetDir, "a", "file.txt") - outside2CheckPath = path.Join(sourceDir, "b", "file.txt") - ) - if err := os.MkdirAll(path.Join(sourceDir, "a"), 0777); err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(path.Join(sourceDir, "b"), 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(targetDir, 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(outside1Dir, 0777); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(outside2Dir, 0777); err != nil { - t.Fatal(err) - } - - if err := createFile(outside1Path); err != nil { - t.Fatal(err) - } - if err := createFile(outside2Path); err != nil { - t.Fatal(err) - } - - // mount the source as shared - if err := MakeShared(sourceDir); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(sourceDir); err != nil { - t.Fatal(err) - } - }() - - // mount the shared directory to a target - if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - // next, make the target slave - if err := MakeSlave(targetDir); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() - - // mount in an outside path to a mounted path inside the _source_ - if err := Mount(outside1Dir, path.Join(sourceDir, "a"), "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(path.Join(sourceDir, "a")); err != nil { - t.Fatal(err) - } - }() - - // check that this file _does_ show in the _target_ - if _, err := os.Stat(outside1CheckPath); err != nil { - t.Fatal(err) - } - - // next mount outside2Dir into the _target_ - if err := Mount(outside2Dir, path.Join(targetDir, "b"), "none", "bind,rw"); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(path.Join(targetDir, "b")); err != nil { - t.Fatal(err) - } - }() - - // check that this file _does_not_ show in the _source_ - if _, err := os.Stat(outside2CheckPath); err != nil && !os.IsNotExist(err) { - t.Fatal(err) - } else if err == nil { - t.Fatalf("%q should not be visible, but is", outside2CheckPath) - } -} - -func TestSubtreeUnbindable(t *testing.T) { - tmp := path.Join(os.TempDir(), "mount-tests") - if err := os.MkdirAll(tmp, 0777); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmp) - - var ( - sourceDir = path.Join(tmp, "source") - targetDir = path.Join(tmp, "target") - ) - if err := os.MkdirAll(sourceDir, 0777); err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(targetDir, 0777); err != nil { - t.Fatal(err) - } - - // next, make the source unbindable - if err := MakeUnbindable(sourceDir); err != nil { - t.Fatal(err) - } - defer func() { - if err := Unmount(sourceDir); err != nil { - t.Fatal(err) - } - }() - - // then attempt to mount it to target. It should fail - if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil && err != syscall.EINVAL { - t.Fatal(err) - } else if err == nil { - t.Fatalf("%q should not have been bindable", sourceDir) - } - defer func() { - if err := Unmount(targetDir); err != nil { - t.Fatal(err) - } - }() -} - -func createFile(path string) error { - f, err := os.Create(path) - if err != nil { - return err - } - f.WriteString("hello world!") - return f.Close() -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.APACHE b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.APACHE deleted file mode 100644 index 9e4bd4dbee9..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.APACHE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2014-2015 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.BSD b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.BSD deleted file mode 100644 index ac74d8f0496..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/LICENSE.BSD +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2014-2015 The Docker & Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/README.md b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/README.md deleted file mode 100644 index 0d1dbb70e64..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Package symlink implements EvalSymlinksInScope which is an extension of filepath.EvalSymlinks -from the [Go standard library](https://golang.org/pkg/path/filepath). - -The code from filepath.EvalSymlinks has been adapted in fs.go. -Please read the LICENSE.BSD file that governs fs.go and LICENSE.APACHE for fs_test.go. diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs.go deleted file mode 100644 index b4bdff24dd3..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.BSD file. - -// This code is a modified version of path/filepath/symlink.go from the Go standard library. - -package symlink - -import ( - "bytes" - "errors" - "os" - "path/filepath" - "strings" -) - -// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an absolute path -func FollowSymlinkInScope(path, root string) (string, error) { - path, err := filepath.Abs(path) - if err != nil { - return "", err - } - root, err = filepath.Abs(root) - if err != nil { - return "", err - } - return evalSymlinksInScope(path, root) -} - -// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return -// a result guaranteed to be contained within the scope `root`, at the time of the call. -// Symlinks in `root` are not evaluated and left as-is. -// Errors encountered while attempting to evaluate symlinks in path will be returned. -// Non-existing paths are valid and do not constitute an error. -// `path` has to contain `root` as a prefix, or else an error will be returned. -// Trying to break out from `root` does not constitute an error. -// -// Example: -// If /foo/bar -> /outside, -// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide" -// -// IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks -// are created and not to create subsequently, additional symlinks that could potentially make a -// previously-safe path, unsafe. Example: if /foo/bar does not exist, evalSymlinksInScope("/foo/bar", "/foo") -// would return "/foo/bar". If one makes /foo/bar a symlink to /baz subsequently, then "/foo/bar" should -// no longer be considered safely contained in "/foo". -func evalSymlinksInScope(path, root string) (string, error) { - root = filepath.Clean(root) - if path == root { - return path, nil - } - if !strings.HasPrefix(path, root) { - return "", errors.New("evalSymlinksInScope: " + path + " is not in " + root) - } - const maxIter = 255 - originalPath := path - // given root of "/a" and path of "/a/b/../../c" we want path to be "/b/../../c" - path = path[len(root):] - if root == string(filepath.Separator) { - path = string(filepath.Separator) + path - } - if !strings.HasPrefix(path, string(filepath.Separator)) { - return "", errors.New("evalSymlinksInScope: " + path + " is not in " + root) - } - path = filepath.Clean(path) - // consume path by taking each frontmost path element, - // expanding it if it's a symlink, and appending it to b - var b bytes.Buffer - // b here will always be considered to be the "current absolute path inside - // root" when we append paths to it, we also append a slash and use - // filepath.Clean after the loop to trim the trailing slash - for n := 0; path != ""; n++ { - if n > maxIter { - return "", errors.New("evalSymlinksInScope: too many links in " + originalPath) - } - - // find next path component, p - i := strings.IndexRune(path, filepath.Separator) - var p string - if i == -1 { - p, path = path, "" - } else { - p, path = path[:i], path[i+1:] - } - - if p == "" { - continue - } - - // this takes a b.String() like "b/../" and a p like "c" and turns it - // into "/b/../c" which then gets filepath.Cleaned into "/c" and then - // root gets prepended and we Clean again (to remove any trailing slash - // if the first Clean gave us just "/") - cleanP := filepath.Clean(string(filepath.Separator) + b.String() + p) - if cleanP == string(filepath.Separator) { - // never Lstat "/" itself - b.Reset() - continue - } - fullP := filepath.Clean(root + cleanP) - - fi, err := os.Lstat(fullP) - if os.IsNotExist(err) { - // if p does not exist, accept it - b.WriteString(p) - b.WriteRune(filepath.Separator) - continue - } - if err != nil { - return "", err - } - if fi.Mode()&os.ModeSymlink == 0 { - b.WriteString(p + string(filepath.Separator)) - continue - } - - // it's a symlink, put it at the front of path - dest, err := os.Readlink(fullP) - if err != nil { - return "", err - } - if filepath.IsAbs(dest) { - b.Reset() - } - path = dest + string(filepath.Separator) + path - } - - // see note above on "fullP := ..." for why this is double-cleaned and - // what's happening here - return filepath.Clean(root + filepath.Clean(string(filepath.Separator)+b.String())), nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs_test.go b/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs_test.go deleted file mode 100644 index 89209484a38..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/docker/pkg/symlink/fs_test.go +++ /dev/null @@ -1,402 +0,0 @@ -// Licensed under the Apache License, Version 2.0; See LICENSE.APACHE - -package symlink - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -type dirOrLink struct { - path string - target string -} - -func makeFs(tmpdir string, fs []dirOrLink) error { - for _, s := range fs { - s.path = filepath.Join(tmpdir, s.path) - if s.target == "" { - os.MkdirAll(s.path, 0755) - continue - } - if err := os.MkdirAll(filepath.Dir(s.path), 0755); err != nil { - return err - } - if err := os.Symlink(s.target, s.path); err != nil && !os.IsExist(err) { - return err - } - } - return nil -} - -func testSymlink(tmpdir, path, expected, scope string) error { - rewrite, err := FollowSymlinkInScope(filepath.Join(tmpdir, path), filepath.Join(tmpdir, scope)) - if err != nil { - return err - } - expected, err = filepath.Abs(filepath.Join(tmpdir, expected)) - if err != nil { - return err - } - if expected != rewrite { - return fmt.Errorf("Expected %q got %q", expected, rewrite) - } - return nil -} - -func TestFollowSymlinkAbsolute(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkAbsolute") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/d", target: "/b"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "testdata/fs/a/d/c/data", "testdata/b/c/data", "testdata"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkRelativePath(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativePath") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/i", target: "a"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "testdata/fs/i", "testdata/fs/a", "testdata"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkSkipSymlinksOutsideScope(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkSkipSymlinksOutsideScope") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - if err := makeFs(tmpdir, []dirOrLink{ - {path: "linkdir", target: "realdir"}, - {path: "linkdir/foo/bar"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "linkdir/foo/bar", "linkdir/foo/bar", "linkdir/foo"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkInvalidScopePathPair(t *testing.T) { - if _, err := FollowSymlinkInScope("toto", "testdata"); err == nil { - t.Fatal("expected an error") - } -} - -func TestFollowSymlinkLastLink(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkLastLink") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/d", target: "/b"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "testdata/fs/a/d", "testdata/b", "testdata"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkRelativeLinkChangeScope(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativeLinkChangeScope") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/e", target: "../b"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "testdata/fs/a/e/c/data", "testdata/fs/b/c/data", "testdata"); err != nil { - t.Fatal(err) - } - // avoid letting allowing symlink e lead us to ../b - // normalize to the "testdata/fs/a" - if err := testSymlink(tmpdir, "testdata/fs/a/e", "testdata/fs/a/b", "testdata/fs/a"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkDeepRelativeLinkChangeScope(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkDeepRelativeLinkChangeScope") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/f", target: "../../../../test"}}); err != nil { - t.Fatal(err) - } - // avoid letting symlink f lead us out of the "testdata" scope - // we don't normalize because symlink f is in scope and there is no - // information leak - if err := testSymlink(tmpdir, "testdata/fs/a/f", "testdata/test", "testdata"); err != nil { - t.Fatal(err) - } - // avoid letting symlink f lead us out of the "testdata/fs" scope - // we don't normalize because symlink f is in scope and there is no - // information leak - if err := testSymlink(tmpdir, "testdata/fs/a/f", "testdata/fs/test", "testdata/fs"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkRelativeLinkChain(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativeLinkChain") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - // avoid letting symlink g (pointed at by symlink h) take out of scope - // TODO: we should probably normalize to scope here because ../[....]/root - // is out of scope and we leak information - if err := makeFs(tmpdir, []dirOrLink{ - {path: "testdata/fs/b/h", target: "../g"}, - {path: "testdata/fs/g", target: "../../../../../../../../../../../../root"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "testdata/fs/b/h", "testdata/root", "testdata"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkBreakoutPath(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkBreakoutPath") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - // avoid letting symlink -> ../directory/file escape from scope - // normalize to "testdata/fs/j" - if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/j/k", target: "../i/a"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "testdata/fs/j/k", "testdata/fs/j/i/a", "testdata/fs/j"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkToRoot(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkToRoot") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - // make sure we don't allow escaping to / - // normalize to dir - if err := makeFs(tmpdir, []dirOrLink{{path: "foo", target: "/"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "foo", "", ""); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkSlashDotdot(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkSlashDotdot") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - tmpdir = filepath.Join(tmpdir, "dir", "subdir") - - // make sure we don't allow escaping to / - // normalize to dir - if err := makeFs(tmpdir, []dirOrLink{{path: "foo", target: "/../../"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "foo", "", ""); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkDotdot(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkDotdot") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - tmpdir = filepath.Join(tmpdir, "dir", "subdir") - - // make sure we stay in scope without leaking information - // this also checks for escaping to / - // normalize to dir - if err := makeFs(tmpdir, []dirOrLink{{path: "foo", target: "../../"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "foo", "", ""); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkRelativePath2(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativePath2") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{{path: "bar/foo", target: "baz/target"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "bar/foo", "bar/baz/target", ""); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkScopeLink(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkScopeLink") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{ - {path: "root2"}, - {path: "root", target: "root2"}, - {path: "root2/foo", target: "../bar"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "root/foo", "root/bar", "root"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkRootScope(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRootScope") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - expected, err := filepath.EvalSymlinks(tmpdir) - if err != nil { - t.Fatal(err) - } - rewrite, err := FollowSymlinkInScope(tmpdir, "/") - if err != nil { - t.Fatal(err) - } - if rewrite != expected { - t.Fatalf("expected %q got %q", expected, rewrite) - } -} - -func TestFollowSymlinkEmpty(t *testing.T) { - res, err := FollowSymlinkInScope("", "") - if err != nil { - t.Fatal(err) - } - wd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - if res != wd { - t.Fatalf("expected %q got %q", wd, res) - } -} - -func TestFollowSymlinkCircular(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkCircular") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{{path: "root/foo", target: "foo"}}); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "root/foo", "", "root"); err == nil { - t.Fatal("expected an error for foo -> foo") - } - - if err := makeFs(tmpdir, []dirOrLink{ - {path: "root/bar", target: "baz"}, - {path: "root/baz", target: "../bak"}, - {path: "root/bak", target: "/bar"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "root/foo", "", "root"); err == nil { - t.Fatal("expected an error for bar -> baz -> bak -> bar") - } -} - -func TestFollowSymlinkComplexChainWithTargetPathsContainingLinks(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkComplexChainWithTargetPathsContainingLinks") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{ - {path: "root2"}, - {path: "root", target: "root2"}, - {path: "root/a", target: "r/s"}, - {path: "root/r", target: "../root/t"}, - {path: "root/root/t/s/b", target: "/../u"}, - {path: "root/u/c", target: "."}, - {path: "root/u/x/y", target: "../v"}, - {path: "root/u/v", target: "/../w"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "root/a/b/c/x/y/z", "root/w/z", "root"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkBreakoutNonExistent(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkBreakoutNonExistent") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{ - {path: "root/slash", target: "/"}, - {path: "root/sym", target: "/idontexist/../slash"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "root/sym/file", "root/file", "root"); err != nil { - t.Fatal(err) - } -} - -func TestFollowSymlinkNoLexicalCleaning(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkNoLexicalCleaning") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - if err := makeFs(tmpdir, []dirOrLink{ - {path: "root/sym", target: "/foo/bar"}, - {path: "root/hello", target: "/sym/../baz"}, - }); err != nil { - t.Fatal(err) - } - if err := testSymlink(tmpdir, "root/hello", "root/foo/baz", "root"); err != nil { - t.Fatal(err) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/.drone.yml b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/.drone.yml deleted file mode 100644 index ce7cd3d37d7..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/.drone.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: dockercore/libcontainer -script: -# Setup the DockerInDocker environment. - - /dind - - sed -i 's!docker/docker!docker/libcontainer!' /go/src/github.com/docker/docker/hack/make/.validate - - bash /go/src/github.com/docker/docker/hack/make/validate-dco - - bash /go/src/github.com/docker/docker/hack/make/validate-gofmt - - export GOPATH="$GOPATH:/go:$(pwd)/vendor" # Drone mucks with our GOPATH - - go get golang.org/x/tools/cmd/vet && go vet ./... - - make direct-test diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/CONTRIBUTING.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/CONTRIBUTING.md deleted file mode 100644 index 667cc5a63fa..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/CONTRIBUTING.md +++ /dev/null @@ -1,257 +0,0 @@ -# The libcontainer Contributors' Guide - -Want to hack on libcontainer? Awesome! Here are instructions to get you -started. They are probably not perfect, please let us know if anything -feels wrong or incomplete. - -## Reporting Issues - -When reporting [issues](https://github.com/docker/libcontainer/issues) -on GitHub please include your host OS (Ubuntu 12.04, Fedora 19, etc), -the output of `uname -a`. Please include the steps required to reproduce -the problem if possible and applicable. -This information will help us review and fix your issue faster. - -## Development Environment - -### Requirements - -For best results, use a Linux development environment. -The following packages are required to compile libcontainer natively. - -- Golang 1.3 -- GCC -- git -- cgutils - -You can develop on OSX, but you are limited to Dockerfile-based builds only. - -### Building libcontainer from Dockerfile - - make all - -This is the easiest way of building libcontainer. -As this build is done using Docker, you can even run this from [OSX](https://github.com/boot2docker/boot2docker) - -### Testing changes with "nsinit" - - make sh - -This will create an container that runs `nsinit exec sh` on a busybox rootfs with the configuration from ['minimal.json'](https://github.com/docker/libcontainer/blob/master/sample_configs/minimal.json). -Like the previous command, you can run this on OSX too! - -### Building libcontainer directly - -> Note: You should add the `vendor` directory to your GOPATH to use the vendored libraries - - ./update-vendor.sh - go get -d ./... - make direct-build - # Run the tests - make direct-test-short | egrep --color 'FAIL|$' - # Run all the test - make direct-test | egrep --color 'FAIL|$' - -### Testing Changes with "nsinit" directly - -To test a change: - - # Install nsinit - make direct-install - - # Optional, add a docker0 bridge - ip link add docker0 type bridge - ifconfig docker0 172.17.0.1/16 up - - mkdir testfs - curl -sSL https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar | tar -xC testfs - cd testfs - cp container.json - nsinit exec sh - -## Contribution Guidelines - -### Pull requests are always welcome - -We are always thrilled to receive pull requests, and do our best to -process them as fast as possible. Not sure if that typo is worth a pull -request? Do it! We will appreciate it. - -If your pull request is not accepted on the first try, don't be -discouraged! If there's a problem with the implementation, hopefully you -received feedback on what to improve. - -We're trying very hard to keep libcontainer lean and focused. We don't want it -to do everything for everybody. This means that we might decide against -incorporating a new feature. However, there might be a way to implement -that feature *on top of* libcontainer. - -### Discuss your design on the mailing list - -We recommend discussing your plans [on the mailing -list](https://groups.google.com/forum/?fromgroups#!forum/libcontainer) -before starting to code - especially for more ambitious contributions. -This gives other contributors a chance to point you in the right -direction, give feedback on your design, and maybe point out if someone -else is working on the same thing. - -### Create issues... - -Any significant improvement should be documented as [a GitHub -issue](https://github.com/docker/libcontainer/issues) before anybody -starts working on it. - -### ...but check for existing issues first! - -Please take a moment to check that an issue doesn't already exist -documenting your bug report or improvement proposal. If it does, it -never hurts to add a quick "+1" or "I have this problem too". This will -help prioritize the most common problems and requests. - -### Conventions - -Fork the repo and make changes on your fork in a feature branch: - -- If it's a bugfix branch, name it XXX-something where XXX is the number of the - issue -- If it's a feature branch, create an enhancement issue to announce your - intentions, and name it XXX-something where XXX is the number of the issue. - -Submit unit tests for your changes. Go has a great test framework built in; use -it! Take a look at existing tests for inspiration. Run the full test suite on -your branch before submitting a pull request. - -Update the documentation when creating or modifying features. Test -your documentation changes for clarity, concision, and correctness, as -well as a clean documentation build. See ``docs/README.md`` for more -information on building the docs and how docs get released. - -Write clean code. Universally formatted code promotes ease of writing, reading, -and maintenance. Always run `gofmt -s -w file.go` on each changed file before -committing your changes. Most editors have plugins that do this automatically. - -Pull requests descriptions should be as clear as possible and include a -reference to all the issues that they address. - -Pull requests must not contain commits from other users or branches. - -Commit messages must start with a capitalized and short summary (max. 50 -chars) written in the imperative, followed by an optional, more detailed -explanatory text which is separated from the summary by an empty line. - -Code review comments may be added to your pull request. Discuss, then make the -suggested modifications and push additional commits to your feature branch. Be -sure to post a comment after pushing. The new commits will show up in the pull -request automatically, but the reviewers will not be notified unless you -comment. - -Before the pull request is merged, make sure that you squash your commits into -logical units of work using `git rebase -i` and `git push -f`. After every -commit the test suite should be passing. Include documentation changes in the -same commit so that a revert would remove all traces of the feature or fix. - -Commits that fix or close an issue should include a reference like `Closes #XXX` -or `Fixes #XXX`, which will automatically close the issue when merged. - -### Testing - -Make sure you include suitable tests, preferably unit tests, in your pull request -and that all the tests pass. - -*Instructions for running tests to be added.* - -### Merge approval - -libcontainer maintainers use LGTM (looks good to me) in comments on the code review -to indicate acceptance. - -A change requires LGTMs from at lease two maintainers. One of those must come from -a maintainer of the component affected. For example, if a change affects `netlink/` -and `security`, it needs at least one LGTM from a maintainer of each. Maintainers -only need one LGTM as presumably they LGTM their own change. - -For more details see [MAINTAINERS.md](MAINTAINERS.md) - -### Sign your work - -The sign-off is a simple line at the end of the explanation for the -patch, which certifies that you wrote it or otherwise have the right to -pass it on as an open-source patch. The rules are pretty simple: if you -can certify the below (from -[developercertificate.org](http://developercertificate.org/)): - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -660 York Street, Suite 102, -San Francisco, CA 94110 USA - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -then you just add a line to every git commit message: - - Docker-DCO-1.1-Signed-off-by: Joe Smith (github: github_handle) - -using your real name (sorry, no pseudonyms or anonymous contributions.) - -One way to automate this, is customise your get ``commit.template`` by adding -a ``prepare-commit-msg`` hook to your libcontainer checkout: - -``` -curl -o .git/hooks/prepare-commit-msg https://raw.githubusercontent.com/docker/docker/master/contrib/prepare-commit-msg.hook && chmod +x .git/hooks/prepare-commit-msg -``` - -* Note: the above script expects to find your GitHub user name in ``git config --get github.user`` - -#### Small patch exception - -There are several exceptions to the signing requirement. Currently these are: - -* Your patch fixes spelling or grammar errors. -* Your patch is a single line change to documentation contained in the - `docs` directory. -* Your patch fixes Markdown formatting or syntax errors in the - documentation contained in the `docs` directory. - -If you have any questions, please refer to the FAQ in the [docs](to be written) - -### How can I become a maintainer? - -* Step 1: learn the component inside out -* Step 2: make yourself useful by contributing code, bugfixes, support etc. -* Step 3: volunteer on the irc channel (#libcontainer@freenode) - -Don't forget: being a maintainer is a time investment. Make sure you will have time to make yourself available. -You don't have to be a maintainer to make a difference on the project! - diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/Dockerfile b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/Dockerfile deleted file mode 100644 index 0771c808ea9..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM golang:1.4 - -RUN go get golang.org/x/tools/cmd/cover - -ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor -RUN go get github.com/docker/docker/pkg/term - -# setup a playground for us to spawn containers in -RUN mkdir /busybox && \ - curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar' | tar -xC /busybox - -RUN curl -sSL https://raw.githubusercontent.com/docker/docker/master/project/dind -o /dind && \ - chmod +x /dind - -COPY . /go/src/github.com/docker/libcontainer -WORKDIR /go/src/github.com/docker/libcontainer -RUN cp sample_configs/minimal.json /busybox/container.json - -RUN go get -d -v ./... -RUN make direct-install - -ENTRYPOINT ["/dind"] -CMD ["make", "direct-test"] diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/LICENSE b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/LICENSE deleted file mode 100644 index 27448585ad4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2014 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/MAINTAINERS b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/MAINTAINERS deleted file mode 100644 index cea3500f2b8..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/MAINTAINERS +++ /dev/null @@ -1,7 +0,0 @@ -Michael Crosby (@crosbymichael) -Rohit Jnagal (@rjnagal) -Victor Marmol (@vmarmol) -Mrunal Patel (@mrunalp) -Alexandr Morozov (@LK4D4) -Daniel, Dao Quang Minh (@dqminh) -update-vendor.sh: Tianon Gravi (@tianon) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/MAINTAINERS_GUIDE.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/MAINTAINERS_GUIDE.md deleted file mode 100644 index 2ac9ca21f4e..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/MAINTAINERS_GUIDE.md +++ /dev/null @@ -1,99 +0,0 @@ -# The libcontainer Maintainers' Guide - -## Introduction - -Dear maintainer. Thank you for investing the time and energy to help -make libcontainer as useful as possible. Maintaining a project is difficult, -sometimes unrewarding work. Sure, you will get to contribute cool -features to the project. But most of your time will be spent reviewing, -cleaning up, documenting, answering questions, justifying design -decisions - while everyone has all the fun! But remember - the quality -of the maintainers work is what distinguishes the good projects from the -great. So please be proud of your work, even the unglamourous parts, -and encourage a culture of appreciation and respect for *every* aspect -of improving the project - not just the hot new features. - -This document is a manual for maintainers old and new. It explains what -is expected of maintainers, how they should work, and what tools are -available to them. - -This is a living document - if you see something out of date or missing, -speak up! - -## What are a maintainer's responsibility? - -It is every maintainer's responsibility to: - -* 1) Expose a clear roadmap for improving their component. -* 2) Deliver prompt feedback and decisions on pull requests. -* 3) Be available to anyone with questions, bug reports, criticism etc. - on their component. This includes IRC, GitHub requests and the mailing - list. -* 4) Make sure their component respects the philosophy, design and - roadmap of the project. - -## How are decisions made? - -Short answer: with pull requests to the libcontainer repository. - -libcontainer is an open-source project with an open design philosophy. This -means that the repository is the source of truth for EVERY aspect of the -project, including its philosophy, design, roadmap and APIs. *If it's -part of the project, it's in the repo. It's in the repo, it's part of -the project.* - -As a result, all decisions can be expressed as changes to the -repository. An implementation change is a change to the source code. An -API change is a change to the API specification. A philosophy change is -a change to the philosophy manifesto. And so on. - -All decisions affecting libcontainer, big and small, follow the same 3 steps: - -* Step 1: Open a pull request. Anyone can do this. - -* Step 2: Discuss the pull request. Anyone can do this. - -* Step 3: Accept (`LGTM`) or refuse a pull request. The relevant maintainers do -this (see below "Who decides what?") - - -## Who decides what? - -All decisions are pull requests, and the relevant maintainers make -decisions by accepting or refusing the pull request. Review and acceptance -by anyone is denoted by adding a comment in the pull request: `LGTM`. -However, only currently listed `MAINTAINERS` are counted towards the required -two LGTMs. - -libcontainer follows the timeless, highly efficient and totally unfair system -known as [Benevolent dictator for life](http://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), with Michael Crosby in the role of BDFL. -This means that all decisions are made by default by Michael. Since making -every decision himself would be highly un-scalable, in practice decisions -are spread across multiple maintainers. - -The relevant maintainers for a pull request can be worked out in two steps: - -* Step 1: Determine the subdirectories affected by the pull request. This - might be `netlink/` and `security/`, or any other part of the repo. - -* Step 2: Find the `MAINTAINERS` file which affects this directory. If the - directory itself does not have a `MAINTAINERS` file, work your way up - the repo hierarchy until you find one. - -### I'm a maintainer, and I'm going on holiday - -Please let your co-maintainers and other contributors know by raising a pull -request that comments out your `MAINTAINERS` file entry using a `#`. - -### I'm a maintainer, should I make pull requests too? - -Yes. Nobody should ever push to master directly. All changes should be -made through a pull request. - -### Who assigns maintainers? - -Michael has final `LGTM` approval for all pull requests to `MAINTAINERS` files. - -### How is this process changed? - -Just like everything else: by making a pull request :) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile deleted file mode 100644 index f94171b0fcc..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/Makefile +++ /dev/null @@ -1,24 +0,0 @@ - -all: - docker build -t dockercore/libcontainer . - -test: - # we need NET_ADMIN for the netlink tests and SYS_ADMIN for mounting - docker run --rm -it --privileged dockercore/libcontainer - -sh: - docker run --rm -it --privileged -w /busybox dockercore/libcontainer nsinit exec sh - -GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune -o -wholename ./.git -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u) - -direct-test: - go test $(TEST_TAGS) -cover -v $(GO_PACKAGES) - -direct-test-short: - go test $(TEST_TAGS) -cover -test.short -v $(GO_PACKAGES) - -direct-build: - go build -v $(GO_PACKAGES) - -direct-install: - go install -v $(GO_PACKAGES) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/NOTICE b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/NOTICE deleted file mode 100644 index ca1635f8964..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/NOTICE +++ /dev/null @@ -1,16 +0,0 @@ -libcontainer -Copyright 2012-2014 Docker, Inc. - -This product includes software developed at Docker, Inc. (http://www.docker.com). - -The following is courtesy of our legal counsel: - - -Use and transfer of Docker may be subject to certain restrictions by the -United States and other governments. -It is your responsibility to ensure that your use and/or transfer does not -violate applicable laws. - -For more information, please see http://www.bis.doc.gov - -See also http://www.apache.org/dev/crypto.html and/or seek legal counsel. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/PRINCIPLES.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/PRINCIPLES.md deleted file mode 100644 index 42396c0eecd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/PRINCIPLES.md +++ /dev/null @@ -1,19 +0,0 @@ -# libcontainer Principles - -In the design and development of libcontainer we try to follow these principles: - -(Work in progress) - -* Don't try to replace every tool. Instead, be an ingredient to improve them. -* Less code is better. -* Fewer components are better. Do you really need to add one more class? -* 50 lines of straightforward, readable code is better than 10 lines of magic that nobody can understand. -* Don't do later what you can do now. "//FIXME: refactor" is not acceptable in new code. -* When hesitating between two options, choose the one that is easier to reverse. -* "No" is temporary; "Yes" is forever. If you're not sure about a new feature, say no. You can change your mind later. -* Containers must be portable to the greatest possible number of machines. Be suspicious of any change which makes machines less interchangeable. -* The fewer moving parts in a container, the better. -* Don't merge it unless you document it. -* Don't document it unless you can keep it up-to-date. -* Don't merge it unless you test it! -* Everyone's problem is slightly different. Focus on the part that is the same for everyone, and solve that. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/README.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/README.md deleted file mode 100644 index 37047e68c86..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/README.md +++ /dev/null @@ -1,62 +0,0 @@ -## libcontainer - reference implementation for containers [![Build Status](https://ci.dockerproject.com/github.com/docker/libcontainer/status.svg?branch=master)](https://ci.dockerproject.com/github.com/docker/libcontainer) - -### Note on API changes: - -Please bear with us while we work on making the libcontainer API stable and something that we can support long term. We are currently discussing the API with the community, therefore, if you currently depend on libcontainer please pin your dependency at a specific tag or commit id. Please join the discussion and help shape the API. - -#### Background - -libcontainer specifies configuration options for what a container is. It provides a native Go implementation for using Linux namespaces with no external dependencies. libcontainer provides many convenience functions for working with namespaces, networking, and management. - - -#### Container -A container is a self contained execution environment that shares the kernel of the host system and which is (optionally) isolated from other containers in the system. - -libcontainer may be used to execute a process in a container. If a user tries to run a new process inside an existing container, the new process is added to the processes executing in the container. - - -#### Root file system - -A container runs with a directory known as its *root file system*, or *rootfs*, mounted as the file system root. The rootfs is usually a full system tree. - - -#### Configuration - -A container is initially configured by supplying configuration data when the container is created. - - -#### nsinit - -`nsinit` is a cli application which demonstrates the use of libcontainer. It is able to spawn new containers or join existing containers, based on the current directory. - -To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into the directory with your specified configuration. Environment, networking, and different capabilities for the container are specified in this file. The configuration is used for each process executed inside the container. - -See the `sample_configs` folder for examples of what the container configuration should look like. - -To execute `/bin/bash` in the current directory as a container just run the following **as root**: -```bash -nsinit exec /bin/bash -``` - -If you wish to spawn another process inside the container while your current bash session is running, run the same command again to get another bash shell (or change the command). If the original process (PID 1) dies, all other processes spawned inside the container will be killed and the namespace will be removed. - -You can identify if a process is running in a container by looking to see if `state.json` is in the root of the directory. - -You may also specify an alternate root place where the `container.json` file is read and where the `state.json` file will be saved. - -#### Future -See the [roadmap](ROADMAP.md). - -## Copyright and license - -Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license. -Docs released under Creative commons. - -## Hacking on libcontainer - -First of all, please familiarise yourself with the [libcontainer Principles](PRINCIPLES.md). - -If you're a *contributor* or aspiring contributor, you should read the [Contributors' Guide](CONTRIBUTING.md). - -If you're a *maintainer* or aspiring maintainer, you should read the [Maintainers' Guide](MAINTAINERS_GUIDE.md) and -"How can I become a maintainer?" in the Contributors' Guide. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/ROADMAP.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/ROADMAP.md deleted file mode 100644 index f59035351a5..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/ROADMAP.md +++ /dev/null @@ -1,20 +0,0 @@ -# libcontainer: what's next? - -This document is a high-level overview of where we want to take libcontainer next. -It is a curated selection of planned improvements which are either important, difficult, or both. - -For a more complete view of planned and requested improvements, see [the Github issues](https://github.com/docker/libcontainer/issues). - -To suggest changes to the roadmap, including additions, please write the change as if it were already in effect, and make a pull request. - -## Broader kernel support - -Our goal is to make libcontainer run everywhere, but currently libcontainer requires Linux version 3.8 or higher. If you’re deploying new machines for the purpose of running libcontainer, this is a fairly easy requirement to meet. However, if you’re adding libcontainer to an existing deployment, you may not have the flexibility to update and patch the kernel. - -## Cross-architecture support - -Our goal is to make libcontainer run everywhere. Recently libcontainer has -expanded from its initial support for x86_64 systems to include POWER (ppc64 -little and big endian variants), IBM System z (s390x 64-bit), and ARM. We plan -to continue expanding architecture support such that libcontainer containers -can be created and used on more architectures. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/SPEC.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/SPEC.md deleted file mode 100644 index d83d758dddb..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/SPEC.md +++ /dev/null @@ -1,346 +0,0 @@ -## Container Specification - v1 - -This is the standard configuration for version 1 containers. It includes -namespaces, standard filesystem setup, a default Linux capability set, and -information about resource reservations. It also has information about any -populated environment settings for the processes running inside a container. - -Along with the configuration of how a container is created the standard also -discusses actions that can be performed on a container to manage and inspect -information about the processes running inside. - -The v1 profile is meant to be able to accommodate the majority of applications -with a strong security configuration. - -### System Requirements and Compatibility - -Minimum requirements: -* Kernel version - 3.8 recommended 2.6.2x minimum(with backported patches) -* Mounted cgroups with each subsystem in its own hierarchy - - -### Namespaces - -| Flag | Enabled | -| ------------ | ------- | -| CLONE_NEWPID | 1 | -| CLONE_NEWUTS | 1 | -| CLONE_NEWIPC | 1 | -| CLONE_NEWNET | 1 | -| CLONE_NEWNS | 1 | -| CLONE_NEWUSER | 0 | - -In v1 the user namespace is not enabled by default for support of older kernels -where the user namespace feature is not fully implemented. Namespaces are -created for the container via the `clone` syscall. - - -### Filesystem - -A root filesystem must be provided to a container for execution. The container -will use this root filesystem (rootfs) to jail and spawn processes inside where -the binaries and system libraries are local to that directory. Any binaries -to be executed must be contained within this rootfs. - -Mounts that happen inside the container are automatically cleaned up when the -container exits as the mount namespace is destroyed and the kernel will -unmount all the mounts that were setup within that namespace. - -For a container to execute properly there are certain filesystems that -are required to be mounted within the rootfs that the runtime will setup. - -| Path | Type | Flags | Data | -| ----------- | ------ | -------------------------------------- | --------------------------------------- | -| /proc | proc | MS_NOEXEC,MS_NOSUID,MS_NODEV | | -| /dev | tmpfs | MS_NOEXEC,MS_STRICTATIME | mode=755 | -| /dev/shm | shm | MS_NOEXEC,MS_NOSUID,MS_NODEV | mode=1777,size=65536k | -| /dev/mqueue | mqueue | MS_NOEXEC,MS_NOSUID,MS_NODEV | | -| /dev/pts | devpts | MS_NOEXEC,MS_NOSUID | newinstance,ptmxmode=0666,mode=620,gid5 | -| /sys | sysfs | MS_NOEXEC,MS_NOSUID,MS_NODEV,MS_RDONLY | | - - -After a container's filesystems are mounted within the newly created -mount namespace `/dev` will need to be populated with a set of device nodes. -It is expected that a rootfs does not need to have any device nodes specified -for `/dev` witin the rootfs as the container will setup the correct devices -that are required for executing a container's process. - -| Path | Mode | Access | -| ------------ | ---- | ---------- | -| /dev/null | 0666 | rwm | -| /dev/zero | 0666 | rwm | -| /dev/full | 0666 | rwm | -| /dev/tty | 0666 | rwm | -| /dev/random | 0666 | rwm | -| /dev/urandom | 0666 | rwm | -| /dev/fuse | 0666 | rwm | - - -**ptmx** -`/dev/ptmx` will need to be a symlink to the host's `/dev/ptmx` within -the container. - -The use of a pseudo TTY is optional within a container and it should support both. -If a pseudo is provided to the container `/dev/console` will need to be -setup by binding the console in `/dev/` after it has been populated and mounted -in tmpfs. - -| Source | Destination | UID GID | Mode | Type | -| --------------- | ------------ | ------- | ---- | ---- | -| *pty host path* | /dev/console | 0 0 | 0600 | bind | - - -After `/dev/null` has been setup we check for any external links between -the container's io, STDIN, STDOUT, STDERR. If the container's io is pointing -to `/dev/null` outside the container we close and `dup2` the the `/dev/null` -that is local to the container's rootfs. - - -After the container has `/proc` mounted a few standard symlinks are setup -within `/dev/` for the io. - -| Source | Destination | -| ------------ | ----------- | -| /proc/1/fd | /dev/fd | -| /proc/1/fd/0 | /dev/stdin | -| /proc/1/fd/1 | /dev/stdout | -| /proc/1/fd/2 | /dev/stderr | - -A `pivot_root` is used to change the root for the process, effectively -jailing the process inside the rootfs. - -```c -put_old = mkdir(...); -pivot_root(rootfs, put_old); -chdir("/"); -unmount(put_old, MS_DETACH); -rmdir(put_old); -``` - -For container's running with a rootfs inside `ramfs` a `MS_MOVE` combined -with a `chroot` is required as `pivot_root` is not supported in `ramfs`. - -```c -mount(rootfs, "/", NULL, MS_MOVE, NULL); -chroot("."); -chdir("/"); -``` - -The `umask` is set back to `0022` after the filesystem setup has been completed. - -### Resources - -Cgroups are used to handle resource allocation for containers. This includes -system resources like cpu, memory, and device access. - -| Subsystem | Enabled | -| ---------- | ------- | -| devices | 1 | -| memory | 1 | -| cpu | 1 | -| cpuacct | 1 | -| cpuset | 1 | -| blkio | 1 | -| perf_event | 1 | -| freezer | 1 | - - -All cgroup subsystem are joined so that statistics can be collected from -each of the subsystems. Freezer does not expose any stats but is joined -so that containers can be paused and resumed. - -The parent process of the container's init must place the init pid inside -the correct cgroups before the initialization begins. This is done so -that no processes or threads escape the cgroups. This sync is -done via a pipe ( specified in the runtime section below ) that the container's -init process will block waiting for the parent to finish setup. - -### Security - -The standard set of Linux capabilities that are set in a container -provide a good default for security and flexibility for the applications. - - -| Capability | Enabled | -| -------------------- | ------- | -| CAP_NET_RAW | 1 | -| CAP_NET_BIND_SERVICE | 1 | -| CAP_AUDIT_WRITE | 1 | -| CAP_DAC_OVERRIDE | 1 | -| CAP_SETFCAP | 1 | -| CAP_SETPCAP | 1 | -| CAP_SETGID | 1 | -| CAP_SETUID | 1 | -| CAP_MKNOD | 1 | -| CAP_CHOWN | 1 | -| CAP_FOWNER | 1 | -| CAP_FSETID | 1 | -| CAP_KILL | 1 | -| CAP_SYS_CHROOT | 1 | -| CAP_NET_BROADCAST | 0 | -| CAP_SYS_MODULE | 0 | -| CAP_SYS_RAWIO | 0 | -| CAP_SYS_PACCT | 0 | -| CAP_SYS_ADMIN | 0 | -| CAP_SYS_NICE | 0 | -| CAP_SYS_RESOURCE | 0 | -| CAP_SYS_TIME | 0 | -| CAP_SYS_TTY_CONFIG | 0 | -| CAP_AUDIT_CONTROL | 0 | -| CAP_MAC_OVERRIDE | 0 | -| CAP_MAC_ADMIN | 0 | -| CAP_NET_ADMIN | 0 | -| CAP_SYSLOG | 0 | -| CAP_DAC_READ_SEARCH | 0 | -| CAP_LINUX_IMMUTABLE | 0 | -| CAP_IPC_LOCK | 0 | -| CAP_IPC_OWNER | 0 | -| CAP_SYS_PTRACE | 0 | -| CAP_SYS_BOOT | 0 | -| CAP_LEASE | 0 | -| CAP_WAKE_ALARM | 0 | -| CAP_BLOCK_SUSPE | 0 | - - -Additional security layers like [apparmor](https://wiki.ubuntu.com/AppArmor) -and [selinux](http://selinuxproject.org/page/Main_Page) can be used with -the containers. A container should support setting an apparmor profile or -selinux process and mount labels if provided in the configuration. - -Standard apparmor profile: -```c -#include -profile flags=(attach_disconnected,mediate_deleted) { - #include - network, - capability, - file, - umount, - - mount fstype=tmpfs, - mount fstype=mqueue, - mount fstype=fuse.*, - mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/, - mount fstype=efivarfs -> /sys/firmware/efi/efivars/, - mount fstype=fusectl -> /sys/fs/fuse/connections/, - mount fstype=securityfs -> /sys/kernel/security/, - mount fstype=debugfs -> /sys/kernel/debug/, - mount fstype=proc -> /proc/, - mount fstype=sysfs -> /sys/, - - deny @{PROC}/sys/fs/** wklx, - deny @{PROC}/sysrq-trigger rwklx, - deny @{PROC}/mem rwklx, - deny @{PROC}/kmem rwklx, - deny @{PROC}/sys/kernel/[^s][^h][^m]* wklx, - deny @{PROC}/sys/kernel/*/** wklx, - - deny mount options=(ro, remount) -> /, - deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/, - deny mount fstype=devpts, - - deny /sys/[^f]*/** wklx, - deny /sys/f[^s]*/** wklx, - deny /sys/fs/[^c]*/** wklx, - deny /sys/fs/c[^g]*/** wklx, - deny /sys/fs/cg[^r]*/** wklx, - deny /sys/firmware/efi/efivars/** rwklx, - deny /sys/kernel/security/** rwklx, -} -``` - -*TODO: seccomp work is being done to find a good default config* - -### Runtime and Init Process - -During container creation the parent process needs to talk to the container's init -process and have a form of synchronization. This is accomplished by creating -a pipe that is passed to the container's init. When the init process first spawns -it will block on its side of the pipe until the parent closes its side. This -allows the parent to have time to set the new process inside a cgroup hierarchy -and/or write any uid/gid mappings required for user namespaces. -The pipe is passed to the init process via FD 3. - -The application consuming libcontainer should be compiled statically. libcontainer -does not define any init process and the arguments provided are used to `exec` the -process inside the application. There should be no long running init within the -container spec. - -If a pseudo tty is provided to a container it will open and `dup2` the console -as the container's STDIN, STDOUT, STDERR as well as mounting the console -as `/dev/console`. - -An extra set of mounts are provided to a container and setup for use. A container's -rootfs can contain some non portable files inside that can cause side effects during -execution of a process. These files are usually created and populated with the container -specific information via the runtime. - -**Extra runtime files:** -* /etc/hosts -* /etc/resolv.conf -* /etc/hostname -* /etc/localtime - - -#### Defaults - -There are a few defaults that can be overridden by users, but in their omission -these apply to processes within a container. - -| Type | Value | -| ------------------- | ------------------------------ | -| Parent Death Signal | SIGKILL | -| UID | 0 | -| GID | 0 | -| GROUPS | 0, NULL | -| CWD | "/" | -| $HOME | Current user's home dir or "/" | -| Readonly rootfs | false | -| Pseudo TTY | false | - - -## Actions - -After a container is created there is a standard set of actions that can -be done to the container. These actions are part of the public API for -a container. - -| Action | Description | -| -------------- | ------------------------------------------------------------------ | -| Get processes | Return all the pids for processes running inside a container | -| Get Stats | Return resource statistics for the container as a whole | -| Wait | Wait waits on the container's init process ( pid 1 ) | -| Wait Process | Wait on any of the container's processes returning the exit status | -| Destroy | Kill the container's init process and remove any filesystem state | -| Signal | Send a signal to the container's init process | -| Signal Process | Send a signal to any of the container's processes | -| Pause | Pause all processes inside the container | -| Resume | Resume all processes inside the container if paused | -| Exec | Execute a new process inside of the container ( requires setns ) | - -### Execute a new process inside of a running container. - -User can execute a new process inside of a running container. Any binaries to be -executed must be accessible within the container's rootfs. - -The started process will run inside the container's rootfs. Any changes -made by the process to the container's filesystem will persist after the -process finished executing. - -The started process will join all the container's existing namespaces. When the -container is paused, the process will also be paused and will resume when -the container is unpaused. The started process will only run when the container's -primary process (PID 1) is running, and will not be restarted when the container -is restarted. - -#### Planned additions - -The started process will have its own cgroups nested inside the container's -cgroups. This is used for process tracking and optionally resource allocation -handling for the new process. Freezer cgroup is required, the rest of the cgroups -are optional. The process executor must place its pid inside the correct -cgroups before starting the process. This is done so that no child processes or -threads can escape the cgroups. - -When the process is stopped, the process executor will try (in a best-effort way) -to stop all its children and remove the sub-cgroups. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/api_temp.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/api_temp.go deleted file mode 100644 index 5c682ee3441..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/api_temp.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -Temporary API endpoint for libcontainer while the full API is finalized (api.go). -*/ -package libcontainer - -import ( - "github.com/docker/libcontainer/cgroups/fs" - "github.com/docker/libcontainer/network" -) - -// TODO(vmarmol): Complete Stats() in final libcontainer API and move users to that. -// DEPRECATED: The below portions are only to be used during the transition to the official API. -// Returns all available stats for the given container. -func GetStats(container *Config, state *State) (stats *ContainerStats, err error) { - stats = &ContainerStats{} - if stats.CgroupStats, err = fs.GetStats(state.CgroupPaths); err != nil { - return stats, err - } - stats.NetworkStats, err = network.GetStats(&state.NetworkState) - return stats, err -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/apparmor.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/apparmor.go deleted file mode 100644 index fb1574dfc6c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/apparmor.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build apparmor,linux - -package apparmor - -// #cgo LDFLAGS: -lapparmor -// #include -// #include -import "C" -import ( - "io/ioutil" - "os" - "unsafe" -) - -func IsEnabled() bool { - if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" { - buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") - return err == nil && len(buf) > 1 && buf[0] == 'Y' - } - return false -} - -func ApplyProfile(name string) error { - if name == "" { - return nil - } - - cName := C.CString(name) - defer C.free(unsafe.Pointer(cName)) - - if _, err := C.aa_change_onexec(cName); err != nil { - return err - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/apparmor_disabled.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/apparmor_disabled.go deleted file mode 100644 index 937bf915c75..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/apparmor_disabled.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !apparmor !linux - -package apparmor - -func IsEnabled() bool { - return false -} - -func ApplyProfile(name string) error { - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/gen.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/gen.go deleted file mode 100644 index 825e646d920..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/gen.go +++ /dev/null @@ -1,94 +0,0 @@ -package apparmor - -import ( - "io" - "os" - "text/template" -) - -type data struct { - Name string - Imports []string - InnerImports []string -} - -const baseTemplate = ` -{{range $value := .Imports}} -{{$value}} -{{end}} - -profile {{.Name}} flags=(attach_disconnected,mediate_deleted) { -{{range $value := .InnerImports}} - {{$value}} -{{end}} - - network, - capability, - file, - umount, - - mount fstype=tmpfs, - mount fstype=mqueue, - mount fstype=fuse.*, - mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/, - mount fstype=efivarfs -> /sys/firmware/efi/efivars/, - mount fstype=fusectl -> /sys/fs/fuse/connections/, - mount fstype=securityfs -> /sys/kernel/security/, - mount fstype=debugfs -> /sys/kernel/debug/, - mount fstype=proc -> /proc/, - mount fstype=sysfs -> /sys/, - - deny @{PROC}/sys/fs/** wklx, - deny @{PROC}/sysrq-trigger rwklx, - deny @{PROC}/mem rwklx, - deny @{PROC}/kmem rwklx, - deny @{PROC}/sys/kernel/[^s][^h][^m]* wklx, - deny @{PROC}/sys/kernel/*/** wklx, - - deny mount options=(ro, remount) -> /, - deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/, - deny mount fstype=devpts, - - deny /sys/[^f]*/** wklx, - deny /sys/f[^s]*/** wklx, - deny /sys/fs/[^c]*/** wklx, - deny /sys/fs/c[^g]*/** wklx, - deny /sys/fs/cg[^r]*/** wklx, - deny /sys/firmware/efi/efivars/** rwklx, - deny /sys/kernel/security/** rwklx, -} -` - -func generateProfile(out io.Writer) error { - compiled, err := template.New("apparmor_profile").Parse(baseTemplate) - if err != nil { - return err - } - data := &data{ - Name: "docker-default", - } - if tuntablesExists() { - data.Imports = append(data.Imports, "#include ") - } else { - data.Imports = append(data.Imports, "@{PROC}=/proc/") - } - if abstrctionsEsists() { - data.InnerImports = append(data.InnerImports, "#include ") - } - if err := compiled.Execute(out, data); err != nil { - return err - } - return nil -} - -// check if the tunables/global exist -func tuntablesExists() bool { - _, err := os.Stat("/etc/apparmor.d/tunables/global") - return err == nil -} - -// check if abstractions/base exist -func abstrctionsEsists() bool { - _, err := os.Stat("/etc/apparmor.d/abstractions/base") - return err == nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/setup.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/setup.go deleted file mode 100644 index 8ed5437470e..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/apparmor/setup.go +++ /dev/null @@ -1,44 +0,0 @@ -package apparmor - -import ( - "fmt" - "os" - "os/exec" - "path" -) - -const ( - DefaultProfilePath = "/etc/apparmor.d/docker" -) - -func InstallDefaultProfile() error { - if !IsEnabled() { - return nil - } - - // Make sure /etc/apparmor.d exists - if err := os.MkdirAll(path.Dir(DefaultProfilePath), 0755); err != nil { - return err - } - - f, err := os.OpenFile(DefaultProfilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return err - } - if err := generateProfile(f); err != nil { - f.Close() - return err - } - f.Close() - - cmd := exec.Command("/sbin/apparmor_parser", "-r", "-W", "docker") - // to use the parser directly we have to make sure we are in the correct - // dir with the profile - cmd.Dir = "/etc/apparmor.d" - - output, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("Error loading docker apparmor profile: %s (%s)", err, output) - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go deleted file mode 100644 index 497437f5e3c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/cgroups.go +++ /dev/null @@ -1,57 +0,0 @@ -package cgroups - -import ( - "fmt" - - "github.com/docker/libcontainer/devices" -) - -type FreezerState string - -const ( - Undefined FreezerState = "" - Frozen FreezerState = "FROZEN" - Thawed FreezerState = "THAWED" -) - -type NotFoundError struct { - Subsystem string -} - -func (e *NotFoundError) Error() string { - return fmt.Sprintf("mountpoint for %s not found", e.Subsystem) -} - -func NewNotFoundError(sub string) error { - return &NotFoundError{ - Subsystem: sub, - } -} - -func IsNotFound(err error) bool { - if err == nil { - return false - } - - _, ok := err.(*NotFoundError) - return ok -} - -type Cgroup struct { - Name string `json:"name,omitempty"` - Parent string `json:"parent,omitempty"` // name of parent cgroup or slice - - AllowAllDevices bool `json:"allow_all_devices,omitempty"` // 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. - AllowedDevices []*devices.Device `json:"allowed_devices,omitempty"` - Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes) - MemoryReservation int64 `json:"memory_reservation,omitempty"` // Memory reservation or soft_limit (in bytes) - MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap - CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers) - CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period. - CpuPeriod int64 `json:"cpu_period,omitempty"` // CPU period to be used for hardcapping (in usecs). 0 to use system default. - CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use - CpusetMems string `json:"cpuset_mems,omitempty"` // MEM to use - BlkioWeight int64 `json:"blkio_weight,omitempty"` // Specifies per cgroup weight, range is from 10 to 1000. - Freezer FreezerState `json:"freezer,omitempty"` // set the freeze value for the process - Slice string `json:"slice,omitempty"` // Parent slice to use for systemd -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go deleted file mode 100644 index bbc0555260e..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go +++ /dev/null @@ -1,247 +0,0 @@ -package fs - -import ( - "io/ioutil" - "os" - "path/filepath" - "strconv" - "sync" - - "github.com/docker/libcontainer/cgroups" -) - -var ( - subsystems = map[string]subsystem{ - "devices": &DevicesGroup{}, - "memory": &MemoryGroup{}, - "cpu": &CpuGroup{}, - "cpuset": &CpusetGroup{}, - "cpuacct": &CpuacctGroup{}, - "blkio": &BlkioGroup{}, - "perf_event": &PerfEventGroup{}, - "freezer": &FreezerGroup{}, - } - CgroupProcesses = "cgroup.procs" -) - -// The absolute path to the root of the cgroup hierarchies. -var cgroupRootLock sync.Mutex -var cgroupRoot string - -// Gets the cgroupRoot. -func getCgroupRoot() (string, error) { - cgroupRootLock.Lock() - defer cgroupRootLock.Unlock() - - if cgroupRoot != "" { - return cgroupRoot, nil - } - - // we can pick any subsystem to find the root - cpuRoot, err := cgroups.FindCgroupMountpoint("cpu") - if err != nil { - return "", err - } - root := filepath.Dir(cpuRoot) - - if _, err := os.Stat(root); err != nil { - return "", err - } - - cgroupRoot = root - return cgroupRoot, nil -} - -type subsystem interface { - // Returns the stats, as 'stats', corresponding to the cgroup under 'path'. - GetStats(path string, stats *cgroups.Stats) error - // Removes the cgroup represented by 'data'. - Remove(*data) error - // Creates and joins the cgroup represented by data. - Set(*data) error -} - -type data struct { - root string - cgroup string - c *cgroups.Cgroup - pid int -} - -func Apply(c *cgroups.Cgroup, pid int) (map[string]string, error) { - d, err := getCgroupData(c, pid) - if err != nil { - return nil, err - } - - paths := make(map[string]string) - defer func() { - if err != nil { - cgroups.RemovePaths(paths) - } - }() - for name, sys := range subsystems { - if err := sys.Set(d); err != nil { - return nil, err - } - // FIXME: Apply should, ideally, be reentrant or be broken up into a separate - // create and join phase so that the cgroup hierarchy for a container can be - // created then join consists of writing the process pids to cgroup.procs - p, err := d.path(name) - if err != nil { - if cgroups.IsNotFound(err) { - continue - } - return nil, err - } - paths[name] = p - } - return paths, nil -} - -// Symmetrical public function to update device based cgroups. Also available -// in the systemd implementation. -func ApplyDevices(c *cgroups.Cgroup, pid int) error { - d, err := getCgroupData(c, pid) - if err != nil { - return err - } - - devices := subsystems["devices"] - - return devices.Set(d) -} - -func GetStats(systemPaths map[string]string) (*cgroups.Stats, error) { - stats := cgroups.NewStats() - for name, path := range systemPaths { - sys, ok := subsystems[name] - if !ok || !cgroups.PathExists(path) { - continue - } - if err := sys.GetStats(path, stats); err != nil { - return nil, err - } - } - - return stats, nil -} - -// Freeze toggles the container's freezer cgroup depending on the state -// provided -func Freeze(c *cgroups.Cgroup, state cgroups.FreezerState) error { - d, err := getCgroupData(c, 0) - if err != nil { - return err - } - - prevState := c.Freezer - c.Freezer = state - - freezer := subsystems["freezer"] - err = freezer.Set(d) - if err != nil { - c.Freezer = prevState - return err - } - - return nil -} - -func GetPids(c *cgroups.Cgroup) ([]int, error) { - d, err := getCgroupData(c, 0) - if err != nil { - return nil, err - } - - dir, err := d.path("devices") - if err != nil { - return nil, err - } - - return cgroups.ReadProcsFile(dir) -} - -func getCgroupData(c *cgroups.Cgroup, pid int) (*data, error) { - root, err := getCgroupRoot() - if err != nil { - return nil, err - } - - cgroup := c.Name - if c.Parent != "" { - cgroup = filepath.Join(c.Parent, cgroup) - } - - return &data{ - root: root, - cgroup: cgroup, - c: c, - pid: pid, - }, nil -} - -func (raw *data) parent(subsystem string) (string, error) { - initPath, err := cgroups.GetInitCgroupDir(subsystem) - if err != nil { - return "", err - } - return filepath.Join(raw.root, subsystem, initPath), nil -} - -func (raw *data) path(subsystem string) (string, error) { - // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. - if filepath.IsAbs(raw.cgroup) { - path := filepath.Join(raw.root, subsystem, raw.cgroup) - - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - return "", cgroups.NewNotFoundError(subsystem) - } - - return "", err - } - - return path, nil - } - - parent, err := raw.parent(subsystem) - if err != nil { - return "", err - } - - return filepath.Join(parent, raw.cgroup), nil -} - -func (raw *data) join(subsystem string) (string, error) { - path, err := raw.path(subsystem) - if err != nil { - return "", err - } - if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) { - return "", err - } - if err := writeFile(path, CgroupProcesses, strconv.Itoa(raw.pid)); err != nil { - return "", err - } - return path, nil -} - -func writeFile(dir, file, data string) error { - return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700) -} - -func readFile(dir, file string) (string, error) { - data, err := ioutil.ReadFile(filepath.Join(dir, file)) - return string(data), err -} - -func removePath(p string, err error) error { - if err != nil { - return err - } - if p != "" { - return os.RemoveAll(p) - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go deleted file mode 100644 index b64e4684370..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/blkio.go +++ /dev/null @@ -1,193 +0,0 @@ -package fs - -import ( - "bufio" - "fmt" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/docker/libcontainer/cgroups" -) - -type BlkioGroup struct { -} - -func (s *BlkioGroup) Set(d *data) error { - dir, err := d.join("blkio") - if err != nil && !cgroups.IsNotFound(err) { - return err - } - - if d.c.BlkioWeight != 0 { - if err := writeFile(dir, "blkio.weight", strconv.FormatInt(d.c.BlkioWeight, 10)); err != nil { - return err - } - } - - return nil -} - -func (s *BlkioGroup) Remove(d *data) error { - return removePath(d.path("blkio")) -} - -/* -examples: - - blkio.sectors - 8:0 6792 - - blkio.io_service_bytes - 8:0 Read 1282048 - 8:0 Write 2195456 - 8:0 Sync 2195456 - 8:0 Async 1282048 - 8:0 Total 3477504 - Total 3477504 - - blkio.io_serviced - 8:0 Read 124 - 8:0 Write 104 - 8:0 Sync 104 - 8:0 Async 124 - 8:0 Total 228 - Total 228 - - blkio.io_queued - 8:0 Read 0 - 8:0 Write 0 - 8:0 Sync 0 - 8:0 Async 0 - 8:0 Total 0 - Total 0 -*/ - -func splitBlkioStatLine(r rune) bool { - return r == ' ' || r == ':' -} - -func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) { - var blkioStats []cgroups.BlkioStatEntry - f, err := os.Open(path) - if err != nil { - if os.IsNotExist(err) { - return blkioStats, nil - } - return nil, err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - // format: dev type amount - fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine) - if len(fields) < 3 { - if len(fields) == 2 && fields[0] == "Total" { - // skip total line - continue - } else { - return nil, fmt.Errorf("Invalid line found while parsing %s: %s", path, sc.Text()) - } - } - - v, err := strconv.ParseUint(fields[0], 10, 64) - if err != nil { - return nil, err - } - major := v - - v, err = strconv.ParseUint(fields[1], 10, 64) - if err != nil { - return nil, err - } - minor := v - - op := "" - valueField := 2 - if len(fields) == 4 { - op = fields[2] - valueField = 3 - } - v, err = strconv.ParseUint(fields[valueField], 10, 64) - if err != nil { - return nil, err - } - blkioStats = append(blkioStats, cgroups.BlkioStatEntry{Major: major, Minor: minor, Op: op, Value: v}) - } - - return blkioStats, nil -} - -func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error { - // Try to read CFQ stats available on all CFQ enabled kernels first - if blkioStats, err := getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err == nil && blkioStats != nil { - return getCFQStats(path, stats) - } - return getStats(path, stats) // Use generic stats as fallback -} - -func getCFQStats(path string, stats *cgroups.Stats) error { - var blkioStats []cgroups.BlkioStatEntry - var err error - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.sectors_recursive")); err != nil { - return err - } - stats.BlkioStats.SectorsRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_bytes_recursive")); err != nil { - return err - } - stats.BlkioStats.IoServiceBytesRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err != nil { - return err - } - stats.BlkioStats.IoServicedRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_queued_recursive")); err != nil { - return err - } - stats.BlkioStats.IoQueuedRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_time_recursive")); err != nil { - return err - } - stats.BlkioStats.IoServiceTimeRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_wait_time_recursive")); err != nil { - return err - } - stats.BlkioStats.IoWaitTimeRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_merged_recursive")); err != nil { - return err - } - stats.BlkioStats.IoMergedRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.time_recursive")); err != nil { - return err - } - stats.BlkioStats.IoTimeRecursive = blkioStats - - return nil -} - -func getStats(path string, stats *cgroups.Stats) error { - var blkioStats []cgroups.BlkioStatEntry - var err error - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_service_bytes")); err != nil { - return err - } - stats.BlkioStats.IoServiceBytesRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_serviced")); err != nil { - return err - } - stats.BlkioStats.IoServicedRecursive = blkioStats - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu.go deleted file mode 100644 index efac9ed16ad..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpu.go +++ /dev/null @@ -1,72 +0,0 @@ -package fs - -import ( - "bufio" - "os" - "path/filepath" - "strconv" - - "github.com/docker/libcontainer/cgroups" -) - -type CpuGroup struct { -} - -func (s *CpuGroup) Set(d *data) error { - // We always want to join the cpu group, to allow fair cpu scheduling - // on a container basis - dir, err := d.join("cpu") - if err != nil { - return err - } - if d.c.CpuShares != 0 { - if err := writeFile(dir, "cpu.shares", strconv.FormatInt(d.c.CpuShares, 10)); err != nil { - return err - } - } - if d.c.CpuPeriod != 0 { - if err := writeFile(dir, "cpu.cfs_period_us", strconv.FormatInt(d.c.CpuPeriod, 10)); err != nil { - return err - } - } - if d.c.CpuQuota != 0 { - if err := writeFile(dir, "cpu.cfs_quota_us", strconv.FormatInt(d.c.CpuQuota, 10)); err != nil { - return err - } - } - return nil -} - -func (s *CpuGroup) Remove(d *data) error { - return removePath(d.path("cpu")) -} - -func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error { - f, err := os.Open(filepath.Join(path, "cpu.stat")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - t, v, err := getCgroupParamKeyValue(sc.Text()) - if err != nil { - return err - } - switch t { - case "nr_periods": - stats.CpuStats.ThrottlingData.Periods = v - - case "nr_throttled": - stats.CpuStats.ThrottlingData.ThrottledPeriods = v - - case "throttled_time": - stats.CpuStats.ThrottlingData.ThrottledTime = v - } - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go deleted file mode 100644 index 14b55ccd4e0..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go +++ /dev/null @@ -1,110 +0,0 @@ -package fs - -import ( - "fmt" - "io/ioutil" - "path/filepath" - "strconv" - "strings" - - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/system" -) - -const ( - cgroupCpuacctStat = "cpuacct.stat" - nanosecondsInSecond = 1000000000 -) - -var clockTicks = uint64(system.GetClockTicks()) - -type CpuacctGroup struct { -} - -func (s *CpuacctGroup) Set(d *data) error { - // we just want to join this group even though we don't set anything - if _, err := d.join("cpuacct"); err != nil && !cgroups.IsNotFound(err) { - return err - } - - return nil -} - -func (s *CpuacctGroup) Remove(d *data) error { - return removePath(d.path("cpuacct")) -} - -func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error { - userModeUsage, kernelModeUsage, err := getCpuUsageBreakdown(path) - if err != nil { - return err - } - - totalUsage, err := getCgroupParamUint(path, "cpuacct.usage") - if err != nil { - return err - } - - percpuUsage, err := getPercpuUsage(path) - if err != nil { - return err - } - - stats.CpuStats.CpuUsage.TotalUsage = totalUsage - stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage - stats.CpuStats.CpuUsage.UsageInUsermode = userModeUsage - stats.CpuStats.CpuUsage.UsageInKernelmode = kernelModeUsage - return nil -} - -// Returns user and kernel usage breakdown in nanoseconds. -func getCpuUsageBreakdown(path string) (uint64, uint64, error) { - userModeUsage := uint64(0) - kernelModeUsage := uint64(0) - const ( - userField = "user" - systemField = "system" - ) - - // Expected format: - // user - // system - data, err := ioutil.ReadFile(filepath.Join(path, cgroupCpuacctStat)) - if err != nil { - return 0, 0, err - } - fields := strings.Fields(string(data)) - if len(fields) != 4 { - return 0, 0, fmt.Errorf("failure - %s is expected to have 4 fields", filepath.Join(path, cgroupCpuacctStat)) - } - if fields[0] != userField { - return 0, 0, fmt.Errorf("unexpected field %q in %q, expected %q", fields[0], cgroupCpuacctStat, userField) - } - if fields[2] != systemField { - return 0, 0, fmt.Errorf("unexpected field %q in %q, expected %q", fields[2], cgroupCpuacctStat, systemField) - } - if userModeUsage, err = strconv.ParseUint(fields[1], 10, 64); err != nil { - return 0, 0, err - } - if kernelModeUsage, err = strconv.ParseUint(fields[3], 10, 64); err != nil { - return 0, 0, err - } - - return (userModeUsage * nanosecondsInSecond) / clockTicks, (kernelModeUsage * nanosecondsInSecond) / clockTicks, nil -} - -func getPercpuUsage(path string) ([]uint64, error) { - percpuUsage := []uint64{} - data, err := ioutil.ReadFile(filepath.Join(path, "cpuacct.usage_percpu")) - if err != nil { - return percpuUsage, err - } - for _, value := range strings.Fields(string(data)) { - value, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return percpuUsage, fmt.Errorf("Unable to convert param value to uint64: %s", err) - } - percpuUsage = append(percpuUsage, value) - } - return percpuUsage, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go deleted file mode 100644 index ff67a53e87d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go +++ /dev/null @@ -1,122 +0,0 @@ -package fs - -import ( - "bytes" - "io/ioutil" - "os" - "path/filepath" - "strconv" - - "github.com/docker/libcontainer/cgroups" -) - -type CpusetGroup struct { -} - -func (s *CpusetGroup) Set(d *data) error { - dir, err := d.path("cpuset") - if err != nil { - return err - } - return s.SetDir(dir, d.c.CpusetCpus, d.c.CpusetMems, d.pid) -} - -func (s *CpusetGroup) Remove(d *data) error { - return removePath(d.path("cpuset")) -} - -func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} - -func (s *CpusetGroup) SetDir(dir, cpus string, mems string, pid int) error { - if err := s.ensureParent(dir); err != nil { - return err - } - - // because we are not using d.join we need to place the pid into the procs file - // unlike the other subsystems - if err := writeFile(dir, "cgroup.procs", strconv.Itoa(pid)); err != nil { - return err - } - - // If we don't use --cpuset-xxx, the default value inherit from parent cgroup - // is set in s.ensureParent, otherwise, use the value we set - if cpus != "" { - if err := writeFile(dir, "cpuset.cpus", cpus); err != nil { - return err - } - } - if mems != "" { - if err := writeFile(dir, "cpuset.mems", mems); err != nil { - return err - } - } - - return nil -} - -func (s *CpusetGroup) getSubsystemSettings(parent string) (cpus []byte, mems []byte, err error) { - if cpus, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.cpus")); err != nil { - return - } - if mems, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.mems")); err != nil { - return - } - return cpus, mems, nil -} - -// ensureParent ensures that the parent directory of current is created -// with the proper cpus and mems files copied from it's parent if the values -// are a file with a new line char -func (s *CpusetGroup) ensureParent(current string) error { - parent := filepath.Dir(current) - - if _, err := os.Stat(parent); err != nil { - if !os.IsNotExist(err) { - return err - } - - if err := s.ensureParent(parent); err != nil { - return err - } - } - - if err := os.MkdirAll(current, 0755); err != nil && !os.IsExist(err) { - return err - } - return s.copyIfNeeded(current, parent) -} - -// copyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent -// directory to the current directory if the file's contents are 0 -func (s *CpusetGroup) copyIfNeeded(current, parent string) error { - var ( - err error - currentCpus, currentMems []byte - parentCpus, parentMems []byte - ) - - if currentCpus, currentMems, err = s.getSubsystemSettings(current); err != nil { - return err - } - if parentCpus, parentMems, err = s.getSubsystemSettings(parent); err != nil { - return err - } - - if s.isEmpty(currentCpus) { - if err := writeFile(current, "cpuset.cpus", string(parentCpus)); err != nil { - return err - } - } - if s.isEmpty(currentMems) { - if err := writeFile(current, "cpuset.mems", string(parentMems)); err != nil { - return err - } - } - return nil -} - -func (s *CpusetGroup) isEmpty(b []byte) bool { - return len(bytes.Trim(b, "\n")) == 0 -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/devices.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/devices.go deleted file mode 100644 index 98d5d2d7dda..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/devices.go +++ /dev/null @@ -1,34 +0,0 @@ -package fs - -import "github.com/docker/libcontainer/cgroups" - -type DevicesGroup struct { -} - -func (s *DevicesGroup) Set(d *data) error { - dir, err := d.join("devices") - if err != nil { - return err - } - - if !d.c.AllowAllDevices { - if err := writeFile(dir, "devices.deny", "a"); err != nil { - return err - } - - for _, dev := range d.c.AllowedDevices { - if err := writeFile(dir, "devices.allow", dev.GetCgroupAllowString()); err != nil { - return err - } - } - } - return nil -} - -func (s *DevicesGroup) Remove(d *data) error { - return removePath(d.path("devices")) -} - -func (s *DevicesGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go deleted file mode 100644 index c6b677fa951..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/freezer.go +++ /dev/null @@ -1,50 +0,0 @@ -package fs - -import ( - "strings" - "time" - - "github.com/docker/libcontainer/cgroups" -) - -type FreezerGroup struct { -} - -func (s *FreezerGroup) Set(d *data) error { - switch d.c.Freezer { - case cgroups.Frozen, cgroups.Thawed: - dir, err := d.path("freezer") - if err != nil { - return err - } - - if err := writeFile(dir, "freezer.state", string(d.c.Freezer)); err != nil { - return err - } - - for { - state, err := readFile(dir, "freezer.state") - if err != nil { - return err - } - if strings.TrimSpace(state) == string(d.c.Freezer) { - break - } - time.Sleep(1 * time.Millisecond) - } - default: - if _, err := d.join("freezer"); err != nil && !cgroups.IsNotFound(err) { - return err - } - } - - return nil -} - -func (s *FreezerGroup) Remove(d *data) error { - return removePath(d.path("freezer")) -} - -func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory.go deleted file mode 100644 index 01713fd7906..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/memory.go +++ /dev/null @@ -1,98 +0,0 @@ -package fs - -import ( - "bufio" - "fmt" - "os" - "path/filepath" - "strconv" - - "github.com/docker/libcontainer/cgroups" -) - -type MemoryGroup struct { -} - -func (s *MemoryGroup) Set(d *data) error { - dir, err := d.join("memory") - // only return an error for memory if it was specified - if err != nil && (d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0) { - return err - } - defer func() { - if err != nil { - os.RemoveAll(dir) - } - }() - - // Only set values if some config was specified. - if d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0 { - if d.c.Memory != 0 { - if err := writeFile(dir, "memory.limit_in_bytes", strconv.FormatInt(d.c.Memory, 10)); err != nil { - return err - } - } - if d.c.MemoryReservation != 0 { - if err := writeFile(dir, "memory.soft_limit_in_bytes", strconv.FormatInt(d.c.MemoryReservation, 10)); err != nil { - return err - } - } - // By default, MemorySwap is set to twice the size of RAM. - // If you want to omit MemorySwap, set it to '-1'. - if d.c.MemorySwap == 0 { - if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(d.c.Memory*2, 10)); err != nil { - return err - } - } - if d.c.MemorySwap > 0 { - if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(d.c.MemorySwap, 10)); err != nil { - return err - } - } - } - return nil -} - -func (s *MemoryGroup) Remove(d *data) error { - return removePath(d.path("memory")) -} - -func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error { - // Set stats from memory.stat. - statsFile, err := os.Open(filepath.Join(path, "memory.stat")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer statsFile.Close() - - sc := bufio.NewScanner(statsFile) - for sc.Scan() { - t, v, err := getCgroupParamKeyValue(sc.Text()) - if err != nil { - return fmt.Errorf("failed to parse memory.stat (%q) - %v", sc.Text(), err) - } - stats.MemoryStats.Stats[t] = v - } - - // Set memory usage and max historical usage. - value, err := getCgroupParamUint(path, "memory.usage_in_bytes") - if err != nil { - return fmt.Errorf("failed to parse memory.usage_in_bytes - %v", err) - } - stats.MemoryStats.Usage = value - value, err = getCgroupParamUint(path, "memory.max_usage_in_bytes") - if err != nil { - return fmt.Errorf("failed to parse memory.max_usage_in_bytes - %v", err) - } - stats.MemoryStats.MaxUsage = value - value, err = getCgroupParamUint(path, "memory.failcnt") - if err != nil { - return fmt.Errorf("failed to parse memory.failcnt - %v", err) - } - stats.MemoryStats.Failcnt = value - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go deleted file mode 100644 index 813274d8cbf..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go +++ /dev/null @@ -1,24 +0,0 @@ -package fs - -import ( - "github.com/docker/libcontainer/cgroups" -) - -type PerfEventGroup struct { -} - -func (s *PerfEventGroup) Set(d *data) error { - // we just want to join this group even though we don't set anything - if _, err := d.join("perf_event"); err != nil && !cgroups.IsNotFound(err) { - return err - } - return nil -} - -func (s *PerfEventGroup) Remove(d *data) error { - return removePath(d.path("perf_event")) -} - -func (s *PerfEventGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils.go deleted file mode 100644 index f37a3a485a5..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/fs/utils.go +++ /dev/null @@ -1,62 +0,0 @@ -package fs - -import ( - "errors" - "fmt" - "io/ioutil" - "path/filepath" - "strconv" - "strings" -) - -var ( - ErrNotSupportStat = errors.New("stats are not supported for subsystem") - ErrNotValidFormat = errors.New("line is not a valid key value format") -) - -// Saturates negative values at zero and returns a uint64. -// Due to kernel bugs, some of the memory cgroup stats can be negative. -func parseUint(s string, base, bitSize int) (uint64, error) { - value, err := strconv.ParseUint(s, base, bitSize) - if err != nil { - intValue, intErr := strconv.ParseInt(s, base, bitSize) - // 1. Handle negative values greater than MinInt64 (and) - // 2. Handle negative values lesser than MinInt64 - if intErr == nil && intValue < 0 { - return 0, nil - } else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 { - return 0, nil - } - - return value, err - } - - return value, nil -} - -// Parses a cgroup param and returns as name, value -// i.e. "io_service_bytes 1234" will return as io_service_bytes, 1234 -func getCgroupParamKeyValue(t string) (string, uint64, error) { - parts := strings.Fields(t) - switch len(parts) { - case 2: - value, err := parseUint(parts[1], 10, 64) - if err != nil { - return "", 0, fmt.Errorf("Unable to convert param value (%q) to uint64: %v", parts[1], err) - } - - return parts[0], value, nil - default: - return "", 0, ErrNotValidFormat - } -} - -// Gets a single uint64 value from the specified cgroup file. -func getCgroupParamUint(cgroupPath, cgroupFile string) (uint64, error) { - contents, err := ioutil.ReadFile(filepath.Join(cgroupPath, cgroupFile)) - if err != nil { - return 0, err - } - - return parseUint(strings.TrimSpace(string(contents)), 10, 64) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/stats.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/stats.go deleted file mode 100644 index dc5dbb3c21b..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/stats.go +++ /dev/null @@ -1,73 +0,0 @@ -package cgroups - -type ThrottlingData struct { - // Number of periods with throttling active - Periods uint64 `json:"periods,omitempty"` - // Number of periods when the container hit its throttling limit. - ThrottledPeriods uint64 `json:"throttled_periods,omitempty"` - // Aggregate time the container was throttled for in nanoseconds. - ThrottledTime uint64 `json:"throttled_time,omitempty"` -} - -// All CPU stats are aggregate since container inception. -type CpuUsage struct { - // Total CPU time consumed. - // Units: nanoseconds. - TotalUsage uint64 `json:"total_usage,omitempty"` - // Total CPU time consumed per core. - // Units: nanoseconds. - PercpuUsage []uint64 `json:"percpu_usage,omitempty"` - // Time spent by tasks of the cgroup in kernel mode. - // Units: nanoseconds. - UsageInKernelmode uint64 `json:"usage_in_kernelmode"` - // Time spent by tasks of the cgroup in user mode. - // Units: nanoseconds. - UsageInUsermode uint64 `json:"usage_in_usermode"` -} - -type CpuStats struct { - CpuUsage CpuUsage `json:"cpu_usage,omitempty"` - ThrottlingData ThrottlingData `json:"throttling_data,omitempty"` -} - -type MemoryStats struct { - // current res_counter usage for memory - Usage uint64 `json:"usage,omitempty"` - // maximum usage ever recorded. - MaxUsage uint64 `json:"max_usage,omitempty"` - // TODO(vishh): Export these as stronger types. - // all the stats exported via memory.stat. - Stats map[string]uint64 `json:"stats,omitempty"` - // number of times memory usage hits limits. - Failcnt uint64 `json:"failcnt"` -} - -type BlkioStatEntry struct { - Major uint64 `json:"major,omitempty"` - Minor uint64 `json:"minor,omitempty"` - Op string `json:"op,omitempty"` - Value uint64 `json:"value,omitempty"` -} - -type BlkioStats struct { - // number of bytes tranferred to and from the block device - IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive,omitempty"` - IoServicedRecursive []BlkioStatEntry `json:"io_serviced_recursive,omitempty"` - IoQueuedRecursive []BlkioStatEntry `json:"io_queue_recursive,omitempty"` - IoServiceTimeRecursive []BlkioStatEntry `json:"io_service_time_recursive,omitempty"` - IoWaitTimeRecursive []BlkioStatEntry `json:"io_wait_time_recursive,omitempty"` - IoMergedRecursive []BlkioStatEntry `json:"io_merged_recursive,omitempty"` - IoTimeRecursive []BlkioStatEntry `json:"io_time_recursive,omitempty"` - SectorsRecursive []BlkioStatEntry `json:"sectors_recursive,omitempty"` -} - -type Stats struct { - CpuStats CpuStats `json:"cpu_stats,omitempty"` - MemoryStats MemoryStats `json:"memory_stats,omitempty"` - BlkioStats BlkioStats `json:"blkio_stats,omitempty"` -} - -func NewStats() *Stats { - memoryStats := MemoryStats{Stats: make(map[string]uint64)} - return &Stats{MemoryStats: memoryStats} -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go deleted file mode 100644 index a360904cce6..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/cgroups/utils.go +++ /dev/null @@ -1,223 +0,0 @@ -package cgroups - -import ( - "bufio" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/docker/docker/pkg/mount" -) - -// https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt -func FindCgroupMountpoint(subsystem string) (string, error) { - mounts, err := mount.GetMounts() - if err != nil { - return "", err - } - - for _, mount := range mounts { - if mount.Fstype == "cgroup" { - for _, opt := range strings.Split(mount.VfsOpts, ",") { - if opt == subsystem { - return mount.Mountpoint, nil - } - } - } - } - - return "", NewNotFoundError(subsystem) -} - -type Mount struct { - Mountpoint string - Subsystems []string -} - -func (m Mount) GetThisCgroupDir() (string, error) { - if len(m.Subsystems) == 0 { - return "", fmt.Errorf("no subsystem for mount") - } - - return GetThisCgroupDir(m.Subsystems[0]) -} - -func GetCgroupMounts() ([]Mount, error) { - mounts, err := mount.GetMounts() - if err != nil { - return nil, err - } - - all, err := GetAllSubsystems() - if err != nil { - return nil, err - } - - allMap := make(map[string]bool) - for _, s := range all { - allMap[s] = true - } - - res := []Mount{} - for _, mount := range mounts { - if mount.Fstype == "cgroup" { - m := Mount{Mountpoint: mount.Mountpoint} - - for _, opt := range strings.Split(mount.VfsOpts, ",") { - if strings.HasPrefix(opt, "name=") { - m.Subsystems = append(m.Subsystems, opt) - } - if allMap[opt] { - m.Subsystems = append(m.Subsystems, opt) - } - } - res = append(res, m) - } - } - return res, nil -} - -// Returns all the cgroup subsystems supported by the kernel -func GetAllSubsystems() ([]string, error) { - f, err := os.Open("/proc/cgroups") - if err != nil { - return nil, err - } - defer f.Close() - - subsystems := []string{} - - s := bufio.NewScanner(f) - for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - text := s.Text() - if text[0] != '#' { - parts := strings.Fields(text) - if len(parts) >= 4 && parts[3] != "0" { - subsystems = append(subsystems, parts[0]) - } - } - } - return subsystems, nil -} - -// Returns the relative path to the cgroup docker is running in. -func GetThisCgroupDir(subsystem string) (string, error) { - f, err := os.Open("/proc/self/cgroup") - if err != nil { - return "", err - } - defer f.Close() - - return ParseCgroupFile(subsystem, f) -} - -func GetInitCgroupDir(subsystem string) (string, error) { - f, err := os.Open("/proc/1/cgroup") - if err != nil { - return "", err - } - defer f.Close() - - return ParseCgroupFile(subsystem, f) -} - -func ReadProcsFile(dir string) ([]int, error) { - f, err := os.Open(filepath.Join(dir, "cgroup.procs")) - if err != nil { - return nil, err - } - defer f.Close() - - var ( - s = bufio.NewScanner(f) - out = []int{} - ) - - for s.Scan() { - if t := s.Text(); t != "" { - pid, err := strconv.Atoi(t) - if err != nil { - return nil, err - } - out = append(out, pid) - } - } - return out, nil -} - -func ParseCgroupFile(subsystem string, r io.Reader) (string, error) { - s := bufio.NewScanner(r) - - for s.Scan() { - if err := s.Err(); err != nil { - return "", err - } - - text := s.Text() - parts := strings.Split(text, ":") - - for _, subs := range strings.Split(parts[1], ",") { - if subs == subsystem { - return parts[2], nil - } - } - } - - return "", NewNotFoundError(subsystem) -} - -func PathExists(path string) bool { - if _, err := os.Stat(path); err != nil { - return false - } - return true -} - -func EnterPid(cgroupPaths map[string]string, pid int) error { - for _, path := range cgroupPaths { - if PathExists(path) { - if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), - []byte(strconv.Itoa(pid)), 0700); err != nil { - return err - } - } - } - return nil -} - -// RemovePaths iterates over the provided paths removing them. -// We trying to remove all paths five times with increasing delay between tries. -// If after all there are not removed cgroups - appropriate error will be -// returned. -func RemovePaths(paths map[string]string) (err error) { - delay := 10 * time.Millisecond - for i := 0; i < 5; i++ { - if i != 0 { - time.Sleep(delay) - delay *= 2 - } - for s, p := range paths { - os.RemoveAll(p) - // TODO: here probably should be logging - _, err := os.Stat(p) - // We need this strange way of checking cgroups existence because - // RemoveAll almost always returns error, even on already removed - // cgroups - if os.IsNotExist(err) { - delete(paths, s) - } - } - if len(paths) == 0 { - return nil - } - } - return fmt.Errorf("Failed to remove paths: %s", paths) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/config.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/config.go deleted file mode 100644 index 3ff4d3d0c42..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/config.go +++ /dev/null @@ -1,166 +0,0 @@ -package libcontainer - -import ( - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/mount" - "github.com/docker/libcontainer/network" -) - -type MountConfig mount.MountConfig - -type Network network.Network - -type NamespaceType string - -const ( - NEWNET NamespaceType = "NEWNET" - NEWPID NamespaceType = "NEWPID" - NEWNS NamespaceType = "NEWNS" - NEWUTS NamespaceType = "NEWUTS" - NEWIPC NamespaceType = "NEWIPC" - NEWUSER NamespaceType = "NEWUSER" -) - -// Namespace defines configuration for each namespace. It specifies an -// alternate path that is able to be joined via setns. -type Namespace struct { - Type NamespaceType `json:"type"` - Path string `json:"path,omitempty"` -} - -type Namespaces []Namespace - -func (n *Namespaces) Remove(t NamespaceType) bool { - i := n.index(t) - if i == -1 { - return false - } - *n = append((*n)[:i], (*n)[i+1:]...) - return true -} - -func (n *Namespaces) Add(t NamespaceType, path string) { - i := n.index(t) - if i == -1 { - *n = append(*n, Namespace{Type: t, Path: path}) - return - } - (*n)[i].Path = path -} - -func (n *Namespaces) index(t NamespaceType) int { - for i, ns := range *n { - if ns.Type == t { - return i - } - } - return -1 -} - -func (n *Namespaces) Contains(t NamespaceType) bool { - return n.index(t) != -1 -} - -// Config defines configuration options for executing a process inside a contained environment. -type Config struct { - // Mount specific options. - MountConfig *MountConfig `json:"mount_config,omitempty"` - - // Pathname to container's root filesystem - RootFs string `json:"root_fs,omitempty"` - - // Hostname optionally sets the container's hostname if provided - Hostname string `json:"hostname,omitempty"` - - // User will set the uid and gid of the executing process running inside the container - User string `json:"user,omitempty"` - - // WorkingDir will change the processes current working directory inside the container's rootfs - WorkingDir string `json:"working_dir,omitempty"` - - // Env will populate the processes environment with the provided values - // Any values from the parent processes will be cleared before the values - // provided in Env are provided to the process - Env []string `json:"environment,omitempty"` - - // Tty when true will allocate a pty slave on the host for access by the container's process - // and ensure that it is mounted inside the container's rootfs - Tty bool `json:"tty,omitempty"` - - // Namespaces specifies the container's namespaces that it should setup when cloning the init process - // If a namespace is not provided that namespace is shared from the container's parent process - Namespaces Namespaces `json:"namespaces,omitempty"` - - // Capabilities specify the capabilities to keep when executing the process inside the container - // All capbilities not specified will be dropped from the processes capability mask - Capabilities []string `json:"capabilities,omitempty"` - - // Networks specifies the container's network setup to be created - Networks []*Network `json:"networks,omitempty"` - - // Routes can be specified to create entries in the route table as the container is started - Routes []*Route `json:"routes,omitempty"` - - // Cgroups specifies specific cgroup settings for the various subsystems that the container is - // placed into to limit the resources the container has available - Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"` - - // AppArmorProfile specifies the profile to apply to the process running in the container and is - // change at the time the process is execed - AppArmorProfile string `json:"apparmor_profile,omitempty"` - - // ProcessLabel specifies the label to apply to the process running in the container. It is - // commonly used by selinux - ProcessLabel string `json:"process_label,omitempty"` - - // RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and - // /proc/bus - RestrictSys bool `json:"restrict_sys,omitempty"` - - // Rlimits specifies the resource limits, such as max open files, to set in the container - // If Rlimits are not set, the container will inherit rlimits from the parent process - Rlimits []Rlimit `json:"rlimits,omitempty"` - - // AdditionalGroups specifies the gids that should be added to supplementary groups - // in addition to those that the user belongs to. - AdditionalGroups []int `json:"additional_groups,omitempty"` - // UidMappings is an array of User ID mappings for User Namespaces - UidMappings []IDMap `json:"uid_mappings,omitempty"` - - // GidMappings is an array of Group ID mappings for User Namespaces - GidMappings []IDMap `json:"gid_mappings,omitempty"` -} - -// Routes can be specified to create entries in the route table as the container is started -// -// All of destination, source, and gateway should be either IPv4 or IPv6. -// One of the three options must be present, and ommitted entries will use their -// IP family default for the route table. For IPv4 for example, setting the -// gateway to 1.2.3.4 and the interface to eth0 will set up a standard -// destination of 0.0.0.0(or *) when viewed in the route table. -type Route struct { - // Sets the destination and mask, should be a CIDR. Accepts IPv4 and IPv6 - Destination string `json:"destination,omitempty"` - - // Sets the source and mask, should be a CIDR. Accepts IPv4 and IPv6 - Source string `json:"source,omitempty"` - - // Sets the gateway. Accepts IPv4 and IPv6 - Gateway string `json:"gateway,omitempty"` - - // The device to set this route up for, for example: eth0 - InterfaceName string `json:"interface_name,omitempty"` -} - -type Rlimit struct { - Type int `json:"type,omitempty"` - Hard uint64 `json:"hard,omitempty"` - Soft uint64 `json:"soft,omitempty"` -} - -// IDMap represents UID/GID Mappings for User Namespaces. -type IDMap struct { - ContainerID int `json:"container_id,omitempty"` - HostID int `json:"host_id,omitempty"` - Size int `json:"size,omitempty"` -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/config_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/config_test.go deleted file mode 100644 index f2287fc7414..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/config_test.go +++ /dev/null @@ -1,172 +0,0 @@ -package libcontainer - -import ( - "encoding/json" - "os" - "path/filepath" - "testing" - - "github.com/docker/libcontainer/devices" -) - -// Checks whether the expected capability is specified in the capabilities. -func contains(expected string, values []string) bool { - for _, v := range values { - if v == expected { - return true - } - } - return false -} - -func containsDevice(expected *devices.Device, values []*devices.Device) bool { - for _, d := range values { - if d.Path == expected.Path && - d.CgroupPermissions == expected.CgroupPermissions && - d.FileMode == expected.FileMode && - d.MajorNumber == expected.MajorNumber && - d.MinorNumber == expected.MinorNumber && - d.Type == expected.Type { - return true - } - } - return false -} - -func loadConfig(name string) (*Config, error) { - f, err := os.Open(filepath.Join("sample_configs", name)) - if err != nil { - return nil, err - } - defer f.Close() - - var container *Config - if err := json.NewDecoder(f).Decode(&container); err != nil { - return nil, err - } - - return container, nil -} - -func TestConfigJsonFormat(t *testing.T) { - container, err := loadConfig("attach_to_bridge.json") - if err != nil { - t.Fatal(err) - } - - if container.Hostname != "koye" { - t.Log("hostname is not set") - t.Fail() - } - - if !container.Tty { - t.Log("tty should be set to true") - t.Fail() - } - - if !container.Namespaces.Contains(NEWNET) { - t.Log("namespaces should contain NEWNET") - t.Fail() - } - - if container.Namespaces.Contains(NEWUSER) { - t.Log("namespaces should not contain NEWUSER") - t.Fail() - } - - if contains("SYS_ADMIN", container.Capabilities) { - t.Log("SYS_ADMIN should not be enabled in capabilities mask") - t.Fail() - } - - if !contains("MKNOD", container.Capabilities) { - t.Log("MKNOD should be enabled in capabilities mask") - t.Fail() - } - - if !contains("SYS_CHROOT", container.Capabilities) { - t.Log("capabilities mask should contain SYS_CHROOT") - t.Fail() - } - - for _, n := range container.Networks { - if n.Type == "veth" { - if n.Bridge != "docker0" { - t.Logf("veth bridge should be docker0 but received %q", n.Bridge) - t.Fail() - } - - if n.Address != "172.17.0.101/16" { - t.Logf("veth address should be 172.17.0.101/61 but received %q", n.Address) - t.Fail() - } - - if n.VethPrefix != "veth" { - t.Logf("veth prefix should be veth but received %q", n.VethPrefix) - t.Fail() - } - - if n.Gateway != "172.17.42.1" { - t.Logf("veth gateway should be 172.17.42.1 but received %q", n.Gateway) - t.Fail() - } - - if n.Mtu != 1500 { - t.Logf("veth mtu should be 1500 but received %d", n.Mtu) - t.Fail() - } - - break - } - } - - for _, d := range devices.DefaultSimpleDevices { - if !containsDevice(d, container.MountConfig.DeviceNodes) { - t.Logf("expected device configuration for %s", d.Path) - t.Fail() - } - } - - if !container.RestrictSys { - t.Log("expected restrict sys to be true") - t.Fail() - } -} - -func TestApparmorProfile(t *testing.T) { - container, err := loadConfig("apparmor.json") - if err != nil { - t.Fatal(err) - } - - if container.AppArmorProfile != "docker-default" { - t.Fatalf("expected apparmor profile to be docker-default but received %q", container.AppArmorProfile) - } -} - -func TestSelinuxLabels(t *testing.T) { - container, err := loadConfig("selinux.json") - if err != nil { - t.Fatal(err) - } - label := "system_u:system_r:svirt_lxc_net_t:s0:c164,c475" - - if container.ProcessLabel != label { - t.Fatalf("expected process label %q but received %q", label, container.ProcessLabel) - } - if container.MountConfig.MountLabel != label { - t.Fatalf("expected mount label %q but received %q", label, container.MountConfig.MountLabel) - } -} - -func TestRemoveNamespace(t *testing.T) { - ns := Namespaces{ - {Type: NEWNET}, - } - if !ns.Remove(NEWNET) { - t.Fatal("NEWNET was not removed") - } - if len(ns) != 0 { - t.Fatalf("namespaces should have 0 items but reports %d", len(ns)) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/console/console.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/console/console.go deleted file mode 100644 index 69af70c19d4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/console/console.go +++ /dev/null @@ -1,128 +0,0 @@ -// +build linux - -package console - -import ( - "fmt" - "os" - "path/filepath" - "syscall" - "unsafe" - - "github.com/docker/libcontainer/label" -) - -// Setup initializes the proper /dev/console inside the rootfs path -func Setup(rootfs, consolePath, mountLabel string, hostRootUid, hostRootGid int) error { - oldMask := syscall.Umask(0000) - defer syscall.Umask(oldMask) - - if err := os.Chmod(consolePath, 0600); err != nil { - return err - } - - if err := os.Chown(consolePath, hostRootUid, hostRootGid); err != nil { - return err - } - - if err := label.SetFileLabel(consolePath, mountLabel); err != nil { - return fmt.Errorf("set file label %s %s", consolePath, err) - } - - dest := filepath.Join(rootfs, "dev/console") - - f, err := os.Create(dest) - if err != nil && !os.IsExist(err) { - return fmt.Errorf("create %s %s", dest, err) - } - - if f != nil { - f.Close() - } - - if err := syscall.Mount(consolePath, dest, "bind", syscall.MS_BIND, ""); err != nil { - return fmt.Errorf("bind %s to %s %s", consolePath, dest, err) - } - - return nil -} - -func OpenAndDup(consolePath string) error { - slave, err := OpenTerminal(consolePath, syscall.O_RDWR) - if err != nil { - return fmt.Errorf("open terminal %s", err) - } - - if err := syscall.Dup2(int(slave.Fd()), 0); err != nil { - return err - } - - if err := syscall.Dup2(int(slave.Fd()), 1); err != nil { - return err - } - - return syscall.Dup2(int(slave.Fd()), 2) -} - -// Unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// Unlockpt should be called before opening the slave side of a pseudoterminal. -func Unlockpt(f *os.File) error { - var u int32 - - return Ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) -} - -// Ptsname retrieves the name of the first available pts for the given master. -func Ptsname(f *os.File) (string, error) { - var n int32 - - if err := Ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil { - return "", err - } - - return fmt.Sprintf("/dev/pts/%d", n), nil -} - -// CreateMasterAndConsole will open /dev/ptmx on the host and retreive the -// pts name for use as the pty slave inside the container -func CreateMasterAndConsole() (*os.File, string, error) { - master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, "", err - } - - console, err := Ptsname(master) - if err != nil { - return nil, "", err - } - - if err := Unlockpt(master); err != nil { - return nil, "", err - } - - return master, console, nil -} - -// OpenPtmx opens /dev/ptmx, i.e. the PTY master. -func OpenPtmx() (*os.File, error) { - // O_NOCTTY and O_CLOEXEC are not present in os package so we use the syscall's one for all. - return os.OpenFile("/dev/ptmx", syscall.O_RDONLY|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0) -} - -// OpenTerminal is a clone of os.OpenFile without the O_CLOEXEC -// used to open the pty slave inside the container namespace -func OpenTerminal(name string, flag int) (*os.File, error) { - r, e := syscall.Open(name, flag, 0) - if e != nil { - return nil, &os.PathError{Op: "open", Path: name, Err: e} - } - return os.NewFile(uintptr(r), name), nil -} - -func Ioctl(fd uintptr, flag, data uintptr) error { - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 { - return err - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/container.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/container.go deleted file mode 100644 index 307e8cbcbb1..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/container.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -NOTE: The API is in flux and mainly not implemented. Proceed with caution until further notice. -*/ -package libcontainer - -// A libcontainer container object. -// -// Each container is thread-safe within the same process. Since a container can -// be destroyed by a separate process, any function may return that the container -// was not found. -type Container interface { - // Returns the ID of the container - ID() string - - // Returns the current run state of the container. - // - // Errors: - // ContainerDestroyed - Container no longer exists, - // SystemError - System error. - RunState() (*RunState, Error) - - // Returns the current config of the container. - Config() *Config - - // Start a process inside the container. Returns the PID of the new process (in the caller process's namespace) and a channel that will return the exit status of the process whenever it dies. - // - // Errors: - // ContainerDestroyed - Container no longer exists, - // ConfigInvalid - config is invalid, - // ContainerPaused - Container is paused, - // SystemError - System error. - Start(config *ProcessConfig) (pid int, exitChan chan int, err Error) - - // Destroys the container after killing all running processes. - // - // Any event registrations are removed before the container is destroyed. - // No error is returned if the container is already destroyed. - // - // Errors: - // SystemError - System error. - Destroy() Error - - // Returns the PIDs inside this container. The PIDs are in the namespace of the calling process. - // - // Errors: - // ContainerDestroyed - Container no longer exists, - // SystemError - System error. - // - // Some of the returned PIDs may no longer refer to processes in the Container, unless - // the Container state is PAUSED in which case every PID in the slice is valid. - Processes() ([]int, Error) - - // Returns statistics for the container. - // - // Errors: - // ContainerDestroyed - Container no longer exists, - // SystemError - System error. - Stats() (*ContainerStats, Error) - - // If the Container state is RUNNING or PAUSING, sets the Container state to PAUSING and pauses - // the execution of any user processes. Asynchronously, when the container finished being paused the - // state is changed to PAUSED. - // If the Container state is PAUSED, do nothing. - // - // Errors: - // ContainerDestroyed - Container no longer exists, - // SystemError - System error. - Pause() Error - - // If the Container state is PAUSED, resumes the execution of any user processes in the - // Container before setting the Container state to RUNNING. - // If the Container state is RUNNING, do nothing. - // - // Errors: - // ContainerDestroyed - Container no longer exists, - // SystemError - System error. - Resume() Error -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/defaults.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/defaults.go deleted file mode 100644 index e0ad0b08f86..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/defaults.go +++ /dev/null @@ -1,159 +0,0 @@ -package devices - -var ( - // These are devices that are to be both allowed and created. - - DefaultSimpleDevices = []*Device{ - // /dev/null and zero - { - Path: "/dev/null", - Type: 'c', - MajorNumber: 1, - MinorNumber: 3, - CgroupPermissions: "rwm", - FileMode: 0666, - }, - { - Path: "/dev/zero", - Type: 'c', - MajorNumber: 1, - MinorNumber: 5, - CgroupPermissions: "rwm", - FileMode: 0666, - }, - - { - Path: "/dev/full", - Type: 'c', - MajorNumber: 1, - MinorNumber: 7, - CgroupPermissions: "rwm", - FileMode: 0666, - }, - - // consoles and ttys - { - Path: "/dev/tty", - Type: 'c', - MajorNumber: 5, - MinorNumber: 0, - CgroupPermissions: "rwm", - FileMode: 0666, - }, - - // /dev/urandom,/dev/random - { - Path: "/dev/urandom", - Type: 'c', - MajorNumber: 1, - MinorNumber: 9, - CgroupPermissions: "rwm", - FileMode: 0666, - }, - { - Path: "/dev/random", - Type: 'c', - MajorNumber: 1, - MinorNumber: 8, - CgroupPermissions: "rwm", - FileMode: 0666, - }, - } - - DefaultAllowedDevices = append([]*Device{ - // allow mknod for any device - { - Type: 'c', - MajorNumber: Wildcard, - MinorNumber: Wildcard, - CgroupPermissions: "m", - }, - { - Type: 'b', - MajorNumber: Wildcard, - MinorNumber: Wildcard, - CgroupPermissions: "m", - }, - - { - Path: "/dev/console", - Type: 'c', - MajorNumber: 5, - MinorNumber: 1, - CgroupPermissions: "rwm", - }, - { - Path: "/dev/tty0", - Type: 'c', - MajorNumber: 4, - MinorNumber: 0, - CgroupPermissions: "rwm", - }, - { - Path: "/dev/tty1", - Type: 'c', - MajorNumber: 4, - MinorNumber: 1, - CgroupPermissions: "rwm", - }, - // /dev/pts/ - pts namespaces are "coming soon" - { - Path: "", - Type: 'c', - MajorNumber: 136, - MinorNumber: Wildcard, - CgroupPermissions: "rwm", - }, - { - Path: "", - Type: 'c', - MajorNumber: 5, - MinorNumber: 2, - CgroupPermissions: "rwm", - }, - - // tuntap - { - Path: "", - Type: 'c', - MajorNumber: 10, - MinorNumber: 200, - CgroupPermissions: "rwm", - }, - - /*// fuse - { - Path: "", - Type: 'c', - MajorNumber: 10, - MinorNumber: 229, - CgroupPermissions: "rwm", - }, - - // rtc - { - Path: "", - Type: 'c', - MajorNumber: 254, - MinorNumber: 0, - CgroupPermissions: "rwm", - }, - */ - }, DefaultSimpleDevices...) - - DefaultAutoCreatedDevices = append([]*Device{ - { - // /dev/fuse is created but not allowed. - // This is to allow java to work. Because java - // Insists on there being a /dev/fuse - // https://github.com/docker/docker/issues/514 - // https://github.com/docker/docker/issues/2393 - // - Path: "/dev/fuse", - Type: 'c', - MajorNumber: 10, - MinorNumber: 229, - CgroupPermissions: "rwm", - }, - }, DefaultSimpleDevices...) -) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/devices.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/devices.go deleted file mode 100644 index 8e86d952929..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/devices.go +++ /dev/null @@ -1,132 +0,0 @@ -package devices - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" -) - -const ( - Wildcard = -1 -) - -var ( - ErrNotADeviceNode = errors.New("not a device node") -) - -// Testing dependencies -var ( - osLstat = os.Lstat - ioutilReadDir = ioutil.ReadDir -) - -type Device struct { - Type rune `json:"type,omitempty"` - Path string `json:"path,omitempty"` // It is fine if this is an empty string in the case that you are using Wildcards - MajorNumber int64 `json:"major_number,omitempty"` // Use the wildcard constant for wildcards. - MinorNumber int64 `json:"minor_number,omitempty"` // Use the wildcard constant for wildcards. - CgroupPermissions string `json:"cgroup_permissions,omitempty"` // Typically just "rwm" - FileMode os.FileMode `json:"file_mode,omitempty"` // The permission bits of the file's mode - Uid uint32 `json:"uid,omitempty"` - Gid uint32 `json:"gid,omitempty"` -} - -func GetDeviceNumberString(deviceNumber int64) string { - if deviceNumber == Wildcard { - return "*" - } else { - return fmt.Sprintf("%d", deviceNumber) - } -} - -func (device *Device) GetCgroupAllowString() string { - return fmt.Sprintf("%c %s:%s %s", device.Type, GetDeviceNumberString(device.MajorNumber), GetDeviceNumberString(device.MinorNumber), device.CgroupPermissions) -} - -// Given the path to a device and it's cgroup_permissions(which cannot be easilly queried) look up the information about a linux device and return that information as a Device struct. -func GetDevice(path, cgroupPermissions string) (*Device, error) { - fileInfo, err := osLstat(path) - if err != nil { - return nil, err - } - - var ( - devType rune - mode = fileInfo.Mode() - fileModePermissionBits = os.FileMode.Perm(mode) - ) - - switch { - case mode&os.ModeDevice == 0: - return nil, ErrNotADeviceNode - case mode&os.ModeCharDevice != 0: - fileModePermissionBits |= syscall.S_IFCHR - devType = 'c' - default: - fileModePermissionBits |= syscall.S_IFBLK - devType = 'b' - } - - stat_t, ok := fileInfo.Sys().(*syscall.Stat_t) - if !ok { - return nil, fmt.Errorf("cannot determine the device number for device %s", path) - } - devNumber := int(stat_t.Rdev) - - return &Device{ - Type: devType, - Path: path, - MajorNumber: Major(devNumber), - MinorNumber: Minor(devNumber), - CgroupPermissions: cgroupPermissions, - FileMode: fileModePermissionBits, - Uid: stat_t.Uid, - Gid: stat_t.Gid, - }, nil -} - -func GetHostDeviceNodes() ([]*Device, error) { - return getDeviceNodes("/dev") -} - -func getDeviceNodes(path string) ([]*Device, error) { - files, err := ioutilReadDir(path) - if err != nil { - return nil, err - } - - out := []*Device{} - for _, f := range files { - switch { - case f.IsDir(): - switch f.Name() { - case "pts", "shm", "fd", "mqueue": - continue - default: - sub, err := getDeviceNodes(filepath.Join(path, f.Name())) - if err != nil { - return nil, err - } - - out = append(out, sub...) - continue - } - case f.Name() == "console": - continue - } - - device, err := GetDevice(filepath.Join(path, f.Name()), "rwm") - if err != nil { - if err == ErrNotADeviceNode { - continue - } - return nil, err - } - out = append(out, device) - } - - return out, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/number.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/number.go deleted file mode 100644 index 3aae380bb1c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/devices/number.go +++ /dev/null @@ -1,26 +0,0 @@ -package devices - -/* - -This code provides support for manipulating linux device numbers. It should be replaced by normal syscall functions once http://code.google.com/p/go/issues/detail?id=8106 is solved. - -You can read what they are here: - - - http://www.makelinux.net/ldd3/chp-3-sect-2 - - http://www.linux-tutorial.info/modules.php?name=MContent&pageid=94 - -Note! These are NOT the same as the MAJOR(dev_t device);, MINOR(dev_t device); and MKDEV(int major, int minor); functions as defined in as the representation of device numbers used by go is different than the one used internally to the kernel! - https://github.com/torvalds/linux/blob/master/include/linux/kdev_t.h#L9 - -*/ - -func Major(devNumber int) int64 { - return int64((devNumber >> 8) & 0xfff) -} - -func Minor(devNumber int) int64 { - return int64((devNumber & 0xff) | ((devNumber >> 12) & 0xfff00)) -} - -func Mkdev(majorNumber int64, minorNumber int64) int { - return int((majorNumber << 8) | (minorNumber & 0xff) | ((minorNumber & 0xfff00) << 12)) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/docs/man/nsinit.1.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/docs/man/nsinit.1.md deleted file mode 100644 index 898dba23068..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/docs/man/nsinit.1.md +++ /dev/null @@ -1,38 +0,0 @@ -% nsinit User Manual -% docker/libcontainer -% JAN 2015 - -NAME: - nsinit - A low-level utility for managing containers. - It is used to spawn new containers or join existing containers. - -USAGE: - nsinit [global options] command [command options] [arguments...] - -VERSION: - 0.1 - -COMMANDS: - config display the container configuration - exec execute a new command inside a container - init runs the init process inside the namespace - oom display oom notifications for a container - pause pause the container's processes - stats display statistics for the container - unpause unpause the container's processes - help, h shows a list of commands or help for one command - -EXAMPLES: - -Get the of an already running docker container. -`sudo docker ps` will return the list of all the running containers. - -take the (e.g. 4addb0b2d307) and go to its config directory -`/var/lib/docker/execdriver/native/4addb0b2d307` and here you can run the nsinit -command line utility. - -e.g. `nsinit exec /bin/bash` will start a shell on the already running container. - -# HISTORY -Jan 2015, Originally compiled by Shishir Mahajan (shishir dot mahajan at redhat dot com) -based on nsinit source material and internal work. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/error.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/error.go deleted file mode 100644 index 5ff56d80baa..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/error.go +++ /dev/null @@ -1,37 +0,0 @@ -package libcontainer - -// API error code type. -type ErrorCode int - -// API error codes. -const ( - // Factory errors - IdInUse ErrorCode = iota - InvalidIdFormat - // TODO: add Load errors - - // Container errors - ContainerDestroyed - ContainerPaused - - // Common errors - ConfigInvalid - SystemError -) - -// API Error type. -type Error interface { - error - - // Returns the stack trace, if any, which identifies the - // point at which the error occurred. - Stack() []byte - - // Returns a verbose string including the error message - // and a representation of the stack trace suitable for - // printing. - Detail() string - - // Returns the error code for this error. - Code() ErrorCode -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go deleted file mode 100644 index e37773b2bd7..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/factory.go +++ /dev/null @@ -1,32 +0,0 @@ -package libcontainer - -type Factory interface { - - // Creates a new container with the given id and starts the initial process inside it. - // id must be a string containing only letters, digits and underscores and must contain - // between 1 and 1024 characters, inclusive. - // - // The id must not already be in use by an existing container. Containers created using - // a factory with the same path (and file system) must have distinct ids. - // - // Returns the new container with a running process. - // - // Errors: - // IdInUse - id is already in use by a container - // InvalidIdFormat - id has incorrect format - // ConfigInvalid - config is invalid - // SystemError - System error - // - // On error, any partially created container parts are cleaned up (the operation is atomic). - Create(id string, config *Config) (Container, Error) - - // Load takes an ID for an existing container and reconstructs the container - // from the state. - // - // Errors: - // Path does not exist - // Container is stopped - // System error - // TODO: fix description - Load(id string) (Container, Error) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/doc.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/doc.go deleted file mode 100644 index 87545bc99c3..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// integration is used for integration testing of libcontainer -package integration diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/exec_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/exec_test.go deleted file mode 100644 index fb1d1d7a103..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/exec_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package integration - -import ( - "os" - "strings" - "testing" - - "github.com/docker/libcontainer" -) - -func TestExecPS(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - config := newTemplateConfig(rootfs) - buffers, exitCode, err := runContainer(config, "", "ps") - if err != nil { - t.Fatal(err) - } - - if exitCode != 0 { - t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) - } - - lines := strings.Split(buffers.Stdout.String(), "\n") - if len(lines) < 2 { - t.Fatalf("more than one process running for output %q", buffers.Stdout.String()) - } - expected := `1 root ps` - actual := strings.Trim(lines[1], "\n ") - if actual != expected { - t.Fatalf("expected output %q but received %q", expected, actual) - } -} - -func TestIPCPrivate(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - l, err := os.Readlink("/proc/1/ns/ipc") - if err != nil { - t.Fatal(err) - } - - config := newTemplateConfig(rootfs) - buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc") - if err != nil { - t.Fatal(err) - } - - if exitCode != 0 { - t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) - } - - if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual == l { - t.Fatalf("ipc link should be private to the container but equals host %q %q", actual, l) - } -} - -func TestIPCHost(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - l, err := os.Readlink("/proc/1/ns/ipc") - if err != nil { - t.Fatal(err) - } - - config := newTemplateConfig(rootfs) - config.Namespaces.Remove(libcontainer.NEWIPC) - buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc") - if err != nil { - t.Fatal(err) - } - - if exitCode != 0 { - t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) - } - - if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l { - t.Fatalf("ipc link not equal to host link %q %q", actual, l) - } -} - -func TestIPCJoinPath(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - l, err := os.Readlink("/proc/1/ns/ipc") - if err != nil { - t.Fatal(err) - } - - config := newTemplateConfig(rootfs) - config.Namespaces.Add(libcontainer.NEWIPC, "/proc/1/ns/ipc") - - buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc") - if err != nil { - t.Fatal(err) - } - - if exitCode != 0 { - t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) - } - - if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l { - t.Fatalf("ipc link not equal to host link %q %q", actual, l) - } -} - -func TestIPCBadPath(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - config := newTemplateConfig(rootfs) - config.Namespaces.Add(libcontainer.NEWIPC, "/proc/1/ns/ipcc") - - _, _, err = runContainer(config, "", "true") - if err == nil { - t.Fatal("container succeeded with bad ipc path") - } -} - -func TestRlimit(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - config := newTemplateConfig(rootfs) - out, _, err := runContainer(config, "", "/bin/sh", "-c", "ulimit -n") - if err != nil { - t.Fatal(err) - } - if limit := strings.TrimSpace(out.Stdout.String()); limit != "1024" { - t.Fatalf("expected rlimit to be 1024, got %s", limit) - } -} - -func TestPIDNSPrivate(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - l, err := os.Readlink("/proc/1/ns/pid") - if err != nil { - t.Fatal(err) - } - - config := newTemplateConfig(rootfs) - buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/pid") - if err != nil { - t.Fatal(err) - } - - if exitCode != 0 { - t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) - } - - if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual == l { - t.Fatalf("pid link should be private to the container but equals host %q %q", actual, l) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/execin_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/execin_test.go deleted file mode 100644 index ce92eff779d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/execin_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package integration - -import ( - "os" - "os/exec" - "strings" - "sync" - "testing" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/namespaces" -) - -func TestExecIn(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - config := newTemplateConfig(rootfs) - if err := writeConfig(config); err != nil { - t.Fatalf("failed to write config %s", err) - } - - containerCmd, statePath, containerErr := startLongRunningContainer(config) - defer func() { - // kill the container - if containerCmd.Process != nil { - containerCmd.Process.Kill() - } - if err := <-containerErr; err != nil { - t.Fatal(err) - } - }() - - // start the exec process - state, err := libcontainer.GetState(statePath) - if err != nil { - t.Fatalf("failed to get state %s", err) - } - buffers := newStdBuffers() - execErr := make(chan error, 1) - go func() { - _, err := namespaces.ExecIn(config, state, []string{"ps"}, - os.Args[0], "exec", buffers.Stdin, buffers.Stdout, buffers.Stderr, - "", nil) - execErr <- err - }() - if err := <-execErr; err != nil { - t.Fatalf("exec finished with error %s", err) - } - - out := buffers.Stdout.String() - if !strings.Contains(out, "sleep 10") || !strings.Contains(out, "ps") { - t.Fatalf("unexpected running process, output %q", out) - } -} - -func TestExecInRlimit(t *testing.T) { - if testing.Short() { - return - } - - rootfs, err := newRootFs() - if err != nil { - t.Fatal(err) - } - defer remove(rootfs) - - config := newTemplateConfig(rootfs) - if err := writeConfig(config); err != nil { - t.Fatalf("failed to write config %s", err) - } - - containerCmd, statePath, containerErr := startLongRunningContainer(config) - defer func() { - // kill the container - if containerCmd.Process != nil { - containerCmd.Process.Kill() - } - if err := <-containerErr; err != nil { - t.Fatal(err) - } - }() - - // start the exec process - state, err := libcontainer.GetState(statePath) - if err != nil { - t.Fatalf("failed to get state %s", err) - } - buffers := newStdBuffers() - execErr := make(chan error, 1) - go func() { - _, err := namespaces.ExecIn(config, state, []string{"/bin/sh", "-c", "ulimit -n"}, - os.Args[0], "exec", buffers.Stdin, buffers.Stdout, buffers.Stderr, - "", nil) - execErr <- err - }() - if err := <-execErr; err != nil { - t.Fatalf("exec finished with error %s", err) - } - - out := buffers.Stdout.String() - if limit := strings.TrimSpace(out); limit != "1024" { - t.Fatalf("expected rlimit to be 1024, got %s", limit) - } -} - -// start a long-running container so we have time to inspect execin processes -func startLongRunningContainer(config *libcontainer.Config) (*exec.Cmd, string, chan error) { - containerErr := make(chan error, 1) - containerCmd := &exec.Cmd{} - setupContainerCmd := &exec.Cmd{} - var statePath string - - createCmd := func(container *libcontainer.Config, console, dataPath, init string, - pipe *os.File, args []string) *exec.Cmd { - containerCmd = namespaces.DefaultCreateCommand(container, console, dataPath, init, pipe, args) - statePath = dataPath - return containerCmd - } - - setupCmd := func(container *libcontainer.Config, console, dataPath, init string) *exec.Cmd { - setupContainerCmd = namespaces.DefaultSetupCommand(container, console, dataPath, init) - statePath = dataPath - return setupContainerCmd - } - - var containerStart sync.WaitGroup - containerStart.Add(1) - go func() { - buffers := newStdBuffers() - _, err := namespaces.Exec(config, - buffers.Stdin, buffers.Stdout, buffers.Stderr, - "", config.RootFs, []string{"sleep", "10"}, - createCmd, setupCmd, containerStart.Done) - containerErr <- err - }() - containerStart.Wait() - - return containerCmd, statePath, containerErr -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/init_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/init_test.go deleted file mode 100644 index 3106a5fb1e7..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/init_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package integration - -import ( - "encoding/json" - "log" - "os" - "runtime" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/namespaces" - _ "github.com/docker/libcontainer/namespaces/nsenter" -) - -// init runs the libcontainer initialization code because of the busybox style needs -// to work around the go runtime and the issues with forking -func init() { - if len(os.Args) < 2 { - return - } - // handle init - if len(os.Args) >= 2 && os.Args[1] == "init" { - runtime.LockOSThread() - - container, err := loadConfig() - if err != nil { - log.Fatal(err) - } - - rootfs, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - - if err := namespaces.Init(container, rootfs, "", os.NewFile(3, "pipe"), os.Args[3:]); err != nil { - log.Fatalf("unable to initialize for container: %s", err) - } - os.Exit(1) - } - - // handle execin - if len(os.Args) >= 2 && os.Args[0] == "nsenter-exec" { - runtime.LockOSThread() - - // User args are passed after '--' in the command line. - userArgs := findUserArgs() - - config, err := loadConfigFromFd() - if err != nil { - log.Fatalf("docker-exec: unable to receive config from sync pipe: %s", err) - } - - if err := namespaces.FinalizeSetns(config, userArgs); err != nil { - log.Fatalf("docker-exec: failed to exec: %s", err) - } - os.Exit(1) - } -} - -func findUserArgs() []string { - for i, a := range os.Args { - if a == "--" { - return os.Args[i+1:] - } - } - return []string{} -} - -// loadConfigFromFd loads a container's config from the sync pipe that is provided by -// fd 3 when running a process -func loadConfigFromFd() (*libcontainer.Config, error) { - var config *libcontainer.Config - if err := json.NewDecoder(os.NewFile(3, "child")).Decode(&config); err != nil { - return nil, err - } - return config, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/template_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/template_test.go deleted file mode 100644 index 98846eb199b..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/template_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package integration - -import ( - "syscall" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/devices" -) - -// newTemplateConfig returns a base template for running a container -// -// it uses a network strategy of just setting a loopback interface -// and the default setup for devices -func newTemplateConfig(rootfs string) *libcontainer.Config { - return &libcontainer.Config{ - RootFs: rootfs, - Tty: false, - Capabilities: []string{ - "CHOWN", - "DAC_OVERRIDE", - "FSETID", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL", - "AUDIT_WRITE", - }, - Namespaces: libcontainer.Namespaces([]libcontainer.Namespace{ - {Type: libcontainer.NEWNS}, - {Type: libcontainer.NEWUTS}, - {Type: libcontainer.NEWIPC}, - {Type: libcontainer.NEWPID}, - {Type: libcontainer.NEWNET}, - }), - Cgroups: &cgroups.Cgroup{ - Parent: "integration", - AllowAllDevices: false, - AllowedDevices: devices.DefaultAllowedDevices, - }, - - MountConfig: &libcontainer.MountConfig{ - DeviceNodes: devices.DefaultAutoCreatedDevices, - }, - Hostname: "integration", - Env: []string{ - "HOME=/root", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=integration", - "TERM=xterm", - }, - Networks: []*libcontainer.Network{ - { - Type: "loopback", - Address: "127.0.0.1/0", - Gateway: "localhost", - }, - }, - Rlimits: []libcontainer.Rlimit{ - { - Type: syscall.RLIMIT_NOFILE, - Hard: uint64(1024), - Soft: uint64(1024), - }, - }, - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/utils_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/utils_test.go deleted file mode 100644 index cf14b61854a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/integration/utils_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package integration - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/namespaces" -) - -func newStdBuffers() *stdBuffers { - return &stdBuffers{ - Stdin: bytes.NewBuffer(nil), - Stdout: bytes.NewBuffer(nil), - Stderr: bytes.NewBuffer(nil), - } -} - -type stdBuffers struct { - Stdin *bytes.Buffer - Stdout *bytes.Buffer - Stderr *bytes.Buffer -} - -func writeConfig(config *libcontainer.Config) error { - f, err := os.OpenFile(filepath.Join(config.RootFs, "container.json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0700) - if err != nil { - return err - } - defer f.Close() - return json.NewEncoder(f).Encode(config) -} - -func loadConfig() (*libcontainer.Config, error) { - f, err := os.Open(filepath.Join(os.Getenv("data_path"), "container.json")) - if err != nil { - return nil, err - } - defer f.Close() - - var container *libcontainer.Config - if err := json.NewDecoder(f).Decode(&container); err != nil { - return nil, err - } - return container, nil -} - -// newRootFs creates a new tmp directory and copies the busybox root filesystem -func newRootFs() (string, error) { - dir, err := ioutil.TempDir("", "") - if err != nil { - return "", err - } - if err := os.MkdirAll(dir, 0700); err != nil { - return "", err - } - if err := copyBusybox(dir); err != nil { - return "", nil - } - return dir, nil -} - -func remove(dir string) { - os.RemoveAll(dir) -} - -// copyBusybox copies the rootfs for a busybox container created for the test image -// into the new directory for the specific test -func copyBusybox(dest string) error { - out, err := exec.Command("sh", "-c", fmt.Sprintf("cp -R /busybox/* %s/", dest)).CombinedOutput() - if err != nil { - return fmt.Errorf("copy error %q: %q", err, out) - } - return nil -} - -// runContainer runs the container with the specific config and arguments -// -// buffers are returned containing the STDOUT and STDERR output for the run -// along with the exit code and any go error -func runContainer(config *libcontainer.Config, console string, args ...string) (buffers *stdBuffers, exitCode int, err error) { - if err := writeConfig(config); err != nil { - return nil, -1, err - } - - buffers = newStdBuffers() - exitCode, err = namespaces.Exec(config, buffers.Stdin, buffers.Stdout, buffers.Stderr, - console, config.RootFs, args, namespaces.DefaultCreateCommand, namespaces.DefaultSetupCommand, nil) - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go deleted file mode 100644 index 5a540fd5a02..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/label/label.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build !selinux !linux - -package label - -// InitLabels returns the process label and file labels to be used within -// the container. A list of options can be passed into this function to alter -// the labels. -func InitLabels(options []string) (string, string, error) { - return "", "", nil -} - -func GenLabels(options string) (string, string, error) { - return "", "", nil -} - -func FormatMountLabel(src string, mountLabel string) string { - return src -} - -func SetProcessLabel(processLabel string) error { - return nil -} - -func SetFileLabel(path string, fileLabel string) error { - return nil -} - -func SetFileCreateLabel(fileLabel string) error { - return nil -} - -func Relabel(path string, fileLabel string, relabel string) error { - return nil -} - -func GetPidLabel(pid int) (string, error) { - return "", nil -} - -func Init() { -} - -func ReserveLabel(label string) error { - return nil -} - -func UnreserveLabel(label string) error { - return nil -} - -// DupSecOpt takes an process label and returns security options that -// can be used to set duplicate labels on future container processes -func DupSecOpt(src string) []string { - return nil -} - -// DisableSecOpt returns a security opt that can disable labeling -// support for future container processes -func DisableSecOpt() []string { - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go deleted file mode 100644 index 5983031ae00..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/label/label_selinux.go +++ /dev/null @@ -1,151 +0,0 @@ -// +build selinux,linux - -package label - -import ( - "fmt" - "strings" - - "github.com/docker/libcontainer/selinux" -) - -// InitLabels returns the process label and file labels to be used within -// the container. A list of options can be passed into this function to alter -// the labels. The labels returned will include a random MCS String, that is -// guaranteed to be unique. -func InitLabels(options []string) (string, string, error) { - if !selinux.SelinuxEnabled() { - return "", "", nil - } - processLabel, mountLabel := selinux.GetLxcContexts() - if processLabel != "" { - pcon := selinux.NewContext(processLabel) - mcon := selinux.NewContext(mountLabel) - for _, opt := range options { - if opt == "disable" { - return "", "", nil - } - if i := strings.Index(opt, ":"); i == -1 { - return "", "", fmt.Errorf("Bad SELinux Option") - } - con := strings.SplitN(opt, ":", 2) - pcon[con[0]] = con[1] - if con[0] == "level" || con[0] == "user" { - mcon[con[0]] = con[1] - } - } - processLabel = pcon.Get() - mountLabel = mcon.Get() - } - return processLabel, mountLabel, nil -} - -// DEPRECATED: The GenLabels function is only to be used during the transition to the official API. -func GenLabels(options string) (string, string, error) { - return InitLabels(strings.Fields(options)) -} - -// FormatMountLabel returns a string to be used by the mount command. -// The format of this string will be used to alter the labeling of the mountpoint. -// The string returned is suitable to be used as the options field of the mount command. -// If you need to have additional mount point options, you can pass them in as -// the first parameter. Second parameter is the label that you wish to apply -// to all content in the mount point. -func FormatMountLabel(src, mountLabel string) string { - if mountLabel != "" { - switch src { - case "": - src = fmt.Sprintf("context=%q", mountLabel) - default: - src = fmt.Sprintf("%s,context=%q", src, mountLabel) - } - } - return src -} - -// SetProcessLabel takes a process label and tells the kernel to assign the -// label to the next program executed by the current process. -func SetProcessLabel(processLabel string) error { - if processLabel == "" { - return nil - } - return selinux.Setexeccon(processLabel) -} - -// GetProcessLabel returns the process label that the kernel will assign -// to the next program executed by the current process. If "" is returned -// this indicates that the default labeling will happen for the process. -func GetProcessLabel() (string, error) { - return selinux.Getexeccon() -} - -// SetFileLabel modifies the "path" label to the specified file label -func SetFileLabel(path string, fileLabel string) error { - if selinux.SelinuxEnabled() && fileLabel != "" { - return selinux.Setfilecon(path, fileLabel) - } - return nil -} - -// Tell the kernel the label for all files to be created -func SetFileCreateLabel(fileLabel string) error { - if selinux.SelinuxEnabled() { - return selinux.Setfscreatecon(fileLabel) - } - return nil -} - -// Change the label of path to the filelabel string. If the relabel string -// is "z", relabel will change the MCS label to s0. This will allow all -// containers to share the content. If the relabel string is a "Z" then -// the MCS label should continue to be used. SELinux will use this field -// to make sure the content can not be shared by other containes. -func Relabel(path string, fileLabel string, relabel string) error { - if fileLabel == "" { - return nil - } - if relabel == "z" { - c := selinux.NewContext(fileLabel) - c["level"] = "s0" - fileLabel = c.Get() - } - return selinux.Chcon(path, fileLabel, true) -} - -// GetPidLabel will return the label of the process running with the specified pid -func GetPidLabel(pid int) (string, error) { - return selinux.Getpidcon(pid) -} - -// Init initialises the labeling system -func Init() { - selinux.SelinuxEnabled() -} - -// ReserveLabel will record the fact that the MCS label has already been used. -// This will prevent InitLabels from using the MCS label in a newly created -// container -func ReserveLabel(label string) error { - selinux.ReserveLabel(label) - return nil -} - -// UnreserveLabel will remove the reservation of the MCS label. -// This will allow InitLabels to use the MCS label in a newly created -// containers -func UnreserveLabel(label string) error { - selinux.FreeLxcContexts(label) - return nil -} - -// DupSecOpt takes an process label and returns security options that -// can be used to set duplicate labels on future container processes -func DupSecOpt(src string) []string { - return selinux.DupSecOpt(src) -} - -// DisableSecOpt returns a security opt that can disable labeling -// support for future container processes -func DisableSecOpt() []string { - return selinux.DisableSecOpt() -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go deleted file mode 100644 index 91a27294a7c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/init.go +++ /dev/null @@ -1,212 +0,0 @@ -// +build linux - -package mount - -import ( - "fmt" - "os" - "path/filepath" - "syscall" - - "github.com/docker/libcontainer/label" - "github.com/docker/libcontainer/mount/nodes" -) - -// default mount point flags -const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV - -type mount struct { - source string - path string - device string - flags int - data string -} - -// InitializeMountNamespace sets up the devices, mount points, and filesystems for use inside a -// new mount namespace. -func InitializeMountNamespace(rootfs, console string, sysReadonly bool, hostRootUid, hostRootGid int, mountConfig *MountConfig) error { - var ( - err error - flag = syscall.MS_PRIVATE - ) - - if mountConfig.NoPivotRoot { - flag = syscall.MS_SLAVE - } - - if err := syscall.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { - return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err) - } - - if err := syscall.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { - return fmt.Errorf("mouting %s as bind %s", rootfs, err) - } - - if err := mountSystem(rootfs, sysReadonly, mountConfig); err != nil { - return fmt.Errorf("mount system %s", err) - } - - // apply any user specified mounts within the new mount namespace - for _, m := range mountConfig.Mounts { - if err := m.Mount(rootfs, mountConfig.MountLabel); err != nil { - return err - } - } - - if err := nodes.CreateDeviceNodes(rootfs, mountConfig.DeviceNodes); err != nil { - return fmt.Errorf("create device nodes %s", err) - } - - if err := SetupPtmx(rootfs, console, mountConfig.MountLabel, hostRootUid, hostRootGid); err != nil { - return err - } - - // stdin, stdout and stderr could be pointing to /dev/null from parent namespace. - // Re-open them inside this namespace. - // FIXME: Need to fix this for user namespaces. - if hostRootUid == 0 { - if err := reOpenDevNull(rootfs); err != nil { - return fmt.Errorf("Failed to reopen /dev/null %s", err) - } - } - - if err := setupDevSymlinks(rootfs); err != nil { - return fmt.Errorf("dev symlinks %s", err) - } - - if err := syscall.Chdir(rootfs); err != nil { - return fmt.Errorf("chdir into %s %s", rootfs, err) - } - - if mountConfig.NoPivotRoot { - err = MsMoveRoot(rootfs) - } else { - err = PivotRoot(rootfs, mountConfig.PivotDir) - } - - if err != nil { - return err - } - - if mountConfig.ReadonlyFs { - if err := SetReadonly(); err != nil { - return fmt.Errorf("set readonly %s", err) - } - } - - syscall.Umask(0022) - - return nil -} - -// mountSystem sets up linux specific system mounts like mqueue, sys, proc, shm, and devpts -// inside the mount namespace -func mountSystem(rootfs string, sysReadonly bool, mountConfig *MountConfig) error { - for _, m := range newSystemMounts(rootfs, mountConfig.MountLabel, sysReadonly) { - if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) { - return fmt.Errorf("mkdirall %s %s", m.path, err) - } - if err := syscall.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil { - return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err) - } - } - return nil -} - -func createIfNotExists(path string, isDir bool) error { - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - if isDir { - if err := os.MkdirAll(path, 0755); err != nil { - return err - } - } else { - if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { - return err - } - f, err := os.OpenFile(path, os.O_CREATE, 0755) - if err != nil { - return err - } - f.Close() - } - } - } - return nil -} - -func setupDevSymlinks(rootfs string) error { - var links = [][2]string{ - {"/proc/self/fd", "/dev/fd"}, - {"/proc/self/fd/0", "/dev/stdin"}, - {"/proc/self/fd/1", "/dev/stdout"}, - {"/proc/self/fd/2", "/dev/stderr"}, - } - - // kcore support can be toggled with CONFIG_PROC_KCORE; only create a symlink - // in /dev if it exists in /proc. - if _, err := os.Stat("/proc/kcore"); err == nil { - links = append(links, [2]string{"/proc/kcore", "/dev/kcore"}) - } - - for _, link := range links { - var ( - src = link[0] - dst = filepath.Join(rootfs, link[1]) - ) - - if err := os.Symlink(src, dst); err != nil && !os.IsExist(err) { - return fmt.Errorf("symlink %s %s %s", src, dst, err) - } - } - - return nil -} - -// TODO: this is crappy right now and should be cleaned up with a better way of handling system and -// standard bind mounts allowing them to be more dynamic -func newSystemMounts(rootfs, mountLabel string, sysReadonly bool) []mount { - systemMounts := []mount{ - {source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags}, - {source: "tmpfs", path: filepath.Join(rootfs, "dev"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, data: label.FormatMountLabel("mode=755", mountLabel)}, - {source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1777,size=65536k", mountLabel)}, - {source: "mqueue", path: filepath.Join(rootfs, "dev", "mqueue"), device: "mqueue", flags: defaultMountFlags}, - {source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)}, - } - - sysMountFlags := defaultMountFlags - if sysReadonly { - sysMountFlags |= syscall.MS_RDONLY - } - - systemMounts = append(systemMounts, mount{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: sysMountFlags}) - - return systemMounts -} - -// Is stdin, stdout or stderr were to be pointing to '/dev/null', -// this method will make them point to '/dev/null' from within this namespace. -func reOpenDevNull(rootfs string) error { - var stat, devNullStat syscall.Stat_t - file, err := os.Open(filepath.Join(rootfs, "/dev/null")) - if err != nil { - return fmt.Errorf("Failed to open /dev/null - %s", err) - } - defer file.Close() - if err = syscall.Fstat(int(file.Fd()), &devNullStat); err != nil { - return fmt.Errorf("Failed to stat /dev/null - %s", err) - } - for fd := 0; fd < 3; fd++ { - if err = syscall.Fstat(fd, &stat); err != nil { - return fmt.Errorf("Failed to stat fd %d - %s", fd, err) - } - if stat.Rdev == devNullStat.Rdev { - // Close and re-open the fd. - if err = syscall.Dup2(int(file.Fd()), fd); err != nil { - return fmt.Errorf("Failed to dup fd %d to fd %d - %s", file.Fd(), fd, err) - } - } - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount.go deleted file mode 100644 index c1b424214f0..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount.go +++ /dev/null @@ -1,109 +0,0 @@ -package mount - -import ( - "fmt" - "os" - "path/filepath" - "syscall" - - "github.com/docker/docker/pkg/symlink" - "github.com/docker/libcontainer/label" -) - -type Mount struct { - Type string `json:"type,omitempty"` - Source string `json:"source,omitempty"` // Source path, in the host namespace - Destination string `json:"destination,omitempty"` // Destination path, in the container - Writable bool `json:"writable,omitempty"` - Relabel string `json:"relabel,omitempty"` // Relabel source if set, "z" indicates shared, "Z" indicates unshared - Private bool `json:"private,omitempty"` - Slave bool `json:"slave,omitempty"` -} - -func (m *Mount) Mount(rootfs, mountLabel string) error { - switch m.Type { - case "bind": - return m.bindMount(rootfs, mountLabel) - case "tmpfs": - return m.tmpfsMount(rootfs, mountLabel) - default: - return fmt.Errorf("unsupported mount type %s for %s", m.Type, m.Destination) - } -} - -func (m *Mount) bindMount(rootfs, mountLabel string) error { - var ( - flags = syscall.MS_BIND | syscall.MS_REC - dest = filepath.Join(rootfs, m.Destination) - ) - - if !m.Writable { - flags = flags | syscall.MS_RDONLY - } - - if m.Slave { - flags = flags | syscall.MS_SLAVE - } - - stat, err := os.Stat(m.Source) - if err != nil { - return err - } - - // FIXME: (crosbymichael) This does not belong here and should be done a layer above - dest, err = symlink.FollowSymlinkInScope(dest, rootfs) - if err != nil { - return err - } - - if err := createIfNotExists(dest, stat.IsDir()); err != nil { - return fmt.Errorf("creating new bind mount target %s", err) - } - - if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil { - return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err) - } - - if !m.Writable { - if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil { - return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err) - } - } - - if m.Relabel != "" { - if err := label.Relabel(m.Source, mountLabel, m.Relabel); err != nil { - return fmt.Errorf("relabeling %s to %s %s", m.Source, mountLabel, err) - } - } - - if m.Private { - if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil { - return fmt.Errorf("mounting %s private %s", dest, err) - } - } - - return nil -} - -func (m *Mount) tmpfsMount(rootfs, mountLabel string) error { - var ( - err error - l = label.FormatMountLabel("", mountLabel) - dest = filepath.Join(rootfs, m.Destination) - ) - - // FIXME: (crosbymichael) This does not belong here and should be done a layer above - if dest, err = symlink.FollowSymlinkInScope(dest, rootfs); err != nil { - return err - } - - if err := createIfNotExists(dest, true); err != nil { - return fmt.Errorf("creating new tmpfs mount target %s", err) - } - - if err := syscall.Mount("tmpfs", dest, "tmpfs", uintptr(defaultMountFlags), l); err != nil { - return fmt.Errorf("%s mounting %s in tmpfs", err, dest) - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount_config.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount_config.go deleted file mode 100644 index f19465e6022..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/mount_config.go +++ /dev/null @@ -1,33 +0,0 @@ -package mount - -import ( - "errors" - - "github.com/docker/libcontainer/devices" -) - -var ErrUnsupported = errors.New("Unsupported method") - -type MountConfig struct { - // NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs - // This is a common option when the container is running in ramdisk - NoPivotRoot bool `json:"no_pivot_root,omitempty"` - - // PivotDir allows a custom directory inside the container's root filesystem to be used as pivot, when NoPivotRoot is not set. - // When a custom PivotDir not set, a temporary dir inside the root filesystem will be used. The pivot dir needs to be writeable. - // This is required when using read only root filesystems. In these cases, a read/writeable path can be (bind) mounted somewhere inside the root filesystem to act as pivot. - PivotDir string `json:"pivot_dir,omitempty"` - - // ReadonlyFs will remount the container's rootfs as readonly where only externally mounted - // bind mounts are writtable - ReadonlyFs bool `json:"readonly_fs,omitempty"` - - // Mounts specify additional source and destination paths that will be mounted inside the container's - // rootfs and mount namespace if specified - Mounts []*Mount `json:"mounts,omitempty"` - - // The device nodes that should be automatically created within the container upon container start. Note, make sure that the node is marked as allowed in the cgroup as well! - DeviceNodes []*devices.Device `json:"device_nodes,omitempty"` - - MountLabel string `json:"mount_label,omitempty"` -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/msmoveroot.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/msmoveroot.go deleted file mode 100644 index 94afd3a99c4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/msmoveroot.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build linux - -package mount - -import ( - "fmt" - "syscall" -) - -func MsMoveRoot(rootfs string) error { - if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil { - return fmt.Errorf("mount move %s into / %s", rootfs, err) - } - - if err := syscall.Chroot("."); err != nil { - return fmt.Errorf("chroot . %s", err) - } - - return syscall.Chdir("/") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/nodes/nodes.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/nodes/nodes.go deleted file mode 100644 index 322c0c0ee27..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/nodes/nodes.go +++ /dev/null @@ -1,57 +0,0 @@ -// +build linux - -package nodes - -import ( - "fmt" - "os" - "path/filepath" - "syscall" - - "github.com/docker/libcontainer/devices" -) - -// Create the device nodes in the container. -func CreateDeviceNodes(rootfs string, nodesToCreate []*devices.Device) error { - oldMask := syscall.Umask(0000) - defer syscall.Umask(oldMask) - - for _, node := range nodesToCreate { - if err := CreateDeviceNode(rootfs, node); err != nil { - return err - } - } - return nil -} - -// Creates the device node in the rootfs of the container. -func CreateDeviceNode(rootfs string, node *devices.Device) error { - var ( - dest = filepath.Join(rootfs, node.Path) - parent = filepath.Dir(dest) - ) - - if err := os.MkdirAll(parent, 0755); err != nil { - return err - } - - fileMode := node.FileMode - switch node.Type { - case 'c': - fileMode |= syscall.S_IFCHR - case 'b': - fileMode |= syscall.S_IFBLK - default: - return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path) - } - - if err := syscall.Mknod(dest, uint32(fileMode), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) { - return fmt.Errorf("mknod %s %s", node.Path, err) - } - - if err := syscall.Chown(dest, int(node.Uid), int(node.Gid)); err != nil { - return fmt.Errorf("chown %s to %d:%d", node.Path, node.Uid, node.Gid) - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/nodes/nodes_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/nodes/nodes_unsupported.go deleted file mode 100644 index 83660715d46..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/nodes/nodes_unsupported.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !linux - -package nodes - -import ( - "errors" - - "github.com/docker/libcontainer/devices" -) - -func CreateDeviceNodes(rootfs string, nodesToCreate []*devices.Device) error { - return errors.New("Unsupported method") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/pivotroot.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/pivotroot.go deleted file mode 100644 index acc3be24c44..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/pivotroot.go +++ /dev/null @@ -1,41 +0,0 @@ -// +build linux - -package mount - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" -) - -func PivotRoot(rootfs, pivotBaseDir string) error { - if pivotBaseDir == "" { - pivotBaseDir = "/" - } - tmpDir := filepath.Join(rootfs, pivotBaseDir) - if err := os.MkdirAll(tmpDir, 0755); err != nil { - return fmt.Errorf("can't create tmp dir %s, error %v", tmpDir, err) - } - pivotDir, err := ioutil.TempDir(tmpDir, ".pivot_root") - if err != nil { - return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err) - } - - if err := syscall.PivotRoot(rootfs, pivotDir); err != nil { - return fmt.Errorf("pivot_root %s", err) - } - - if err := syscall.Chdir("/"); err != nil { - return fmt.Errorf("chdir / %s", err) - } - - // path to pivot dir now changed, update - pivotDir = filepath.Join(pivotBaseDir, filepath.Base(pivotDir)) - if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil { - return fmt.Errorf("unmount pivot_root dir %s", err) - } - - return os.Remove(pivotDir) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/ptmx.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/ptmx.go deleted file mode 100644 index 5b558775b18..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/ptmx.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build linux - -package mount - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/docker/libcontainer/console" -) - -func SetupPtmx(rootfs, consolePath, mountLabel string, hostRootUid, hostRootGid int) error { - ptmx := filepath.Join(rootfs, "dev/ptmx") - if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) { - return err - } - - if err := os.Symlink("pts/ptmx", ptmx); err != nil { - return fmt.Errorf("symlink dev ptmx %s", err) - } - - if consolePath != "" { - if err := console.Setup(rootfs, consolePath, mountLabel, hostRootUid, hostRootGid); err != nil { - return err - } - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/readonly.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/readonly.go deleted file mode 100644 index 9b4a6f704c4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/readonly.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build linux - -package mount - -import ( - "syscall" -) - -func SetReadonly() error { - return syscall.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/remount.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/remount.go deleted file mode 100644 index 99a01209d1f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/mount/remount.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build linux - -package mount - -import "syscall" - -func RemountProc() error { - if err := syscall.Unmount("/proc", syscall.MNT_DETACH); err != nil { - return err - } - - if err := syscall.Mount("proc", "/proc", "proc", uintptr(defaultMountFlags), ""); err != nil { - return err - } - - return nil -} - -func RemountSys() error { - if err := syscall.Unmount("/sys", syscall.MNT_DETACH); err != nil { - if err != syscall.EINVAL { - return err - } - } else { - if err := syscall.Mount("sysfs", "/sys", "sysfs", uintptr(defaultMountFlags), ""); err != nil { - return err - } - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/create.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/create.go deleted file mode 100644 index 68ddaafbb07..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/create.go +++ /dev/null @@ -1,11 +0,0 @@ -package namespaces - -import ( - "os" - "os/exec" - - "github.com/docker/libcontainer" -) - -type CreateCommand func(container *libcontainer.Config, console, dataPath, init string, childPipe *os.File, args []string) *exec.Cmd -type SetupCommand func(container *libcontainer.Config, console, dataPath, init string) *exec.Cmd diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/exec.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/exec.go deleted file mode 100644 index 5a1f19c929e..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/exec.go +++ /dev/null @@ -1,349 +0,0 @@ -// +build linux - -package namespaces - -import ( - "encoding/json" - "fmt" - "io" - "os" - "os/exec" - "syscall" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/cgroups/fs" - "github.com/docker/libcontainer/cgroups/systemd" - "github.com/docker/libcontainer/network" - "github.com/docker/libcontainer/system" -) - -const ( - EXIT_SIGNAL_OFFSET = 128 -) - -// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work. -// Move this to libcontainer package. -// Exec performs setup outside of a namespace so that a container can be -// executed. Exec is a high level function for working with container namespaces. -func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console, dataPath string, args []string, createCommand CreateCommand, setupCommand SetupCommand, startCallback func()) (int, error) { - var err error - - // create a pipe so that we can syncronize with the namespaced process and - // pass the state and configuration to the child process - parent, child, err := newInitPipe() - if err != nil { - return -1, err - } - defer parent.Close() - - command := createCommand(container, console, dataPath, os.Args[0], child, args) - // Note: these are only used in non-tty mode - // if there is a tty for the container it will be opened within the namespace and the - // fds will be duped to stdin, stdiout, and stderr - command.Stdin = stdin - command.Stdout = stdout - command.Stderr = stderr - - if err := command.Start(); err != nil { - child.Close() - return -1, err - } - child.Close() - - wait := func() (*os.ProcessState, error) { - ps, err := command.Process.Wait() - // we should kill all processes in cgroup when init is died if we use - // host PID namespace - if !container.Namespaces.Contains(libcontainer.NEWPID) { - killAllPids(container) - } - return ps, err - } - - terminate := func(terr error) (int, error) { - // TODO: log the errors for kill and wait - command.Process.Kill() - wait() - return -1, terr - } - - started, err := system.GetProcessStartTime(command.Process.Pid) - if err != nil { - return terminate(err) - } - - // Do this before syncing with child so that no children - // can escape the cgroup - cgroupPaths, err := SetupCgroups(container, command.Process.Pid) - if err != nil { - return terminate(err) - } - defer cgroups.RemovePaths(cgroupPaths) - - var networkState network.NetworkState - if err := InitializeNetworking(container, command.Process.Pid, &networkState); err != nil { - return terminate(err) - } - - state := &libcontainer.State{ - InitPid: command.Process.Pid, - InitStartTime: started, - NetworkState: networkState, - CgroupPaths: cgroupPaths, - } - - if err := libcontainer.SaveState(dataPath, state); err != nil { - return terminate(err) - } - defer libcontainer.DeleteState(dataPath) - - // Start the setup process to setup the init process - if container.Namespaces.Contains(libcontainer.NEWUSER) { - setupCmd := setupCommand(container, console, dataPath, os.Args[0]) - output, err := setupCmd.CombinedOutput() - if err != nil || setupCmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() != 0 { - command.Process.Kill() - wait() - return -1, fmt.Errorf("setup failed: %s %s", err, output) - } - } - - // send the state to the container's init process then shutdown writes for the parent - if err := json.NewEncoder(parent).Encode(networkState); err != nil { - return terminate(err) - } - // shutdown writes for the parent side of the pipe - if err := syscall.Shutdown(int(parent.Fd()), syscall.SHUT_WR); err != nil { - return terminate(err) - } - - // wait for the child process to fully complete and receive an error message - // if one was encoutered - var ierr *initError - if err := json.NewDecoder(parent).Decode(&ierr); err != nil && err != io.EOF { - return terminate(err) - } - if ierr != nil { - return terminate(ierr) - } - - if startCallback != nil { - startCallback() - } - - ps, err := wait() - if err != nil { - if _, ok := err.(*exec.ExitError); !ok { - return -1, err - } - } - // waiting for pipe flushing - command.Wait() - - waitStatus := ps.Sys().(syscall.WaitStatus) - if waitStatus.Signaled() { - return EXIT_SIGNAL_OFFSET + int(waitStatus.Signal()), nil - } - return waitStatus.ExitStatus(), nil -} - -// killAllPids iterates over all of the container's processes -// sending a SIGKILL to each process. -func killAllPids(container *libcontainer.Config) error { - var ( - procs []*os.Process - freeze = fs.Freeze - getPids = fs.GetPids - ) - if systemd.UseSystemd() { - freeze = systemd.Freeze - getPids = systemd.GetPids - } - freeze(container.Cgroups, cgroups.Frozen) - pids, err := getPids(container.Cgroups) - if err != nil { - return err - } - for _, pid := range pids { - // TODO: log err without aborting if we are unable to find - // a single PID - if p, err := os.FindProcess(pid); err == nil { - procs = append(procs, p) - p.Kill() - } - } - freeze(container.Cgroups, cgroups.Thawed) - for _, p := range procs { - p.Wait() - } - return err -} - -// Utility function that gets a host ID for a container ID from user namespace map -// if that ID is present in the map. -func hostIDFromMapping(containerID int, uMap []libcontainer.IDMap) (int, bool) { - for _, m := range uMap { - if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) { - hostID := m.HostID + (containerID - m.ContainerID) - return hostID, true - } - } - return -1, false -} - -// Gets the root gid for the process on host which could be non-zero -// when user namespaces are enabled. -func GetHostRootGid(container *libcontainer.Config) (int, error) { - if container.Namespaces.Contains(libcontainer.NEWUSER) { - if container.GidMappings == nil { - return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.") - } - hostRootGid, found := hostIDFromMapping(0, container.GidMappings) - if !found { - return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.") - } - return hostRootGid, nil - } - - // Return default root gid 0 - return 0, nil -} - -// Gets the root uid for the process on host which could be non-zero -// when user namespaces are enabled. -func GetHostRootUid(container *libcontainer.Config) (int, error) { - if container.Namespaces.Contains(libcontainer.NEWUSER) { - if container.UidMappings == nil { - return -1, fmt.Errorf("User namespaces enabled, but no uid mappings found.") - } - hostRootUid, found := hostIDFromMapping(0, container.UidMappings) - if !found { - return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.") - } - return hostRootUid, nil - } - - // Return default root uid 0 - return 0, nil -} - -// Converts IDMap to SysProcIDMap array and adds it to SysProcAttr. -func AddUidGidMappings(sys *syscall.SysProcAttr, container *libcontainer.Config) { - if container.UidMappings != nil { - sys.UidMappings = make([]syscall.SysProcIDMap, len(container.UidMappings)) - for i, um := range container.UidMappings { - sys.UidMappings[i].ContainerID = um.ContainerID - sys.UidMappings[i].HostID = um.HostID - sys.UidMappings[i].Size = um.Size - } - } - - if container.GidMappings != nil { - sys.GidMappings = make([]syscall.SysProcIDMap, len(container.GidMappings)) - for i, gm := range container.GidMappings { - sys.GidMappings[i].ContainerID = gm.ContainerID - sys.GidMappings[i].HostID = gm.HostID - sys.GidMappings[i].Size = gm.Size - } - } -} - -// DefaultCreateCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces -// defined on the container's configuration and use the current binary as the init with the -// args provided -// -// console: the /dev/console to setup inside the container -// init: the program executed inside the namespaces -// dataPath: the path to the directory under which the container's state file is stored -// pipe: sync pipe to synchronize the parent and child processes -// args: the arguments to pass to the container to run as the user's program -func DefaultCreateCommand(container *libcontainer.Config, console, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { - // get our binary name from arg0 so we can always reexec ourself - env := []string{ - "console=" + console, - "pipe=3", - "data_path=" + dataPath, - } - - command := exec.Command(init, append([]string{"init", "--"}, args...)...) - // make sure the process is executed inside the context of the rootfs - command.Dir = container.RootFs - command.Env = append(os.Environ(), env...) - - if command.SysProcAttr == nil { - command.SysProcAttr = &syscall.SysProcAttr{} - } - command.SysProcAttr.Cloneflags = uintptr(GetNamespaceFlags(container.Namespaces)) - - command.SysProcAttr.Pdeathsig = syscall.SIGKILL - command.ExtraFiles = []*os.File{pipe} - - if container.Namespaces.Contains(libcontainer.NEWUSER) { - AddUidGidMappings(command.SysProcAttr, container) - - // Default to root user when user namespaces are enabled. - if command.SysProcAttr.Credential == nil { - command.SysProcAttr.Credential = &syscall.Credential{} - } - } - - return command -} - -// DefaultSetupCommand will return an exec.Cmd that joins the init process to set it up. -// -// console: the /dev/console to setup inside the container -// dataPath: the path to the directory under which the container's state file is stored -// init: the program executed inside the namespaces -func DefaultSetupCommand(container *libcontainer.Config, console, dataPath, init string) *exec.Cmd { - env := []string{ - "console=" + console, - "data_path=" + dataPath, - } - - if dataPath == "" { - dataPath, _ = os.Getwd() - } - - if container.RootFs == "" { - container.RootFs, _ = os.Getwd() - } - args := []string{dataPath, container.RootFs, console} - - command := exec.Command(init, append([]string{"exec", "--func", "setup", "--"}, args...)...) - - // make sure the process is executed inside the context of the rootfs - command.Dir = container.RootFs - command.Env = append(os.Environ(), env...) - - return command -} - -// SetupCgroups applies the cgroup restrictions to the process running in the container based -// on the container's configuration -func SetupCgroups(container *libcontainer.Config, nspid int) (map[string]string, error) { - if container.Cgroups != nil { - c := container.Cgroups - if systemd.UseSystemd() { - return systemd.Apply(c, nspid) - } - return fs.Apply(c, nspid) - } - return map[string]string{}, nil -} - -// InitializeNetworking creates the container's network stack outside of the namespace and moves -// interfaces into the container's net namespaces if necessary -func InitializeNetworking(container *libcontainer.Config, nspid int, networkState *network.NetworkState) error { - for _, config := range container.Networks { - strategy, err := network.GetStrategy(config.Type) - if err != nil { - return err - } - if err := strategy.Create((*network.Network)(config), nspid, networkState); err != nil { - return err - } - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/execin.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/execin.go deleted file mode 100644 index 6bae9f1eb5c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/execin.go +++ /dev/null @@ -1,201 +0,0 @@ -// +build linux - -package namespaces - -import ( - "encoding/json" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "strconv" - "syscall" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/apparmor" - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/label" - "github.com/docker/libcontainer/mount" - "github.com/docker/libcontainer/system" - "github.com/docker/libcontainer/utils" -) - -// ExecIn reexec's the initPath with the argv 0 rewrite to "nsenter" so that it is able to run the -// setns code in a single threaded environment joining the existing containers' namespaces. -func ExecIn(container *libcontainer.Config, state *libcontainer.State, userArgs []string, initPath, action string, - stdin io.Reader, stdout, stderr io.Writer, console string, startCallback func(*exec.Cmd)) (int, error) { - - args := []string{fmt.Sprintf("nsenter-%s", action), "--nspid", strconv.Itoa(state.InitPid)} - - if console != "" { - args = append(args, "--console", console) - } - - cmd := &exec.Cmd{ - Path: initPath, - Args: append(args, append([]string{"--"}, userArgs...)...), - } - - if filepath.Base(initPath) == initPath { - if lp, err := exec.LookPath(initPath); err == nil { - cmd.Path = lp - } - } - - parent, child, err := newInitPipe() - if err != nil { - return -1, err - } - defer parent.Close() - - // Note: these are only used in non-tty mode - // if there is a tty for the container it will be opened within the namespace and the - // fds will be duped to stdin, stdiout, and stderr - cmd.Stdin = stdin - cmd.Stdout = stdout - cmd.Stderr = stderr - cmd.ExtraFiles = []*os.File{child} - - if err := cmd.Start(); err != nil { - child.Close() - return -1, err - } - child.Close() - - terminate := func(terr error) (int, error) { - // TODO: log the errors for kill and wait - cmd.Process.Kill() - cmd.Wait() - return -1, terr - } - - // Enter cgroups. - if err := EnterCgroups(state, cmd.Process.Pid); err != nil { - return terminate(err) - } - - // finish cgroups' setup, unblock the child process. - if _, err := parent.WriteString("1"); err != nil { - return terminate(err) - } - - if err := json.NewEncoder(parent).Encode(container); err != nil { - return terminate(err) - } - - if startCallback != nil { - startCallback(cmd) - } - - if err := cmd.Wait(); err != nil { - if _, ok := err.(*exec.ExitError); !ok { - return -1, err - } - } - return cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil -} - -// Finalize expects that the setns calls have been setup and that is has joined an -// existing namespace -func FinalizeSetns(container *libcontainer.Config, args []string) error { - // clear the current processes env and replace it with the environment defined on the container - if err := LoadContainerEnvironment(container); err != nil { - return err - } - - if err := setupRlimits(container); err != nil { - return fmt.Errorf("setup rlimits %s", err) - } - - if err := FinalizeNamespace(container); err != nil { - return err - } - - if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { - return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) - } - - if container.ProcessLabel != "" { - if err := label.SetProcessLabel(container.ProcessLabel); err != nil { - return err - } - } - - if err := system.Execv(args[0], args[0:], os.Environ()); err != nil { - return err - } - - panic("unreachable") -} - -// SetupContainer is run to setup mounts and networking related operations -// for a user namespace enabled process as a user namespace root doesn't -// have permissions to perform these operations. -// The setup process joins all the namespaces of user namespace enabled init -// except the user namespace, so it run as root in the root user namespace -// to perform these operations. -func SetupContainer(container *libcontainer.Config, dataPath, uncleanRootfs, consolePath string) error { - rootfs, err := utils.ResolveRootfs(uncleanRootfs) - if err != nil { - return err - } - - // clear the current processes env and replace it with the environment - // defined on the container - if err := LoadContainerEnvironment(container); err != nil { - return err - } - - state, err := libcontainer.GetState(dataPath) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("unable to read state: %s", err) - } - - cloneFlags := GetNamespaceFlags(container.Namespaces) - - if (cloneFlags & syscall.CLONE_NEWNET) == 0 { - if len(container.Networks) != 0 || len(container.Routes) != 0 { - return fmt.Errorf("unable to apply network parameters without network namespace") - } - } else { - if err := setupNetwork(container, &state.NetworkState); err != nil { - return fmt.Errorf("setup networking %s", err) - } - if err := setupRoute(container); err != nil { - return fmt.Errorf("setup route %s", err) - } - } - - label.Init() - - hostRootUid, err := GetHostRootUid(container) - if err != nil { - return fmt.Errorf("failed to get hostRootUid %s", err) - } - - hostRootGid, err := GetHostRootGid(container) - if err != nil { - return fmt.Errorf("failed to get hostRootGid %s", err) - } - - // InitializeMountNamespace() can be executed only for a new mount namespace - if (cloneFlags & syscall.CLONE_NEWNS) == 0 { - if container.MountConfig != nil { - return fmt.Errorf("mount config is set without mount namespace") - } - } else if err := mount.InitializeMountNamespace(rootfs, - consolePath, - container.RestrictSys, - hostRootUid, - hostRootGid, - (*mount.MountConfig)(container.MountConfig)); err != nil { - return fmt.Errorf("setup mount namespace %s", err) - } - - return nil -} - -func EnterCgroups(state *libcontainer.State, pid int) error { - return cgroups.EnterPid(state.CgroupPaths, pid) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/init.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/init.go deleted file mode 100644 index 3d23135046c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/init.go +++ /dev/null @@ -1,444 +0,0 @@ -// +build linux - -package namespaces - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "strings" - "syscall" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/apparmor" - "github.com/docker/libcontainer/console" - "github.com/docker/libcontainer/label" - "github.com/docker/libcontainer/mount" - "github.com/docker/libcontainer/netlink" - "github.com/docker/libcontainer/network" - "github.com/docker/libcontainer/security/capabilities" - "github.com/docker/libcontainer/security/restrict" - "github.com/docker/libcontainer/system" - "github.com/docker/libcontainer/user" - "github.com/docker/libcontainer/utils" -) - -// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work. -// Move this to libcontainer package. -// Init is the init process that first runs inside a new namespace to setup mounts, users, networking, -// and other options required for the new container. -// The caller of Init function has to ensure that the go runtime is locked to an OS thread -// (using runtime.LockOSThread) else system calls like setns called within Init may not work as intended. -func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) { - defer func() { - // if we have an error during the initialization of the container's init then send it back to the - // parent process in the form of an initError. - if err != nil { - // ensure that any data sent from the parent is consumed so it doesn't - // receive ECONNRESET when the child writes to the pipe. - ioutil.ReadAll(pipe) - if err := json.NewEncoder(pipe).Encode(initError{ - Message: err.Error(), - }); err != nil { - panic(err) - } - } - // ensure that this pipe is always closed - pipe.Close() - }() - - if container.Namespaces.Contains(libcontainer.NEWUSER) { - return initUserNs(container, uncleanRootfs, consolePath, pipe, args) - } else { - return initDefault(container, uncleanRootfs, consolePath, pipe, args) - } -} - -func initDefault(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) { - rootfs, err := utils.ResolveRootfs(uncleanRootfs) - if err != nil { - return err - } - - // clear the current processes env and replace it with the environment - // defined on the container - if err := LoadContainerEnvironment(container); err != nil { - return err - } - - // We always read this as it is a way to sync with the parent as well - var networkState *network.NetworkState - if err := json.NewDecoder(pipe).Decode(&networkState); err != nil { - return err - } - // join any namespaces via a path to the namespace fd if provided - if err := joinExistingNamespaces(container.Namespaces); err != nil { - return err - } - if consolePath != "" { - if err := console.OpenAndDup(consolePath); err != nil { - return err - } - } - if _, err := syscall.Setsid(); err != nil { - return fmt.Errorf("setsid %s", err) - } - if consolePath != "" { - if err := system.Setctty(); err != nil { - return fmt.Errorf("setctty %s", err) - } - } - - cloneFlags := GetNamespaceFlags(container.Namespaces) - - if (cloneFlags & syscall.CLONE_NEWNET) == 0 { - if len(container.Networks) != 0 || len(container.Routes) != 0 { - return fmt.Errorf("unable to apply network parameters without network namespace") - } - } else { - if err := setupNetwork(container, networkState); err != nil { - return fmt.Errorf("setup networking %s", err) - } - if err := setupRoute(container); err != nil { - return fmt.Errorf("setup route %s", err) - } - } - - if err := setupRlimits(container); err != nil { - return fmt.Errorf("setup rlimits %s", err) - } - - label.Init() - - // InitializeMountNamespace() can be executed only for a new mount namespace - if (cloneFlags & syscall.CLONE_NEWNS) == 0 { - if container.MountConfig != nil { - return fmt.Errorf("mount config is set without mount namespace") - } - } else if err := mount.InitializeMountNamespace(rootfs, - consolePath, - container.RestrictSys, - 0, // Default Root Uid - 0, // Default Root Gid - (*mount.MountConfig)(container.MountConfig)); err != nil { - return fmt.Errorf("setup mount namespace %s", err) - } - - if container.Hostname != "" { - if (cloneFlags & syscall.CLONE_NEWUTS) == 0 { - return fmt.Errorf("unable to set the hostname without UTS namespace") - } - if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { - return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err) - } - } - - if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { - return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) - } - - if err := label.SetProcessLabel(container.ProcessLabel); err != nil { - return fmt.Errorf("set process label %s", err) - } - - // TODO: (crosbymichael) make this configurable at the Config level - if container.RestrictSys { - if (cloneFlags & syscall.CLONE_NEWNS) == 0 { - return fmt.Errorf("unable to restrict access to kernel files without mount namespace") - } - if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { - return err - } - } - - pdeathSignal, err := system.GetParentDeathSignal() - if err != nil { - return fmt.Errorf("get parent death signal %s", err) - } - - if err := FinalizeNamespace(container); err != nil { - return fmt.Errorf("finalize namespace %s", err) - } - - // FinalizeNamespace can change user/group which clears the parent death - // signal, so we restore it here. - if err := RestoreParentDeathSignal(pdeathSignal); err != nil { - return fmt.Errorf("restore parent death signal %s", err) - } - - return system.Execv(args[0], args[0:], os.Environ()) -} - -func initUserNs(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) { - // clear the current processes env and replace it with the environment - // defined on the container - if err := LoadContainerEnvironment(container); err != nil { - return err - } - - // We always read this as it is a way to sync with the parent as well - var networkState *network.NetworkState - if err := json.NewDecoder(pipe).Decode(&networkState); err != nil { - return err - } - // join any namespaces via a path to the namespace fd if provided - if err := joinExistingNamespaces(container.Namespaces); err != nil { - return err - } - if consolePath != "" { - if err := console.OpenAndDup("/dev/console"); err != nil { - return err - } - } - if _, err := syscall.Setsid(); err != nil { - return fmt.Errorf("setsid %s", err) - } - if consolePath != "" { - if err := system.Setctty(); err != nil { - return fmt.Errorf("setctty %s", err) - } - } - - if container.WorkingDir == "" { - container.WorkingDir = "/" - } - - if err := setupRlimits(container); err != nil { - return fmt.Errorf("setup rlimits %s", err) - } - - cloneFlags := GetNamespaceFlags(container.Namespaces) - - if container.Hostname != "" { - if (cloneFlags & syscall.CLONE_NEWUTS) == 0 { - return fmt.Errorf("unable to set the hostname without UTS namespace") - } - if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { - return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err) - } - } - - if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { - return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) - } - - if err := label.SetProcessLabel(container.ProcessLabel); err != nil { - return fmt.Errorf("set process label %s", err) - } - - if container.RestrictSys { - if (cloneFlags & syscall.CLONE_NEWNS) == 0 { - return fmt.Errorf("unable to restrict access to kernel files without mount namespace") - } - if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { - return err - } - } - - pdeathSignal, err := system.GetParentDeathSignal() - if err != nil { - return fmt.Errorf("get parent death signal %s", err) - } - - if err := FinalizeNamespace(container); err != nil { - return fmt.Errorf("finalize namespace %s", err) - } - - // FinalizeNamespace can change user/group which clears the parent death - // signal, so we restore it here. - if err := RestoreParentDeathSignal(pdeathSignal); err != nil { - return fmt.Errorf("restore parent death signal %s", err) - } - - return system.Execv(args[0], args[0:], os.Environ()) -} - -// RestoreParentDeathSignal sets the parent death signal to old. -func RestoreParentDeathSignal(old int) error { - if old == 0 { - return nil - } - - current, err := system.GetParentDeathSignal() - if err != nil { - return fmt.Errorf("get parent death signal %s", err) - } - - if old == current { - return nil - } - - if err := system.ParentDeathSignal(uintptr(old)); err != nil { - return fmt.Errorf("set parent death signal %s", err) - } - - // Signal self if parent is already dead. Does nothing if running in a new - // PID namespace, as Getppid will always return 0. - if syscall.Getppid() == 1 { - return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) - } - - return nil -} - -// SetupUser changes the groups, gid, and uid for the user inside the container -func SetupUser(container *libcontainer.Config) error { - // Set up defaults. - defaultExecUser := user.ExecUser{ - Uid: syscall.Getuid(), - Gid: syscall.Getgid(), - Home: "/", - } - - passwdPath, err := user.GetPasswdPath() - if err != nil { - return err - } - - groupPath, err := user.GetGroupPath() - if err != nil { - return err - } - - execUser, err := user.GetExecUserPath(container.User, &defaultExecUser, passwdPath, groupPath) - if err != nil { - return fmt.Errorf("get supplementary groups %s", err) - } - - suppGroups := append(execUser.Sgids, container.AdditionalGroups...) - - if err := syscall.Setgroups(suppGroups); err != nil { - return fmt.Errorf("setgroups %s", err) - } - - if err := system.Setgid(execUser.Gid); err != nil { - return fmt.Errorf("setgid %s", err) - } - - if err := system.Setuid(execUser.Uid); err != nil { - return fmt.Errorf("setuid %s", err) - } - - // if we didn't get HOME already, set it based on the user's HOME - if envHome := os.Getenv("HOME"); envHome == "" { - if err := os.Setenv("HOME", execUser.Home); err != nil { - return fmt.Errorf("set HOME %s", err) - } - } - - return nil -} - -// setupVethNetwork uses the Network config if it is not nil to initialize -// the new veth interface inside the container for use by changing the name to eth0 -// setting the MTU and IP address along with the default gateway -func setupNetwork(container *libcontainer.Config, networkState *network.NetworkState) error { - for _, config := range container.Networks { - strategy, err := network.GetStrategy(config.Type) - if err != nil { - return err - } - - err1 := strategy.Initialize((*network.Network)(config), networkState) - if err1 != nil { - return err1 - } - } - return nil -} - -func setupRoute(container *libcontainer.Config) error { - for _, config := range container.Routes { - if err := netlink.AddRoute(config.Destination, config.Source, config.Gateway, config.InterfaceName); err != nil { - return err - } - } - return nil -} - -func setupRlimits(container *libcontainer.Config) error { - for _, rlimit := range container.Rlimits { - l := &syscall.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft} - if err := syscall.Setrlimit(rlimit.Type, l); err != nil { - return fmt.Errorf("error setting rlimit type %v: %v", rlimit.Type, err) - } - } - return nil -} - -// FinalizeNamespace drops the caps, sets the correct user -// and working dir, and closes any leaky file descriptors -// before execing the command inside the namespace -func FinalizeNamespace(container *libcontainer.Config) error { - // Ensure that all non-standard fds we may have accidentally - // inherited are marked close-on-exec so they stay out of the - // container - if err := utils.CloseExecFrom(3); err != nil { - return fmt.Errorf("close open file descriptors %s", err) - } - - // drop capabilities in bounding set before changing user - if err := capabilities.DropBoundingSet(container.Capabilities); err != nil { - return fmt.Errorf("drop bounding set %s", err) - } - - // preserve existing capabilities while we change users - if err := system.SetKeepCaps(); err != nil { - return fmt.Errorf("set keep caps %s", err) - } - - if err := SetupUser(container); err != nil { - return fmt.Errorf("setup user %s", err) - } - - if err := system.ClearKeepCaps(); err != nil { - return fmt.Errorf("clear keep caps %s", err) - } - - // drop all other capabilities - if err := capabilities.DropCapabilities(container.Capabilities); err != nil { - return fmt.Errorf("drop capabilities %s", err) - } - - if container.WorkingDir != "" { - if err := syscall.Chdir(container.WorkingDir); err != nil { - return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) - } - } - - return nil -} - -func LoadContainerEnvironment(container *libcontainer.Config) error { - os.Clearenv() - for _, pair := range container.Env { - p := strings.SplitN(pair, "=", 2) - if len(p) < 2 { - return fmt.Errorf("invalid environment '%v'", pair) - } - if err := os.Setenv(p[0], p[1]); err != nil { - return err - } - } - return nil -} - -// joinExistingNamespaces gets all the namespace paths specified for the container and -// does a setns on the namespace fd so that the current process joins the namespace. -func joinExistingNamespaces(namespaces []libcontainer.Namespace) error { - for _, ns := range namespaces { - if ns.Path != "" { - f, err := os.OpenFile(ns.Path, os.O_RDONLY, 0) - if err != nil { - return err - } - err = system.Setns(f.Fd(), uintptr(namespaceInfo[ns.Type])) - f.Close() - if err != nil { - return err - } - } - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/README.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/README.md deleted file mode 100644 index ac94cba0591..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## nsenter - -The `nsenter` package registers a special init constructor that is called before the Go runtime has -a chance to boot. This provides us the ability to `setns` on existing namespaces and avoid the issues -that the Go runtime has with multiple threads. This constructor is only called if this package is -registered, imported, in your go application and the argv 0 is `nsenter`. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.c b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.c deleted file mode 100644 index 747fce3a42c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.c +++ /dev/null @@ -1,261 +0,0 @@ -// +build cgo -// -// formated with indent -linux nsenter.c - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define pr_perror(fmt, ...) fprintf(stderr, "nsenter: " fmt ": %m\n", ##__VA_ARGS__) - -static const kBufSize = 256; -static const char *kNsEnter = "nsenter"; - -void get_args(int *argc, char ***argv) -{ - // Read argv - int fd = open("/proc/self/cmdline", O_RDONLY); - if (fd < 0) { - pr_perror("Unable to open /proc/self/cmdline"); - exit(1); - } - // Read the whole commandline. - ssize_t contents_size = 0; - ssize_t contents_offset = 0; - char *contents = NULL; - ssize_t bytes_read = 0; - do { - contents_size += kBufSize; - contents = (char *)realloc(contents, contents_size); - bytes_read = - read(fd, contents + contents_offset, - contents_size - contents_offset); - if (bytes_read < 0) { - pr_perror("Unable to read from /proc/self/cmdline"); - exit(1); - } - contents_offset += bytes_read; - } - while (bytes_read > 0); - close(fd); - - // Parse the commandline into an argv. /proc/self/cmdline has \0 delimited args. - ssize_t i; - *argc = 0; - for (i = 0; i < contents_offset; i++) { - if (contents[i] == '\0') { - (*argc)++; - } - } - *argv = (char **)malloc(sizeof(char *) * ((*argc) + 1)); - int idx; - for (idx = 0; idx < (*argc); idx++) { - (*argv)[idx] = contents; - contents += strlen(contents) + 1; - } - (*argv)[*argc] = NULL; -} - -// Use raw setns syscall for versions of glibc that don't include it (namely glibc-2.12) -#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 14 -#define _GNU_SOURCE -#include -#include "syscall.h" -#ifdef SYS_setns -int setns(int fd, int nstype) -{ - return syscall(SYS_setns, fd, nstype); -} -#endif -#endif - -void print_usage() -{ - fprintf(stderr, - "nsenter --nspid --console -- cmd1 arg1 arg2...\n"); -} - -void child_handler(int sig) -{ - while (waitpid(-1, NULL, WNOHANG) > 0) { - } -} - -void nsenter() -{ - int argc, c; - char **argv; - get_args(&argc, &argv); - - // check argv 0 to ensure that we are supposed to setns - // we use strncmp to test for a value of "nsenter" but also allows alternate implmentations - // after the setns code path to continue to use the argv 0 to determine actions to be run - // resulting in the ability to specify "nsenter-mknod", "nsenter-exec", etc... - if (strncmp(argv[0], kNsEnter, strlen(kNsEnter)) != 0) { - return; - } -#ifdef PR_SET_CHILD_SUBREAPER - if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) == -1) { - pr_perror("Failed to set child subreaper"); - exit(1); - } - // setup SIGCHLD handler to reap zombie processes - struct sigaction sa; - sigemptyset(&sa.sa_mask); - sa.sa_handler = &child_handler; - sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; - if (sigaction(SIGCHLD, &sa, NULL) == -1) { - pr_perror("Failed to set SIGCHLD handler"); - exit(1); - } -#endif - - static const struct option longopts[] = { - {"nspid", required_argument, NULL, 'n'}, - {"console", required_argument, NULL, 't'}, - {NULL, 0, NULL, 0} - }; - - pid_t init_pid = -1; - char *init_pid_str = NULL; - char *console = NULL; - while ((c = getopt_long_only(argc, argv, "n:c:", longopts, NULL)) != -1) { - switch (c) { - case 'n': - init_pid_str = optarg; - break; - case 't': - console = optarg; - break; - } - } - - if (init_pid_str == NULL) { - print_usage(); - exit(1); - } - - init_pid = strtol(init_pid_str, NULL, 10); - if ((init_pid == 0 && errno == EINVAL) || errno == ERANGE) { - pr_perror("Failed to parse PID from \"%s\" with output \"%d\"", - init_pid_str, init_pid); - print_usage(); - exit(1); - } - - argc -= 3; - argv += 3; - - if (setsid() == -1) { - pr_perror("setsid failed"); - exit(1); - } - // before we setns we need to dup the console - int consolefd = -1; - if (console != NULL) { - consolefd = open(console, O_RDWR); - if (consolefd < 0) { - pr_perror("Failed to open console %s", console); - exit(1); - } - } - // blocking until the parent placed the process inside correct cgroups. - unsigned char s; - if (read(3, &s, 1) != 1 || s != '1') { - pr_perror("failed to receive synchronization data from parent"); - exit(1); - } - // Setns on all supported namespaces. - char ns_dir[PATH_MAX]; - memset(ns_dir, 0, PATH_MAX); - snprintf(ns_dir, PATH_MAX - 1, "/proc/%d/ns/", init_pid); - - int ns_dir_fd; - ns_dir_fd = open(ns_dir, O_RDONLY | O_DIRECTORY); - if (ns_dir_fd < 0) { - pr_perror("Unable to open %s", ns_dir); - exit(1); - } - - char *namespaces[] = { "ipc", "uts", "net", "pid", "mnt" }; - const int num = sizeof(namespaces) / sizeof(char *); - int i; - for (i = 0; i < num; i++) { - // A zombie process has links on namespaces, but they can't be opened - struct stat st; - if (fstatat(ns_dir_fd, namespaces[i], &st, AT_SYMLINK_NOFOLLOW) - == -1) { - if (errno == ENOENT) - continue; - pr_perror("Failed to stat ns file %s for ns %s", - ns_dir, namespaces[i]); - exit(1); - } - - int fd = openat(ns_dir_fd, namespaces[i], O_RDONLY); - if (fd == -1) { - pr_perror("Failed to open ns file %s for ns %s", - ns_dir, namespaces[i]); - exit(1); - } - // Set the namespace. - if (setns(fd, 0) == -1) { - pr_perror("Failed to setns for %s", namespaces[i]); - exit(1); - } - close(fd); - } - close(ns_dir_fd); - - // We must fork to actually enter the PID namespace. - int child = fork(); - if (child == -1) { - pr_perror("Unable to fork a process"); - exit(1); - } - if (child == 0) { - if (consolefd != -1) { - if (dup2(consolefd, STDIN_FILENO) != 0) { - pr_perror("Failed to dup 0"); - exit(1); - } - if (dup2(consolefd, STDOUT_FILENO) != STDOUT_FILENO) { - pr_perror("Failed to dup 1"); - exit(1); - } - if (dup2(consolefd, STDERR_FILENO) != STDERR_FILENO) { - pr_perror("Failed to dup 2\n"); - exit(1); - } - } - // Finish executing, let the Go runtime take over. - return; - } else { - // Parent, wait for the child. - int status = 0; - if (waitpid(child, &status, 0) == -1) { - pr_perror("nsenter: Failed to waitpid with error"); - exit(1); - } - // Forward the child's exit code or re-send its death signal. - if (WIFEXITED(status)) { - exit(WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - kill(getpid(), WTERMSIG(status)); - } - - exit(1); - } - - return; -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.go deleted file mode 100644 index 7d21e8e59fd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build linux - -package nsenter - -/* -__attribute__((constructor)) init() { - nsenter(); -} -*/ -import "C" diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_test.go deleted file mode 100644 index 14870c457eb..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package nsenter - -import ( - "fmt" - "os" - "os/exec" - "os/signal" - "strings" - "syscall" - "testing" -) - -func TestNsenterAlivePid(t *testing.T) { - args := []string{"nsenter-exec", "--nspid", fmt.Sprintf("%d", os.Getpid())} - r, w, err := os.Pipe() - if err != nil { - t.Fatalf("failed to create pipe %v", err) - } - - cmd := &exec.Cmd{ - Path: os.Args[0], - Args: args, - ExtraFiles: []*os.File{r}, - } - - if err := cmd.Start(); err != nil { - t.Fatalf("nsenter failed to start %v", err) - } - r.Close() - - // unblock the child process - if _, err := w.WriteString("1"); err != nil { - t.Fatalf("parent failed to write synchronization data %v", err) - } - - if err := cmd.Wait(); err != nil { - t.Fatalf("nsenter exits with a non-zero exit status") - } -} - -func TestNsenterInvalidPid(t *testing.T) { - args := []string{"nsenter-exec", "--nspid", "-1"} - - cmd := &exec.Cmd{ - Path: os.Args[0], - Args: args, - } - - err := cmd.Run() - if err == nil { - t.Fatal("nsenter exits with a zero exit status") - } -} - -func TestNsenterDeadPid(t *testing.T) { - - c := make(chan os.Signal) - signal.Notify(c, syscall.SIGCHLD) - dead_cmd := exec.Command("true") - if err := dead_cmd.Start(); err != nil { - t.Fatal(err) - } - defer dead_cmd.Wait() - <-c // dead_cmd is zombie - - args := []string{"nsenter-exec", "--nspid", fmt.Sprintf("%d", dead_cmd.Process.Pid)} - - cmd := &exec.Cmd{ - Path: os.Args[0], - Args: args, - } - - err := cmd.Run() - if err == nil { - t.Fatal("nsenter exits with a zero exit status") - } -} - -func init() { - if strings.HasPrefix(os.Args[0], "nsenter-") { - os.Exit(0) - } - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_unsupported.go deleted file mode 100644 index 2459c6367e4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_unsupported.go +++ /dev/null @@ -1,3 +0,0 @@ -// +build !linux !cgo - -package nsenter diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/utils.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/utils.go deleted file mode 100644 index 20db08788f2..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/namespaces/utils.go +++ /dev/null @@ -1,48 +0,0 @@ -// +build linux - -package namespaces - -import ( - "os" - "syscall" - - "github.com/docker/libcontainer" -) - -type initError struct { - Message string `json:"message,omitempty"` -} - -func (i initError) Error() string { - return i.Message -} - -var namespaceInfo = map[libcontainer.NamespaceType]int{ - libcontainer.NEWNET: syscall.CLONE_NEWNET, - libcontainer.NEWNS: syscall.CLONE_NEWNS, - libcontainer.NEWUSER: syscall.CLONE_NEWUSER, - libcontainer.NEWIPC: syscall.CLONE_NEWIPC, - libcontainer.NEWUTS: syscall.CLONE_NEWUTS, - libcontainer.NEWPID: syscall.CLONE_NEWPID, -} - -// New returns a newly initialized Pipe for communication between processes -func newInitPipe() (parent *os.File, child *os.File, err error) { - fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) - if err != nil { - return nil, nil, err - } - return os.NewFile(uintptr(fds[1]), "parent"), os.NewFile(uintptr(fds[0]), "child"), nil -} - -// GetNamespaceFlags parses the container's Namespaces options to set the correct -// flags on clone, unshare. This functions returns flags only for new namespaces. -func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) { - for _, v := range namespaces { - if v.Path != "" { - continue - } - flag |= namespaceInfo[v.Type] - } - return flag -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/MAINTAINERS b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/MAINTAINERS deleted file mode 100644 index 1cb551364dd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Michael Crosby (@crosbymichael) -Guillaume J. Charmes (@creack) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink.go deleted file mode 100644 index 90883660612..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink.go +++ /dev/null @@ -1,31 +0,0 @@ -// Packet netlink provide access to low level Netlink sockets and messages. -// -// Actual implementations are in: -// netlink_linux.go -// netlink_darwin.go -package netlink - -import ( - "errors" - "net" -) - -var ( - ErrWrongSockType = errors.New("Wrong socket type") - ErrShortResponse = errors.New("Got short response from netlink") - ErrInterfaceExists = errors.New("Network interface already exists") -) - -// A Route is a subnet associated with the interface to reach it. -type Route struct { - *net.IPNet - Iface *net.Interface - Default bool -} - -// An IfAddr defines IP network settings for a given network interface -type IfAddr struct { - Iface *net.Interface - IP net.IP - IPNet *net.IPNet -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux.go deleted file mode 100644 index 3cc3cc94f74..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux.go +++ /dev/null @@ -1,1299 +0,0 @@ -package netlink - -import ( - "encoding/binary" - "fmt" - "io" - "math/rand" - "net" - "os" - "path/filepath" - "sync/atomic" - "syscall" - "unsafe" -) - -const ( - IFNAMSIZ = 16 - DEFAULT_CHANGE = 0xFFFFFFFF - IFLA_INFO_KIND = 1 - IFLA_INFO_DATA = 2 - VETH_INFO_PEER = 1 - IFLA_MACVLAN_MODE = 1 - IFLA_VLAN_ID = 1 - IFLA_NET_NS_FD = 28 - IFLA_ADDRESS = 1 - SIOC_BRADDBR = 0x89a0 - SIOC_BRDELBR = 0x89a1 - SIOC_BRADDIF = 0x89a2 -) - -const ( - MACVLAN_MODE_PRIVATE = 1 << iota - MACVLAN_MODE_VEPA - MACVLAN_MODE_BRIDGE - MACVLAN_MODE_PASSTHRU -) - -var nextSeqNr uint32 - -type ifreqHwaddr struct { - IfrnName [IFNAMSIZ]byte - IfruHwaddr syscall.RawSockaddr -} - -type ifreqIndex struct { - IfrnName [IFNAMSIZ]byte - IfruIndex int32 -} - -type ifreqFlags struct { - IfrnName [IFNAMSIZ]byte - Ifruflags uint16 -} - -var native binary.ByteOrder - -func init() { - var x uint32 = 0x01020304 - if *(*byte)(unsafe.Pointer(&x)) == 0x01 { - native = binary.BigEndian - } else { - native = binary.LittleEndian - } -} - -func getIpFamily(ip net.IP) int { - if len(ip) <= net.IPv4len { - return syscall.AF_INET - } - if ip.To4() != nil { - return syscall.AF_INET - } - return syscall.AF_INET6 -} - -type NetlinkRequestData interface { - Len() int - ToWireFormat() []byte -} - -type IfInfomsg struct { - syscall.IfInfomsg -} - -func newIfInfomsg(family int) *IfInfomsg { - return &IfInfomsg{ - IfInfomsg: syscall.IfInfomsg{ - Family: uint8(family), - }, - } -} - -func newIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg { - msg := newIfInfomsg(family) - parent.children = append(parent.children, msg) - return msg -} - -func (msg *IfInfomsg) ToWireFormat() []byte { - length := syscall.SizeofIfInfomsg - b := make([]byte, length) - b[0] = msg.Family - b[1] = 0 - native.PutUint16(b[2:4], msg.Type) - native.PutUint32(b[4:8], uint32(msg.Index)) - native.PutUint32(b[8:12], msg.Flags) - native.PutUint32(b[12:16], msg.Change) - return b -} - -func (msg *IfInfomsg) Len() int { - return syscall.SizeofIfInfomsg -} - -type IfAddrmsg struct { - syscall.IfAddrmsg -} - -func newIfAddrmsg(family int) *IfAddrmsg { - return &IfAddrmsg{ - IfAddrmsg: syscall.IfAddrmsg{ - Family: uint8(family), - }, - } -} - -func (msg *IfAddrmsg) ToWireFormat() []byte { - length := syscall.SizeofIfAddrmsg - b := make([]byte, length) - b[0] = msg.Family - b[1] = msg.Prefixlen - b[2] = msg.Flags - b[3] = msg.Scope - native.PutUint32(b[4:8], msg.Index) - return b -} - -func (msg *IfAddrmsg) Len() int { - return syscall.SizeofIfAddrmsg -} - -type RtMsg struct { - syscall.RtMsg -} - -func newRtMsg() *RtMsg { - return &RtMsg{ - RtMsg: syscall.RtMsg{ - Table: syscall.RT_TABLE_MAIN, - Scope: syscall.RT_SCOPE_UNIVERSE, - Protocol: syscall.RTPROT_BOOT, - Type: syscall.RTN_UNICAST, - }, - } -} - -func (msg *RtMsg) ToWireFormat() []byte { - length := syscall.SizeofRtMsg - b := make([]byte, length) - b[0] = msg.Family - b[1] = msg.Dst_len - b[2] = msg.Src_len - b[3] = msg.Tos - b[4] = msg.Table - b[5] = msg.Protocol - b[6] = msg.Scope - b[7] = msg.Type - native.PutUint32(b[8:12], msg.Flags) - return b -} - -func (msg *RtMsg) Len() int { - return syscall.SizeofRtMsg -} - -func rtaAlignOf(attrlen int) int { - return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) -} - -type RtAttr struct { - syscall.RtAttr - Data []byte - children []NetlinkRequestData -} - -func newRtAttr(attrType int, data []byte) *RtAttr { - return &RtAttr{ - RtAttr: syscall.RtAttr{ - Type: uint16(attrType), - }, - children: []NetlinkRequestData{}, - Data: data, - } -} - -func newRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr { - attr := newRtAttr(attrType, data) - parent.children = append(parent.children, attr) - return attr -} - -func (a *RtAttr) Len() int { - if len(a.children) == 0 { - return (syscall.SizeofRtAttr + len(a.Data)) - } - - l := 0 - for _, child := range a.children { - l += child.Len() - } - l += syscall.SizeofRtAttr - return rtaAlignOf(l + len(a.Data)) -} - -func (a *RtAttr) ToWireFormat() []byte { - length := a.Len() - buf := make([]byte, rtaAlignOf(length)) - - if a.Data != nil { - copy(buf[4:], a.Data) - } else { - next := 4 - for _, child := range a.children { - childBuf := child.ToWireFormat() - copy(buf[next:], childBuf) - next += rtaAlignOf(len(childBuf)) - } - } - - if l := uint16(length); l != 0 { - native.PutUint16(buf[0:2], l) - } - native.PutUint16(buf[2:4], a.Type) - return buf -} - -func uint32Attr(t int, n uint32) *RtAttr { - buf := make([]byte, 4) - native.PutUint32(buf, n) - return newRtAttr(t, buf) -} - -type NetlinkRequest struct { - syscall.NlMsghdr - Data []NetlinkRequestData -} - -func (rr *NetlinkRequest) ToWireFormat() []byte { - length := rr.Len - dataBytes := make([][]byte, len(rr.Data)) - for i, data := range rr.Data { - dataBytes[i] = data.ToWireFormat() - length += uint32(len(dataBytes[i])) - } - b := make([]byte, length) - native.PutUint32(b[0:4], length) - native.PutUint16(b[4:6], rr.Type) - native.PutUint16(b[6:8], rr.Flags) - native.PutUint32(b[8:12], rr.Seq) - native.PutUint32(b[12:16], rr.Pid) - - next := 16 - for _, data := range dataBytes { - copy(b[next:], data) - next += len(data) - } - return b -} - -func (rr *NetlinkRequest) AddData(data NetlinkRequestData) { - if data != nil { - rr.Data = append(rr.Data, data) - } -} - -func newNetlinkRequest(proto, flags int) *NetlinkRequest { - return &NetlinkRequest{ - NlMsghdr: syscall.NlMsghdr{ - Len: uint32(syscall.NLMSG_HDRLEN), - Type: uint16(proto), - Flags: syscall.NLM_F_REQUEST | uint16(flags), - Seq: atomic.AddUint32(&nextSeqNr, 1), - }, - } -} - -type NetlinkSocket struct { - fd int - lsa syscall.SockaddrNetlink -} - -func getNetlinkSocket() (*NetlinkSocket, error) { - fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE) - if err != nil { - return nil, err - } - s := &NetlinkSocket{ - fd: fd, - } - s.lsa.Family = syscall.AF_NETLINK - if err := syscall.Bind(fd, &s.lsa); err != nil { - syscall.Close(fd) - return nil, err - } - - return s, nil -} - -func (s *NetlinkSocket) Close() { - syscall.Close(s.fd) -} - -func (s *NetlinkSocket) Send(request *NetlinkRequest) error { - if err := syscall.Sendto(s.fd, request.ToWireFormat(), 0, &s.lsa); err != nil { - return err - } - return nil -} - -func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { - rb := make([]byte, syscall.Getpagesize()) - nr, _, err := syscall.Recvfrom(s.fd, rb, 0) - if err != nil { - return nil, err - } - if nr < syscall.NLMSG_HDRLEN { - return nil, ErrShortResponse - } - rb = rb[:nr] - return syscall.ParseNetlinkMessage(rb) -} - -func (s *NetlinkSocket) GetPid() (uint32, error) { - lsa, err := syscall.Getsockname(s.fd) - if err != nil { - return 0, err - } - switch v := lsa.(type) { - case *syscall.SockaddrNetlink: - return v.Pid, nil - } - return 0, ErrWrongSockType -} - -func (s *NetlinkSocket) CheckMessage(m syscall.NetlinkMessage, seq, pid uint32) error { - if m.Header.Seq != seq { - return fmt.Errorf("netlink: invalid seq %d, expected %d", m.Header.Seq, seq) - } - if m.Header.Pid != pid { - return fmt.Errorf("netlink: wrong pid %d, expected %d", m.Header.Pid, pid) - } - if m.Header.Type == syscall.NLMSG_DONE { - return io.EOF - } - if m.Header.Type == syscall.NLMSG_ERROR { - e := int32(native.Uint32(m.Data[0:4])) - if e == 0 { - return io.EOF - } - return syscall.Errno(-e) - } - return nil -} - -func (s *NetlinkSocket) HandleAck(seq uint32) error { - pid, err := s.GetPid() - if err != nil { - return err - } - -outer: - for { - msgs, err := s.Receive() - if err != nil { - return err - } - for _, m := range msgs { - if err := s.CheckMessage(m, seq, pid); err != nil { - if err == io.EOF { - break outer - } - return err - } - } - } - - return nil -} - -func zeroTerminated(s string) []byte { - return []byte(s + "\000") -} - -func nonZeroTerminated(s string) []byte { - return []byte(s) -} - -// Add a new network link of a specified type. -// This is identical to running: ip link add $name type $linkType -func NetworkLinkAdd(name string, linkType string) error { - if name == "" || linkType == "" { - return fmt.Errorf("Neither link name nor link type can be empty!") - } - - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - wb.AddData(msg) - - linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil) - newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType)) - wb.AddData(linkInfo) - - nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name)) - wb.AddData(nameData) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Delete a network link. -// This is identical to running: ip link del $name -func NetworkLinkDel(name string) error { - if name == "" { - return fmt.Errorf("Network link name can not be empty!") - } - - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - - wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Index = int32(iface.Index) - wb.AddData(msg) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Bring up a particular network interface. -// This is identical to running: ip link set dev $name up -func NetworkLinkUp(iface *net.Interface) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Index = int32(iface.Index) - msg.Flags = syscall.IFF_UP - msg.Change = syscall.IFF_UP - wb.AddData(msg) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Bring down a particular network interface. -// This is identical to running: ip link set $name down -func NetworkLinkDown(iface *net.Interface) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Index = int32(iface.Index) - msg.Flags = 0 & ^syscall.IFF_UP - msg.Change = DEFAULT_CHANGE - wb.AddData(msg) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Set link layer address ie. MAC Address. -// This is identical to running: ip link set dev $name address $macaddress -func NetworkSetMacAddress(iface *net.Interface, macaddr string) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - hwaddr, err := net.ParseMAC(macaddr) - if err != nil { - return err - } - - var ( - MULTICAST byte = 0x1 - ) - - if hwaddr[0]&0x1 == MULTICAST { - return fmt.Errorf("Multicast MAC Address is not supported: %s", macaddr) - } - - wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Index = int32(iface.Index) - msg.Change = DEFAULT_CHANGE - wb.AddData(msg) - - macdata := make([]byte, 6) - copy(macdata, hwaddr) - data := newRtAttr(IFLA_ADDRESS, macdata) - wb.AddData(data) - - if err := s.Send(wb); err != nil { - return err - } - return s.HandleAck(wb.Seq) -} - -// Set link Maximum Transmission Unit -// This is identical to running: ip link set dev $name mtu $MTU -// bridge is a bitch here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=292088 -// https://bugzilla.redhat.com/show_bug.cgi?id=697021 -// There is a discussion about how to deal with ifcs joining bridge with MTU > 1500 -// Regular network nterfaces do seem to work though! -func NetworkSetMTU(iface *net.Interface, mtu int) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Type = syscall.RTM_SETLINK - msg.Flags = syscall.NLM_F_REQUEST - msg.Index = int32(iface.Index) - msg.Change = DEFAULT_CHANGE - wb.AddData(msg) - wb.AddData(uint32Attr(syscall.IFLA_MTU, uint32(mtu))) - - if err := s.Send(wb); err != nil { - return err - } - return s.HandleAck(wb.Seq) -} - -// Set link queue length -// This is identical to running: ip link set dev $name txqueuelen $QLEN -func NetworkSetTxQueueLen(iface *net.Interface, txQueueLen int) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Type = syscall.RTM_SETLINK - msg.Flags = syscall.NLM_F_REQUEST - msg.Index = int32(iface.Index) - msg.Change = DEFAULT_CHANGE - wb.AddData(msg) - wb.AddData(uint32Attr(syscall.IFLA_TXQLEN, uint32(txQueueLen))) - - if err := s.Send(wb); err != nil { - return err - } - return s.HandleAck(wb.Seq) -} - -func networkMasterAction(iface *net.Interface, rtattr *RtAttr) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Type = syscall.RTM_SETLINK - msg.Flags = syscall.NLM_F_REQUEST - msg.Index = int32(iface.Index) - msg.Change = DEFAULT_CHANGE - wb.AddData(msg) - wb.AddData(rtattr) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Add an interface to bridge. -// This is identical to running: ip link set $name master $master -func NetworkSetMaster(iface, master *net.Interface) error { - data := uint32Attr(syscall.IFLA_MASTER, uint32(master.Index)) - return networkMasterAction(iface, data) -} - -// Remove an interface from the bridge -// This is is identical to to running: ip link $name set nomaster -func NetworkSetNoMaster(iface *net.Interface) error { - data := uint32Attr(syscall.IFLA_MASTER, 0) - return networkMasterAction(iface, data) -} - -func networkSetNsAction(iface *net.Interface, rtattr *RtAttr) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Index = int32(iface.Index) - wb.AddData(msg) - wb.AddData(rtattr) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Move a particular network interface to a particular network namespace -// specified by PID. This is idential to running: ip link set dev $name netns $pid -func NetworkSetNsPid(iface *net.Interface, nspid int) error { - data := uint32Attr(syscall.IFLA_NET_NS_PID, uint32(nspid)) - return networkSetNsAction(iface, data) -} - -// Move a particular network interface to a particular mounted -// network namespace specified by file descriptor. -// This is idential to running: ip link set dev $name netns $fd -func NetworkSetNsFd(iface *net.Interface, fd int) error { - data := uint32Attr(IFLA_NET_NS_FD, uint32(fd)) - return networkSetNsAction(iface, data) -} - -// Rname a particular interface to a different name -// !!! Note that you can't rename an active interface. You need to bring it down before renaming it. -// This is identical to running: ip link set dev ${oldName} name ${newName} -func NetworkChangeName(iface *net.Interface, newName string) error { - if len(newName) >= IFNAMSIZ { - return fmt.Errorf("Interface name %s too long", newName) - } - - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - msg.Index = int32(iface.Index) - msg.Change = DEFAULT_CHANGE - wb.AddData(msg) - - nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(newName)) - wb.AddData(nameData) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Add a new VETH pair link on the host -// This is identical to running: ip link add name $name type veth peer name $peername -func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - wb.AddData(msg) - - nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1)) - wb.AddData(nameData) - - txqLen := make([]byte, 4) - native.PutUint32(txqLen, uint32(txQueueLen)) - txqData := newRtAttr(syscall.IFLA_TXQLEN, txqLen) - wb.AddData(txqData) - - nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) - newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth")) - nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) - nest3 := newRtAttrChild(nest2, VETH_INFO_PEER, nil) - - newIfInfomsgChild(nest3, syscall.AF_UNSPEC) - newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2)) - - txqLen2 := make([]byte, 4) - native.PutUint32(txqLen2, uint32(txQueueLen)) - newRtAttrChild(nest3, syscall.IFLA_TXQLEN, txqLen2) - - wb.AddData(nest1) - - if err := s.Send(wb); err != nil { - return err - } - - if err := s.HandleAck(wb.Seq); err != nil { - if os.IsExist(err) { - return ErrInterfaceExists - } - - return err - } - - return nil -} - -// Add a new VLAN interface with masterDev as its upper device -// This is identical to running: -// ip link add name $name link $masterdev type vlan id $id -func NetworkLinkAddVlan(masterDev, vlanDev string, vlanId uint16) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) - - masterDevIfc, err := net.InterfaceByName(masterDev) - if err != nil { - return err - } - - msg := newIfInfomsg(syscall.AF_UNSPEC) - wb.AddData(msg) - - nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) - newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated("vlan")) - - nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) - vlanData := make([]byte, 2) - native.PutUint16(vlanData, vlanId) - newRtAttrChild(nest2, IFLA_VLAN_ID, vlanData) - wb.AddData(nest1) - - wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index))) - wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(vlanDev))) - - if err := s.Send(wb); err != nil { - return err - } - return s.HandleAck(wb.Seq) -} - -// MacVlan link has LowerDev, UpperDev and operates in Mode mode -// This simplifies the code when creating MacVlan or MacVtap interface -type MacVlanLink struct { - MasterDev string - SlaveDev string - mode string -} - -func (m MacVlanLink) Mode() uint32 { - modeMap := map[string]uint32{ - "private": MACVLAN_MODE_PRIVATE, - "vepa": MACVLAN_MODE_VEPA, - "bridge": MACVLAN_MODE_BRIDGE, - "passthru": MACVLAN_MODE_PASSTHRU, - } - - return modeMap[m.mode] -} - -// Add MAC VLAN network interface with masterDev as its upper device -// This is identical to running: -// ip link add name $name link $masterdev type macvlan mode $mode -func networkLinkMacVlan(dev_type string, mcvln *MacVlanLink) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) - - masterDevIfc, err := net.InterfaceByName(mcvln.MasterDev) - if err != nil { - return err - } - - msg := newIfInfomsg(syscall.AF_UNSPEC) - wb.AddData(msg) - - nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) - newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated(dev_type)) - - nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) - macVlanData := make([]byte, 4) - native.PutUint32(macVlanData, mcvln.Mode()) - newRtAttrChild(nest2, IFLA_MACVLAN_MODE, macVlanData) - wb.AddData(nest1) - - wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index))) - wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(mcvln.SlaveDev))) - - if err := s.Send(wb); err != nil { - return err - } - return s.HandleAck(wb.Seq) -} - -func NetworkLinkAddMacVlan(masterDev, macVlanDev string, mode string) error { - return networkLinkMacVlan("macvlan", &MacVlanLink{ - MasterDev: masterDev, - SlaveDev: macVlanDev, - mode: mode, - }) -} - -func NetworkLinkAddMacVtap(masterDev, macVlanDev string, mode string) error { - return networkLinkMacVlan("macvtap", &MacVlanLink{ - MasterDev: masterDev, - SlaveDev: macVlanDev, - mode: mode, - }) -} - -func networkLinkIpAction(action, flags int, ifa IfAddr) error { - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - family := getIpFamily(ifa.IP) - - wb := newNetlinkRequest(action, flags) - - msg := newIfAddrmsg(family) - msg.Index = uint32(ifa.Iface.Index) - prefixLen, _ := ifa.IPNet.Mask.Size() - msg.Prefixlen = uint8(prefixLen) - wb.AddData(msg) - - var ipData []byte - if family == syscall.AF_INET { - ipData = ifa.IP.To4() - } else { - ipData = ifa.IP.To16() - } - - localData := newRtAttr(syscall.IFA_LOCAL, ipData) - wb.AddData(localData) - - addrData := newRtAttr(syscall.IFA_ADDRESS, ipData) - wb.AddData(addrData) - - if err := s.Send(wb); err != nil { - return err - } - - return s.HandleAck(wb.Seq) -} - -// Delete an IP address from an interface. This is identical to: -// ip addr del $ip/$ipNet dev $iface -func NetworkLinkDelIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error { - return networkLinkIpAction( - syscall.RTM_DELADDR, - syscall.NLM_F_ACK, - IfAddr{iface, ip, ipNet}, - ) -} - -// Add an Ip address to an interface. This is identical to: -// ip addr add $ip/$ipNet dev $iface -func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error { - return networkLinkIpAction( - syscall.RTM_NEWADDR, - syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK, - IfAddr{iface, ip, ipNet}, - ) -} - -// Returns an array of IPNet for all the currently routed subnets on ipv4 -// This is similar to the first column of "ip route" output -func NetworkGetRoutes() ([]Route, error) { - s, err := getNetlinkSocket() - if err != nil { - return nil, err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP) - - msg := newIfInfomsg(syscall.AF_UNSPEC) - wb.AddData(msg) - - if err := s.Send(wb); err != nil { - return nil, err - } - - pid, err := s.GetPid() - if err != nil { - return nil, err - } - - res := make([]Route, 0) - -outer: - for { - msgs, err := s.Receive() - if err != nil { - return nil, err - } - for _, m := range msgs { - if err := s.CheckMessage(m, wb.Seq, pid); err != nil { - if err == io.EOF { - break outer - } - return nil, err - } - if m.Header.Type != syscall.RTM_NEWROUTE { - continue - } - - var r Route - - msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0])) - - if msg.Flags&syscall.RTM_F_CLONED != 0 { - // Ignore cloned routes - continue - } - - if msg.Table != syscall.RT_TABLE_MAIN { - // Ignore non-main tables - continue - } - - if msg.Family != syscall.AF_INET { - // Ignore non-ipv4 routes - continue - } - - if msg.Dst_len == 0 { - // Default routes - r.Default = true - } - - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return nil, err - } - for _, attr := range attrs { - switch attr.Attr.Type { - case syscall.RTA_DST: - ip := attr.Value - r.IPNet = &net.IPNet{ - IP: ip, - Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)), - } - case syscall.RTA_OIF: - index := int(native.Uint32(attr.Value[0:4])) - r.Iface, _ = net.InterfaceByIndex(index) - } - } - if r.Default || r.IPNet != nil { - res = append(res, r) - } - } - } - - return res, nil -} - -// Add a new route table entry. -func AddRoute(destination, source, gateway, device string) error { - if destination == "" && source == "" && gateway == "" { - return fmt.Errorf("one of destination, source or gateway must not be blank") - } - - s, err := getNetlinkSocket() - if err != nil { - return err - } - defer s.Close() - - wb := newNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) - msg := newRtMsg() - currentFamily := -1 - var rtAttrs []*RtAttr - - if destination != "" { - destIP, destNet, err := net.ParseCIDR(destination) - if err != nil { - return fmt.Errorf("destination CIDR %s couldn't be parsed", destination) - } - destFamily := getIpFamily(destIP) - currentFamily = destFamily - destLen, bits := destNet.Mask.Size() - if destLen == 0 && bits == 0 { - return fmt.Errorf("destination CIDR %s generated a non-canonical Mask", destination) - } - msg.Family = uint8(destFamily) - msg.Dst_len = uint8(destLen) - var destData []byte - if destFamily == syscall.AF_INET { - destData = destIP.To4() - } else { - destData = destIP.To16() - } - rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_DST, destData)) - } - - if source != "" { - srcIP := net.ParseIP(source) - if srcIP == nil { - return fmt.Errorf("source IP %s couldn't be parsed", source) - } - srcFamily := getIpFamily(srcIP) - if currentFamily != -1 && currentFamily != srcFamily { - return fmt.Errorf("source and destination ip were not the same IP family") - } - currentFamily = srcFamily - msg.Family = uint8(srcFamily) - var srcData []byte - if srcFamily == syscall.AF_INET { - srcData = srcIP.To4() - } else { - srcData = srcIP.To16() - } - rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_PREFSRC, srcData)) - } - - if gateway != "" { - gwIP := net.ParseIP(gateway) - if gwIP == nil { - return fmt.Errorf("gateway IP %s couldn't be parsed", gateway) - } - gwFamily := getIpFamily(gwIP) - if currentFamily != -1 && currentFamily != gwFamily { - return fmt.Errorf("gateway, source, and destination ip were not the same IP family") - } - msg.Family = uint8(gwFamily) - var gwData []byte - if gwFamily == syscall.AF_INET { - gwData = gwIP.To4() - } else { - gwData = gwIP.To16() - } - rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_GATEWAY, gwData)) - } - - wb.AddData(msg) - for _, attr := range rtAttrs { - wb.AddData(attr) - } - - iface, err := net.InterfaceByName(device) - if err != nil { - return err - } - wb.AddData(uint32Attr(syscall.RTA_OIF, uint32(iface.Index))) - - if err := s.Send(wb); err != nil { - return err - } - return s.HandleAck(wb.Seq) -} - -// Add a new default gateway. Identical to: -// ip route add default via $ip -func AddDefaultGw(ip, device string) error { - return AddRoute("", "", ip, device) -} - -// THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE -// IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS -// WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK -func getIfSocket() (fd int, err error) { - for _, socket := range []int{ - syscall.AF_INET, - syscall.AF_PACKET, - syscall.AF_INET6, - } { - if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil { - break - } - } - if err == nil { - return fd, nil - } - return -1, err -} - -// Create the actual bridge device. This is more backward-compatible than -// netlink.NetworkLinkAdd and works on RHEL 6. -func CreateBridge(name string, setMacAddr bool) error { - if len(name) >= IFNAMSIZ { - return fmt.Errorf("Interface name %s too long", name) - } - - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - nameBytePtr, err := syscall.BytePtrFromString(name) - if err != nil { - return err - } - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 { - return err - } - if setMacAddr { - return SetMacAddress(name, randMacAddr()) - } - return nil -} - -// Delete the actual bridge device. -func DeleteBridge(name string) error { - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - nameBytePtr, err := syscall.BytePtrFromString(name) - if err != nil { - return err - } - - var ifr ifreqFlags - copy(ifr.IfrnName[:len(ifr.IfrnName)-1], []byte(name)) - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), - syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifr))); err != 0 { - return err - } - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), - SIOC_BRDELBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 { - return err - } - return nil -} - -// Add a slave to abridge device. This is more backward-compatible than -// netlink.NetworkSetMaster and works on RHEL 6. -func AddToBridge(iface, master *net.Interface) error { - if len(master.Name) >= IFNAMSIZ { - return fmt.Errorf("Interface name %s too long", master.Name) - } - - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - ifr := ifreqIndex{} - copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name) - ifr.IfruIndex = int32(iface.Index) - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDIF, uintptr(unsafe.Pointer(&ifr))); err != 0 { - return err - } - - return nil -} - -func randMacAddr() string { - hw := make(net.HardwareAddr, 6) - for i := 0; i < 6; i++ { - hw[i] = byte(rand.Intn(255)) - } - hw[0] &^= 0x1 // clear multicast bit - hw[0] |= 0x2 // set local assignment bit (IEEE802) - return hw.String() -} - -func SetMacAddress(name, addr string) error { - if len(name) >= IFNAMSIZ { - return fmt.Errorf("Interface name %s too long", name) - } - - hw, err := net.ParseMAC(addr) - if err != nil { - return err - } - - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - ifr := ifreqHwaddr{} - ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER - copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name) - - for i := 0; i < 6; i++ { - ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i]) - } - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 { - return err - } - return nil -} - -func SetHairpinMode(iface *net.Interface, enabled bool) error { - sysPath := filepath.Join("/sys/class/net", iface.Name, "brport/hairpin_mode") - - sysFile, err := os.OpenFile(sysPath, os.O_WRONLY, 0) - if err != nil { - return err - } - defer sysFile.Close() - - var writeVal []byte - if enabled { - writeVal = []byte("1") - } else { - writeVal = []byte("0") - } - if _, err := sysFile.Write(writeVal); err != nil { - return err - } - - return nil -} - -func ChangeName(iface *net.Interface, newName string) error { - if len(newName) >= IFNAMSIZ { - return fmt.Errorf("Interface name %s too long", newName) - } - - fd, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(fd) - - data := [IFNAMSIZ * 2]byte{} - // the "-1"s here are very important for ensuring we get proper null - // termination of our new C strings - copy(data[:IFNAMSIZ-1], iface.Name) - copy(data[IFNAMSIZ:IFNAMSIZ*2-1], newName) - - if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&data[0]))); errno != 0 { - return errno - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux_arm.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux_arm.go deleted file mode 100644 index 779e58a771f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux_arm.go +++ /dev/null @@ -1,5 +0,0 @@ -package netlink - -func ifrDataByte(b byte) uint8 { - return uint8(b) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux_notarm.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux_notarm.go deleted file mode 100644 index f151722a1b4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_linux_notarm.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !arm - -package netlink - -func ifrDataByte(b byte) int8 { - return int8(b) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_unsupported.go deleted file mode 100644 index 4b11bf8ba56..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/netlink/netlink_unsupported.go +++ /dev/null @@ -1,88 +0,0 @@ -// +build !linux - -package netlink - -import ( - "errors" - "net" -) - -var ( - ErrNotImplemented = errors.New("not implemented") -) - -func NetworkGetRoutes() ([]Route, error) { - return nil, ErrNotImplemented -} - -func NetworkLinkAdd(name string, linkType string) error { - return ErrNotImplemented -} - -func NetworkLinkDel(name string) error { - return ErrNotImplemented -} - -func NetworkLinkUp(iface *net.Interface) error { - return ErrNotImplemented -} - -func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error { - return ErrNotImplemented -} - -func NetworkLinkDelIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error { - return ErrNotImplemented -} - -func AddRoute(destination, source, gateway, device string) error { - return ErrNotImplemented -} - -func AddDefaultGw(ip, device string) error { - return ErrNotImplemented -} - -func NetworkSetMTU(iface *net.Interface, mtu int) error { - return ErrNotImplemented -} - -func NetworkSetTxQueueLen(iface *net.Interface, txQueueLen int) error { - return ErrNotImplemented -} - -func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error { - return ErrNotImplemented -} - -func NetworkChangeName(iface *net.Interface, newName string) error { - return ErrNotImplemented -} - -func NetworkSetNsFd(iface *net.Interface, fd int) error { - return ErrNotImplemented -} - -func NetworkSetNsPid(iface *net.Interface, nspid int) error { - return ErrNotImplemented -} - -func NetworkSetMaster(iface, master *net.Interface) error { - return ErrNotImplemented -} - -func NetworkLinkDown(iface *net.Interface) error { - return ErrNotImplemented -} - -func CreateBridge(name string, setMacAddr bool) error { - return ErrNotImplemented -} - -func DeleteBridge(name string) error { - return ErrNotImplemented -} - -func AddToBridge(iface, master *net.Interface) error { - return ErrNotImplemented -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/loopback.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/loopback.go deleted file mode 100644 index 1667b4d82a3..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/loopback.go +++ /dev/null @@ -1,23 +0,0 @@ -// +build linux - -package network - -import ( - "fmt" -) - -// Loopback is a network strategy that provides a basic loopback device -type Loopback struct { -} - -func (l *Loopback) Create(n *Network, nspid int, networkState *NetworkState) error { - return nil -} - -func (l *Loopback) Initialize(config *Network, networkState *NetworkState) error { - // Do not set the MTU on the loopback interface - use the default. - if err := InterfaceUp("lo"); err != nil { - return fmt.Errorf("lo up %s", err) - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/network.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/network.go deleted file mode 100644 index 40b25b135b0..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/network.go +++ /dev/null @@ -1,117 +0,0 @@ -// +build linux - -package network - -import ( - "net" - - "github.com/docker/libcontainer/netlink" -) - -func InterfaceUp(name string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.NetworkLinkUp(iface) -} - -func InterfaceDown(name string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.NetworkLinkDown(iface) -} - -func ChangeInterfaceName(old, newName string) error { - iface, err := net.InterfaceByName(old) - if err != nil { - return err - } - return netlink.NetworkChangeName(iface, newName) -} - -func CreateVethPair(name1, name2 string, txQueueLen int) error { - return netlink.NetworkCreateVethPair(name1, name2, txQueueLen) -} - -func SetInterfaceInNamespacePid(name string, nsPid int) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.NetworkSetNsPid(iface, nsPid) -} - -func SetInterfaceInNamespaceFd(name string, fd uintptr) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.NetworkSetNsFd(iface, int(fd)) -} - -func SetInterfaceMaster(name, master string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - masterIface, err := net.InterfaceByName(master) - if err != nil { - return err - } - return netlink.AddToBridge(iface, masterIface) -} - -func SetDefaultGateway(ip, ifaceName string) error { - return netlink.AddDefaultGw(ip, ifaceName) -} - -func SetInterfaceMac(name string, macaddr string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.NetworkSetMacAddress(iface, macaddr) -} - -func SetInterfaceIp(name string, rawIp string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - ip, ipNet, err := net.ParseCIDR(rawIp) - if err != nil { - return err - } - return netlink.NetworkLinkAddIp(iface, ip, ipNet) -} - -func DeleteInterfaceIp(name string, rawIp string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - ip, ipNet, err := net.ParseCIDR(rawIp) - if err != nil { - return err - } - return netlink.NetworkLinkDelIp(iface, ip, ipNet) -} - -func SetMtu(name string, mtu int) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.NetworkSetMTU(iface, mtu) -} - -func SetHairpinMode(name string, enabled bool) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return err - } - return netlink.SetHairpinMode(iface, enabled) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/stats.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/stats.go deleted file mode 100644 index e2156c74da4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/stats.go +++ /dev/null @@ -1,74 +0,0 @@ -package network - -import ( - "io/ioutil" - "path/filepath" - "strconv" - "strings" -) - -type NetworkStats struct { - RxBytes uint64 `json:"rx_bytes"` - RxPackets uint64 `json:"rx_packets"` - RxErrors uint64 `json:"rx_errors"` - RxDropped uint64 `json:"rx_dropped"` - TxBytes uint64 `json:"tx_bytes"` - TxPackets uint64 `json:"tx_packets"` - TxErrors uint64 `json:"tx_errors"` - TxDropped uint64 `json:"tx_dropped"` -} - -// Returns the network statistics for the network interfaces represented by the NetworkRuntimeInfo. -func GetStats(networkState *NetworkState) (*NetworkStats, error) { - // This can happen if the network runtime information is missing - possible if the container was created by an old version of libcontainer. - if networkState.VethHost == "" { - return &NetworkStats{}, nil - } - - out := &NetworkStats{} - - type netStatsPair struct { - // Where to write the output. - Out *uint64 - - // The network stats file to read. - File string - } - - // Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container. - netStats := []netStatsPair{ - {Out: &out.RxBytes, File: "tx_bytes"}, - {Out: &out.RxPackets, File: "tx_packets"}, - {Out: &out.RxErrors, File: "tx_errors"}, - {Out: &out.RxDropped, File: "tx_dropped"}, - - {Out: &out.TxBytes, File: "rx_bytes"}, - {Out: &out.TxPackets, File: "rx_packets"}, - {Out: &out.TxErrors, File: "rx_errors"}, - {Out: &out.TxDropped, File: "rx_dropped"}, - } - for _, netStat := range netStats { - data, err := readSysfsNetworkStats(networkState.VethHost, netStat.File) - if err != nil { - return nil, err - } - *(netStat.Out) = data - } - - return out, nil -} - -// Reads the specified statistics available under /sys/class/net//statistics -func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) { - fullPath := filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile) - data, err := ioutil.ReadFile(fullPath) - if err != nil { - return 0, err - } - value, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) - if err != nil { - return 0, err - } - - return value, err -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/strategy.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/strategy.go deleted file mode 100644 index 019fe62f419..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/strategy.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build linux - -package network - -import ( - "errors" -) - -var ( - ErrNotValidStrategyType = errors.New("not a valid network strategy type") -) - -var strategies = map[string]NetworkStrategy{ - "veth": &Veth{}, - "loopback": &Loopback{}, -} - -// NetworkStrategy represents a specific network configuration for -// a container's networking stack -type NetworkStrategy interface { - Create(*Network, int, *NetworkState) error - Initialize(*Network, *NetworkState) error -} - -// GetStrategy returns the specific network strategy for the -// provided type. If no strategy is registered for the type an -// ErrNotValidStrategyType is returned. -func GetStrategy(tpe string) (NetworkStrategy, error) { - s, exists := strategies[tpe] - if !exists { - return nil, ErrNotValidStrategyType - } - return s, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/types.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/types.go deleted file mode 100644 index a1668e06c77..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/types.go +++ /dev/null @@ -1,56 +0,0 @@ -package network - -// Network defines configuration for a container's networking stack -// -// The network configuration can be omited from a container causing the -// container to be setup with the host's networking stack -type Network struct { - // Type sets the networks type, commonly veth and loopback - Type string `json:"type,omitempty"` - - // The bridge to use. - Bridge string `json:"bridge,omitempty"` - - // Prefix for the veth interfaces. - VethPrefix string `json:"veth_prefix,omitempty"` - - // MacAddress contains the MAC address to set on the network interface - MacAddress string `json:"mac_address,omitempty"` - - // Address contains the IPv4 and mask to set on the network interface - Address string `json:"address,omitempty"` - - // IPv6Address contains the IPv6 and mask to set on the network interface - IPv6Address string `json:"ipv6_address,omitempty"` - - // Gateway sets the gateway address that is used as the default for the interface - Gateway string `json:"gateway,omitempty"` - - // IPv6Gateway sets the ipv6 gateway address that is used as the default for the interface - IPv6Gateway string `json:"ipv6_gateway,omitempty"` - - // Mtu sets the mtu value for the interface and will be mirrored on both the host and - // container's interfaces if a pair is created, specifically in the case of type veth - // Note: This does not apply to loopback interfaces. - Mtu int `json:"mtu,omitempty"` - - // TxQueueLen sets the tx_queuelen value for the interface and will be mirrored on both the host and - // container's interfaces if a pair is created, specifically in the case of type veth - // Note: This does not apply to loopback interfaces. - TxQueueLen int `json:"txqueuelen,omitempty"` - - // HairpinMode specifies if hairpin NAT should be enabled on the virtual interface - // bridge port in the case of type veth - // Note: This is unsupported on some systems. - // Note: This does not apply to loopback interfaces. - HairpinMode bool `json:"hairpin_mode"` -} - -// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers -// Do not depend on it outside of libcontainer. -type NetworkState struct { - // The name of the veth interface on the Host. - VethHost string `json:"veth_host,omitempty"` - // The name of the veth interface created inside the container for the child. - VethChild string `json:"veth_child,omitempty"` -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/veth.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/veth.go deleted file mode 100644 index 25e559d1bcd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/network/veth.go +++ /dev/null @@ -1,127 +0,0 @@ -// +build linux - -package network - -import ( - "fmt" - - "github.com/docker/libcontainer/netlink" - "github.com/docker/libcontainer/utils" -) - -// Veth is a network strategy that uses a bridge and creates -// a veth pair, one that stays outside on the host and the other -// is placed inside the container's namespace -type Veth struct { -} - -const defaultDevice = "eth0" - -func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error { - var ( - bridge = n.Bridge - prefix = n.VethPrefix - txQueueLen = n.TxQueueLen - ) - if bridge == "" { - return fmt.Errorf("bridge is not specified") - } - if prefix == "" { - return fmt.Errorf("veth prefix is not specified") - } - name1, name2, err := createVethPair(prefix, txQueueLen) - if err != nil { - return err - } - if err := SetInterfaceMaster(name1, bridge); err != nil { - return err - } - if err := SetMtu(name1, n.Mtu); err != nil { - return err - } - if n.HairpinMode { - if err := SetHairpinMode(name1, true); err != nil { - return err - } - } - if err := InterfaceUp(name1); err != nil { - return err - } - if err := SetInterfaceInNamespacePid(name2, nspid); err != nil { - return err - } - networkState.VethHost = name1 - networkState.VethChild = name2 - - return nil -} - -func (v *Veth) Initialize(config *Network, networkState *NetworkState) error { - var vethChild = networkState.VethChild - if vethChild == "" { - return fmt.Errorf("vethChild is not specified") - } - if err := InterfaceDown(vethChild); err != nil { - return fmt.Errorf("interface down %s %s", vethChild, err) - } - if err := ChangeInterfaceName(vethChild, defaultDevice); err != nil { - return fmt.Errorf("change %s to %s %s", vethChild, defaultDevice, err) - } - if config.MacAddress != "" { - if err := SetInterfaceMac(defaultDevice, config.MacAddress); err != nil { - return fmt.Errorf("set %s mac %s", defaultDevice, err) - } - } - if err := SetInterfaceIp(defaultDevice, config.Address); err != nil { - return fmt.Errorf("set %s ip %s", defaultDevice, err) - } - if config.IPv6Address != "" { - if err := SetInterfaceIp(defaultDevice, config.IPv6Address); err != nil { - return fmt.Errorf("set %s ipv6 %s", defaultDevice, err) - } - } - - if err := SetMtu(defaultDevice, config.Mtu); err != nil { - return fmt.Errorf("set %s mtu to %d %s", defaultDevice, config.Mtu, err) - } - if err := InterfaceUp(defaultDevice); err != nil { - return fmt.Errorf("%s up %s", defaultDevice, err) - } - if config.Gateway != "" { - if err := SetDefaultGateway(config.Gateway, defaultDevice); err != nil { - return fmt.Errorf("set gateway to %s on device %s failed with %s", config.Gateway, defaultDevice, err) - } - } - if config.IPv6Gateway != "" { - if err := SetDefaultGateway(config.IPv6Gateway, defaultDevice); err != nil { - return fmt.Errorf("set gateway for ipv6 to %s on device %s failed with %s", config.IPv6Gateway, defaultDevice, err) - } - } - return nil -} - -// createVethPair will automatically generage two random names for -// the veth pair and ensure that they have been created -func createVethPair(prefix string, txQueueLen int) (name1 string, name2 string, err error) { - for i := 0; i < 10; i++ { - if name1, err = utils.GenerateRandomName(prefix, 7); err != nil { - return - } - - if name2, err = utils.GenerateRandomName(prefix, 7); err != nil { - return - } - - if err = CreateVethPair(name1, name2, txQueueLen); err != nil { - if err == netlink.ErrInterfaceExists { - continue - } - - return - } - - break - } - - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/notify_linux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/notify_linux.go deleted file mode 100644 index a4923273a30..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/notify_linux.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build linux - -package libcontainer - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" -) - -const oomCgroupName = "memory" - -// NotifyOnOOM returns channel on which you can expect event about OOM, -// if process died without OOM this channel will be closed. -// s is current *libcontainer.State for container. -func NotifyOnOOM(s *State) (<-chan struct{}, error) { - dir := s.CgroupPaths[oomCgroupName] - if dir == "" { - return nil, fmt.Errorf("There is no path for %q in state", oomCgroupName) - } - oomControl, err := os.Open(filepath.Join(dir, "memory.oom_control")) - if err != nil { - return nil, err - } - fd, _, syserr := syscall.RawSyscall(syscall.SYS_EVENTFD2, 0, syscall.FD_CLOEXEC, 0) - if syserr != 0 { - return nil, syserr - } - - eventfd := os.NewFile(fd, "eventfd") - - eventControlPath := filepath.Join(dir, "cgroup.event_control") - data := fmt.Sprintf("%d %d", eventfd.Fd(), oomControl.Fd()) - if err := ioutil.WriteFile(eventControlPath, []byte(data), 0700); err != nil { - eventfd.Close() - oomControl.Close() - return nil, err - } - ch := make(chan struct{}) - go func() { - defer func() { - close(ch) - eventfd.Close() - oomControl.Close() - }() - buf := make([]byte, 8) - for { - if _, err := eventfd.Read(buf); err != nil { - return - } - // When a cgroup is destroyed, an event is sent to eventfd. - // So if the control path is gone, return instead of notifying. - if _, err := os.Lstat(eventControlPath); os.IsNotExist(err) { - return - } - ch <- struct{}{} - } - }() - return ch, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/notify_linux_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/notify_linux_test.go deleted file mode 100644 index 5d1d54576b9..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/notify_linux_test.go +++ /dev/null @@ -1,98 +0,0 @@ -// +build linux - -package libcontainer - -import ( - "encoding/binary" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" - "testing" - "time" -) - -func TestNotifyOnOOM(t *testing.T) { - memoryPath, err := ioutil.TempDir("", "testnotifyoom-") - if err != nil { - t.Fatal(err) - } - oomPath := filepath.Join(memoryPath, "memory.oom_control") - eventPath := filepath.Join(memoryPath, "cgroup.event_control") - if err := ioutil.WriteFile(oomPath, []byte{}, 0700); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(eventPath, []byte{}, 0700); err != nil { - t.Fatal(err) - } - var eventFd, oomControlFd int - st := &State{ - CgroupPaths: map[string]string{ - "memory": memoryPath, - }, - } - ooms, err := NotifyOnOOM(st) - if err != nil { - t.Fatal("expected no error, got:", err) - } - - data, err := ioutil.ReadFile(eventPath) - if err != nil { - t.Fatal("couldn't read event control file:", err) - } - - if _, err := fmt.Sscanf(string(data), "%d %d", &eventFd, &oomControlFd); err != nil { - t.Fatalf("invalid control data %q: %s", data, err) - } - - // re-open the eventfd - efd, err := syscall.Dup(eventFd) - if err != nil { - t.Fatal("unable to reopen eventfd:", err) - } - defer syscall.Close(efd) - - if err != nil { - t.Fatal("unable to dup event fd:", err) - } - - buf := make([]byte, 8) - binary.LittleEndian.PutUint64(buf, 1) - - if _, err := syscall.Write(efd, buf); err != nil { - t.Fatal("unable to write to eventfd:", err) - } - - select { - case <-ooms: - case <-time.After(100 * time.Millisecond): - t.Fatal("no notification on oom channel after 100ms") - } - - // simulate what happens when a cgroup is destroyed by cleaning up and then - // writing to the eventfd. - if err := os.RemoveAll(memoryPath); err != nil { - t.Fatal(err) - } - if _, err := syscall.Write(efd, buf); err != nil { - t.Fatal("unable to write to eventfd:", err) - } - - // give things a moment to shut down - select { - case _, ok := <-ooms: - if ok { - t.Fatal("expected no oom to be triggered") - } - case <-time.After(100 * time.Millisecond): - } - - if _, _, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(oomControlFd), syscall.F_GETFD, 0); err != syscall.EBADF { - t.Error("expected oom control to be closed") - } - - if _, _, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(eventFd), syscall.F_GETFD, 0); err != syscall.EBADF { - t.Error("expected event fd to be closed") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/config.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/config.go deleted file mode 100644 index 74c7b3c09f7..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/config.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" - - "github.com/codegangsta/cli" -) - -var configCommand = cli.Command{ - Name: "config", - Usage: "display the container configuration", - Action: configAction, -} - -func configAction(context *cli.Context) { - container, err := loadConfig() - if err != nil { - log.Fatal(err) - } - - data, err := json.MarshalIndent(container, "", "\t") - if err != nil { - log.Fatal(err) - } - - fmt.Printf("%s", data) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/exec.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/exec.go deleted file mode 100644 index f06cc63a4dd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/exec.go +++ /dev/null @@ -1,212 +0,0 @@ -package main - -import ( - "fmt" - "io" - "log" - "os" - "os/exec" - "os/signal" - "syscall" - "text/tabwriter" - - "github.com/codegangsta/cli" - "github.com/docker/docker/pkg/term" - "github.com/docker/libcontainer" - consolepkg "github.com/docker/libcontainer/console" - "github.com/docker/libcontainer/namespaces" -) - -var execCommand = cli.Command{ - Name: "exec", - Usage: "execute a new command inside a container", - Action: execAction, - Flags: []cli.Flag{ - cli.BoolFlag{Name: "list", Usage: "list all registered exec functions"}, - cli.StringFlag{Name: "func", Value: "exec", Usage: "function name to exec inside a container"}, - }, -} - -func execAction(context *cli.Context) { - if context.Bool("list") { - w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0) - fmt.Fprint(w, "NAME\tUSAGE\n") - - for k, f := range argvs { - fmt.Fprintf(w, "%s\t%s\n", k, f.Usage) - } - - w.Flush() - - return - } - - var exitCode int - - container, err := loadConfig() - if err != nil { - log.Fatal(err) - } - - state, err := libcontainer.GetState(dataPath) - if err != nil && !os.IsNotExist(err) { - log.Fatalf("unable to read state.json: %s", err) - } - - if state != nil { - exitCode, err = startInExistingContainer(container, state, context.String("func"), context) - } else { - exitCode, err = startContainer(container, dataPath, []string(context.Args())) - } - - if err != nil { - log.Fatalf("failed to exec: %s", err) - } - - os.Exit(exitCode) -} - -// the process for execing a new process inside an existing container is that we have to exec ourself -// with the nsenter argument so that the C code can setns an the namespaces that we require. Then that -// code path will drop us into the path that we can do the final setup of the namespace and exec the users -// application. -func startInExistingContainer(config *libcontainer.Config, state *libcontainer.State, action string, context *cli.Context) (int, error) { - var ( - master *os.File - console string - err error - - sigc = make(chan os.Signal, 10) - - stdin = os.Stdin - stdout = os.Stdout - stderr = os.Stderr - ) - signal.Notify(sigc) - - if config.Tty && action != "setup" { - stdin = nil - stdout = nil - stderr = nil - - master, console, err = consolepkg.CreateMasterAndConsole() - if err != nil { - return -1, err - } - - go io.Copy(master, os.Stdin) - go io.Copy(os.Stdout, master) - - state, err := term.SetRawTerminal(os.Stdin.Fd()) - if err != nil { - return -1, err - } - - defer term.RestoreTerminal(os.Stdin.Fd(), state) - } - - startCallback := func(cmd *exec.Cmd) { - go func() { - resizeTty(master) - - for sig := range sigc { - switch sig { - case syscall.SIGWINCH: - resizeTty(master) - default: - cmd.Process.Signal(sig) - } - } - }() - } - - return namespaces.ExecIn(config, state, context.Args(), os.Args[0], action, stdin, stdout, stderr, console, startCallback) -} - -// startContainer starts the container. Returns the exit status or -1 and an -// error. -// -// Signals sent to the current process will be forwarded to container. -func startContainer(container *libcontainer.Config, dataPath string, args []string) (int, error) { - var ( - cmd *exec.Cmd - sigc = make(chan os.Signal, 10) - ) - - signal.Notify(sigc) - - createCommand := func(container *libcontainer.Config, console, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { - cmd = namespaces.DefaultCreateCommand(container, console, dataPath, init, pipe, args) - if logPath != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("log=%s", logPath)) - } - return cmd - } - - setupCommand := func(container *libcontainer.Config, console, dataPath, init string) *exec.Cmd { - return namespaces.DefaultSetupCommand(container, console, dataPath, init) - } - - var ( - master *os.File - console string - err error - - stdin = os.Stdin - stdout = os.Stdout - stderr = os.Stderr - ) - - if container.Tty { - stdin = nil - stdout = nil - stderr = nil - - master, console, err = consolepkg.CreateMasterAndConsole() - if err != nil { - return -1, err - } - - go io.Copy(master, os.Stdin) - go io.Copy(os.Stdout, master) - - state, err := term.SetRawTerminal(os.Stdin.Fd()) - if err != nil { - return -1, err - } - - defer term.RestoreTerminal(os.Stdin.Fd(), state) - } - - startCallback := func() { - go func() { - resizeTty(master) - - for sig := range sigc { - switch sig { - case syscall.SIGWINCH: - resizeTty(master) - default: - cmd.Process.Signal(sig) - } - } - }() - } - - return namespaces.Exec(container, stdin, stdout, stderr, console, dataPath, args, createCommand, setupCommand, startCallback) -} - -func resizeTty(master *os.File) { - if master == nil { - return - } - - ws, err := term.GetWinsize(os.Stdin.Fd()) - if err != nil { - return - } - - if err := term.SetWinsize(master.Fd(), ws); err != nil { - return - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/init.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/init.go deleted file mode 100644 index 6df9b1d894d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/init.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "log" - "os" - "runtime" - "strconv" - - "github.com/codegangsta/cli" - "github.com/docker/libcontainer/namespaces" -) - -var ( - dataPath = os.Getenv("data_path") - console = os.Getenv("console") - rawPipeFd = os.Getenv("pipe") - - initCommand = cli.Command{ - Name: "init", - Usage: "runs the init process inside the namespace", - Action: initAction, - } -) - -func initAction(context *cli.Context) { - runtime.LockOSThread() - - container, err := loadConfig() - if err != nil { - log.Fatal(err) - } - - rootfs, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - - pipeFd, err := strconv.Atoi(rawPipeFd) - if err != nil { - log.Fatal(err) - } - - pipe := os.NewFile(uintptr(pipeFd), "pipe") - if err := namespaces.Init(container, rootfs, console, pipe, []string(context.Args())); err != nil { - log.Fatalf("unable to initialize for container: %s", err) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main.go deleted file mode 100644 index bb8145338e2..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/main.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - "log" - "os" - "strings" - - "github.com/codegangsta/cli" -) - -var ( - logPath = os.Getenv("log") - argvs = make(map[string]*rFunc) -) - -func init() { - argvs["exec"] = &rFunc{ - Usage: "execute a process inside an existing container", - Action: nsenterExec, - } - - argvs["mknod"] = &rFunc{ - Usage: "mknod a device inside an existing container", - Action: nsenterMknod, - } - - argvs["ip"] = &rFunc{ - Usage: "display the container's network interfaces", - Action: nsenterIp, - } - - argvs["setup"] = &rFunc{ - Usage: "finish setting up init before it is ready to exec", - Action: nsenterSetup, - } -} - -func main() { - // we need to check our argv 0 for any registred functions to run instead of the - // normal cli code path - f, exists := argvs[strings.TrimPrefix(os.Args[0], "nsenter-")] - if exists { - runFunc(f) - - return - } - - app := cli.NewApp() - - app.Name = "nsinit" - app.Version = "0.1" - app.Author = "libcontainer maintainers" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "nspid"}, - cli.StringFlag{Name: "console"}, - } - - app.Before = preload - - app.Commands = []cli.Command{ - configCommand, - execCommand, - initCommand, - oomCommand, - pauseCommand, - statsCommand, - unpauseCommand, - } - - if err := app.Run(os.Args); err != nil { - log.Fatal(err) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/nsenter.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/nsenter.go deleted file mode 100644 index e9dc387a3c5..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/nsenter.go +++ /dev/null @@ -1,102 +0,0 @@ -package main - -import ( - "fmt" - "log" - "net" - "os" - "strconv" - "strings" - "text/tabwriter" - - "github.com/docker/libcontainer" - "github.com/docker/libcontainer/devices" - "github.com/docker/libcontainer/mount/nodes" - "github.com/docker/libcontainer/namespaces" - _ "github.com/docker/libcontainer/namespaces/nsenter" -) - -// nsenterExec exec's a process inside an existing container -func nsenterExec(config *libcontainer.Config, args []string) { - if err := namespaces.FinalizeSetns(config, args); err != nil { - log.Fatalf("failed to nsenter: %s", err) - } -} - -// nsenterMknod runs mknod inside an existing container -// -// mknod -func nsenterMknod(config *libcontainer.Config, args []string) { - if len(args) != 4 { - log.Fatalf("expected mknod to have 4 arguments not %d", len(args)) - } - - t := rune(args[1][0]) - - major, err := strconv.Atoi(args[2]) - if err != nil { - log.Fatal(err) - } - - minor, err := strconv.Atoi(args[3]) - if err != nil { - log.Fatal(err) - } - - n := &devices.Device{ - Path: args[0], - Type: t, - MajorNumber: int64(major), - MinorNumber: int64(minor), - } - - if err := nodes.CreateDeviceNode("/", n); err != nil { - log.Fatal(err) - } -} - -// nsenterIp displays the network interfaces inside a container's net namespace -func nsenterIp(config *libcontainer.Config, args []string) { - interfaces, err := net.Interfaces() - if err != nil { - log.Fatal(err) - } - - w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0) - fmt.Fprint(w, "NAME\tMTU\tMAC\tFLAG\tADDRS\n") - - for _, iface := range interfaces { - addrs, err := iface.Addrs() - if err != nil { - log.Fatal(err) - } - - o := []string{} - - for _, a := range addrs { - o = append(o, a.String()) - } - - fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\n", iface.Name, iface.MTU, iface.HardwareAddr, iface.Flags, strings.Join(o, ",")) - } - - w.Flush() -} - -func nsenterSetup(config *libcontainer.Config, args []string) { - if len(args) < 2 || len(args) > 3 { - log.Fatalf("expected setup to have 2 or 3 arguments not %d", len(args)) - } - - dataPath := args[0] - uncleanRootfs := args[1] - - consolePath := "" - if len(args) == 3 { - consolePath = args[2] - } - - if err := namespaces.SetupContainer(config, dataPath, uncleanRootfs, consolePath); err != nil { - log.Fatalf("failed to nsenter setup: %s", err) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/oom.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/oom.go deleted file mode 100644 index 106abeb2687..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/oom.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "log" - - "github.com/codegangsta/cli" - "github.com/docker/libcontainer" -) - -var oomCommand = cli.Command{ - Name: "oom", - Usage: "display oom notifications for a container", - Action: oomAction, -} - -func oomAction(context *cli.Context) { - state, err := libcontainer.GetState(dataPath) - if err != nil { - log.Fatal(err) - } - n, err := libcontainer.NotifyOnOOM(state) - if err != nil { - log.Fatal(err) - } - for _ = range n { - log.Printf("OOM notification received") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/pause.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/pause.go deleted file mode 100644 index ada24250c15..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/pause.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "log" - - "github.com/codegangsta/cli" - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/cgroups/fs" - "github.com/docker/libcontainer/cgroups/systemd" -) - -var pauseCommand = cli.Command{ - Name: "pause", - Usage: "pause the container's processes", - Action: pauseAction, -} - -var unpauseCommand = cli.Command{ - Name: "unpause", - Usage: "unpause the container's processes", - Action: unpauseAction, -} - -func pauseAction(context *cli.Context) { - if err := toggle(cgroups.Frozen); err != nil { - log.Fatal(err) - } -} - -func unpauseAction(context *cli.Context) { - if err := toggle(cgroups.Thawed); err != nil { - log.Fatal(err) - } -} - -func toggle(state cgroups.FreezerState) error { - container, err := loadConfig() - if err != nil { - return err - } - - if systemd.UseSystemd() { - err = systemd.Freeze(container.Cgroups, state) - } else { - err = fs.Freeze(container.Cgroups, state) - } - - return err -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/stats.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/stats.go deleted file mode 100644 index 612b4a4baeb..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/stats.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" - - "github.com/codegangsta/cli" - "github.com/docker/libcontainer" -) - -var statsCommand = cli.Command{ - Name: "stats", - Usage: "display statistics for the container", - Action: statsAction, -} - -func statsAction(context *cli.Context) { - container, err := loadConfig() - if err != nil { - log.Fatal(err) - } - - state, err := libcontainer.GetState(dataPath) - if err != nil { - log.Fatal(err) - } - - stats, err := libcontainer.GetStats(container, state) - if err != nil { - log.Fatal(err) - } - data, err := json.MarshalIndent(stats, "", "\t") - if err != nil { - log.Fatal(err) - } - - fmt.Printf("%s", data) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/utils.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/utils.go deleted file mode 100644 index 6a8aafbf170..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/nsinit/utils.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "encoding/json" - "log" - "os" - "path/filepath" - - "github.com/codegangsta/cli" - "github.com/docker/libcontainer" -) - -// rFunc is a function registration for calling after an execin -type rFunc struct { - Usage string - Action func(*libcontainer.Config, []string) -} - -func loadConfig() (*libcontainer.Config, error) { - f, err := os.Open(filepath.Join(dataPath, "container.json")) - if err != nil { - return nil, err - } - defer f.Close() - - var container *libcontainer.Config - if err := json.NewDecoder(f).Decode(&container); err != nil { - return nil, err - } - - return container, nil -} - -func openLog(name string) error { - f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0755) - if err != nil { - return err - } - - log.SetOutput(f) - - return nil -} - -func findUserArgs() []string { - i := 0 - for _, a := range os.Args { - i++ - - if a == "--" { - break - } - } - - return os.Args[i:] -} - -// loadConfigFromFd loads a container's config from the sync pipe that is provided by -// fd 3 when running a process -func loadConfigFromFd() (*libcontainer.Config, error) { - pipe := os.NewFile(3, "pipe") - defer pipe.Close() - - var config *libcontainer.Config - if err := json.NewDecoder(pipe).Decode(&config); err != nil { - return nil, err - } - return config, nil -} - -func preload(context *cli.Context) error { - if logPath != "" { - if err := openLog(logPath); err != nil { - return err - } - } - - return nil -} - -func runFunc(f *rFunc) { - userArgs := findUserArgs() - - config, err := loadConfigFromFd() - if err != nil { - log.Fatalf("unable to receive config from sync pipe: %s", err) - } - - f.Action(config, userArgs) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/process.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/process.go deleted file mode 100644 index 489666a5878..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/process.go +++ /dev/null @@ -1,27 +0,0 @@ -package libcontainer - -import "io" - -// Configuration for a process to be run inside a container. -type ProcessConfig struct { - // The command to be run followed by any arguments. - Args []string - - // Map of environment variables to their values. - Env []string - - // Stdin is a pointer to a reader which provides the standard input stream. - // Stdout is a pointer to a writer which receives the standard output stream. - // Stderr is a pointer to a writer which receives the standard error stream. - // - // If a reader or writer is nil, the input stream is assumed to be empty and the output is - // discarded. - // - // The readers and writers, if supplied, are closed when the process terminates. Their Close - // methods should be idempotent. - // - // Stdout and Stderr may refer to the same writer in which case the output is interspersed. - Stdin io.ReadCloser - Stdout io.WriteCloser - Stderr io.WriteCloser -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/README.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/README.md deleted file mode 100644 index 4ccc6cde944..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/README.md +++ /dev/null @@ -1,5 +0,0 @@ -These configuration files can be used with `nsinit` to quickly develop, test, -and experiment with features of libcontainer. - -When consuming these configuration files, copy them into your rootfs and rename -the file to `container.json` for use with `nsinit`. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/apparmor.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/apparmor.json deleted file mode 100644 index 96f73cb7949..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/apparmor.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "apparmor_profile": "docker-default", - "mount_config": { - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type":"NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWPID"}, - {"type": "NEWUTS"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - } - ], - "tty": true, - "user": "daemon" -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json deleted file mode 100644 index e5c03a7ef42..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "mount_config": { - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type": "NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWPID"}, - {"type": "NEWUTS"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - }, - { - "address": "172.17.0.101/16", - "bridge": "docker0", - "veth_prefix": "veth", - "gateway": "172.17.42.1", - "mtu": 1500, - "type": "veth" - } - ], - "tty": true -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/host-pid.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/host-pid.json deleted file mode 100644 index f47af930e6e..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/host-pid.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "mount_config": { - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "mounts": [ - { - "type": "tmpfs", - "destination": "/tmp" - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type": "NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWUTS"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - } - ], - "tty": true, - "user": "daemon" -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json deleted file mode 100644 index 01de467468f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/minimal.json +++ /dev/null @@ -1,201 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "mount_config": { - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "mounts": [ - { - "type": "tmpfs", - "destination": "/tmp" - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type": "NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWPID"}, - {"type": "NEWUTS"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - } - ], - "tty": true, - "user": "daemon" -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/route_source_address_selection.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/route_source_address_selection.json deleted file mode 100644 index 9c62045a4bb..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/route_source_address_selection.json +++ /dev/null @@ -1,209 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "mount_config": { - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type": "NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWPID"}, - {"type": "NEWUTS"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - }, - { - "address": "172.17.0.101/16", - "bridge": "docker0", - "veth_prefix": "veth", - "mtu": 1500, - "type": "veth" - } - ], - "routes": [ - { - "destination": "0.0.0.0/0", - "source": "172.17.0.101", - "gateway": "172.17.42.1", - "interface_name": "eth0" - } - ], - "tty": true -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/selinux.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/selinux.json deleted file mode 100644 index 15556488a27..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/selinux.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "process_label": "system_u:system_r:svirt_lxc_net_t:s0:c164,c475", - "mount_config": { - "mount_label": "system_u:system_r:svirt_lxc_net_t:s0:c164,c475", - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type": "NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWPID"}, - {"type": "NEWUTS"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - } - ], - "tty": true, - "user": "daemon" -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/userns.json b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/userns.json deleted file mode 100644 index 8c9c841f14a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/sample_configs/userns.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "capabilities": [ - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "MKNOD", - "NET_RAW", - "SETGID", - "SETUID", - "SETFCAP", - "SETPCAP", - "NET_BIND_SERVICE", - "SYS_CHROOT", - "KILL" - ], - "cgroups": { - "allowed_devices": [ - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "m", - "major_number": -1, - "minor_number": -1, - "type": 98 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 1, - "path": "/dev/console", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "path": "/dev/tty0", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 4, - "minor_number": 1, - "path": "/dev/tty1", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 136, - "minor_number": -1, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 5, - "minor_number": 2, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "major_number": 10, - "minor_number": 200, - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "name": "docker-koye", - "parent": "docker" - }, - "restrict_sys": true, - "mount_config": { - "device_nodes": [ - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 3, - "path": "/dev/null", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 5, - "path": "/dev/zero", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 7, - "path": "/dev/full", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 5, - "path": "/dev/tty", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 9, - "path": "/dev/urandom", - "type": 99 - }, - { - "cgroup_permissions": "rwm", - "file_mode": 438, - "major_number": 1, - "minor_number": 8, - "path": "/dev/random", - "type": 99 - } - ], - "mounts": [ - { - "type": "tmpfs", - "destination": "/tmp" - } - ] - }, - "environment": [ - "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "HOSTNAME=koye", - "TERM=xterm" - ], - "hostname": "koye", - "namespaces": [ - {"type": "NEWIPC"}, - {"type": "NEWNET"}, - {"type": "NEWNS"}, - {"type": "NEWPID"}, - {"type": "NEWUTS"}, - {"type": "NEWUSER"} - ], - "networks": [ - { - "address": "127.0.0.1/0", - "gateway": "localhost", - "mtu": 1500, - "type": "loopback" - }, - { - "address": "172.17.0.9/16", - "gateway": "172.17.42.1", - "bridge": "docker0", - "veth_prefix": "veth", - "mtu": 1500, - "type": "veth" - } - ], - "tty": true, - "user": "root", - "uid_mappings": [ - { - "container_id": 0, - "host_id": 1000, - "size": 1 - }, - { - "container_id": 1, - "host_id": 1, - "size": 999 - }, - { - "container_id": 1001, - "host_id": 1001, - "size": 9000 - } - ], - "gid_mappings": [ - { - "container_id": 0, - "host_id": 1000, - "size": 1 - }, - { - "container_id": 1, - "host_id": 1, - "size": 999 - }, - { - "container_id": 1001, - "host_id": 1001, - "size": 9000 - } - ], - "rlimits": [ - { - "type": 7, - "hard": 999, - "soft": 999 - } - ] -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/capabilities.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/capabilities.go deleted file mode 100644 index e01464fdb34..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/capabilities.go +++ /dev/null @@ -1,54 +0,0 @@ -package capabilities - -import ( - "github.com/syndtr/gocapability/capability" -) - -const allCapabilityTypes = capability.CAPS | capability.BOUNDS - -// DropBoundingSet drops the capability bounding set to those specified in the -// container configuration. -func DropBoundingSet(capabilities []string) error { - c, err := capability.NewPid(0) - if err != nil { - return err - } - - keep := getEnabledCapabilities(capabilities) - c.Clear(capability.BOUNDS) - c.Set(capability.BOUNDS, keep...) - - if err := c.Apply(capability.BOUNDS); err != nil { - return err - } - - return nil -} - -// DropCapabilities drops all capabilities for the current process except those specified in the container configuration. -func DropCapabilities(capList []string) error { - c, err := capability.NewPid(0) - if err != nil { - return err - } - - keep := getEnabledCapabilities(capList) - c.Clear(allCapabilityTypes) - c.Set(allCapabilityTypes, keep...) - - if err := c.Apply(allCapabilityTypes); err != nil { - return err - } - return nil -} - -// getEnabledCapabilities returns the capabilities that should not be dropped by the container. -func getEnabledCapabilities(capList []string) []capability.Cap { - keep := []capability.Cap{} - for _, capability := range capList { - if c := GetCapability(capability); c != nil { - keep = append(keep, c.Value) - } - } - return keep -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/types.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/types.go deleted file mode 100644 index a960b804c68..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/types.go +++ /dev/null @@ -1,88 +0,0 @@ -package capabilities - -import "github.com/syndtr/gocapability/capability" - -type ( - CapabilityMapping struct { - Key string `json:"key,omitempty"` - Value capability.Cap `json:"value,omitempty"` - } - Capabilities []*CapabilityMapping -) - -func (c *CapabilityMapping) String() string { - return c.Key -} - -func GetCapability(key string) *CapabilityMapping { - for _, capp := range capabilityList { - if capp.Key == key { - cpy := *capp - return &cpy - } - } - return nil -} - -func GetAllCapabilities() []string { - output := make([]string, len(capabilityList)) - for i, capability := range capabilityList { - output[i] = capability.String() - } - return output -} - -// Contains returns true if the specified Capability is -// in the slice -func (c Capabilities) contains(capp string) bool { - return c.get(capp) != nil -} - -func (c Capabilities) get(capp string) *CapabilityMapping { - for _, cap := range c { - if cap.Key == capp { - return cap - } - } - return nil -} - -var capabilityList = Capabilities{ - {Key: "SETPCAP", Value: capability.CAP_SETPCAP}, - {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE}, - {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO}, - {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT}, - {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN}, - {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE}, - {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE}, - {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME}, - {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG}, - {Key: "MKNOD", Value: capability.CAP_MKNOD}, - {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE}, - {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL}, - {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE}, - {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN}, - {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN}, - {Key: "SYSLOG", Value: capability.CAP_SYSLOG}, - {Key: "CHOWN", Value: capability.CAP_CHOWN}, - {Key: "NET_RAW", Value: capability.CAP_NET_RAW}, - {Key: "DAC_OVERRIDE", Value: capability.CAP_DAC_OVERRIDE}, - {Key: "FOWNER", Value: capability.CAP_FOWNER}, - {Key: "DAC_READ_SEARCH", Value: capability.CAP_DAC_READ_SEARCH}, - {Key: "FSETID", Value: capability.CAP_FSETID}, - {Key: "KILL", Value: capability.CAP_KILL}, - {Key: "SETGID", Value: capability.CAP_SETGID}, - {Key: "SETUID", Value: capability.CAP_SETUID}, - {Key: "LINUX_IMMUTABLE", Value: capability.CAP_LINUX_IMMUTABLE}, - {Key: "NET_BIND_SERVICE", Value: capability.CAP_NET_BIND_SERVICE}, - {Key: "NET_BROADCAST", Value: capability.CAP_NET_BROADCAST}, - {Key: "IPC_LOCK", Value: capability.CAP_IPC_LOCK}, - {Key: "IPC_OWNER", Value: capability.CAP_IPC_OWNER}, - {Key: "SYS_CHROOT", Value: capability.CAP_SYS_CHROOT}, - {Key: "SYS_PTRACE", Value: capability.CAP_SYS_PTRACE}, - {Key: "SYS_BOOT", Value: capability.CAP_SYS_BOOT}, - {Key: "LEASE", Value: capability.CAP_LEASE}, - {Key: "SETFCAP", Value: capability.CAP_SETFCAP}, - {Key: "WAKE_ALARM", Value: capability.CAP_WAKE_ALARM}, - {Key: "BLOCK_SUSPEND", Value: capability.CAP_BLOCK_SUSPEND}, -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/types_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/types_test.go deleted file mode 100644 index 06e8a2b01c8..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/capabilities/types_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package capabilities - -import ( - "testing" -) - -func TestCapabilitiesContains(t *testing.T) { - caps := Capabilities{ - GetCapability("MKNOD"), - GetCapability("SETPCAP"), - } - - if caps.contains("SYS_ADMIN") { - t.Fatal("capabilities should not contain SYS_ADMIN") - } - if !caps.contains("MKNOD") { - t.Fatal("capabilities should contain MKNOD but does not") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/restrict/restrict.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/restrict/restrict.go deleted file mode 100644 index dd765b1f1b8..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/restrict/restrict.go +++ /dev/null @@ -1,53 +0,0 @@ -// +build linux - -package restrict - -import ( - "fmt" - "os" - "syscall" - "time" -) - -const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV - -func mountReadonly(path string) error { - for i := 0; i < 5; i++ { - if err := syscall.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil && !os.IsNotExist(err) { - switch err { - case syscall.EINVAL: - // Probably not a mountpoint, use bind-mount - if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil { - return err - } - - return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "") - case syscall.EBUSY: - time.Sleep(100 * time.Millisecond) - continue - default: - return err - } - } - - return nil - } - - return fmt.Errorf("unable to mount %s as readonly max retries reached", path) -} - -// This has to be called while the container still has CAP_SYS_ADMIN (to be able to perform mounts). -// However, afterwards, CAP_SYS_ADMIN should be dropped (otherwise the user will be able to revert those changes). -func Restrict(mounts ...string) error { - for _, dest := range mounts { - if err := mountReadonly(dest); err != nil { - return fmt.Errorf("unable to remount %s readonly: %s", dest, err) - } - } - - if err := syscall.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("unable to bind-mount /dev/null over /proc/kcore: %s", err) - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/restrict/unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/restrict/unsupported.go deleted file mode 100644 index 464e8d498d7..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/security/restrict/unsupported.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !linux - -package restrict - -import "fmt" - -func Restrict() error { - return fmt.Errorf("not supported") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/selinux/selinux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/selinux/selinux.go deleted file mode 100644 index e5bd8209809..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/selinux/selinux.go +++ /dev/null @@ -1,461 +0,0 @@ -// +build linux - -package selinux - -import ( - "bufio" - "crypto/rand" - "encoding/binary" - "fmt" - "io" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" - "syscall" - - "github.com/docker/docker/pkg/mount" - "github.com/docker/libcontainer/system" -) - -const ( - Enforcing = 1 - Permissive = 0 - Disabled = -1 - selinuxDir = "/etc/selinux/" - selinuxConfig = selinuxDir + "config" - selinuxTypeTag = "SELINUXTYPE" - selinuxTag = "SELINUX" - selinuxPath = "/sys/fs/selinux" - xattrNameSelinux = "security.selinux" - stRdOnly = 0x01 -) - -var ( - assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`) - spaceRegex = regexp.MustCompile(`^([^=]+) (.*)$`) - mcsList = make(map[string]bool) - selinuxfs = "unknown" - selinuxEnabled = false - selinuxEnabledChecked = false -) - -type SELinuxContext map[string]string - -// SetDisabled disables selinux support for the package -func SetDisabled() { - selinuxEnabled, selinuxEnabledChecked = false, true -} - -func getSelinuxMountPoint() string { - if selinuxfs != "unknown" { - return selinuxfs - } - selinuxfs = "" - - mounts, err := mount.GetMounts() - if err != nil { - return selinuxfs - } - for _, mount := range mounts { - if mount.Fstype == "selinuxfs" { - selinuxfs = mount.Mountpoint - break - } - } - if selinuxfs != "" { - var buf syscall.Statfs_t - syscall.Statfs(selinuxfs, &buf) - if (buf.Flags & stRdOnly) == 1 { - selinuxfs = "" - } - } - return selinuxfs -} - -func SelinuxEnabled() bool { - if selinuxEnabledChecked { - return selinuxEnabled - } - selinuxEnabledChecked = true - if fs := getSelinuxMountPoint(); fs != "" { - if con, _ := Getcon(); con != "kernel" { - selinuxEnabled = true - } - } - return selinuxEnabled -} - -func readConfig(target string) (value string) { - var ( - val, key string - bufin *bufio.Reader - ) - - in, err := os.Open(selinuxConfig) - if err != nil { - return "" - } - defer in.Close() - - bufin = bufio.NewReader(in) - - for done := false; !done; { - var line string - if line, err = bufin.ReadString('\n'); err != nil { - if err != io.EOF { - return "" - } - done = true - } - line = strings.TrimSpace(line) - if len(line) == 0 { - // Skip blank lines - continue - } - if line[0] == ';' || line[0] == '#' { - // Skip comments - continue - } - if groups := assignRegex.FindStringSubmatch(line); groups != nil { - key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2]) - if key == target { - return strings.Trim(val, "\"") - } - } - } - return "" -} - -func getSELinuxPolicyRoot() string { - return selinuxDir + readConfig(selinuxTypeTag) -} - -func readCon(name string) (string, error) { - var val string - - in, err := os.Open(name) - if err != nil { - return "", err - } - defer in.Close() - - _, err = fmt.Fscanf(in, "%s", &val) - return val, err -} - -func Setfilecon(path string, scon string) error { - return system.Lsetxattr(path, xattrNameSelinux, []byte(scon), 0) -} - -// Return the SELinux label for this path -func Getfilecon(path string) (string, error) { - con, err := system.Lgetxattr(path, xattrNameSelinux) - return string(con), err -} - -func Setfscreatecon(scon string) error { - return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), scon) -} - -func Getfscreatecon() (string, error) { - return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid())) -} - -// Return the SELinux label of the current process thread. -func Getcon() (string, error) { - return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid())) -} - -func Getpidcon(pid int) (string, error) { - return readCon(fmt.Sprintf("/proc/%d/attr/current", pid)) -} - -func Getexeccon() (string, error) { - return readCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid())) -} - -func writeCon(name string, val string) error { - out, err := os.OpenFile(name, os.O_WRONLY, 0) - if err != nil { - return err - } - defer out.Close() - - if val != "" { - _, err = out.Write([]byte(val)) - } else { - _, err = out.Write(nil) - } - return err -} - -func Setexeccon(scon string) error { - return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), scon) -} - -func (c SELinuxContext) Get() string { - return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"]) -} - -func NewContext(scon string) SELinuxContext { - c := make(SELinuxContext) - - if len(scon) != 0 { - con := strings.SplitN(scon, ":", 4) - c["user"] = con[0] - c["role"] = con[1] - c["type"] = con[2] - c["level"] = con[3] - } - return c -} - -func ReserveLabel(scon string) { - if len(scon) != 0 { - con := strings.SplitN(scon, ":", 4) - mcsAdd(con[3]) - } -} - -func SelinuxGetEnforce() int { - var enforce int - - enforceS, err := readCon(fmt.Sprintf("%s/enforce", selinuxPath)) - if err != nil { - return -1 - } - - enforce, err = strconv.Atoi(string(enforceS)) - if err != nil { - return -1 - } - return enforce -} - -func SelinuxGetEnforceMode() int { - switch readConfig(selinuxTag) { - case "enforcing": - return Enforcing - case "permissive": - return Permissive - } - return Disabled -} - -func mcsAdd(mcs string) error { - if mcsList[mcs] { - return fmt.Errorf("MCS Label already exists") - } - mcsList[mcs] = true - return nil -} - -func mcsDelete(mcs string) { - mcsList[mcs] = false -} - -func mcsExists(mcs string) bool { - return mcsList[mcs] -} - -func IntToMcs(id int, catRange uint32) string { - var ( - SETSIZE = int(catRange) - TIER = SETSIZE - ORD = id - ) - - if id < 1 || id > 523776 { - return "" - } - - for ORD > TIER { - ORD = ORD - TIER - TIER -= 1 - } - TIER = SETSIZE - TIER - ORD = ORD + TIER - return fmt.Sprintf("s0:c%d,c%d", TIER, ORD) -} - -func uniqMcs(catRange uint32) string { - var ( - n uint32 - c1, c2 uint32 - mcs string - ) - - for { - binary.Read(rand.Reader, binary.LittleEndian, &n) - c1 = n % catRange - binary.Read(rand.Reader, binary.LittleEndian, &n) - c2 = n % catRange - if c1 == c2 { - continue - } else { - if c1 > c2 { - t := c1 - c1 = c2 - c2 = t - } - } - mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2) - if err := mcsAdd(mcs); err != nil { - continue - } - break - } - return mcs -} - -func FreeLxcContexts(scon string) { - if len(scon) != 0 { - con := strings.SplitN(scon, ":", 4) - mcsDelete(con[3]) - } -} - -func GetLxcContexts() (processLabel string, fileLabel string) { - var ( - val, key string - bufin *bufio.Reader - ) - - if !SelinuxEnabled() { - return "", "" - } - lxcPath := fmt.Sprintf("%s/contexts/lxc_contexts", getSELinuxPolicyRoot()) - in, err := os.Open(lxcPath) - if err != nil { - return "", "" - } - defer in.Close() - - bufin = bufio.NewReader(in) - - for done := false; !done; { - var line string - if line, err = bufin.ReadString('\n'); err != nil { - if err == io.EOF { - done = true - } else { - goto exit - } - } - line = strings.TrimSpace(line) - if len(line) == 0 { - // Skip blank lines - continue - } - if line[0] == ';' || line[0] == '#' { - // Skip comments - continue - } - if groups := assignRegex.FindStringSubmatch(line); groups != nil { - key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2]) - if key == "process" { - processLabel = strings.Trim(val, "\"") - } - if key == "file" { - fileLabel = strings.Trim(val, "\"") - } - } - } - - if processLabel == "" || fileLabel == "" { - return "", "" - } - -exit: - // mcs := IntToMcs(os.Getpid(), 1024) - mcs := uniqMcs(1024) - scon := NewContext(processLabel) - scon["level"] = mcs - processLabel = scon.Get() - scon = NewContext(fileLabel) - scon["level"] = mcs - fileLabel = scon.Get() - return processLabel, fileLabel -} - -func SecurityCheckContext(val string) error { - return writeCon(fmt.Sprintf("%s.context", selinuxPath), val) -} - -func CopyLevel(src, dest string) (string, error) { - if src == "" { - return "", nil - } - if err := SecurityCheckContext(src); err != nil { - return "", err - } - if err := SecurityCheckContext(dest); err != nil { - return "", err - } - scon := NewContext(src) - tcon := NewContext(dest) - mcsDelete(tcon["level"]) - mcsAdd(scon["level"]) - tcon["level"] = scon["level"] - return tcon.Get(), nil -} - -// Prevent users from relabing system files -func badPrefix(fpath string) error { - var badprefixes = []string{"/usr"} - - for _, prefix := range badprefixes { - if fpath == prefix || strings.HasPrefix(fpath, fmt.Sprintf("%s/", prefix)) { - return fmt.Errorf("Relabeling content in %s is not allowed.", prefix) - } - } - return nil -} - -// Change the fpath file object to the SELinux label scon. -// If the fpath is a directory and recurse is true Chcon will walk the -// directory tree setting the label -func Chcon(fpath string, scon string, recurse bool) error { - if scon == "" { - return nil - } - if err := badPrefix(fpath); err != nil { - return err - } - callback := func(p string, info os.FileInfo, err error) error { - return Setfilecon(p, scon) - } - - if recurse { - return filepath.Walk(fpath, callback) - } - - return Setfilecon(fpath, scon) -} - -// DupSecOpt takes an SELinux process label and returns security options that -// can will set the SELinux Type and Level for future container processes -func DupSecOpt(src string) []string { - if src == "" { - return nil - } - con := NewContext(src) - if con["user"] == "" || - con["role"] == "" || - con["type"] == "" || - con["level"] == "" { - return nil - } - return []string{"label:user:" + con["user"], - "label:role:" + con["role"], - "label:type:" + con["type"], - "label:level:" + con["level"]} -} - -// DisableSecOpt returns a security opt that can be used to disabling SELinux -// labeling support for future container processes -func DisableSecOpt() []string { - return []string{"label:disable"} -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/state.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/state.go deleted file mode 100644 index 208b4c62762..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/state.go +++ /dev/null @@ -1,77 +0,0 @@ -package libcontainer - -import ( - "encoding/json" - "os" - "path/filepath" - - "github.com/docker/libcontainer/network" -) - -// State represents a running container's state -type State struct { - // InitPid is the init process id in the parent namespace - InitPid int `json:"init_pid,omitempty"` - - // InitStartTime is the init process start time - InitStartTime string `json:"init_start_time,omitempty"` - - // Network runtime state. - NetworkState network.NetworkState `json:"network_state,omitempty"` - - // Path to all the cgroups setup for a container. Key is cgroup subsystem name. - CgroupPaths map[string]string `json:"cgroup_paths,omitempty"` -} - -// The running state of the container. -type RunState int - -const ( - // The name of the runtime state file - stateFile = "state.json" - - // The container exists and is running. - Running RunState = iota - - // The container exists, it is in the process of being paused. - Pausing - - // The container exists, but all its processes are paused. - Paused - - // The container does not exist. - Destroyed -) - -// SaveState writes the container's runtime state to a state.json file -// in the specified path -func SaveState(basePath string, state *State) error { - f, err := os.Create(filepath.Join(basePath, stateFile)) - if err != nil { - return err - } - defer f.Close() - - return json.NewEncoder(f).Encode(state) -} - -// GetState reads the state.json file for a running container -func GetState(basePath string) (*State, error) { - f, err := os.Open(filepath.Join(basePath, stateFile)) - if err != nil { - return nil, err - } - defer f.Close() - - var state *State - if err := json.NewDecoder(f).Decode(&state); err != nil { - return nil, err - } - - return state, nil -} - -// DeleteState deletes the state.json file -func DeleteState(basePath string) error { - return os.Remove(filepath.Join(basePath, stateFile)) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/linux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/linux.go deleted file mode 100644 index c07ef1532dd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/linux.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build linux - -package system - -import ( - "os/exec" - "syscall" - "unsafe" -) - -func Execv(cmd string, args []string, env []string) error { - name, err := exec.LookPath(cmd) - if err != nil { - return err - } - - return syscall.Exec(name, args, env) -} - -func ParentDeathSignal(sig uintptr) error { - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, sig, 0); err != 0 { - return err - } - return nil -} - -func GetParentDeathSignal() (int, error) { - var sig int - - _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0) - - if err != 0 { - return -1, err - } - - return sig, nil -} - -func SetKeepCaps() error { - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 { - return err - } - - return nil -} - -func ClearKeepCaps() error { - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 { - return err - } - - return nil -} - -func Setctty() error { - if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 { - return err - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/proc.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/proc.go deleted file mode 100644 index 37808a29f6a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/proc.go +++ /dev/null @@ -1,27 +0,0 @@ -package system - -import ( - "io/ioutil" - "path/filepath" - "strconv" - "strings" -) - -// look in /proc to find the process start time so that we can verify -// that this pid has started after ourself -func GetProcessStartTime(pid int) (string, error) { - data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat")) - if err != nil { - return "", err - } - - parts := strings.Split(string(data), " ") - // the starttime is located at pos 22 - // from the man page - // - // starttime %llu (was %lu before Linux 2.6) - // (22) The time the process started after system boot. In kernels before Linux 2.6, this - // value was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks - // (divide by sysconf(_SC_CLK_TCK)). - return parts[22-1], nil // starts at 1 -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/setns_linux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/setns_linux.go deleted file mode 100644 index 228e6ccd7f4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/setns_linux.go +++ /dev/null @@ -1,34 +0,0 @@ -package system - -import ( - "fmt" - "runtime" - "syscall" -) - -// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092 -// -// We need different setns values for the different platforms and arch -// We are declaring the macro here because the SETNS syscall does not exist in th stdlib -var setNsMap = map[string]uintptr{ - "linux/386": 346, - "linux/amd64": 308, - "linux/arm": 374, - "linux/ppc64": 350, - "linux/ppc64le": 350, - "linux/s390x": 339, -} - -func Setns(fd uintptr, flags uintptr) error { - ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)] - if !exists { - return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH) - } - - _, _, err := syscall.RawSyscall(ns, fd, flags, 0) - if err != 0 { - return err - } - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_386.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_386.go deleted file mode 100644 index 2fcbf21309e..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_386.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build linux,386 -package system - -import ( - "syscall" -) - -// Setuid sets the uid of the calling thread to the specified uid. -func Setuid(uid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// Setgid sets the gid of the calling thread to the specified gid. -func Setgid(gid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_64.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_64.go deleted file mode 100644 index 6840c3770f4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_64.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build linux,amd64 linux,ppc64 linux,ppc64le linux,s390x - -package system - -import ( - "syscall" -) - -// Setuid sets the uid of the calling thread to the specified uid. -func Setuid(uid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// Setgid sets the gid of the calling thread to the specified gid. -func Setgid(gid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID, uintptr(gid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_arm.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_arm.go deleted file mode 100644 index 7d8cda9d009..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/syscall_linux_arm.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build linux,arm -package system - -import ( - "syscall" -) - -// Setuid sets the uid of the calling thread to the specified uid. -func Setuid(uid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// Setgid sets the gid of the calling thread to the specified gid. -func Setgid(gid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/sysconfig.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/sysconfig.go deleted file mode 100644 index 5efddefa79f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/sysconfig.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build cgo - -package system - -/* -#include -*/ -import "C" - -func GetClockTicks() int { - return int(C.sysconf(C._SC_CLK_TCK)) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/sysconfig_notcgo.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/sysconfig_notcgo.go deleted file mode 100644 index 663db82bce8..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/sysconfig_notcgo.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build !cgo - -package system - -func GetClockTicks() int { - // TODO figure out a better alternative for platforms where we're missing cgo - return 100 -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/xattrs_linux.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/xattrs_linux.go deleted file mode 100644 index 30f74dfb1b4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/system/xattrs_linux.go +++ /dev/null @@ -1,99 +0,0 @@ -package system - -import ( - "syscall" - "unsafe" -) - -var _zero uintptr - -// Returns the size of xattrs and nil error -// Requires path, takes allocated []byte or nil as last argument -func Llistxattr(path string, dest []byte) (size int, err error) { - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return -1, err - } - var newpathBytes unsafe.Pointer - if len(dest) > 0 { - newpathBytes = unsafe.Pointer(&dest[0]) - } else { - newpathBytes = unsafe.Pointer(&_zero) - } - - _size, _, errno := syscall.Syscall6(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0) - size = int(_size) - if errno != 0 { - return -1, errno - } - - return size, nil -} - -// Returns a []byte slice if the xattr is set and nil otherwise -// Requires path and its attribute as arguments -func Lgetxattr(path string, attr string) ([]byte, error) { - var sz int - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return nil, err - } - attrBytes, err := syscall.BytePtrFromString(attr) - if err != nil { - return nil, err - } - - // Start with a 128 length byte array - sz = 128 - dest := make([]byte, sz) - destBytes := unsafe.Pointer(&dest[0]) - _sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) - - switch { - case errno == syscall.ENODATA: - return nil, errno - case errno == syscall.ENOTSUP: - return nil, errno - case errno == syscall.ERANGE: - // 128 byte array might just not be good enough, - // A dummy buffer is used ``uintptr(0)`` to get real size - // of the xattrs on disk - _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0) - sz = int(_sz) - if sz < 0 { - return nil, errno - } - dest = make([]byte, sz) - destBytes := unsafe.Pointer(&dest[0]) - _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) - if errno != 0 { - return nil, errno - } - case errno != 0: - return nil, errno - } - sz = int(_sz) - return dest[:sz], nil -} - -func Lsetxattr(path string, attr string, data []byte, flags int) error { - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - attrBytes, err := syscall.BytePtrFromString(attr) - if err != nil { - return err - } - var dataBytes unsafe.Pointer - if len(data) > 0 { - dataBytes = unsafe.Pointer(&data[0]) - } else { - dataBytes = unsafe.Pointer(&_zero) - } - _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) - if errno != 0 { - return errno - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/types.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/types.go deleted file mode 100644 index c341137ec8d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/types.go +++ /dev/null @@ -1,11 +0,0 @@ -package libcontainer - -import ( - "github.com/docker/libcontainer/cgroups" - "github.com/docker/libcontainer/network" -) - -type ContainerStats struct { - NetworkStats *network.NetworkStats `json:"network_stats,omitempty"` - CgroupStats *cgroups.Stats `json:"cgroup_stats,omitempty"` -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/update-vendor.sh b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/update-vendor.sh deleted file mode 100644 index 6f61083cbdb..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/update-vendor.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -set -e - -cd "$(dirname "$BASH_SOURCE")" - -# Downloads dependencies into vendor/ directory -mkdir -p vendor -cd vendor - -clone() { - vcs=$1 - pkg=$2 - rev=$3 - - pkg_url=https://$pkg - target_dir=src/$pkg - - echo -n "$pkg @ $rev: " - - if [ -d $target_dir ]; then - echo -n 'rm old, ' - rm -fr $target_dir - fi - - echo -n 'clone, ' - case $vcs in - git) - git clone --quiet --no-checkout $pkg_url $target_dir - ( cd $target_dir && git reset --quiet --hard $rev ) - ;; - hg) - hg clone --quiet --updaterev $rev $pkg_url $target_dir - ;; - esac - - echo -n 'rm VCS, ' - ( cd $target_dir && rm -rf .{git,hg} ) - - echo done -} - -# the following lines are in sorted order, FYI -clone git github.com/codegangsta/cli 1.1.0 -clone git github.com/coreos/go-systemd v2 -clone git github.com/godbus/dbus v2 -clone git github.com/syndtr/gocapability 1cf3ac4dc4 - -# intentionally not vendoring Docker itself... that'd be a circle :) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/MAINTAINERS b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/MAINTAINERS deleted file mode 100644 index edbe2006694..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Tianon Gravi (@tianon) -Aleksa Sarai (@cyphar) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup.go deleted file mode 100644 index 6f8a982ff72..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup.go +++ /dev/null @@ -1,108 +0,0 @@ -package user - -import ( - "errors" - "fmt" - "syscall" -) - -var ( - // The current operating system does not provide the required data for user lookups. - ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data") -) - -func lookupUser(filter func(u User) bool) (User, error) { - // Get operating system-specific passwd reader-closer. - passwd, err := GetPasswd() - if err != nil { - return User{}, err - } - defer passwd.Close() - - // Get the users. - users, err := ParsePasswdFilter(passwd, filter) - if err != nil { - return User{}, err - } - - // No user entries found. - if len(users) == 0 { - return User{}, fmt.Errorf("no matching entries in passwd file") - } - - // Assume the first entry is the "correct" one. - return users[0], nil -} - -// CurrentUser looks up the current user by their user id in /etc/passwd. If the -// user cannot be found (or there is no /etc/passwd file on the filesystem), -// then CurrentUser returns an error. -func CurrentUser() (User, error) { - return LookupUid(syscall.Getuid()) -} - -// LookupUser looks up a user by their username in /etc/passwd. If the user -// cannot be found (or there is no /etc/passwd file on the filesystem), then -// LookupUser returns an error. -func LookupUser(username string) (User, error) { - return lookupUser(func(u User) bool { - return u.Name == username - }) -} - -// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot -// be found (or there is no /etc/passwd file on the filesystem), then LookupId -// returns an error. -func LookupUid(uid int) (User, error) { - return lookupUser(func(u User) bool { - return u.Uid == uid - }) -} - -func lookupGroup(filter func(g Group) bool) (Group, error) { - // Get operating system-specific group reader-closer. - group, err := GetGroup() - if err != nil { - return Group{}, err - } - defer group.Close() - - // Get the users. - groups, err := ParseGroupFilter(group, filter) - if err != nil { - return Group{}, err - } - - // No user entries found. - if len(groups) == 0 { - return Group{}, fmt.Errorf("no matching entries in group file") - } - - // Assume the first entry is the "correct" one. - return groups[0], nil -} - -// CurrentGroup looks up the current user's group by their primary group id's -// entry in /etc/passwd. If the group cannot be found (or there is no -// /etc/group file on the filesystem), then CurrentGroup returns an error. -func CurrentGroup() (Group, error) { - return LookupGid(syscall.Getgid()) -} - -// LookupGroup looks up a group by its name in /etc/group. If the group cannot -// be found (or there is no /etc/group file on the filesystem), then LookupGroup -// returns an error. -func LookupGroup(groupname string) (Group, error) { - return lookupGroup(func(g Group) bool { - return g.Name == groupname - }) -} - -// LookupGid looks up a group by its group id in /etc/group. If the group cannot -// be found (or there is no /etc/group file on the filesystem), then LookupGid -// returns an error. -func LookupGid(gid int) (Group, error) { - return lookupGroup(func(g Group) bool { - return g.Gid == gid - }) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup_unix.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup_unix.go deleted file mode 100644 index 758b734c225..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup_unix.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build darwin dragonfly freebsd linux netbsd openbsd solaris - -package user - -import ( - "io" - "os" -) - -// Unix-specific path to the passwd and group formatted files. -const ( - unixPasswdPath = "/etc/passwd" - unixGroupPath = "/etc/group" -) - -func GetPasswdPath() (string, error) { - return unixPasswdPath, nil -} - -func GetPasswd() (io.ReadCloser, error) { - return os.Open(unixPasswdPath) -} - -func GetGroupPath() (string, error) { - return unixGroupPath, nil -} - -func GetGroup() (io.ReadCloser, error) { - return os.Open(unixGroupPath) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup_unsupported.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup_unsupported.go deleted file mode 100644 index 7217948870c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/lookup_unsupported.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris - -package user - -import "io" - -func GetPasswdPath() (string, error) { - return "", ErrUnsupported -} - -func GetPasswd() (io.ReadCloser, error) { - return nil, ErrUnsupported -} - -func GetGroupPath() (string, error) { - return "", ErrUnsupported -} - -func GetGroup() (io.ReadCloser, error) { - return nil, ErrUnsupported -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/user.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/user.go deleted file mode 100644 index d7439f12e39..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/user.go +++ /dev/null @@ -1,350 +0,0 @@ -package user - -import ( - "bufio" - "fmt" - "io" - "os" - "strconv" - "strings" -) - -const ( - minId = 0 - maxId = 1<<31 - 1 //for 32-bit systems compatibility -) - -var ( - ErrRange = fmt.Errorf("Uids and gids must be in range %d-%d", minId, maxId) -) - -type User struct { - Name string - Pass string - Uid int - Gid int - Gecos string - Home string - Shell string -} - -type Group struct { - Name string - Pass string - Gid int - List []string -} - -func parseLine(line string, v ...interface{}) { - if line == "" { - return - } - - parts := strings.Split(line, ":") - for i, p := range parts { - if len(v) <= i { - // if we have more "parts" than we have places to put them, bail for great "tolerance" of naughty configuration files - break - } - - switch e := v[i].(type) { - case *string: - // "root", "adm", "/bin/bash" - *e = p - case *int: - // "0", "4", "1000" - // ignore string to int conversion errors, for great "tolerance" of naughty configuration files - *e, _ = strconv.Atoi(p) - case *[]string: - // "", "root", "root,adm,daemon" - if p != "" { - *e = strings.Split(p, ",") - } else { - *e = []string{} - } - default: - // panic, because this is a programming/logic error, not a runtime one - panic("parseLine expects only pointers! argument " + strconv.Itoa(i) + " is not a pointer!") - } - } -} - -func ParsePasswdFile(path string) ([]User, error) { - passwd, err := os.Open(path) - if err != nil { - return nil, err - } - defer passwd.Close() - return ParsePasswd(passwd) -} - -func ParsePasswd(passwd io.Reader) ([]User, error) { - return ParsePasswdFilter(passwd, nil) -} - -func ParsePasswdFileFilter(path string, filter func(User) bool) ([]User, error) { - passwd, err := os.Open(path) - if err != nil { - return nil, err - } - defer passwd.Close() - return ParsePasswdFilter(passwd, filter) -} - -func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) { - if r == nil { - return nil, fmt.Errorf("nil source for passwd-formatted data") - } - - var ( - s = bufio.NewScanner(r) - out = []User{} - ) - - for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - text := strings.TrimSpace(s.Text()) - if text == "" { - continue - } - - // see: man 5 passwd - // name:password:UID:GID:GECOS:directory:shell - // Name:Pass:Uid:Gid:Gecos:Home:Shell - // root:x:0:0:root:/root:/bin/bash - // adm:x:3:4:adm:/var/adm:/bin/false - p := User{} - parseLine( - text, - &p.Name, &p.Pass, &p.Uid, &p.Gid, &p.Gecos, &p.Home, &p.Shell, - ) - - if filter == nil || filter(p) { - out = append(out, p) - } - } - - return out, nil -} - -func ParseGroupFile(path string) ([]Group, error) { - group, err := os.Open(path) - if err != nil { - return nil, err - } - defer group.Close() - return ParseGroup(group) -} - -func ParseGroup(group io.Reader) ([]Group, error) { - return ParseGroupFilter(group, nil) -} - -func ParseGroupFileFilter(path string, filter func(Group) bool) ([]Group, error) { - group, err := os.Open(path) - if err != nil { - return nil, err - } - defer group.Close() - return ParseGroupFilter(group, filter) -} - -func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { - if r == nil { - return nil, fmt.Errorf("nil source for group-formatted data") - } - - var ( - s = bufio.NewScanner(r) - out = []Group{} - ) - - for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - text := s.Text() - if text == "" { - continue - } - - // see: man 5 group - // group_name:password:GID:user_list - // Name:Pass:Gid:List - // root:x:0:root - // adm:x:4:root,adm,daemon - p := Group{} - parseLine( - text, - &p.Name, &p.Pass, &p.Gid, &p.List, - ) - - if filter == nil || filter(p) { - out = append(out, p) - } - } - - return out, nil -} - -type ExecUser struct { - Uid, Gid int - Sgids []int - Home string -} - -// GetExecUserPath is a wrapper for GetExecUser. It reads data from each of the -// given file paths and uses that data as the arguments to GetExecUser. If the -// files cannot be opened for any reason, the error is ignored and a nil -// io.Reader is passed instead. -func GetExecUserPath(userSpec string, defaults *ExecUser, passwdPath, groupPath string) (*ExecUser, error) { - passwd, err := os.Open(passwdPath) - if err != nil { - passwd = nil - } else { - defer passwd.Close() - } - - group, err := os.Open(groupPath) - if err != nil { - group = nil - } else { - defer group.Close() - } - - return GetExecUser(userSpec, defaults, passwd, group) -} - -// GetExecUser parses a user specification string (using the passwd and group -// readers as sources for /etc/passwd and /etc/group data, respectively). In -// the case of blank fields or missing data from the sources, the values in -// defaults is used. -// -// GetExecUser will return an error if a user or group literal could not be -// found in any entry in passwd and group respectively. -// -// Examples of valid user specifications are: -// * "" -// * "user" -// * "uid" -// * "user:group" -// * "uid:gid -// * "user:gid" -// * "uid:group" -func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (*ExecUser, error) { - var ( - userArg, groupArg string - name string - ) - - if defaults == nil { - defaults = new(ExecUser) - } - - // Copy over defaults. - user := &ExecUser{ - Uid: defaults.Uid, - Gid: defaults.Gid, - Sgids: defaults.Sgids, - Home: defaults.Home, - } - - // Sgids slice *cannot* be nil. - if user.Sgids == nil { - user.Sgids = []int{} - } - - // allow for userArg to have either "user" syntax, or optionally "user:group" syntax - parseLine(userSpec, &userArg, &groupArg) - - users, err := ParsePasswdFilter(passwd, func(u User) bool { - if userArg == "" { - return u.Uid == user.Uid - } - return u.Name == userArg || strconv.Itoa(u.Uid) == userArg - }) - if err != nil && passwd != nil { - if userArg == "" { - userArg = strconv.Itoa(user.Uid) - } - return nil, fmt.Errorf("Unable to find user %v: %v", userArg, err) - } - - haveUser := users != nil && len(users) > 0 - if haveUser { - // if we found any user entries that matched our filter, let's take the first one as "correct" - name = users[0].Name - user.Uid = users[0].Uid - user.Gid = users[0].Gid - user.Home = users[0].Home - } else if userArg != "" { - // we asked for a user but didn't find them... let's check to see if we wanted a numeric user - user.Uid, err = strconv.Atoi(userArg) - if err != nil { - // not numeric - we have to bail - return nil, fmt.Errorf("Unable to find user %v", userArg) - } - - // Must be inside valid uid range. - if user.Uid < minId || user.Uid > maxId { - return nil, ErrRange - } - - // if userArg couldn't be found in /etc/passwd but is numeric, just roll with it - this is legit - } - - if groupArg != "" || name != "" { - groups, err := ParseGroupFilter(group, func(g Group) bool { - // Explicit group format takes precedence. - if groupArg != "" { - return g.Name == groupArg || strconv.Itoa(g.Gid) == groupArg - } - - // Check if user is a member. - for _, u := range g.List { - if u == name { - return true - } - } - - return false - }) - if err != nil && group != nil { - return nil, fmt.Errorf("Unable to find groups for user %v: %v", users[0].Name, err) - } - - haveGroup := groups != nil && len(groups) > 0 - if groupArg != "" { - if haveGroup { - // if we found any group entries that matched our filter, let's take the first one as "correct" - user.Gid = groups[0].Gid - } else { - // we asked for a group but didn't find id... let's check to see if we wanted a numeric group - user.Gid, err = strconv.Atoi(groupArg) - if err != nil { - // not numeric - we have to bail - return nil, fmt.Errorf("Unable to find group %v", groupArg) - } - - // Ensure gid is inside gid range. - if user.Gid < minId || user.Gid > maxId { - return nil, ErrRange - } - - // if groupArg couldn't be found in /etc/group but is numeric, just roll with it - this is legit - } - } else if haveGroup { - // If implicit group format, fill supplementary gids. - user.Sgids = make([]int, len(groups)) - for i, group := range groups { - user.Sgids[i] = group.Gid - } - } - } - - return user, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/user_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/user_test.go deleted file mode 100644 index 4fe008fb397..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/user/user_test.go +++ /dev/null @@ -1,352 +0,0 @@ -package user - -import ( - "io" - "reflect" - "strings" - "testing" -) - -func TestUserParseLine(t *testing.T) { - var ( - a, b string - c []string - d int - ) - - parseLine("", &a, &b) - if a != "" || b != "" { - t.Fatalf("a and b should be empty ('%v', '%v')", a, b) - } - - parseLine("a", &a, &b) - if a != "a" || b != "" { - t.Fatalf("a should be 'a' and b should be empty ('%v', '%v')", a, b) - } - - parseLine("bad boys:corny cows", &a, &b) - if a != "bad boys" || b != "corny cows" { - t.Fatalf("a should be 'bad boys' and b should be 'corny cows' ('%v', '%v')", a, b) - } - - parseLine("", &c) - if len(c) != 0 { - t.Fatalf("c should be empty (%#v)", c) - } - - parseLine("d,e,f:g:h:i,j,k", &c, &a, &b, &c) - if a != "g" || b != "h" || len(c) != 3 || c[0] != "i" || c[1] != "j" || c[2] != "k" { - t.Fatalf("a should be 'g', b should be 'h', and c should be ['i','j','k'] ('%v', '%v', '%#v')", a, b, c) - } - - parseLine("::::::::::", &a, &b, &c) - if a != "" || b != "" || len(c) != 0 { - t.Fatalf("a, b, and c should all be empty ('%v', '%v', '%#v')", a, b, c) - } - - parseLine("not a number", &d) - if d != 0 { - t.Fatalf("d should be 0 (%v)", d) - } - - parseLine("b:12:c", &a, &d, &b) - if a != "b" || b != "c" || d != 12 { - t.Fatalf("a should be 'b' and b should be 'c', and d should be 12 ('%v', '%v', %v)", a, b, d) - } -} - -func TestUserParsePasswd(t *testing.T) { - users, err := ParsePasswdFilter(strings.NewReader(` -root:x:0:0:root:/root:/bin/bash -adm:x:3:4:adm:/var/adm:/bin/false -this is just some garbage data -`), nil) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if len(users) != 3 { - t.Fatalf("Expected 3 users, got %v", len(users)) - } - if users[0].Uid != 0 || users[0].Name != "root" { - t.Fatalf("Expected users[0] to be 0 - root, got %v - %v", users[0].Uid, users[0].Name) - } - if users[1].Uid != 3 || users[1].Name != "adm" { - t.Fatalf("Expected users[1] to be 3 - adm, got %v - %v", users[1].Uid, users[1].Name) - } -} - -func TestUserParseGroup(t *testing.T) { - groups, err := ParseGroupFilter(strings.NewReader(` -root:x:0:root -adm:x:4:root,adm,daemon -this is just some garbage data -`), nil) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if len(groups) != 3 { - t.Fatalf("Expected 3 groups, got %v", len(groups)) - } - if groups[0].Gid != 0 || groups[0].Name != "root" || len(groups[0].List) != 1 { - t.Fatalf("Expected groups[0] to be 0 - root - 1 member, got %v - %v - %v", groups[0].Gid, groups[0].Name, len(groups[0].List)) - } - if groups[1].Gid != 4 || groups[1].Name != "adm" || len(groups[1].List) != 3 { - t.Fatalf("Expected groups[1] to be 4 - adm - 3 members, got %v - %v - %v", groups[1].Gid, groups[1].Name, len(groups[1].List)) - } -} - -func TestValidGetExecUser(t *testing.T) { - const passwdContent = ` -root:x:0:0:root user:/root:/bin/bash -adm:x:42:43:adm:/var/adm:/bin/false -this is just some garbage data -` - const groupContent = ` -root:x:0:root -adm:x:43: -grp:x:1234:root,adm -this is just some garbage data -` - defaultExecUser := ExecUser{ - Uid: 8888, - Gid: 8888, - Sgids: []int{8888}, - Home: "/8888", - } - - tests := []struct { - ref string - expected ExecUser - }{ - { - ref: "root", - expected: ExecUser{ - Uid: 0, - Gid: 0, - Sgids: []int{0, 1234}, - Home: "/root", - }, - }, - { - ref: "adm", - expected: ExecUser{ - Uid: 42, - Gid: 43, - Sgids: []int{1234}, - Home: "/var/adm", - }, - }, - { - ref: "root:adm", - expected: ExecUser{ - Uid: 0, - Gid: 43, - Sgids: defaultExecUser.Sgids, - Home: "/root", - }, - }, - { - ref: "adm:1234", - expected: ExecUser{ - Uid: 42, - Gid: 1234, - Sgids: defaultExecUser.Sgids, - Home: "/var/adm", - }, - }, - { - ref: "42:1234", - expected: ExecUser{ - Uid: 42, - Gid: 1234, - Sgids: defaultExecUser.Sgids, - Home: "/var/adm", - }, - }, - { - ref: "1337:1234", - expected: ExecUser{ - Uid: 1337, - Gid: 1234, - Sgids: defaultExecUser.Sgids, - Home: defaultExecUser.Home, - }, - }, - { - ref: "1337", - expected: ExecUser{ - Uid: 1337, - Gid: defaultExecUser.Gid, - Sgids: defaultExecUser.Sgids, - Home: defaultExecUser.Home, - }, - }, - { - ref: "", - expected: ExecUser{ - Uid: defaultExecUser.Uid, - Gid: defaultExecUser.Gid, - Sgids: defaultExecUser.Sgids, - Home: defaultExecUser.Home, - }, - }, - } - - for _, test := range tests { - passwd := strings.NewReader(passwdContent) - group := strings.NewReader(groupContent) - - execUser, err := GetExecUser(test.ref, &defaultExecUser, passwd, group) - if err != nil { - t.Logf("got unexpected error when parsing '%s': %s", test.ref, err.Error()) - t.Fail() - continue - } - - if !reflect.DeepEqual(test.expected, *execUser) { - t.Logf("got: %#v", execUser) - t.Logf("expected: %#v", test.expected) - t.Fail() - continue - } - } -} - -func TestInvalidGetExecUser(t *testing.T) { - const passwdContent = ` -root:x:0:0:root user:/root:/bin/bash -adm:x:42:43:adm:/var/adm:/bin/false -this is just some garbage data -` - const groupContent = ` -root:x:0:root -adm:x:43: -grp:x:1234:root,adm -this is just some garbage data -` - - tests := []string{ - // No such user/group. - "notuser", - "notuser:notgroup", - "root:notgroup", - "notuser:adm", - "8888:notgroup", - "notuser:8888", - - // Invalid user/group values. - "-1:0", - "0:-3", - "-5:-2", - } - - for _, test := range tests { - passwd := strings.NewReader(passwdContent) - group := strings.NewReader(groupContent) - - execUser, err := GetExecUser(test, nil, passwd, group) - if err == nil { - t.Logf("got unexpected success when parsing '%s': %#v", test, execUser) - t.Fail() - continue - } - } -} - -func TestGetExecUserNilSources(t *testing.T) { - const passwdContent = ` -root:x:0:0:root user:/root:/bin/bash -adm:x:42:43:adm:/var/adm:/bin/false -this is just some garbage data -` - const groupContent = ` -root:x:0:root -adm:x:43: -grp:x:1234:root,adm -this is just some garbage data -` - - defaultExecUser := ExecUser{ - Uid: 8888, - Gid: 8888, - Sgids: []int{8888}, - Home: "/8888", - } - - tests := []struct { - ref string - passwd, group bool - expected ExecUser - }{ - { - ref: "", - passwd: false, - group: false, - expected: ExecUser{ - Uid: 8888, - Gid: 8888, - Sgids: []int{8888}, - Home: "/8888", - }, - }, - { - ref: "root", - passwd: true, - group: false, - expected: ExecUser{ - Uid: 0, - Gid: 0, - Sgids: []int{8888}, - Home: "/root", - }, - }, - { - ref: "0", - passwd: false, - group: false, - expected: ExecUser{ - Uid: 0, - Gid: 8888, - Sgids: []int{8888}, - Home: "/8888", - }, - }, - { - ref: "0:0", - passwd: false, - group: false, - expected: ExecUser{ - Uid: 0, - Gid: 0, - Sgids: []int{8888}, - Home: "/8888", - }, - }, - } - - for _, test := range tests { - var passwd, group io.Reader - - if test.passwd { - passwd = strings.NewReader(passwdContent) - } - - if test.group { - group = strings.NewReader(groupContent) - } - - execUser, err := GetExecUser(test.ref, &defaultExecUser, passwd, group) - if err != nil { - t.Logf("got unexpected error when parsing '%s': %s", test.ref, err.Error()) - t.Fail() - continue - } - - if !reflect.DeepEqual(test.expected, *execUser) { - t.Logf("got: %#v", execUser) - t.Logf("expected: %#v", test.expected) - t.Fail() - continue - } - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/utils/utils.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/utils/utils.go deleted file mode 100644 index 76184ce00b7..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/utils/utils.go +++ /dev/null @@ -1,55 +0,0 @@ -package utils - -import ( - "crypto/rand" - "encoding/hex" - "io" - "io/ioutil" - "path/filepath" - "strconv" - "syscall" -) - -// GenerateRandomName returns a new name joined with a prefix. This size -// specified is used to truncate the randomly generated value -func GenerateRandomName(prefix string, size int) (string, error) { - id := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, id); err != nil { - return "", err - } - return prefix + hex.EncodeToString(id)[:size], nil -} - -// ResolveRootfs ensures that the current working directory is -// not a symlink and returns the absolute path to the rootfs -func ResolveRootfs(uncleanRootfs string) (string, error) { - rootfs, err := filepath.Abs(uncleanRootfs) - if err != nil { - return "", err - } - return filepath.EvalSymlinks(rootfs) -} - -func CloseExecFrom(minFd int) error { - fdList, err := ioutil.ReadDir("/proc/self/fd") - if err != nil { - return err - } - for _, fi := range fdList { - fd, err := strconv.Atoi(fi.Name()) - if err != nil { - // ignore non-numeric file names - continue - } - - if fd < minFd { - // ignore descriptors lower than our specified minimum - continue - } - - // intentionally ignore errors from syscall.CloseOnExec - syscall.CloseOnExec(fd) - // the cases where this might fail are basically file descriptors that have already been closed (including and especially the one that was created when ioutil.ReadDir did the "opendir" syscall) - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml deleted file mode 100644 index baf46abc6f0..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go -go: 1.1 - -script: -- go vet ./... -- go test -v ./... diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE deleted file mode 100644 index 5515ccfb716..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (C) 2013 Jeremy Saenz -All Rights Reserved. - -MIT LICENSE - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md deleted file mode 100644 index 59806f4b90d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md +++ /dev/null @@ -1,257 +0,0 @@ -[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli) - -# cli.go -cli.go is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. - -You can view the API docs here: -http://godoc.org/github.com/codegangsta/cli - -## Overview -Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app. - -This is where cli.go comes into play. cli.go makes command line programming fun, organized, and expressive! - -## Installation -Make sure you have a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html). - -To install cli.go, simply run: -``` -$ go get github.com/codegangsta/cli -``` - -Make sure your PATH includes to the `$GOPATH/bin` directory so your commands can be easily used: -``` -export PATH=$PATH:$GOPATH/bin -``` - -## Getting Started -One of the philosophies behind cli.go is that an API should be playful and full of discovery. So a cli.go app can be as little as one line of code in `main()`. - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - cli.NewApp().Run(os.Args) -} -``` - -This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation: - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "boom" - app.Usage = "make an explosive entrance" - app.Action = func(c *cli.Context) { - println("boom! I say!") - } - - app.Run(os.Args) -} -``` - -Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below. - -## Example - -Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness! - -``` go -/* greet.go */ -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "greet" - app.Usage = "fight the loneliness!" - app.Action = func(c *cli.Context) { - println("Hello friend!") - } - - app.Run(os.Args) -} -``` - -Install our command to the `$GOPATH/bin` directory: - -``` -$ go install -``` - -Finally run our new command: - -``` -$ greet -Hello friend! -``` - -cli.go also generates some bitchass help text: -``` -$ greet help -NAME: - greet - fight the loneliness! - -USAGE: - greet [global options] command [command options] [arguments...] - -VERSION: - 0.0.0 - -COMMANDS: - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS - --version Shows version information -``` - -### Arguments -You can lookup arguments by calling the `Args` function on cli.Context. - -``` go -... -app.Action = func(c *cli.Context) { - println("Hello", c.Args()[0]) -} -... -``` - -### Flags -Setting and querying flags is simple. -``` go -... -app.Flags = []cli.Flag { - cli.StringFlag{Name: "lang", Value: "english", Usage: "language for the greeting"}, -} -app.Action = func(c *cli.Context) { - name := "someone" - if len(c.Args()) > 0 { - name = c.Args()[0] - } - if c.String("lang") == "spanish" { - println("Hola", name) - } else { - println("Hello", name) - } -} -... -``` - -#### Alternate Names - -You can set alternate (or short) names for flags by providing a comma-delimited list for the Name. e.g. - -``` go -app.Flags = []cli.Flag { - cli.StringFlag{Name: "lang, l", Value: "english", Usage: "language for the greeting"}, -} -``` - -That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error. - -### Subcommands - -Subcommands can be defined for a more git-like command line app. -```go -... -app.Commands = []cli.Command{ - { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) - }, - }, - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - }, - { - Name: "template", - ShortName: "r", - Usage: "options for task templates", - Subcommands: []cli.Command{ - { - Name: "add", - Usage: "add a new template", - Action: func(c *cli.Context) { - println("new task template: ", c.Args().First()) - }, - }, - { - Name: "remove", - Usage: "remove an existing template", - Action: func(c *cli.Context) { - println("removed task template: ", c.Args().First()) - }, - }, - }, - }, -} -... -``` - -### Bash Completion - -You can enable completion commands by setting the EnableBashCompletion -flag on the App object. By default, this setting will only auto-complete to -show an app's subcommands, but you can write your own completion methods for -the App or its subcommands. -```go -... -var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"} -app := cli.NewApp() -app.EnableBashCompletion = true -app.Commands = []cli.Command{ - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - BashComplete: func(c *cli.Context) { - // This will complete if no args are passed - if len(c.Args()) > 0 { - return - } - for _, t := range tasks { - println(t) - } - }, - } -} -... -``` - -#### To Enable - -Source the autocomplete/bash_autocomplete file in your .bashrc file while -setting the PROG variable to the name of your program: - -`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` - - -## About -cli.go is written by none other than the [Code Gangsta](http://codegangsta.io) diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go deleted file mode 100644 index e193b8282eb..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go +++ /dev/null @@ -1,248 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "os" - "time" -) - -// App is the main structure of a cli application. It is recomended that -// and app be created with the cli.NewApp() function -type App struct { - // The name of the program. Defaults to os.Args[0] - Name string - // Description of the program. - Usage string - // Version of the program - Version string - // List of commands to execute - Commands []Command - // List of flags to parse - Flags []Flag - // Boolean to enable bash completion commands - EnableBashCompletion bool - // Boolean to hide built-in help command - HideHelp bool - // An action to execute when the bash-completion flag is set - BashComplete func(context *Context) - // An action to execute before any subcommands are run, but after the context is ready - // If a non-nil error is returned, no subcommands are run - Before func(context *Context) error - // The action to execute when no subcommands are specified - Action func(context *Context) - // Execute this function if the proper command cannot be found - CommandNotFound func(context *Context, command string) - // Compilation date - Compiled time.Time - // Author - Author string - // Author e-mail - Email string -} - -// Tries to find out when this binary was compiled. -// Returns the current time if it fails to find it. -func compileTime() time.Time { - info, err := os.Stat(os.Args[0]) - if err != nil { - return time.Now() - } - return info.ModTime() -} - -// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action. -func NewApp() *App { - return &App{ - Name: os.Args[0], - Usage: "A new cli application", - Version: "0.0.0", - BashComplete: DefaultAppComplete, - Action: helpCommand.Action, - Compiled: compileTime(), - Author: "Author", - Email: "unknown@email", - } -} - -// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination -func (a *App) Run(arguments []string) error { - // append help to commands - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - a.appendFlag(HelpFlag) - } - - //append version/help flags - if a.EnableBashCompletion { - a.appendFlag(BashCompletionFlag) - } - a.appendFlag(VersionFlag) - - // parse flags - set := flagSet(a.Name, a.Flags) - set.SetOutput(ioutil.Discard) - err := set.Parse(arguments[1:]) - nerr := normalizeFlags(a.Flags, set) - if nerr != nil { - fmt.Println(nerr) - context := NewContext(a, set, set) - ShowAppHelp(context) - fmt.Println("") - return nerr - } - context := NewContext(a, set, set) - - if err != nil { - fmt.Printf("Incorrect Usage.\n\n") - ShowAppHelp(context) - fmt.Println("") - return err - } - - if checkCompletions(context) { - return nil - } - - if checkHelp(context) { - return nil - } - - if checkVersion(context) { - return nil - } - - if a.Before != nil { - err := a.Before(context) - if err != nil { - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - a.Action(context) - return nil -} - -// Another entry point to the cli app, takes care of passing arguments and error handling -func (a *App) RunAndExitOnError() { - if err := a.Run(os.Args); err != nil { - os.Stderr.WriteString(fmt.Sprintln(err)) - os.Exit(1) - } -} - -// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags -func (a *App) RunAsSubcommand(ctx *Context) error { - // append help to commands - if len(a.Commands) > 0 { - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - a.appendFlag(HelpFlag) - } - } - - // append flags - if a.EnableBashCompletion { - a.appendFlag(BashCompletionFlag) - } - - // parse flags - set := flagSet(a.Name, a.Flags) - set.SetOutput(ioutil.Discard) - err := set.Parse(ctx.Args().Tail()) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, ctx.globalSet) - - if nerr != nil { - fmt.Println(nerr) - if len(a.Commands) > 0 { - ShowSubcommandHelp(context) - } else { - ShowCommandHelp(ctx, context.Args().First()) - } - fmt.Println("") - return nerr - } - - if err != nil { - fmt.Printf("Incorrect Usage.\n\n") - ShowSubcommandHelp(context) - return err - } - - if checkCompletions(context) { - return nil - } - - if len(a.Commands) > 0 { - if checkSubcommandHelp(context) { - return nil - } - } else { - if checkCommandHelp(ctx, context.Args().First()) { - return nil - } - } - - if a.Before != nil { - err := a.Before(context) - if err != nil { - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - if len(a.Commands) > 0 { - a.Action(context) - } else { - a.Action(ctx) - } - - return nil -} - -// Returns the named command on App. Returns nil if the command does not exist -func (a *App) Command(name string) *Command { - for _, c := range a.Commands { - if c.HasName(name) { - return &c - } - } - - return nil -} - -func (a *App) hasFlag(flag Flag) bool { - for _, f := range a.Flags { - if flag == f { - return true - } - } - - return false -} - -func (a *App) appendFlag(flag Flag) { - if !a.hasFlag(flag) { - a.Flags = append(a.Flags, flag) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go deleted file mode 100644 index a9156241032..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go +++ /dev/null @@ -1,399 +0,0 @@ -package cli_test - -import ( - "fmt" - "os" - "testing" - - "github.com/codegangsta/cli" -) - -func ExampleApp() { - // set args for examples sake - os.Args = []string{"greet", "--name", "Jeremy"} - - app := cli.NewApp() - app.Name = "greet" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, - } - app.Action = func(c *cli.Context) { - fmt.Printf("Hello %v\n", c.String("name")) - } - app.Run(os.Args) - // Output: - // Hello Jeremy -} - -func ExampleAppSubcommand() { - // set args for examples sake - os.Args = []string{"say", "hi", "english", "--name", "Jeremy"} - app := cli.NewApp() - app.Name = "say" - app.Commands = []cli.Command{ - { - Name: "hello", - ShortName: "hi", - Usage: "use it to see a description", - Description: "This is how we describe hello the function", - Subcommands: []cli.Command{ - { - Name: "english", - ShortName: "en", - Usage: "sends a greeting in english", - Description: "greets someone in english", - Flags: []cli.Flag{ - cli.StringFlag{Name: "name", Value: "Bob", Usage: "Name of the person to greet"}, - }, - Action: func(c *cli.Context) { - fmt.Println("Hello,", c.String("name")) - }, - }, - }, - }, - } - - app.Run(os.Args) - // Output: - // Hello, Jeremy -} - -func ExampleAppHelp() { - // set args for examples sake - os.Args = []string{"greet", "h", "describeit"} - - app := cli.NewApp() - app.Name = "greet" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, - } - app.Commands = []cli.Command{ - { - Name: "describeit", - ShortName: "d", - Usage: "use it to see a description", - Description: "This is how we describe describeit the function", - Action: func(c *cli.Context) { - fmt.Printf("i like to describe things") - }, - }, - } - app.Run(os.Args) - // Output: - // NAME: - // describeit - use it to see a description - // - // USAGE: - // command describeit [arguments...] - // - // DESCRIPTION: - // This is how we describe describeit the function -} - -func ExampleAppBashComplete() { - // set args for examples sake - os.Args = []string{"greet", "--generate-bash-completion"} - - app := cli.NewApp() - app.Name = "greet" - app.EnableBashCompletion = true - app.Commands = []cli.Command{ - { - Name: "describeit", - ShortName: "d", - Usage: "use it to see a description", - Description: "This is how we describe describeit the function", - Action: func(c *cli.Context) { - fmt.Printf("i like to describe things") - }, - }, { - Name: "next", - Usage: "next example", - Description: "more stuff to see when generating bash completion", - Action: func(c *cli.Context) { - fmt.Printf("the next example") - }, - }, - } - - app.Run(os.Args) - // Output: - // describeit - // d - // next - // help - // h -} - -func TestApp_Run(t *testing.T) { - s := "" - - app := cli.NewApp() - app.Action = func(c *cli.Context) { - s = s + c.Args().First() - } - - err := app.Run([]string{"command", "foo"}) - expect(t, err, nil) - err = app.Run([]string{"command", "bar"}) - expect(t, err, nil) - expect(t, s, "foobar") -} - -var commandAppTests = []struct { - name string - expected bool -}{ - {"foobar", true}, - {"batbaz", true}, - {"b", true}, - {"f", true}, - {"bat", false}, - {"nothing", false}, -} - -func TestApp_Command(t *testing.T) { - app := cli.NewApp() - fooCommand := cli.Command{Name: "foobar", ShortName: "f"} - batCommand := cli.Command{Name: "batbaz", ShortName: "b"} - app.Commands = []cli.Command{ - fooCommand, - batCommand, - } - - for _, test := range commandAppTests { - expect(t, app.Command(test.name) != nil, test.expected) - } -} - -func TestApp_CommandWithArgBeforeFlags(t *testing.T) { - var parsedOption, firstArg string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.StringFlag{Name: "option", Value: "", Usage: "some option"}, - }, - Action: func(c *cli.Context) { - parsedOption = c.String("option") - firstArg = c.Args().First() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"}) - - expect(t, parsedOption, "my-option") - expect(t, firstArg, "my-arg") -} - -func TestApp_Float64Flag(t *testing.T) { - var meters float64 - - app := cli.NewApp() - app.Flags = []cli.Flag{ - cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"}, - } - app.Action = func(c *cli.Context) { - meters = c.Float64("height") - } - - app.Run([]string{"", "--height", "1.93"}) - expect(t, meters, 1.93) -} - -func TestApp_ParseSliceFlags(t *testing.T) { - var parsedOption, firstArg string - var parsedIntSlice []int - var parsedStringSlice []string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"}, - cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"}, - }, - Action: func(c *cli.Context) { - parsedIntSlice = c.IntSlice("p") - parsedStringSlice = c.StringSlice("ip") - parsedOption = c.String("option") - firstArg = c.Args().First() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"}) - - IntsEquals := func(a, b []int) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true - } - - StrsEquals := func(a, b []string) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true - } - var expectedIntSlice = []int{22, 80} - var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"} - - if !IntsEquals(parsedIntSlice, expectedIntSlice) { - t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice) - } - - if !StrsEquals(parsedStringSlice, expectedStringSlice) { - t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice) - } -} - -func TestApp_BeforeFunc(t *testing.T) { - beforeRun, subcommandRun := false, false - beforeError := fmt.Errorf("fail") - var err error - - app := cli.NewApp() - - app.Before = func(c *cli.Context) error { - beforeRun = true - s := c.String("opt") - if s == "fail" { - return beforeError - } - - return nil - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "sub", - Action: func(c *cli.Context) { - subcommandRun = true - }, - }, - } - - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "opt"}, - } - - // run with the Before() func succeeding - err = app.Run([]string{"command", "--opt", "succeed", "sub"}) - - if err != nil { - t.Fatalf("Run error: %s", err) - } - - if beforeRun == false { - t.Errorf("Before() not executed when expected") - } - - if subcommandRun == false { - t.Errorf("Subcommand not executed when expected") - } - - // reset - beforeRun, subcommandRun = false, false - - // run with the Before() func failing - err = app.Run([]string{"command", "--opt", "fail", "sub"}) - - // should be the same error produced by the Before func - if err != beforeError { - t.Errorf("Run error expected, but not received") - } - - if beforeRun == false { - t.Errorf("Before() not executed when expected") - } - - if subcommandRun == true { - t.Errorf("Subcommand executed when NOT expected") - } - -} - -func TestAppHelpPrinter(t *testing.T) { - oldPrinter := cli.HelpPrinter - defer func() { - cli.HelpPrinter = oldPrinter - }() - - var wasCalled = false - cli.HelpPrinter = func(template string, data interface{}) { - wasCalled = true - } - - app := cli.NewApp() - app.Run([]string{"-h"}) - - if wasCalled == false { - t.Errorf("Help printer expected to be called, but was not") - } -} - -func TestAppCommandNotFound(t *testing.T) { - beforeRun, subcommandRun := false, false - app := cli.NewApp() - - app.CommandNotFound = func(c *cli.Context, command string) { - beforeRun = true - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "bar", - Action: func(c *cli.Context) { - subcommandRun = true - }, - }, - } - - app.Run([]string{"command", "foo"}) - - expect(t, beforeRun, true) - expect(t, subcommandRun, false) -} - -func TestGlobalFlagsInSubcommands(t *testing.T) { - subcommandRun := false - app := cli.NewApp() - - app.Flags = []cli.Flag{ - cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "foo", - Subcommands: []cli.Command{ - { - Name: "bar", - Action: func(c *cli.Context) { - if c.GlobalBool("debug") { - subcommandRun = true - } - }, - }, - }, - }, - } - - app.Run([]string{"command", "-d", "foo", "bar"}) - - expect(t, subcommandRun, true) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete deleted file mode 100644 index a860e038d86..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/bash - -_cli_bash_autocomplete() { - local cur prev opts base - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - opts=$( ${COMP_WORDS[@]:0:COMP_CWORD} --generate-bash-completion ) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - } - - complete -F _cli_bash_autocomplete $PROG \ No newline at end of file diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go deleted file mode 100644 index b7425458123..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go +++ /dev/null @@ -1,19 +0,0 @@ -// Package cli provides a minimal framework for creating and organizing command line -// Go applications. cli is designed to be easy to understand and write, the most simple -// cli application can be written as follows: -// func main() { -// cli.NewApp().Run(os.Args) -// } -// -// Of course this application does not do much, so let's make this an actual application: -// func main() { -// app := cli.NewApp() -// app.Name = "greet" -// app.Usage = "say a greeting" -// app.Action = func(c *cli.Context) { -// println("Greetings") -// } -// -// app.Run(os.Args) -// } -package cli diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go deleted file mode 100644 index 4d7bd8479a4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package cli_test - -import ( - "os" - - "github.com/codegangsta/cli" -) - -func Example() { - app := cli.NewApp() - app.Name = "todo" - app.Usage = "task list on the command line" - app.Commands = []cli.Command{ - { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) - }, - }, - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - }, - } - - app.Run(os.Args) -} - -func ExampleSubcommand() { - app := cli.NewApp() - app.Name = "say" - app.Commands = []cli.Command{ - { - Name: "hello", - ShortName: "hi", - Usage: "use it to see a description", - Description: "This is how we describe hello the function", - Subcommands: []cli.Command{ - { - Name: "english", - ShortName: "en", - Usage: "sends a greeting in english", - Description: "greets someone in english", - Flags: []cli.Flag{ - cli.StringFlag{Name: "name", Value: "Bob", Usage: "Name of the person to greet"}, - }, - Action: func(c *cli.Context) { - println("Hello, ", c.String("name")) - }, - }, { - Name: "spanish", - ShortName: "sp", - Usage: "sends a greeting in spanish", - Flags: []cli.Flag{ - cli.StringFlag{Name: "surname", Value: "Jones", Usage: "Surname of the person to greet"}, - }, - Action: func(c *cli.Context) { - println("Hola, ", c.String("surname")) - }, - }, { - Name: "french", - ShortName: "fr", - Usage: "sends a greeting in french", - Flags: []cli.Flag{ - cli.StringFlag{Name: "nickname", Value: "Stevie", Usage: "Nickname of the person to greet"}, - }, - Action: func(c *cli.Context) { - println("Bonjour, ", c.String("nickname")) - }, - }, - }, - }, { - Name: "bye", - Usage: "says goodbye", - Action: func(c *cli.Context) { - println("bye") - }, - }, - } - - app.Run(os.Args) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go deleted file mode 100644 index dcc8de5c9a9..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go +++ /dev/null @@ -1,141 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "strings" -) - -// Command is a subcommand for a cli.App. -type Command struct { - // The name of the command - Name string - // short name of the command. Typically one character - ShortName string - // A short description of the usage of this command - Usage string - // A longer explanation of how the command works - Description string - // The function to call when checking for bash command completions - BashComplete func(context *Context) - // An action to execute before any sub-subcommands are run, but after the context is ready - // If a non-nil error is returned, no sub-subcommands are run - Before func(context *Context) error - // The function to call when this command is invoked - Action func(context *Context) - // List of child commands - Subcommands []Command - // List of flags to parse - Flags []Flag - // Treat all flags as normal arguments if true - SkipFlagParsing bool - // Boolean to hide built-in help command - HideHelp bool -} - -// Invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c Command) Run(ctx *Context) error { - - if len(c.Subcommands) > 0 || c.Before != nil { - return c.startApp(ctx) - } - - if !c.HideHelp { - // append help to flags - c.Flags = append( - c.Flags, - HelpFlag, - ) - } - - if ctx.App.EnableBashCompletion { - c.Flags = append(c.Flags, BashCompletionFlag) - } - - set := flagSet(c.Name, c.Flags) - set.SetOutput(ioutil.Discard) - - firstFlagIndex := -1 - for index, arg := range ctx.Args() { - if strings.HasPrefix(arg, "-") { - firstFlagIndex = index - break - } - } - - var err error - if firstFlagIndex > -1 && !c.SkipFlagParsing { - args := ctx.Args() - regularArgs := args[1:firstFlagIndex] - flagArgs := args[firstFlagIndex:] - err = set.Parse(append(flagArgs, regularArgs...)) - } else { - err = set.Parse(ctx.Args().Tail()) - } - - if err != nil { - fmt.Printf("Incorrect Usage.\n\n") - ShowCommandHelp(ctx, c.Name) - fmt.Println("") - return err - } - - nerr := normalizeFlags(c.Flags, set) - if nerr != nil { - fmt.Println(nerr) - fmt.Println("") - ShowCommandHelp(ctx, c.Name) - fmt.Println("") - return nerr - } - context := NewContext(ctx.App, set, ctx.globalSet) - - if checkCommandCompletions(context, c.Name) { - return nil - } - - if checkCommandHelp(context, c.Name) { - return nil - } - context.Command = c - c.Action(context) - return nil -} - -// Returns true if Command.Name or Command.ShortName matches given name -func (c Command) HasName(name string) bool { - return c.Name == name || c.ShortName == name -} - -func (c Command) startApp(ctx *Context) error { - app := NewApp() - - // set the name and usage - app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) - if c.Description != "" { - app.Usage = c.Description - } else { - app.Usage = c.Usage - } - - // set the flags and commands - app.Commands = c.Subcommands - app.Flags = c.Flags - app.HideHelp = c.HideHelp - - // bash completion - app.EnableBashCompletion = ctx.App.EnableBashCompletion - if c.BashComplete != nil { - app.BashComplete = c.BashComplete - } - - // set the actions - app.Before = c.Before - if c.Action != nil { - app.Action = c.Action - } else { - app.Action = helpSubcommand.Action - } - - return app.RunAsSubcommand(ctx) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go deleted file mode 100644 index 3afd83e7a67..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package cli_test - -import ( - "flag" - "github.com/codegangsta/cli" - "testing" -) - -func TestCommandDoNotIgnoreFlags(t *testing.T) { - app := cli.NewApp() - set := flag.NewFlagSet("test", 0) - test := []string{"blah", "blah", "-break"} - set.Parse(test) - - c := cli.NewContext(app, set, set) - - command := cli.Command { - Name: "test-cmd", - ShortName: "tc", - Usage: "this is for testing", - Description: "testing", - Action: func(_ *cli.Context) { }, - } - err := command.Run(c) - - expect(t, err.Error(), "flag provided but not defined: -break") -} - -func TestCommandIgnoreFlags(t *testing.T) { - app := cli.NewApp() - set := flag.NewFlagSet("test", 0) - test := []string{"blah", "blah"} - set.Parse(test) - - c := cli.NewContext(app, set, set) - - command := cli.Command { - Name: "test-cmd", - ShortName: "tc", - Usage: "this is for testing", - Description: "testing", - Action: func(_ *cli.Context) { }, - SkipFlagParsing: true, - } - err := command.Run(c) - - expect(t, err, nil) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go deleted file mode 100644 index 1e023ceff95..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go +++ /dev/null @@ -1,280 +0,0 @@ -package cli - -import ( - "errors" - "flag" - "strconv" - "strings" -) - -// Context is a type that is passed through to -// each Handler action in a cli application. Context -// can be used to retrieve context-specific Args and -// parsed command-line options. -type Context struct { - App *App - Command Command - flagSet *flag.FlagSet - globalSet *flag.FlagSet - setFlags map[string]bool -} - -// Creates a new context. For use in when invoking an App or Command action. -func NewContext(app *App, set *flag.FlagSet, globalSet *flag.FlagSet) *Context { - return &Context{App: app, flagSet: set, globalSet: globalSet} -} - -// Looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Int(name string) int { - return lookupInt(name, c.flagSet) -} - -// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists -func (c *Context) Float64(name string) float64 { - return lookupFloat64(name, c.flagSet) -} - -// Looks up the value of a local bool flag, returns false if no bool flag exists -func (c *Context) Bool(name string) bool { - return lookupBool(name, c.flagSet) -} - -// Looks up the value of a local boolT flag, returns false if no bool flag exists -func (c *Context) BoolT(name string) bool { - return lookupBoolT(name, c.flagSet) -} - -// Looks up the value of a local string flag, returns "" if no string flag exists -func (c *Context) String(name string) string { - return lookupString(name, c.flagSet) -} - -// Looks up the value of a local string slice flag, returns nil if no string slice flag exists -func (c *Context) StringSlice(name string) []string { - return lookupStringSlice(name, c.flagSet) -} - -// Looks up the value of a local int slice flag, returns nil if no int slice flag exists -func (c *Context) IntSlice(name string) []int { - return lookupIntSlice(name, c.flagSet) -} - -// Looks up the value of a local generic flag, returns nil if no generic flag exists -func (c *Context) Generic(name string) interface{} { - return lookupGeneric(name, c.flagSet) -} - -// Looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalInt(name string) int { - return lookupInt(name, c.globalSet) -} - -// Looks up the value of a global bool flag, returns false if no bool flag exists -func (c *Context) GlobalBool(name string) bool { - return lookupBool(name, c.globalSet) -} - -// Looks up the value of a global string flag, returns "" if no string flag exists -func (c *Context) GlobalString(name string) string { - return lookupString(name, c.globalSet) -} - -// Looks up the value of a global string slice flag, returns nil if no string slice flag exists -func (c *Context) GlobalStringSlice(name string) []string { - return lookupStringSlice(name, c.globalSet) -} - -// Looks up the value of a global int slice flag, returns nil if no int slice flag exists -func (c *Context) GlobalIntSlice(name string) []int { - return lookupIntSlice(name, c.globalSet) -} - -// Looks up the value of a global generic flag, returns nil if no generic flag exists -func (c *Context) GlobalGeneric(name string) interface{} { - return lookupGeneric(name, c.globalSet) -} - -// Determines if the flag was actually set exists -func (c *Context) IsSet(name string) bool { - if c.setFlags == nil { - c.setFlags = make(map[string]bool) - c.flagSet.Visit(func(f *flag.Flag) { - c.setFlags[f.Name] = true - }) - } - return c.setFlags[name] == true -} - -type Args []string - -// Returns the command line arguments associated with the context. -func (c *Context) Args() Args { - args := Args(c.flagSet.Args()) - return args -} - -// Returns the nth argument, or else a blank string -func (a Args) Get(n int) string { - if len(a) > n { - return a[n] - } - return "" -} - -// Returns the first argument, or else a blank string -func (a Args) First() string { - return a.Get(0) -} - -// Return the rest of the arguments (not the first one) -// or else an empty string slice -func (a Args) Tail() []string { - if len(a) >= 2 { - return []string(a)[1:] - } - return []string{} -} - -// Checks if there are any arguments present -func (a Args) Present() bool { - return len(a) != 0 -} - -// Swaps arguments at the given indexes -func (a Args) Swap(from, to int) error { - if from >= len(a) || to >= len(a) { - return errors.New("index out of range") - } - a[from], a[to] = a[to], a[from] - return nil -} - -func lookupInt(name string, set *flag.FlagSet) int { - f := set.Lookup(name) - if f != nil { - val, err := strconv.Atoi(f.Value.String()) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupFloat64(name string, set *flag.FlagSet) float64 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseFloat(f.Value.String(), 64) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupString(name string, set *flag.FlagSet) string { - f := set.Lookup(name) - if f != nil { - return f.Value.String() - } - - return "" -} - -func lookupStringSlice(name string, set *flag.FlagSet) []string { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*StringSlice)).Value() - - } - - return nil -} - -func lookupIntSlice(name string, set *flag.FlagSet) []int { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*IntSlice)).Value() - - } - - return nil -} - -func lookupGeneric(name string, set *flag.FlagSet) interface{} { - f := set.Lookup(name) - if f != nil { - return f.Value - } - return nil -} - -func lookupBool(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return false - } - return val - } - - return false -} - -func lookupBoolT(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return true - } - return val - } - - return false -} - -func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { - switch ff.Value.(type) { - case *StringSlice: - default: - set.Set(name, ff.Value.String()) - } -} - -func normalizeFlags(flags []Flag, set *flag.FlagSet) error { - visited := make(map[string]bool) - set.Visit(func(f *flag.Flag) { - visited[f.Name] = true - }) - for _, f := range flags { - parts := strings.Split(f.getName(), ",") - if len(parts) == 1 { - continue - } - var ff *flag.Flag - for _, name := range parts { - name = strings.Trim(name, " ") - if visited[name] { - if ff != nil { - return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name) - } - ff = set.Lookup(name) - } - } - if ff == nil { - continue - } - for _, name := range parts { - name = strings.Trim(name, " ") - if !visited[name] { - copyFlag(name, ff, set) - } - } - } - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go deleted file mode 100644 index 89041b99d40..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package cli_test - -import ( - "flag" - "github.com/codegangsta/cli" - "testing" -) - -func TestNewContext(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Int("myflag", 12, "doc") - globalSet := flag.NewFlagSet("test", 0) - globalSet.Int("myflag", 42, "doc") - command := cli.Command{Name: "mycommand"} - c := cli.NewContext(nil, set, globalSet) - c.Command = command - expect(t, c.Int("myflag"), 12) - expect(t, c.GlobalInt("myflag"), 42) - expect(t, c.Command.Name, "mycommand") -} - -func TestContext_Int(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Int("myflag", 12, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Int("myflag"), 12) -} - -func TestContext_String(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.String("myflag", "hello world", "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.String("myflag"), "hello world") -} - -func TestContext_Bool(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Bool("myflag"), false) -} - -func TestContext_BoolT(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", true, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.BoolT("myflag"), true) -} - -func TestContext_Args(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - c := cli.NewContext(nil, set, set) - set.Parse([]string{"--myflag", "bat", "baz"}) - expect(t, len(c.Args()), 2) - expect(t, c.Bool("myflag"), true) -} - -func TestContext_IsSet(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - set.String("otherflag", "hello world", "doc") - c := cli.NewContext(nil, set, set) - set.Parse([]string{"--myflag", "bat", "baz"}) - expect(t, c.IsSet("myflag"), true) - expect(t, c.IsSet("otherflag"), false) - expect(t, c.IsSet("bogusflag"), false) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go deleted file mode 100644 index e6f8838a9d1..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go +++ /dev/null @@ -1,280 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "strconv" - "strings" -) - -// This flag enables bash-completion for all commands and subcommands -var BashCompletionFlag = BoolFlag{"generate-bash-completion", ""} - -// This flag prints the version for the application -var VersionFlag = BoolFlag{"version, v", "print the version"} - -// This flag prints the help for all commands and subcommands -var HelpFlag = BoolFlag{"help, h", "show help"} - -// Flag is a common interface related to parsing flags in cli. -// For more advanced flag parsing techniques, it is recomended that -// this interface be implemented. -type Flag interface { - fmt.Stringer - // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) - getName() string -} - -func flagSet(name string, flags []Flag) *flag.FlagSet { - set := flag.NewFlagSet(name, flag.ContinueOnError) - - for _, f := range flags { - f.Apply(set) - } - return set -} - -func eachName(longName string, fn func(string)) { - parts := strings.Split(longName, ",") - for _, name := range parts { - name = strings.Trim(name, " ") - fn(name) - } -} - -// Generic is a generic parseable type identified by a specific flag -type Generic interface { - Set(value string) error - String() string -} - -// GenericFlag is the flag type for types implementing Generic -type GenericFlag struct { - Name string - Value Generic - Usage string -} - -func (f GenericFlag) String() string { - return fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage) -} - -func (f GenericFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f GenericFlag) getName() string { - return f.Name -} - -type StringSlice []string - -func (f *StringSlice) Set(value string) error { - *f = append(*f, value) - return nil -} - -func (f *StringSlice) String() string { - return fmt.Sprintf("%s", *f) -} - -func (f *StringSlice) Value() []string { - return *f -} - -type StringSliceFlag struct { - Name string - Value *StringSlice - Usage string -} - -func (f StringSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage) -} - -func (f StringSliceFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f StringSliceFlag) getName() string { - return f.Name -} - -type IntSlice []int - -func (f *IntSlice) Set(value string) error { - - tmp, err := strconv.Atoi(value) - if err != nil { - return err - } else { - *f = append(*f, tmp) - } - return nil -} - -func (f *IntSlice) String() string { - return fmt.Sprintf("%d", *f) -} - -func (f *IntSlice) Value() []int { - return *f -} - -type IntSliceFlag struct { - Name string - Value *IntSlice - Usage string -} - -func (f IntSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage) -} - -func (f IntSliceFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f IntSliceFlag) getName() string { - return f.Name -} - -type BoolFlag struct { - Name string - Usage string -} - -func (f BoolFlag) String() string { - return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage) -} - -func (f BoolFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Bool(name, false, f.Usage) - }) -} - -func (f BoolFlag) getName() string { - return f.Name -} - -type BoolTFlag struct { - Name string - Usage string -} - -func (f BoolTFlag) String() string { - return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage) -} - -func (f BoolTFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Bool(name, true, f.Usage) - }) -} - -func (f BoolTFlag) getName() string { - return f.Name -} - -type StringFlag struct { - Name string - Value string - Usage string -} - -func (f StringFlag) String() string { - var fmtString string - fmtString = "%s %v\t%v" - - if len(f.Value) > 0 { - fmtString = "%s '%v'\t%v" - } else { - fmtString = "%s %v\t%v" - } - - return fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage) -} - -func (f StringFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.String(name, f.Value, f.Usage) - }) -} - -func (f StringFlag) getName() string { - return f.Name -} - -type IntFlag struct { - Name string - Value int - Usage string -} - -func (f IntFlag) String() string { - return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage) -} - -func (f IntFlag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Int(name, f.Value, f.Usage) - }) -} - -func (f IntFlag) getName() string { - return f.Name -} - -type Float64Flag struct { - Name string - Value float64 - Usage string -} - -func (f Float64Flag) String() string { - return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage) -} - -func (f Float64Flag) Apply(set *flag.FlagSet) { - eachName(f.Name, func(name string) { - set.Float64(name, f.Value, f.Usage) - }) -} - -func (f Float64Flag) getName() string { - return f.Name -} - -func prefixFor(name string) (prefix string) { - if len(name) == 1 { - prefix = "-" - } else { - prefix = "--" - } - - return -} - -func prefixedNames(fullName string) (prefixed string) { - parts := strings.Split(fullName, ",") - for i, name := range parts { - name = strings.Trim(name, " ") - prefixed += prefixFor(name) + name - if i < len(parts)-1 { - prefixed += ", " - } - } - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go deleted file mode 100644 index 1c05f0144d4..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package cli_test - -import ( - "github.com/codegangsta/cli" - - "fmt" - "reflect" - "strings" - "testing" -) - -var boolFlagTests = []struct { - name string - expected string -}{ - {"help", "--help\t"}, - {"h", "-h\t"}, -} - -func TestBoolFlagHelpOutput(t *testing.T) { - - for _, test := range boolFlagTests { - flag := cli.BoolFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -var stringFlagTests = []struct { - name string - value string - expected string -}{ - {"help", "", "--help \t"}, - {"h", "", "-h \t"}, - {"h", "", "-h \t"}, - {"test", "Something", "--test 'Something'\t"}, -} - -func TestStringFlagHelpOutput(t *testing.T) { - - for _, test := range stringFlagTests { - flag := cli.StringFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -var intFlagTests = []struct { - name string - expected string -}{ - {"help", "--help '0'\t"}, - {"h", "-h '0'\t"}, -} - -func TestIntFlagHelpOutput(t *testing.T) { - - for _, test := range intFlagTests { - flag := cli.IntFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -var float64FlagTests = []struct { - name string - expected string -}{ - {"help", "--help '0'\t"}, - {"h", "-h '0'\t"}, -} - -func TestFloat64FlagHelpOutput(t *testing.T) { - - for _, test := range float64FlagTests { - flag := cli.Float64Flag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestParseMultiString(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.StringFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.String("serve") != "10" { - t.Errorf("main name not set") - } - if ctx.String("s") != "10" { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10"}) -} - -func TestParseMultiStringSlice(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10", "-s", "20"}) -} - -func TestParseMultiInt(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.IntFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Int("serve") != 10 { - t.Errorf("main name not set") - } - if ctx.Int("s") != 10 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10"}) -} - -func TestParseMultiBool(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Bool("serve") != true { - t.Errorf("main name not set") - } - if ctx.Bool("s") != true { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "--serve"}) -} - -type Parser [2]string - -func (p *Parser) Set(value string) error { - parts := strings.Split(value, ",") - if len(parts) != 2 { - return fmt.Errorf("invalid format") - } - - (*p)[0] = parts[0] - (*p)[1] = parts[1] - - return nil -} - -func (p *Parser) String() string { - return fmt.Sprintf("%s,%s", p[0], p[1]) -} - -func TestParseGeneric(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.GenericFlag{Name: "serve, s", Value: &Parser{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10,20"}) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go deleted file mode 100644 index ccca036276b..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go +++ /dev/null @@ -1,213 +0,0 @@ -package cli - -import ( - "fmt" - "os" - "text/tabwriter" - "text/template" -) - -// The text template for the Default help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var AppHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - {{.Name}} {{ if .Flags }}[global options] {{ end }}command{{ if .Flags }} [command options]{{ end }} [arguments...] - -VERSION: - {{.Version}} - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{ if .Flags }} -GLOBAL OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{ end }} -` - -// The text template for the command help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var CommandHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - command {{.Name}}{{ if .Flags }} [command options]{{ end }} [arguments...] - -DESCRIPTION: - {{.Description}}{{ if .Flags }} - -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{ end }} -` - -// The text template for the subcommand help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var SubcommandHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - {{.Name}} command{{ if .Flags }} [command options]{{ end }} [arguments...] - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{ if .Flags }} -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{ end }} -` - -var helpCommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", - Action: func(c *Context) { - args := c.Args() - if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowAppHelp(c) - } - }, -} - -var helpSubcommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", - Action: func(c *Context) { - args := c.Args() - if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowSubcommandHelp(c) - } - }, -} - -// Prints help for the App -var HelpPrinter = printHelp - -func ShowAppHelp(c *Context) { - HelpPrinter(AppHelpTemplate, c.App) -} - -// Prints the list of subcommands as the default app completion method -func DefaultAppComplete(c *Context) { - for _, command := range c.App.Commands { - fmt.Println(command.Name) - if command.ShortName != "" { - fmt.Println(command.ShortName) - } - } -} - -// Prints help for the given command -func ShowCommandHelp(c *Context, command string) { - for _, c := range c.App.Commands { - if c.HasName(command) { - HelpPrinter(CommandHelpTemplate, c) - return - } - } - - if c.App.CommandNotFound != nil { - c.App.CommandNotFound(c, command) - } else { - fmt.Printf("No help topic for '%v'\n", command) - } -} - -// Prints help for the given subcommand -func ShowSubcommandHelp(c *Context) { - HelpPrinter(SubcommandHelpTemplate, c.App) -} - -// Prints the version number of the App -func ShowVersion(c *Context) { - fmt.Printf("%v version %v\n", c.App.Name, c.App.Version) -} - -// Prints the lists of commands within a given context -func ShowCompletions(c *Context) { - a := c.App - if a != nil && a.BashComplete != nil { - a.BashComplete(c) - } -} - -// Prints the custom completions for a given command -func ShowCommandCompletions(ctx *Context, command string) { - c := ctx.App.Command(command) - if c != nil && c.BashComplete != nil { - c.BashComplete(ctx) - } -} - -func printHelp(templ string, data interface{}) { - w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0) - t := template.Must(template.New("help").Parse(templ)) - err := t.Execute(w, data) - if err != nil { - panic(err) - } - w.Flush() -} - -func checkVersion(c *Context) bool { - if c.GlobalBool("version") { - ShowVersion(c) - return true - } - - return false -} - -func checkHelp(c *Context) bool { - if c.GlobalBool("h") || c.GlobalBool("help") { - ShowAppHelp(c) - return true - } - - return false -} - -func checkCommandHelp(c *Context, name string) bool { - if c.Bool("h") || c.Bool("help") { - ShowCommandHelp(c, name) - return true - } - - return false -} - -func checkSubcommandHelp(c *Context) bool { - if c.GlobalBool("h") || c.GlobalBool("help") { - ShowSubcommandHelp(c) - return true - } - - return false -} - -func checkCompletions(c *Context) bool { - if c.GlobalBool(BashCompletionFlag.Name) && c.App.EnableBashCompletion { - ShowCompletions(c) - return true - } - - return false -} - -func checkCommandCompletions(c *Context, name string) bool { - if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion { - ShowCommandCompletions(c, name) - return true - } - - return false -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go deleted file mode 100644 index cdc4feb2fcd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package cli_test - -import ( - "reflect" - "testing" -) - -/* Test Helpers */ -func expect(t *testing.T, a interface{}, b interface{}) { - if a != b { - t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} - -func refute(t *testing.T, a interface{}, b interface{}) { - if a == b { - t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml deleted file mode 100644 index 8c9f56e44a6..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: 1.2 - -install: - - echo "Skip install" - -script: - - ./test diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE deleted file mode 100644 index 37ec93a14fd..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md deleted file mode 100644 index 0ee09fec0ab..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# go-systemd - -Go bindings to systemd. The project has three packages: - -- activation - for writing and using socket activation from Go -- journal - for writing to systemd's logging service, journal -- dbus - for starting/stopping/inspecting running services and units - -Go docs for the entire project are here: - -http://godoc.org/github.com/coreos/go-systemd - -## Socket Activation - -An example HTTP server using socket activation can be quickly setup by -following this README on a Linux machine running systemd: - -https://github.com/coreos/go-systemd/tree/master/examples/activation/httpserver - -## Journal - -Using this package you can submit journal entries directly to systemd's journal taking advantage of features like indexed key/value pairs for each log entry. - -## D-Bus - -The D-Bus API lets you start, stop and introspect systemd units. The API docs are here: - -http://godoc.org/github.com/coreos/go-systemd/dbus - -### Debugging - -Create `/etc/dbus-1/system-local.conf` that looks like this: - -``` - - - - - - - -``` diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go deleted file mode 100644 index 74b4fc10f3a..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package activation implements primitives for systemd socket activation. -package activation - -import ( - "os" - "strconv" - "syscall" -) - -// based on: https://gist.github.com/alberts/4640792 -const ( - listenFdsStart = 3 -) - -func Files(unsetEnv bool) []*os.File { - if unsetEnv { - // there is no way to unset env in golang os package for now - // https://code.google.com/p/go/issues/detail?id=6423 - defer os.Setenv("LISTEN_PID", "") - defer os.Setenv("LISTEN_FDS", "") - } - - pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) - if err != nil || pid != os.Getpid() { - return nil - } - - nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) - if err != nil || nfds == 0 { - return nil - } - - var files []*os.File - for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { - syscall.CloseOnExec(fd) - files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd))) - } - - return files -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go deleted file mode 100644 index a1c6948fb2c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package activation - -import ( - "bytes" - "io" - "os" - "os/exec" - "testing" -) - -// correctStringWritten fails the text if the correct string wasn't written -// to the other side of the pipe. -func correctStringWritten(t *testing.T, r *os.File, expected string) bool { - bytes := make([]byte, len(expected)) - io.ReadAtLeast(r, bytes, len(expected)) - - if string(bytes) != expected { - t.Fatalf("Unexpected string %s", string(bytes)) - } - - return true -} - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestActivation(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - - r1, w1, _ := os.Pipe() - r2, w2, _ := os.Pipe() - cmd.ExtraFiles = []*os.File{ - w1, - w2, - } - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - err := cmd.Run() - if err != nil { - t.Fatalf(err.Error()) - } - - correctStringWritten(t, r1, "Hello world") - correctStringWritten(t, r2, "Goodbye world") -} - -func TestActivationNoFix(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2") - - out, _ := cmd.CombinedOutput() - if bytes.Contains(out, []byte("No files")) == false { - t.Fatalf("Child didn't error out as expected") - } -} - -func TestActivationNoFiles(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1") - - out, _ := cmd.CombinedOutput() - if bytes.Contains(out, []byte("No files")) == false { - t.Fatalf("Child didn't error out as expected") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go deleted file mode 100644 index cdb2cf4bb4f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2014 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package activation - -import ( - "fmt" - "net" -) - -// Listeners returns net.Listeners for all socket activated fds passed to this process. -func Listeners(unsetEnv bool) ([]net.Listener, error) { - files := Files(unsetEnv) - listeners := make([]net.Listener, len(files)) - - for i, f := range files { - var err error - listeners[i], err = net.FileListener(f) - if err != nil { - return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error()) - } - } - - return listeners, nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go deleted file mode 100644 index c3627d6d4d8..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2014 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package activation - -import ( - "io" - "net" - "os" - "os/exec" - "testing" -) - -// correctStringWritten fails the text if the correct string wasn't written -// to the other side of the pipe. -func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool { - bytes := make([]byte, len(expected)) - io.ReadAtLeast(r, bytes, len(expected)) - - if string(bytes) != expected { - t.Fatalf("Unexpected string %s", string(bytes)) - } - - return true -} - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestListeners(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/listen.go") - - l1, err := net.Listen("tcp", ":9999") - if err != nil { - t.Fatalf(err.Error()) - } - l2, err := net.Listen("tcp", ":1234") - if err != nil { - t.Fatalf(err.Error()) - } - - t1 := l1.(*net.TCPListener) - t2 := l2.(*net.TCPListener) - - f1, _ := t1.File() - f2, _ := t2.File() - - cmd.ExtraFiles = []*os.File{ - f1, - f2, - } - - r1, err := net.Dial("tcp", "127.0.0.1:9999") - if err != nil { - t.Fatalf(err.Error()) - } - r1.Write([]byte("Hi")) - - r2, err := net.Dial("tcp", "127.0.0.1:1234") - if err != nil { - t.Fatalf(err.Error()) - } - r2.Write([]byte("Hi")) - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - out, err := cmd.Output() - if err != nil { - println(string(out)) - t.Fatalf(err.Error()) - } - - correctStringWrittenNet(t, r1, "Hello world") - correctStringWrittenNet(t, r2, "Goodbye world") -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go deleted file mode 100644 index 91d71121451..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Integration with the systemd D-Bus API. See http://www.freedesktop.org/wiki/Software/systemd/dbus/ -package dbus - -import ( - "os" - "strconv" - "strings" - "sync" - - "github.com/godbus/dbus" -) - -const signalBuffer = 100 - -// ObjectPath creates a dbus.ObjectPath using the rules that systemd uses for -// serializing special characters. -func ObjectPath(path string) dbus.ObjectPath { - path = strings.Replace(path, ".", "_2e", -1) - path = strings.Replace(path, "-", "_2d", -1) - path = strings.Replace(path, "@", "_40", -1) - - return dbus.ObjectPath(path) -} - -// Conn is a connection to systemds dbus endpoint. -type Conn struct { - sysconn *dbus.Conn - sysobj *dbus.Object - jobListener struct { - jobs map[dbus.ObjectPath]chan string - sync.Mutex - } - subscriber struct { - updateCh chan<- *SubStateUpdate - errCh chan<- error - sync.Mutex - ignore map[dbus.ObjectPath]int64 - cleanIgnore int64 - } - dispatch map[string]func(dbus.Signal) -} - -// New() establishes a connection to the system bus and authenticates. -func New() (*Conn, error) { - c := new(Conn) - - if err := c.initConnection(); err != nil { - return nil, err - } - - c.initJobs() - return c, nil -} - -func (c *Conn) initConnection() error { - var err error - c.sysconn, err = dbus.SystemBusPrivate() - if err != nil { - return err - } - - // Only use EXTERNAL method, and hardcode the uid (not username) - // to avoid a username lookup (which requires a dynamically linked - // libc) - methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))} - - err = c.sysconn.Auth(methods) - if err != nil { - c.sysconn.Close() - return err - } - - err = c.sysconn.Hello() - if err != nil { - c.sysconn.Close() - return err - } - - c.sysobj = c.sysconn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1")) - - // Setup the listeners on jobs so that we can get completions - c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'") - c.initSubscription() - c.initDispatch() - - return nil -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go deleted file mode 100644 index 2e80f73ef74..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dbus - -import ( - "testing" -) - -// TestObjectPath ensures path encoding of the systemd rules works. -func TestObjectPath(t *testing.T) { - input := "/silly-path/to@a/unit..service" - output := ObjectPath(input) - expected := "/silly_2dpath/to_40a/unit_2e_2eservice" - - if string(output) != expected { - t.Fatalf("Output '%s' did not match expected '%s'", output, expected) - } -} - -// TestNew ensures that New() works without errors. -func TestNew(t *testing.T) { - _, err := New() - - if err != nil { - t.Fatal(err) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go deleted file mode 100644 index a60de059e66..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go +++ /dev/null @@ -1,396 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dbus - -import ( - "errors" - "github.com/godbus/dbus" -) - -func (c *Conn) initJobs() { - c.jobListener.jobs = make(map[dbus.ObjectPath]chan string) -} - -func (c *Conn) jobComplete(signal *dbus.Signal) { - var id uint32 - var job dbus.ObjectPath - var unit string - var result string - dbus.Store(signal.Body, &id, &job, &unit, &result) - c.jobListener.Lock() - out, ok := c.jobListener.jobs[job] - if ok { - out <- result - delete(c.jobListener.jobs, job) - } - c.jobListener.Unlock() -} - -func (c *Conn) startJob(job string, args ...interface{}) (<-chan string, error) { - c.jobListener.Lock() - defer c.jobListener.Unlock() - - ch := make(chan string, 1) - var path dbus.ObjectPath - err := c.sysobj.Call(job, 0, args...).Store(&path) - if err != nil { - return nil, err - } - c.jobListener.jobs[path] = ch - return ch, nil -} - -func (c *Conn) runJob(job string, args ...interface{}) (string, error) { - respCh, err := c.startJob(job, args...) - if err != nil { - return "", err - } - return <-respCh, nil -} - -// StartUnit enqeues a start job and depending jobs, if any (unless otherwise -// specified by the mode string). -// -// Takes the unit to activate, plus a mode string. The mode needs to be one of -// replace, fail, isolate, ignore-dependencies, ignore-requirements. If -// "replace" the call will start the unit and its dependencies, possibly -// replacing already queued jobs that conflict with this. If "fail" the call -// will start the unit and its dependencies, but will fail if this would change -// an already queued job. If "isolate" the call will start the unit in question -// and terminate all units that aren't dependencies of it. If -// "ignore-dependencies" it will start a unit but ignore all its dependencies. -// If "ignore-requirements" it will start a unit but only ignore the -// requirement dependencies. It is not recommended to make use of the latter -// two options. -// -// Result string: one of done, canceled, timeout, failed, dependency, skipped. -// done indicates successful execution of a job. canceled indicates that a job -// has been canceled before it finished execution. timeout indicates that the -// job timeout was reached. failed indicates that the job failed. dependency -// indicates that a job this job has been depending on failed and the job hence -// has been removed too. skipped indicates that a job was skipped because it -// didn't apply to the units current state. -func (c *Conn) StartUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.StartUnit", name, mode) -} - -// StopUnit is similar to StartUnit but stops the specified unit rather -// than starting it. -func (c *Conn) StopUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.StopUnit", name, mode) -} - -// ReloadUnit reloads a unit. Reloading is done only if the unit is already running and fails otherwise. -func (c *Conn) ReloadUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.ReloadUnit", name, mode) -} - -// RestartUnit restarts a service. If a service is restarted that isn't -// running it will be started. -func (c *Conn) RestartUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.RestartUnit", name, mode) -} - -// TryRestartUnit is like RestartUnit, except that a service that isn't running -// is not affected by the restart. -func (c *Conn) TryRestartUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode) -} - -// ReloadOrRestart attempts a reload if the unit supports it and use a restart -// otherwise. -func (c *Conn) ReloadOrRestartUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode) -} - -// ReloadOrTryRestart attempts a reload if the unit supports it and use a "Try" -// flavored restart otherwise. -func (c *Conn) ReloadOrTryRestartUnit(name string, mode string) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode) -} - -// StartTransientUnit() may be used to create and start a transient unit, which -// will be released as soon as it is not running or referenced anymore or the -// system is rebooted. name is the unit name including suffix, and must be -// unique. mode is the same as in StartUnit(), properties contains properties -// of the unit. -func (c *Conn) StartTransientUnit(name string, mode string, properties ...Property) (string, error) { - return c.runJob("org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0)) -} - -// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's -// processes are killed. -func (c *Conn) KillUnit(name string, signal int32) { - c.sysobj.Call("org.freedesktop.systemd1.Manager.KillUnit", 0, name, "all", signal).Store() -} - -// getProperties takes the unit name and returns all of its dbus object properties, for the given dbus interface -func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]interface{}, error) { - var err error - var props map[string]dbus.Variant - - path := ObjectPath("/org/freedesktop/systemd1/unit/" + unit) - if !path.IsValid() { - return nil, errors.New("invalid unit name: " + unit) - } - - obj := c.sysconn.Object("org.freedesktop.systemd1", path) - err = obj.Call("org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props) - if err != nil { - return nil, err - } - - out := make(map[string]interface{}, len(props)) - for k, v := range props { - out[k] = v.Value() - } - - return out, nil -} - -// GetUnitProperties takes the unit name and returns all of its dbus object properties. -func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) { - return c.getProperties(unit, "org.freedesktop.systemd1.Unit") -} - -func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) { - var err error - var prop dbus.Variant - - path := ObjectPath("/org/freedesktop/systemd1/unit/" + unit) - if !path.IsValid() { - return nil, errors.New("invalid unit name: " + unit) - } - - obj := c.sysconn.Object("org.freedesktop.systemd1", path) - err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop) - if err != nil { - return nil, err - } - - return &Property{Name: propertyName, Value: prop}, nil -} - -func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) { - return c.getProperty(unit, "org.freedesktop.systemd1.Unit", propertyName) -} - -// GetUnitTypeProperties returns the extra properties for a unit, specific to the unit type. -// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope -// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit -func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) { - return c.getProperties(unit, "org.freedesktop.systemd1."+unitType) -} - -// SetUnitProperties() may be used to modify certain unit properties at runtime. -// Not all properties may be changed at runtime, but many resource management -// settings (primarily those in systemd.cgroup(5)) may. The changes are applied -// instantly, and stored on disk for future boots, unless runtime is true, in which -// case the settings only apply until the next reboot. name is the name of the unit -// to modify. properties are the settings to set, encoded as an array of property -// name and value pairs. -func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error { - return c.sysobj.Call("org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store() -} - -func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) { - return c.getProperty(unit, "org.freedesktop.systemd1." + unitType, propertyName) -} - -// ListUnits returns an array with all currently loaded units. Note that -// units may be known by multiple names at the same time, and hence there might -// be more unit names loaded than actual units behind them. -func (c *Conn) ListUnits() ([]UnitStatus, error) { - result := make([][]interface{}, 0) - err := c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnits", 0).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - status := make([]UnitStatus, len(result)) - statusInterface := make([]interface{}, len(status)) - for i := range status { - statusInterface[i] = &status[i] - } - - err = dbus.Store(resultInterface, statusInterface...) - if err != nil { - return nil, err - } - - return status, nil -} - -type UnitStatus struct { - Name string // The primary unit name as string - Description string // The human readable description string - LoadState string // The load state (i.e. whether the unit file has been loaded successfully) - ActiveState string // The active state (i.e. whether the unit is currently started or not) - SubState string // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not) - Followed string // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string. - Path dbus.ObjectPath // The unit object path - JobId uint32 // If there is a job queued for the job unit the numeric job id, 0 otherwise - JobType string // The job type as string - JobPath dbus.ObjectPath // The job object path -} - -type LinkUnitFileChange EnableUnitFileChange - -// LinkUnitFiles() links unit files (that are located outside of the -// usual unit search paths) into the unit search path. -// -// It takes a list of absolute paths to unit files to link and two -// booleans. The first boolean controls whether the unit shall be -// enabled for runtime only (true, /run), or persistently (false, -// /etc). -// The second controls whether symlinks pointing to other units shall -// be replaced if necessary. -// -// This call returns a list of the changes made. The list consists of -// structures with three strings: the type of the change (one of symlink -// or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.Call("org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]LinkUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -// EnableUnitFiles() may be used to enable one or more units in the system (by -// creating symlinks to them in /etc or /run). -// -// It takes a list of unit files to enable (either just file names or full -// absolute paths if the unit files are residing outside the usual unit -// search paths), and two booleans: the first controls whether the unit shall -// be enabled for runtime only (true, /run), or persistently (false, /etc). -// The second one controls whether symlinks pointing to other units shall -// be replaced if necessary. -// -// This call returns one boolean and an array with the changes made. The -// boolean signals whether the unit files contained any enablement -// information (i.e. an [Install]) section. The changes list consists of -// structures with three strings: the type of the change (one of symlink -// or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { - var carries_install_info bool - - result := make([][]interface{}, 0) - err := c.sysobj.Call("org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result) - if err != nil { - return false, nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]EnableUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return false, nil, err - } - - return carries_install_info, changes, nil -} - -type EnableUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// DisableUnitFiles() may be used to disable one or more units in the system (by -// removing symlinks to them from /etc or /run). -// -// It takes a list of unit files to disable (either just file names or full -// absolute paths if the unit files are residing outside the usual unit -// search paths), and one boolean: whether the unit was enabled for runtime -// only (true, /run), or persistently (false, /etc). -// -// This call returns an array with the changes made. The changes list -// consists of structures with three strings: the type of the change (one of -// symlink or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.Call("org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]DisableUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type DisableUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Reload instructs systemd to scan for and reload unit files. This is -// equivalent to a 'systemctl daemon-reload'. -func (c *Conn) Reload() error { - return c.sysobj.Call("org.freedesktop.systemd1.Manager.Reload", 0).Store() -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go deleted file mode 100644 index 8c7ab93eb36..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go +++ /dev/null @@ -1,332 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dbus - -import ( - "fmt" - "math/rand" - "os" - "path/filepath" - "reflect" - "testing" - - "github.com/godbus/dbus" -) - -func setupConn(t *testing.T) *Conn { - conn, err := New() - if err != nil { - t.Fatal(err) - } - - return conn -} - -func findFixture(target string, t *testing.T) string { - abs, err := filepath.Abs("../fixtures/" + target) - if err != nil { - t.Fatal(err) - } - return abs -} - -func setupUnit(target string, conn *Conn, t *testing.T) { - // Blindly stop the unit in case it is running - conn.StopUnit(target, "replace") - - // Blindly remove the symlink in case it exists - targetRun := filepath.Join("/run/systemd/system/", target) - os.Remove(targetRun) -} - -func linkUnit(target string, conn *Conn, t *testing.T) { - abs := findFixture(target, t) - fixture := []string{abs} - - changes, err := conn.LinkUnitFiles(fixture, true, true) - if err != nil { - t.Fatal(err) - } - - if len(changes) < 1 { - t.Fatalf("Expected one change, got %v", changes) - } - - runPath := filepath.Join("/run/systemd/system/", target) - if changes[0].Filename != runPath { - t.Fatal("Unexpected target filename") - } -} - -// Ensure that basic unit starting and stopping works. -func TestStartStopUnit(t *testing.T) { - target := "start-stop.service" - conn := setupConn(t) - - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - // 2. Start the unit - job, err := conn.StartUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - if job != "done" { - t.Fatal("Job is not done:", job) - } - - units, err := conn.ListUnits() - - var unit *UnitStatus - for _, u := range units { - if u.Name == target { - unit = &u - } - } - - if unit == nil { - t.Fatalf("Test unit not found in list") - } - - if unit.ActiveState != "active" { - t.Fatalf("Test unit not active") - } - - // 3. Stop the unit - job, err = conn.StopUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - units, err = conn.ListUnits() - - unit = nil - for _, u := range units { - if u.Name == target { - unit = &u - } - } - - if unit != nil { - t.Fatalf("Test unit found in list, should be stopped") - } -} - -// Enables a unit and then immediately tears it down -func TestEnableDisableUnit(t *testing.T) { - target := "enable-disable.service" - conn := setupConn(t) - - setupUnit(target, conn, t) - abs := findFixture(target, t) - runPath := filepath.Join("/run/systemd/system/", target) - - // 1. Enable the unit - install, changes, err := conn.EnableUnitFiles([]string{abs}, true, true) - if err != nil { - t.Fatal(err) - } - - if install != false { - t.Fatal("Install was true") - } - - if len(changes) < 1 { - t.Fatalf("Expected one change, got %v", changes) - } - - if changes[0].Filename != runPath { - t.Fatal("Unexpected target filename") - } - - // 2. Disable the unit - dChanges, err := conn.DisableUnitFiles([]string{abs}, true) - if err != nil { - t.Fatal(err) - } - - if len(dChanges) != 1 { - t.Fatalf("Changes should include the path, %v", dChanges) - } - if dChanges[0].Filename != runPath { - t.Fatalf("Change should include correct filename, %+v", dChanges[0]) - } - if dChanges[0].Destination != "" { - t.Fatalf("Change destination should be empty, %+v", dChanges[0]) - } -} - -// TestGetUnitProperties reads the `-.mount` which should exist on all systemd -// systems and ensures that one of its properties is valid. -func TestGetUnitProperties(t *testing.T) { - conn := setupConn(t) - - unit := "-.mount" - - info, err := conn.GetUnitProperties(unit) - if err != nil { - t.Fatal(err) - } - - names := info["Wants"].([]string) - - if len(names) < 1 { - t.Fatal("/ is unwanted") - } - - if names[0] != "system.slice" { - t.Fatal("unexpected wants for /") - } - - prop, err := conn.GetUnitProperty(unit, "Wants") - if err != nil { - t.Fatal(err) - } - - if prop.Name != "Wants" { - t.Fatal("unexpected property name") - } - - val := prop.Value.Value().([]string) - if !reflect.DeepEqual(val, names) { - t.Fatal("unexpected property value") - } -} - -// TestGetUnitPropertiesRejectsInvalidName attempts to get the properties for a -// unit with an invalid name. This test should be run with --test.timeout set, -// as a fail will manifest as GetUnitProperties hanging indefinitely. -func TestGetUnitPropertiesRejectsInvalidName(t *testing.T) { - conn := setupConn(t) - - unit := "//invalid#$^/" - - _, err := conn.GetUnitProperties(unit) - if err == nil { - t.Fatal("Expected an error, got nil") - } - - _, err = conn.GetUnitProperty(unit, "Wants") - if err == nil { - t.Fatal("Expected an error, got nil") - } -} - -// TestSetUnitProperties changes a cgroup setting on the `tmp.mount` -// which should exist on all systemd systems and ensures that the -// property was set. -func TestSetUnitProperties(t *testing.T) { - conn := setupConn(t) - - unit := "tmp.mount" - - if err := conn.SetUnitProperties(unit, true, Property{"CPUShares", dbus.MakeVariant(uint64(1023))}); err != nil { - t.Fatal(err) - } - - info, err := conn.GetUnitTypeProperties(unit, "Mount") - if err != nil { - t.Fatal(err) - } - - value := info["CPUShares"].(uint64) - if value != 1023 { - t.Fatal("CPUShares of unit is not 1023:", value) - } -} - -// Ensure that basic transient unit starting and stopping works. -func TestStartStopTransientUnit(t *testing.T) { - conn := setupConn(t) - - props := []Property{ - PropExecStart([]string{"/bin/sleep", "400"}, false), - } - target := fmt.Sprintf("testing-transient-%d.service", rand.Int()) - - // Start the unit - job, err := conn.StartTransientUnit(target, "replace", props...) - if err != nil { - t.Fatal(err) - } - - if job != "done" { - t.Fatal("Job is not done:", job) - } - - units, err := conn.ListUnits() - - var unit *UnitStatus - for _, u := range units { - if u.Name == target { - unit = &u - } - } - - if unit == nil { - t.Fatalf("Test unit not found in list") - } - - if unit.ActiveState != "active" { - t.Fatalf("Test unit not active") - } - - // 3. Stop the unit - job, err = conn.StopUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - units, err = conn.ListUnits() - - unit = nil - for _, u := range units { - if u.Name == target { - unit = &u - } - } - - if unit != nil { - t.Fatalf("Test unit found in list, should be stopped") - } -} - -func TestConnJobListener(t *testing.T) { - target := "start-stop.service" - conn := setupConn(t) - - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - jobSize := len(conn.jobListener.jobs) - - _, err := conn.StartUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - _, err = conn.StopUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - currentJobSize := len(conn.jobListener.jobs) - if jobSize != currentJobSize { - t.Fatal("JobListener jobs leaked") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go deleted file mode 100644 index a06ccda761d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go +++ /dev/null @@ -1,220 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dbus - -import ( - "github.com/godbus/dbus" -) - -// From the systemd docs: -// -// The properties array of StartTransientUnit() may take many of the settings -// that may also be configured in unit files. Not all parameters are currently -// accepted though, but we plan to cover more properties with future release. -// Currently you may set the Description, Slice and all dependency types of -// units, as well as RemainAfterExit, ExecStart for service units, -// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares, -// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth, -// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit, -// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map -// directly to their counterparts in unit files and as normal D-Bus object -// properties. The exception here is the PIDs field of scope units which is -// used for construction of the scope only and specifies the initial PIDs to -// add to the scope object. - -type Property struct { - Name string - Value dbus.Variant -} - -type PropertyCollection struct { - Name string - Properties []Property -} - -type execStart struct { - Path string // the binary path to execute - Args []string // an array with all arguments to pass to the executed command, starting with argument 0 - UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly -} - -// PropExecStart sets the ExecStart service property. The first argument is a -// slice with the binary path to execute followed by the arguments to pass to -// the executed command. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= -func PropExecStart(command []string, uncleanIsFailure bool) Property { - execStarts := []execStart{ - execStart{ - Path: command[0], - Args: command, - UncleanIsFailure: uncleanIsFailure, - }, - } - - return Property{ - Name: "ExecStart", - Value: dbus.MakeVariant(execStarts), - } -} - -// PropRemainAfterExit sets the RemainAfterExit service property. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit= -func PropRemainAfterExit(b bool) Property { - return Property{ - Name: "RemainAfterExit", - Value: dbus.MakeVariant(b), - } -} - -// PropDescription sets the Description unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description= -func PropDescription(desc string) Property { - return Property{ - Name: "Description", - Value: dbus.MakeVariant(desc), - } -} - -func propDependency(name string, units []string) Property { - return Property{ - Name: name, - Value: dbus.MakeVariant(units), - } -} - -// PropRequires sets the Requires unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires= -func PropRequires(units ...string) Property { - return propDependency("Requires", units) -} - -// PropRequiresOverridable sets the RequiresOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable= -func PropRequiresOverridable(units ...string) Property { - return propDependency("RequiresOverridable", units) -} - -// PropRequisite sets the Requisite unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite= -func PropRequisite(units ...string) Property { - return propDependency("Requisite", units) -} - -// PropRequisiteOverridable sets the RequisiteOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable= -func PropRequisiteOverridable(units ...string) Property { - return propDependency("RequisiteOverridable", units) -} - -// PropWants sets the Wants unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants= -func PropWants(units ...string) Property { - return propDependency("Wants", units) -} - -// PropBindsTo sets the BindsTo unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo= -func PropBindsTo(units ...string) Property { - return propDependency("BindsTo", units) -} - -// PropRequiredBy sets the RequiredBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy= -func PropRequiredBy(units ...string) Property { - return propDependency("RequiredBy", units) -} - -// PropRequiredByOverridable sets the RequiredByOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable= -func PropRequiredByOverridable(units ...string) Property { - return propDependency("RequiredByOverridable", units) -} - -// PropWantedBy sets the WantedBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy= -func PropWantedBy(units ...string) Property { - return propDependency("WantedBy", units) -} - -// PropBoundBy sets the BoundBy unit property. See -// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy= -func PropBoundBy(units ...string) Property { - return propDependency("BoundBy", units) -} - -// PropConflicts sets the Conflicts unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts= -func PropConflicts(units ...string) Property { - return propDependency("Conflicts", units) -} - -// PropConflictedBy sets the ConflictedBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy= -func PropConflictedBy(units ...string) Property { - return propDependency("ConflictedBy", units) -} - -// PropBefore sets the Before unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before= -func PropBefore(units ...string) Property { - return propDependency("Before", units) -} - -// PropAfter sets the After unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After= -func PropAfter(units ...string) Property { - return propDependency("After", units) -} - -// PropOnFailure sets the OnFailure unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure= -func PropOnFailure(units ...string) Property { - return propDependency("OnFailure", units) -} - -// PropTriggers sets the Triggers unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers= -func PropTriggers(units ...string) Property { - return propDependency("Triggers", units) -} - -// PropTriggeredBy sets the TriggeredBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy= -func PropTriggeredBy(units ...string) Property { - return propDependency("TriggeredBy", units) -} - -// PropPropagatesReloadTo sets the PropagatesReloadTo unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo= -func PropPropagatesReloadTo(units ...string) Property { - return propDependency("PropagatesReloadTo", units) -} - -// PropRequiresMountsFor sets the RequiresMountsFor unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor= -func PropRequiresMountsFor(units ...string) Property { - return propDependency("RequiresMountsFor", units) -} - -// PropSlice sets the Slice unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice= -func PropSlice(slice string) Property { - return Property{ - Name: "Slice", - Value: dbus.MakeVariant(slice), - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go deleted file mode 100644 index 45ad1fb3991..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go +++ /dev/null @@ -1,33 +0,0 @@ -package dbus - -type set struct { - data map[string]bool -} - -func (s *set) Add(value string) { - s.data[value] = true -} - -func (s *set) Remove(value string) { - delete(s.data, value) -} - -func (s *set) Contains(value string) (exists bool) { - _, exists = s.data[value] - return -} - -func (s *set) Length() (int) { - return len(s.data) -} - -func (s *set) Values() (values []string) { - for val, _ := range s.data { - values = append(values, val) - } - return -} - -func newSet() (*set) { - return &set{make(map[string] bool)} -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go deleted file mode 100644 index c4435f8800c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package dbus - -import ( - "testing" -) - -// TestBasicSetActions asserts that Add & Remove behavior is correct -func TestBasicSetActions(t *testing.T) { - s := newSet() - - if s.Contains("foo") { - t.Fatal("set should not contain 'foo'") - } - - s.Add("foo") - - if !s.Contains("foo") { - t.Fatal("set should contain 'foo'") - } - - v := s.Values() - if len(v) != 1 { - t.Fatal("set.Values did not report correct number of values") - } - if v[0] != "foo" { - t.Fatal("set.Values did not report value") - } - - s.Remove("foo") - - if s.Contains("foo") { - t.Fatal("set should not contain 'foo'") - } - - v = s.Values() - if len(v) != 0 { - t.Fatal("set.Values did not report correct number of values") - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go deleted file mode 100644 index fcd29b6e8fa..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dbus - -import ( - "errors" - "time" - - "github.com/godbus/dbus" -) - -const ( - cleanIgnoreInterval = int64(10 * time.Second) - ignoreInterval = int64(30 * time.Millisecond) -) - -// Subscribe sets up this connection to subscribe to all systemd dbus events. -// This is required before calling SubscribeUnits. When the connection closes -// systemd will automatically stop sending signals so there is no need to -// explicitly call Unsubscribe(). -func (c *Conn) Subscribe() error { - c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'") - c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'") - - err := c.sysobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() - if err != nil { - return err - } - - return nil -} - -// Unsubscribe this connection from systemd dbus events. -func (c *Conn) Unsubscribe() error { - err := c.sysobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() - if err != nil { - return err - } - - return nil -} - -func (c *Conn) initSubscription() { - c.subscriber.ignore = make(map[dbus.ObjectPath]int64) -} - -func (c *Conn) initDispatch() { - ch := make(chan *dbus.Signal, signalBuffer) - - c.sysconn.Signal(ch) - - go func() { - for { - signal, ok := <-ch - if !ok { - return - } - - switch signal.Name { - case "org.freedesktop.systemd1.Manager.JobRemoved": - c.jobComplete(signal) - - unitName := signal.Body[2].(string) - var unitPath dbus.ObjectPath - c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath) - if unitPath != dbus.ObjectPath("") { - c.sendSubStateUpdate(unitPath) - } - case "org.freedesktop.systemd1.Manager.UnitNew": - c.sendSubStateUpdate(signal.Body[1].(dbus.ObjectPath)) - case "org.freedesktop.DBus.Properties.PropertiesChanged": - if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" { - // we only care about SubState updates, which are a Unit property - c.sendSubStateUpdate(signal.Path) - } - } - } - }() -} - -// Returns two unbuffered channels which will receive all changed units every -// interval. Deleted units are sent as nil. -func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) { - return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil) -} - -// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer -// size of the channels, the comparison function for detecting changes and a filter -// function for cutting down on the noise that your channel receives. -func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func (string) bool) (<-chan map[string]*UnitStatus, <-chan error) { - old := make(map[string]*UnitStatus) - statusChan := make(chan map[string]*UnitStatus, buffer) - errChan := make(chan error, buffer) - - go func() { - for { - timerChan := time.After(interval) - - units, err := c.ListUnits() - if err == nil { - cur := make(map[string]*UnitStatus) - for i := range units { - if filterUnit != nil && filterUnit(units[i].Name) { - continue - } - cur[units[i].Name] = &units[i] - } - - // add all new or changed units - changed := make(map[string]*UnitStatus) - for n, u := range cur { - if oldU, ok := old[n]; !ok || isChanged(oldU, u) { - changed[n] = u - } - delete(old, n) - } - - // add all deleted units - for oldN := range old { - changed[oldN] = nil - } - - old = cur - - if len(changed) != 0 { - statusChan <- changed - } - } else { - errChan <- err - } - - <-timerChan - } - }() - - return statusChan, errChan -} - -type SubStateUpdate struct { - UnitName string - SubState string -} - -// SetSubStateSubscriber writes to updateCh when any unit's substate changes. -// Although this writes to updateCh on every state change, the reported state -// may be more recent than the change that generated it (due to an unavoidable -// race in the systemd dbus interface). That is, this method provides a good -// way to keep a current view of all units' states, but is not guaranteed to -// show every state transition they go through. Furthermore, state changes -// will only be written to the channel with non-blocking writes. If updateCh -// is full, it attempts to write an error to errCh; if errCh is full, the error -// passes silently. -func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) { - c.subscriber.Lock() - defer c.subscriber.Unlock() - c.subscriber.updateCh = updateCh - c.subscriber.errCh = errCh -} - -func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) { - c.subscriber.Lock() - defer c.subscriber.Unlock() - if c.subscriber.updateCh == nil { - return - } - - if c.shouldIgnore(path) { - return - } - - info, err := c.GetUnitProperties(string(path)) - if err != nil { - select { - case c.subscriber.errCh <- err: - default: - } - } - - name := info["Id"].(string) - substate := info["SubState"].(string) - - update := &SubStateUpdate{name, substate} - select { - case c.subscriber.updateCh <- update: - default: - select { - case c.subscriber.errCh <- errors.New("update channel full!"): - default: - } - } - - c.updateIgnore(path, info) -} - -// The ignore functions work around a wart in the systemd dbus interface. -// Requesting the properties of an unloaded unit will cause systemd to send a -// pair of UnitNew/UnitRemoved signals. Because we need to get a unit's -// properties on UnitNew (as that's the only indication of a new unit coming up -// for the first time), we would enter an infinite loop if we did not attempt -// to detect and ignore these spurious signals. The signal themselves are -// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an -// unloaded unit's signals for a short time after requesting its properties. -// This means that we will miss e.g. a transient unit being restarted -// *immediately* upon failure and also a transient unit being started -// immediately after requesting its status (with systemctl status, for example, -// because this causes a UnitNew signal to be sent which then causes us to fetch -// the properties). - -func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool { - t, ok := c.subscriber.ignore[path] - return ok && t >= time.Now().UnixNano() -} - -func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) { - c.cleanIgnore() - - // unit is unloaded - it will trigger bad systemd dbus behavior - if info["LoadState"].(string) == "not-found" { - c.subscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval - } -} - -// without this, ignore would grow unboundedly over time -func (c *Conn) cleanIgnore() { - now := time.Now().UnixNano() - if c.subscriber.cleanIgnore < now { - c.subscriber.cleanIgnore = now + cleanIgnoreInterval - - for p, t := range c.subscriber.ignore { - if t < now { - delete(c.subscriber.ignore, p) - } - } - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go deleted file mode 100644 index 26257860522..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go +++ /dev/null @@ -1,32 +0,0 @@ -package dbus - -import ( - "time" -) - -// SubscriptionSet returns a subscription set which is like conn.Subscribe but -// can filter to only return events for a set of units. -type SubscriptionSet struct { - *set - conn *Conn -} - - -func (s *SubscriptionSet) filter(unit string) bool { - return !s.Contains(unit) -} - -// Subscribe starts listening for dbus events for all of the units in the set. -// Returns channels identical to conn.SubscribeUnits. -func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) { - // TODO: Make fully evented by using systemd 209 with properties changed values - return s.conn.SubscribeUnitsCustom(time.Second, 0, - func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, - func(unit string) bool { return s.filter(unit) }, - ) -} - -// NewSubscriptionSet returns a new subscription set. -func (conn *Conn) NewSubscriptionSet() (*SubscriptionSet) { - return &SubscriptionSet{newSet(), conn} -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go deleted file mode 100644 index 4ecd15376d3..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package dbus - -import ( - "testing" - "time" -) - -// TestSubscribeUnit exercises the basics of subscription of a particular unit. -func TestSubscriptionSetUnit(t *testing.T) { - target := "subscribe-events-set.service" - - conn, err := New() - - if err != nil { - t.Fatal(err) - } - - err = conn.Subscribe() - if err != nil { - t.Fatal(err) - } - - subSet := conn.NewSubscriptionSet() - evChan, errChan := subSet.Subscribe() - - subSet.Add(target) - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - job, err := conn.StartUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - if job != "done" { - t.Fatal("Couldn't start", target) - } - - timeout := make(chan bool, 1) - go func() { - time.Sleep(3 * time.Second) - close(timeout) - }() - - for { - select { - case changes := <-evChan: - tCh, ok := changes[target] - - if !ok { - t.Fatal("Unexpected event:", changes) - } - - if tCh.ActiveState == "active" && tCh.Name == target { - goto success - } - case err = <-errChan: - t.Fatal(err) - case <-timeout: - t.Fatal("Reached timeout") - } - } - -success: - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go deleted file mode 100644 index f2b5dfc28c1..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package dbus - -import ( - "testing" - "time" -) - -// TestSubscribe exercises the basics of subscription -func TestSubscribe(t *testing.T) { - conn, err := New() - - if err != nil { - t.Fatal(err) - } - - err = conn.Subscribe() - if err != nil { - t.Fatal(err) - } - - err = conn.Unsubscribe() - if err != nil { - t.Fatal(err) - } -} - -// TestSubscribeUnit exercises the basics of subscription of a particular unit. -func TestSubscribeUnit(t *testing.T) { - target := "subscribe-events.service" - - conn, err := New() - - if err != nil { - t.Fatal(err) - } - - err = conn.Subscribe() - if err != nil { - t.Fatal(err) - } - - err = conn.Unsubscribe() - if err != nil { - t.Fatal(err) - } - - evChan, errChan := conn.SubscribeUnits(time.Second) - - setupUnit(target, conn, t) - linkUnit(target, conn, t) - - job, err := conn.StartUnit(target, "replace") - if err != nil { - t.Fatal(err) - } - - if job != "done" { - t.Fatal("Couldn't start", target) - } - - timeout := make(chan bool, 1) - go func() { - time.Sleep(3 * time.Second) - close(timeout) - }() - - for { - select { - case changes := <-evChan: - tCh, ok := changes[target] - - // Just continue until we see our event. - if !ok { - continue - } - - if tCh.ActiveState == "active" && tCh.Name == target { - goto success - } - case err = <-errChan: - t.Fatal(err) - case <-timeout: - t.Fatal("Reached timeout") - } - } - -success: - return -} - - diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go deleted file mode 100644 index b3cf70ed84b..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go +++ /dev/null @@ -1,44 +0,0 @@ -// Activation example used by the activation unit tests. -package main - -import ( - "fmt" - "os" - - "github.com/coreos/go-systemd/activation" -) - -func fixListenPid() { - if os.Getenv("FIX_LISTEN_PID") != "" { - // HACK: real systemd would set LISTEN_PID before exec'ing but - // this is too difficult in golang for the purpose of a test. - // Do not do this in real code. - os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())) - } -} - -func main() { - fixListenPid() - - files := activation.Files(false) - - if len(files) == 0 { - panic("No files") - } - - if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" { - panic("Should not unset envs") - } - - files = activation.Files(true) - - if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" { - panic("Can not unset envs") - } - - // Write out the expected strings to the two pipes - files[0].Write([]byte("Hello world")) - files[1].Write([]byte("Goodbye world")) - - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md deleted file mode 100644 index a350cca5e56..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md +++ /dev/null @@ -1,19 +0,0 @@ -## socket activated http server - -This is a simple example of using socket activation with systemd to serve a -simple HTTP server on http://127.0.0.1:8076 - -To try it out `go get` the httpserver and run it under the systemd-activate helper - -``` -export GOPATH=`pwd` -go get github.com/coreos/go-systemd/examples/activation/httpserver -sudo /usr/lib/systemd/systemd-activate -l 127.0.0.1:8076 ./bin/httpserver -``` - -Then curl the URL and you will notice that it starts up: - -``` -curl 127.0.0.1:8076 -hello socket activated world! -``` diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service deleted file mode 100644 index c8dea0f6b3f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Hello World HTTP -Requires=network.target -After=multi-user.target - -[Service] -Type=simple -ExecStart=/usr/local/bin/httpserver - -[Install] -WantedBy=multi-user.target diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket deleted file mode 100644 index 723ed7ed92d..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket +++ /dev/null @@ -1,5 +0,0 @@ -[Socket] -ListenStream=127.0.0.1:8076 - -[Install] -WantedBy=sockets.target diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go deleted file mode 100644 index 380c325d61b..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "io" - "net/http" - - "github.com/coreos/go-systemd/activation" -) - -func HelloServer(w http.ResponseWriter, req *http.Request) { - io.WriteString(w, "hello socket activated world!\n") -} - -func main() { - listeners, err := activation.Listeners(true) - if err != nil { - panic(err) - } - - if len(listeners) != 1 { - panic("Unexpected number of socket activation fds") - } - - http.HandleFunc("/", HelloServer) - http.Serve(listeners[0], nil) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go deleted file mode 100644 index 5850a8b796f..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go +++ /dev/null @@ -1,50 +0,0 @@ -// Activation example used by the activation unit tests. -package main - -import ( - "fmt" - "os" - - "github.com/coreos/go-systemd/activation" -) - -func fixListenPid() { - if os.Getenv("FIX_LISTEN_PID") != "" { - // HACK: real systemd would set LISTEN_PID before exec'ing but - // this is too difficult in golang for the purpose of a test. - // Do not do this in real code. - os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())) - } -} - -func main() { - fixListenPid() - - listeners, _ := activation.Listeners(false) - - if len(listeners) == 0 { - panic("No listeners") - } - - if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" { - panic("Should not unset envs") - } - - listeners, err := activation.Listeners(true) - if err != nil { - panic(err) - } - - if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" { - panic("Can not unset envs") - } - - c0, _ := listeners[0].Accept() - c1, _ := listeners[1].Accept() - - // Write out the expected strings to the two pipes - c0.Write([]byte("Hello world")) - c1.Write([]byte("Goodbye world")) - - return -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service deleted file mode 100644 index 74c9459088c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service +++ /dev/null @@ -1,5 +0,0 @@ -[Unit] -Description=enable disable test - -[Service] -ExecStart=/bin/sleep 400 diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service deleted file mode 100644 index a1f8c367732..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service +++ /dev/null @@ -1,5 +0,0 @@ -[Unit] -Description=start stop test - -[Service] -ExecStart=/bin/sleep 400 diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service deleted file mode 100644 index a1f8c367732..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service +++ /dev/null @@ -1,5 +0,0 @@ -[Unit] -Description=start stop test - -[Service] -ExecStart=/bin/sleep 400 diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service deleted file mode 100644 index a1f8c367732..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service +++ /dev/null @@ -1,5 +0,0 @@ -[Unit] -Description=start stop test - -[Service] -ExecStart=/bin/sleep 400 diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go deleted file mode 100644 index b52e120988c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go +++ /dev/null @@ -1,168 +0,0 @@ -/* -Copyright 2013 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package journal provides write bindings to the systemd journal -package journal - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "io/ioutil" - "net" - "os" - "strconv" - "strings" - "syscall" -) - -// Priority of a journal message -type Priority int - -const ( - PriEmerg Priority = iota - PriAlert - PriCrit - PriErr - PriWarning - PriNotice - PriInfo - PriDebug -) - -var conn net.Conn - -func init() { - var err error - conn, err = net.Dial("unixgram", "/run/systemd/journal/socket") - if err != nil { - conn = nil - } -} - -// Enabled returns true iff the systemd journal is available for logging -func Enabled() bool { - return conn != nil -} - -// Send a message to the systemd journal. vars is a map of journald fields to -// values. Fields must be composed of uppercase letters, numbers, and -// underscores, but must not start with an underscore. Within these -// restrictions, any arbitrary field name may be used. Some names have special -// significance: see the journalctl documentation -// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html) -// for more details. vars may be nil. -func Send(message string, priority Priority, vars map[string]string) error { - if conn == nil { - return journalError("could not connect to journald socket") - } - - data := new(bytes.Buffer) - appendVariable(data, "PRIORITY", strconv.Itoa(int(priority))) - appendVariable(data, "MESSAGE", message) - for k, v := range vars { - appendVariable(data, k, v) - } - - _, err := io.Copy(conn, data) - if err != nil && isSocketSpaceError(err) { - file, err := tempFd() - if err != nil { - return journalError(err.Error()) - } - _, err = io.Copy(file, data) - if err != nil { - return journalError(err.Error()) - } - - rights := syscall.UnixRights(int(file.Fd())) - - /* this connection should always be a UnixConn, but better safe than sorry */ - unixConn, ok := conn.(*net.UnixConn) - if !ok { - return journalError("can't send file through non-Unix connection") - } - unixConn.WriteMsgUnix([]byte{}, rights, nil) - } else if err != nil { - return journalError(err.Error()) - } - return nil -} - -func appendVariable(w io.Writer, name, value string) { - if !validVarName(name) { - journalError("variable name contains invalid character, ignoring") - } - if strings.ContainsRune(value, '\n') { - /* When the value contains a newline, we write: - * - the variable name, followed by a newline - * - the size (in 64bit little endian format) - * - the data, followed by a newline - */ - fmt.Fprintln(w, name) - binary.Write(w, binary.LittleEndian, uint64(len(value))) - fmt.Fprintln(w, value) - } else { - /* just write the variable and value all on one line */ - fmt.Fprintf(w, "%s=%s\n", name, value) - } -} - -func validVarName(name string) bool { - /* The variable name must be in uppercase and consist only of characters, - * numbers and underscores, and may not begin with an underscore. (from the docs) - */ - - valid := name[0] != '_' - for _, c := range name { - valid = valid && ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' - } - return valid -} - -func isSocketSpaceError(err error) bool { - opErr, ok := err.(*net.OpError) - if !ok { - return false - } - - sysErr, ok := opErr.Err.(syscall.Errno) - if !ok { - return false - } - - return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS -} - -func tempFd() (*os.File, error) { - file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX") - if err != nil { - return nil, err - } - syscall.Unlink(file.Name()) - if err != nil { - return nil, err - } - return file, nil -} - -func journalError(s string) error { - s = "journal error: " + s - fmt.Fprintln(os.Stderr, s) - return errors.New(s) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go deleted file mode 100644 index d00dd110b51..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2014 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Integration with the systemd logind API. See http://www.freedesktop.org/wiki/Software/systemd/logind/ -package login1 - -import ( - "os" - "strconv" - - "github.com/godbus/dbus" -) - -const ( - dbusInterface = "org.freedesktop.login1.Manager" - dbusPath = "/org/freedesktop/login1" -) - -// Conn is a connection to systemds dbus endpoint. -type Conn struct { - conn *dbus.Conn - object *dbus.Object -} - -// New() establishes a connection to the system bus and authenticates. -func New() (*Conn, error) { - c := new(Conn) - - if err := c.initConnection(); err != nil { - return nil, err - } - - return c, nil -} - -func (c *Conn) initConnection() error { - var err error - c.conn, err = dbus.SystemBusPrivate() - if err != nil { - return err - } - - // Only use EXTERNAL method, and hardcode the uid (not username) - // to avoid a username lookup (which requires a dynamically linked - // libc) - methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))} - - err = c.conn.Auth(methods) - if err != nil { - c.conn.Close() - return err - } - - err = c.conn.Hello() - if err != nil { - c.conn.Close() - return err - } - - c.object = c.conn.Object("org.freedesktop.login1", dbus.ObjectPath(dbusPath)) - - return nil -} - -// Reboot asks logind for a reboot optionally asking for auth. -func (c *Conn) Reboot(askForAuth bool) { - c.object.Call(dbusInterface+".Reboot", 0, askForAuth) -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go deleted file mode 100644 index 4439d37380c..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2014 CoreOS Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package login1 - -import ( - "testing" -) - -// TestNew ensures that New() works without errors. -func TestNew(t *testing.T) { - _, err := New() - - if err != nil { - t.Fatal(err) - } -} diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test deleted file mode 100644 index 6e043658aee..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -go test -v ./... diff --git a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/CONTRIBUTING.md b/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/CONTRIBUTING.md deleted file mode 100644 index c88f9b2bdd0..00000000000 --- a/agent/Godeps/_workspace/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# How to Contribute - -## Getting Started - -- Fork the repository on GitHub -- Read the [README](README.markdown) for build and test instructions -- Play with the project, submit bugs, submit patches! - -## Contribution Flow - -This is a rough outline of what a contributor's workflow looks like: - -- Create a topic branch from where you want to base your work (usually master). -- Make commits of logical units. -- Make sure your commit messages are in the proper format (see below). -- Push your changes to a topic branch in your fork of the repository. -- Make sure the tests pass, and add any new tests as appropriate. -- Submit a pull request to the original repository. - -Thanks for your contributions! - -### Format of the Commit Message - -We follow a rough convention for commit messages that is designed to answer two -questions: what changed and why. The subject line should feature the what and -the body of the commit should describe the why. - -``` -scripts: add the test-cluster command - -this uses tmux to setup a test cluster that you can easily kill and -start for debugging. - -Fixes #38 -``` - -The format can be described more formally as follows: - -``` -: - - - -