From a7e181c8576e0413da888bea95fb7155173714ea Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Sat, 22 Mar 2014 12:02:30 +0900 Subject: Add a test for mount.GetMounts Because mount.parseInfoFile is only available on Linux Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi (github: kzys) --- pkg/mount/mount_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/mount/mount_test.go b/pkg/mount/mount_test.go index 6edc31d410..9272504a77 100644 --- a/pkg/mount/mount_test.go +++ b/pkg/mount/mount_test.go @@ -108,3 +108,21 @@ func TestMountReadonly(t *testing.T) { 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") + } +} -- cgit v1.2.1 From ca7a0e6d6e31c02baf692315d2481ef35a7e9134 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Sat, 22 Mar 2014 12:03:09 +0900 Subject: FreeBSD's nullfs doesn't support file mount FreeBSD doesn't have "bind" mount, but nullfs might be a similar feature. However nullfs can mount only directories. Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi (github: kzys) --- pkg/mount/mount_test.go | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/pkg/mount/mount_test.go b/pkg/mount/mount_test.go index 9272504a77..94552dbeab 100644 --- a/pkg/mount/mount_test.go +++ b/pkg/mount/mount_test.go @@ -31,10 +31,15 @@ func TestMounted(t *testing.T) { defer os.RemoveAll(tmp) var ( - sourcePath = path.Join(tmp, "sourcefile.txt") - targetPath = path.Join(tmp, "targetfile.txt") + 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) @@ -48,23 +53,23 @@ func TestMounted(t *testing.T) { } f.Close() - if err := Mount(sourcePath, targetPath, "none", "bind,rw"); err != nil { + if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil { t.Fatal(err) } defer func() { - if err := Unmount(targetPath); err != nil { + if err := Unmount(targetDir); err != nil { t.Fatal(err) } }() - mounted, err := Mounted(targetPath) + mounted, err := Mounted(targetDir) if err != nil { t.Fatal(err) } if !mounted { - t.Fatalf("Expected %s to be mounted", targetPath) + t.Fatalf("Expected %s to be mounted", targetDir) } - if _, err := os.Stat(targetPath); err != nil { + if _, err := os.Stat(targetDir); err != nil { t.Fatal(err) } } @@ -77,10 +82,15 @@ func TestMountReadonly(t *testing.T) { defer os.RemoveAll(tmp) var ( - sourcePath = path.Join(tmp, "sourcefile.txt") - targetPath = path.Join(tmp, "targetfile.txt") + 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) @@ -94,7 +104,7 @@ func TestMountReadonly(t *testing.T) { } f.Close() - if err := Mount(sourcePath, targetPath, "none", "bind,ro"); err != nil { + if err := Mount(sourceDir, targetDir, "none", "bind,ro"); err != nil { t.Fatal(err) } defer func() { -- cgit v1.2.1 From 3754fdd7caae423b606c6fb5160683534a830a1a Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Fri, 21 Mar 2014 00:52:12 +0900 Subject: Support FreeBSD on pkg/mount Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi (github: kzys) --- pkg/mount/flags.go | 62 ++++++ pkg/mount/flags_freebsd.go | 28 +++ pkg/mount/flags_linux.go | 73 ++---- pkg/mount/flags_unsupported.go | 23 +- pkg/mount/mount_test.go | 7 +- pkg/mount/mounter_freebsd.go | 59 +++++ pkg/mount/mounter_unsupported.go | 2 +- pkg/mount/mountinfo.go | 72 ------ pkg/mount/mountinfo_freebsd.go | 38 ++++ pkg/mount/mountinfo_linux.go | 73 ++++++ pkg/mount/mountinfo_test.go | 445 ------------------------------------- pkg/mount/mountinfo_test_linux.go | 445 +++++++++++++++++++++++++++++++++++++ pkg/mount/mountinfo_unsupported.go | 12 + 13 files changed, 757 insertions(+), 582 deletions(-) create mode 100644 pkg/mount/flags.go create mode 100644 pkg/mount/flags_freebsd.go create mode 100644 pkg/mount/mounter_freebsd.go create mode 100644 pkg/mount/mountinfo_freebsd.go create mode 100644 pkg/mount/mountinfo_linux.go delete mode 100644 pkg/mount/mountinfo_test.go create mode 100644 pkg/mount/mountinfo_test_linux.go create mode 100644 pkg/mount/mountinfo_unsupported.go diff --git a/pkg/mount/flags.go b/pkg/mount/flags.go new file mode 100644 index 0000000000..742698e8d3 --- /dev/null +++ b/pkg/mount/flags.go @@ -0,0 +1,62 @@ +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}, + "private": {false, PRIVATE}, + "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/pkg/mount/flags_freebsd.go b/pkg/mount/flags_freebsd.go new file mode 100644 index 0000000000..4ddf4d7090 --- /dev/null +++ b/pkg/mount/flags_freebsd.go @@ -0,0 +1,28 @@ +// +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 + PRIVATE = 0 + RBIND = 0 + RELATIVE = 0 + RELATIME = 0 + REMOUNT = 0 + STRICTATIME = 0 +) diff --git a/pkg/mount/flags_linux.go b/pkg/mount/flags_linux.go index b7124b1dfa..19c882fcd8 100644 --- a/pkg/mount/flags_linux.go +++ b/pkg/mount/flags_linux.go @@ -3,62 +3,23 @@ package mount import ( - "strings" "syscall" ) -// 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, syscall.MS_RDONLY}, - "rw": {true, syscall.MS_RDONLY}, - "suid": {true, syscall.MS_NOSUID}, - "nosuid": {false, syscall.MS_NOSUID}, - "dev": {true, syscall.MS_NODEV}, - "nodev": {false, syscall.MS_NODEV}, - "exec": {true, syscall.MS_NOEXEC}, - "noexec": {false, syscall.MS_NOEXEC}, - "sync": {false, syscall.MS_SYNCHRONOUS}, - "async": {true, syscall.MS_SYNCHRONOUS}, - "dirsync": {false, syscall.MS_DIRSYNC}, - "remount": {false, syscall.MS_REMOUNT}, - "mand": {false, syscall.MS_MANDLOCK}, - "nomand": {true, syscall.MS_MANDLOCK}, - "atime": {true, syscall.MS_NOATIME}, - "noatime": {false, syscall.MS_NOATIME}, - "diratime": {true, syscall.MS_NODIRATIME}, - "nodiratime": {false, syscall.MS_NODIRATIME}, - "bind": {false, syscall.MS_BIND}, - "rbind": {false, syscall.MS_BIND | syscall.MS_REC}, - "private": {false, syscall.MS_PRIVATE}, - "relatime": {false, syscall.MS_RELATIME}, - "norelatime": {true, syscall.MS_RELATIME}, - "strictatime": {false, syscall.MS_STRICTATIME}, - "nostrictatime": {true, syscall.MS_STRICTATIME}, - } - - for _, o := range strings.Split(options, ",") { - // If the option does not exist in the flags table then it is a - // data value for a specific fs type - if f, exists := flags[o]; exists { - if f.clear { - flag &= ^f.flag - } else { - flag |= f.flag - } - } else { - data = append(data, o) - } - } - return flag, strings.Join(data, ",") -} +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 + PRIVATE = syscall.MS_PRIVATE + RELATIME = syscall.MS_RELATIME + STRICTATIME = syscall.MS_STRICTATIME +) diff --git a/pkg/mount/flags_unsupported.go b/pkg/mount/flags_unsupported.go index c894efe5b1..e598354151 100644 --- a/pkg/mount/flags_unsupported.go +++ b/pkg/mount/flags_unsupported.go @@ -1,7 +1,22 @@ -// +build !linux !amd64 +// +build !linux,!freebsd linux,!amd64 freebsd,!cgo package mount -func parseOptions(options string) (int, string) { - panic("Not implemented") -} +const ( + BIND = 0 + DIRSYNC = 0 + MANDLOCK = 0 + NOATIME = 0 + NODEV = 0 + NODIRATIME = 0 + NOEXEC = 0 + NOSUID = 0 + PRIVATE = 0 + RBIND = 0 + RELATIME = 0 + RELATIVE = 0 + REMOUNT = 0 + STRICTATIME = 0 + SYNCHRONOUS = 0 + RDONLY = 0 +) diff --git a/pkg/mount/mount_test.go b/pkg/mount/mount_test.go index 94552dbeab..5c7f1b86a0 100644 --- a/pkg/mount/mount_test.go +++ b/pkg/mount/mount_test.go @@ -3,12 +3,11 @@ package mount import ( "os" "path" - "syscall" "testing" ) func TestMountOptionsParsing(t *testing.T) { - options := "bind,ro,size=10k" + options := "noatime,ro,size=10k" flag, data := parseOptions(options) @@ -16,7 +15,7 @@ func TestMountOptionsParsing(t *testing.T) { t.Fatalf("Expected size=10 got %s", data) } - expectedFlag := syscall.MS_BIND | syscall.MS_RDONLY + expectedFlag := NOATIME | RDONLY if flag != expectedFlag { t.Fatalf("Expected %d got %d", expectedFlag, flag) @@ -108,7 +107,7 @@ func TestMountReadonly(t *testing.T) { t.Fatal(err) } defer func() { - if err := Unmount(targetPath); err != nil { + if err := Unmount(targetDir); err != nil { t.Fatal(err) } }() diff --git a/pkg/mount/mounter_freebsd.go b/pkg/mount/mounter_freebsd.go new file mode 100644 index 0000000000..bb870e6f59 --- /dev/null +++ b/pkg/mount/mounter_freebsd.go @@ -0,0 +1,59 @@ +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/pkg/mount/mounter_unsupported.go b/pkg/mount/mounter_unsupported.go index ee27b35f89..06f2ac00b2 100644 --- a/pkg/mount/mounter_unsupported.go +++ b/pkg/mount/mounter_unsupported.go @@ -1,4 +1,4 @@ -// +build !linux !amd64 +// +build !linux,!freebsd linux,!amd64 freebsd,!cgo package mount diff --git a/pkg/mount/mountinfo.go b/pkg/mount/mountinfo.go index 32996f05c8..78b83ced4a 100644 --- a/pkg/mount/mountinfo.go +++ b/pkg/mount/mountinfo.go @@ -1,79 +1,7 @@ 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 " -) - type MountInfo struct { Id, Parent, Major, Minor int Root, Mountpoint, Opts string Fstype, Source, VfsOpts string } - -// 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() - ) - - if _, err := fmt.Sscanf(text, mountinfoFormat, - &p.Id, &p.Parent, &p.Major, &p.Minor, - &p.Root, &p.Mountpoint, &p.Opts); 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 did not find 3 fields post '-' in '%s'", text) - } - p.Fstype = postSeparatorFields[0] - p.Source = postSeparatorFields[1] - p.VfsOpts = postSeparatorFields[2] - out = append(out, p) - } - return out, nil -} diff --git a/pkg/mount/mountinfo_freebsd.go b/pkg/mount/mountinfo_freebsd.go new file mode 100644 index 0000000000..a16bdb84f8 --- /dev/null +++ b/pkg/mount/mountinfo_freebsd.go @@ -0,0 +1,38 @@ +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]) + out = append(out, &mountinfo) + } + return out, nil +} diff --git a/pkg/mount/mountinfo_linux.go b/pkg/mount/mountinfo_linux.go new file mode 100644 index 0000000000..01c954fff3 --- /dev/null +++ b/pkg/mount/mountinfo_linux.go @@ -0,0 +1,73 @@ +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 " +) + +// 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() + ) + + if _, err := fmt.Sscanf(text, mountinfoFormat, + &p.Id, &p.Parent, &p.Major, &p.Minor, + &p.Root, &p.Mountpoint, &p.Opts); 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 did not find 3 fields post '-' in '%s'", text) + } + p.Fstype = postSeparatorFields[0] + p.Source = postSeparatorFields[1] + p.VfsOpts = postSeparatorFields[2] + out = append(out, p) + } + return out, nil +} diff --git a/pkg/mount/mountinfo_test.go b/pkg/mount/mountinfo_test.go deleted file mode 100644 index f2e3daa8b3..0000000000 --- a/pkg/mount/mountinfo_test.go +++ /dev/null @@ -1,445 +0,0 @@ -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` - - 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) - } -} diff --git a/pkg/mount/mountinfo_test_linux.go b/pkg/mount/mountinfo_test_linux.go new file mode 100644 index 0000000000..f2e3daa8b3 --- /dev/null +++ b/pkg/mount/mountinfo_test_linux.go @@ -0,0 +1,445 @@ +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` + + 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) + } +} diff --git a/pkg/mount/mountinfo_unsupported.go b/pkg/mount/mountinfo_unsupported.go new file mode 100644 index 0000000000..352336b9a3 --- /dev/null +++ b/pkg/mount/mountinfo_unsupported.go @@ -0,0 +1,12 @@ +// +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) +} -- cgit v1.2.1 From 05e9574cf34b4615030d23a0f816cc309aa2e949 Mon Sep 17 00:00:00 2001 From: Sam Bailey Date: Sat, 31 May 2014 20:58:58 +1000 Subject: add mkimage support for mageia using urpmi Docker-DCO-1.1-Signed-off-by: Sam Bailey (github: thatsamguy) --- contrib/mkimage.sh | 2 ++ contrib/mkimage/mageia-urpmi | 79 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100755 contrib/mkimage/mageia-urpmi diff --git a/contrib/mkimage.sh b/contrib/mkimage.sh index db4815c204..ab8f71a307 100755 --- a/contrib/mkimage.sh +++ b/contrib/mkimage.sh @@ -9,6 +9,8 @@ usage() { echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal trusty" echo >&2 " $mkimg -t someuser/busybox busybox-static" echo >&2 " $mkimg -t someuser/centos:5 rinse --distribution centos-5" + echo >&2 " $mkimg -t someuser/mageia:4 mageia-urpmi --version=4" + echo >&2 " $mkimg -t someuser/mageia:4 mageia-urpmi --version=4 --mirror=http://somemirror/" exit 1 } diff --git a/contrib/mkimage/mageia-urpmi b/contrib/mkimage/mageia-urpmi new file mode 100755 index 0000000000..252e827877 --- /dev/null +++ b/contrib/mkimage/mageia-urpmi @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# +# Needs to be run from Mageia 4 or greater for kernel support for docker. +# +# Mageia 4 does not have docker available in official repos, so please +# install and run the docker binary manually. +# +# Tested working versions are for Mageia 2 onwards (inc. cauldron). +# +set -e + +rootfsDir="$1" +shift + +optTemp=$(getopt --options '+v:,m:' --longoptions 'version:,mirror:' --name mageia-urpmi -- "$@") +eval set -- "$optTemp" +unset optTemp + +installversion= +mirror= +while true; do + case "$1" in + -v|--version) installversion="$2" ; shift 2 ;; + -m|--mirror) mirror="$2" ; shift 2 ;; + --) shift ; break ;; + esac +done + +if [ -z $installversion ]; then + # Attempt to match host version + if [ -r /etc/mageia-release ]; then + installversion="$(sed 's/^[^0-9\]*\([0-9.]\+\).*$/\1/' /etc/mageia-release)" + else + echo "Error: no version supplied and unable to detect host mageia version" + exit 1 + fi +fi + +if [ -z $mirror ]; then + # No mirror provided, default to mirrorlist + mirror="--mirrorlist https://mirrors.mageia.org/api/mageia.$installversion.x86_64.list" +fi + +( + set -x + urpmi.addmedia --distrib \ + $mirror \ + --urpmi-root "$rootfsDir" + urpmi basesystem-minimal urpmi \ + --auto \ + --no-suggests \ + --urpmi-root "$rootfsDir" \ + --root "$rootfsDir" +) + +( + # Clean cruft to reduce image size - stolen and modifed from .febootstrap-minimize + set -x + cd "$rootfsDir" + # locales + rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive} + # docs + rm -rf usr/share/{man,doc,info,gnome/help} + # cracklib + rm -rf usr/share/cracklib + # i18n + rm -rf usr/share/i18n + # sln + rm -rf sbin/sln + # ldconfig + #rm -rf sbin/ldconfig + rm -rf etc/ld.so.cache var/cache/ldconfig + mkdir -p --mode=0755 var/cache/ldconfig +) + +if [ -d "$rootfsDir/etc/sysconfig" ]; then + # allow networking init scripts inside the container to work without extra steps + echo 'NETWORKING=yes' > "$rootfsDir/etc/sysconfig/network" +fi -- cgit v1.2.1 From d9885abdc4a7e028092fc18715b69075bb7c2f8d Mon Sep 17 00:00:00 2001 From: Sam Bailey Date: Tue, 3 Jun 2014 20:41:32 +1000 Subject: reuse the febootstrap-minimize from rinse Docker-DCO-1.1-Signed-off-by: Sam Bailey (github: thatsamguy) --- contrib/mkimage/.febootstrap-minimize | 2 +- contrib/mkimage/mageia-urpmi | 20 +------------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/contrib/mkimage/.febootstrap-minimize b/contrib/mkimage/.febootstrap-minimize index 7dab4eb8b5..8a71f5ed67 100755 --- a/contrib/mkimage/.febootstrap-minimize +++ b/contrib/mkimage/.febootstrap-minimize @@ -13,7 +13,7 @@ shift # docs rm -rf usr/share/{man,doc,info,gnome/help} # cracklib - #rm -rf usr/share/cracklib + rm -rf usr/share/cracklib # i18n rm -rf usr/share/i18n # yum cache diff --git a/contrib/mkimage/mageia-urpmi b/contrib/mkimage/mageia-urpmi index 252e827877..93fb289cac 100755 --- a/contrib/mkimage/mageia-urpmi +++ b/contrib/mkimage/mageia-urpmi @@ -53,25 +53,7 @@ fi --root "$rootfsDir" ) -( - # Clean cruft to reduce image size - stolen and modifed from .febootstrap-minimize - set -x - cd "$rootfsDir" - # locales - rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive} - # docs - rm -rf usr/share/{man,doc,info,gnome/help} - # cracklib - rm -rf usr/share/cracklib - # i18n - rm -rf usr/share/i18n - # sln - rm -rf sbin/sln - # ldconfig - #rm -rf sbin/ldconfig - rm -rf etc/ld.so.cache var/cache/ldconfig - mkdir -p --mode=0755 var/cache/ldconfig -) +"$(dirname "$BASH_SOURCE")/.febootstrap-minimize" "$rootfsDir" if [ -d "$rootfsDir/etc/sysconfig" ]; then # allow networking init scripts inside the container to work without extra steps -- cgit v1.2.1 From c11fadb282ea7e96eef2280a5e422fd2c94e8c45 Mon Sep 17 00:00:00 2001 From: Joe Beda Date: Tue, 3 Jun 2014 16:28:06 -0700 Subject: Make debian init work when called quickly. We use the start-stop-daemon pid creation mechanism in addition the intrinsic built into docker. This means the pid file is guaranteed to be written out by the time the script exits. See #6184. Docker-DCO-1.1-Signed-off-by: Joe Beda (github: jbeda) --- contrib/init/sysvinit-debian/docker | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/contrib/init/sysvinit-debian/docker b/contrib/init/sysvinit-debian/docker index 9b50fad448..a3b9353754 100755 --- a/contrib/init/sysvinit-debian/docker +++ b/contrib/init/sysvinit-debian/docker @@ -22,7 +22,10 @@ BASE=$(basename $0) # modify these in /etc/default/$BASE (/etc/default/docker) DOCKER=/usr/bin/$BASE +# This is the pid file managed by docker itself DOCKER_PIDFILE=/var/run/$BASE.pid +# This is the pid file created/managed by start-stop-daemon +DOCKER_SSD_PIDFILE=/var/run/$BASE-ssd.pid DOCKER_LOGFILE=/var/log/$BASE.log DOCKER_OPTS= DOCKER_DESC="Docker" @@ -89,7 +92,8 @@ case "$1" in start-stop-daemon --start --background \ --no-close \ --exec "$DOCKER" \ - --pidfile "$DOCKER_PIDFILE" \ + --pidfile "$DOCKER_SSD_PIDFILE" \ + --make-pidfile \ -- \ -d -p "$DOCKER_PIDFILE" \ $DOCKER_OPTS \ @@ -100,13 +104,13 @@ case "$1" in stop) fail_unless_root log_begin_msg "Stopping $DOCKER_DESC: $BASE" - start-stop-daemon --stop --pidfile "$DOCKER_PIDFILE" + start-stop-daemon --stop --pidfile "$DOCKER_SSD_PIDFILE" log_end_msg $? ;; restart) fail_unless_root - docker_pid=`cat "$DOCKER_PIDFILE" 2>/dev/null` + docker_pid=`cat "$DOCKER_SSD_PIDFILE" 2>/dev/null` [ -n "$docker_pid" ] \ && ps -p $docker_pid > /dev/null 2>&1 \ && $0 stop @@ -119,7 +123,7 @@ case "$1" in ;; status) - status_of_proc -p "$DOCKER_PIDFILE" "$DOCKER" docker + status_of_proc -p "$DOCKER_SSD_PIDFILE" "$DOCKER" docker ;; *) -- cgit v1.2.1 From 338e87f6b34f36dcbb68db3b2999ce2bce5b40da Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Wed, 11 Jun 2014 14:35:16 -0700 Subject: api/server/MAINTAINERS: add proppy and vieux Docker-DCO-1.1-Signed-off-by: Johan Euphrosine (github: proppy) --- api/server/MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 api/server/MAINTAINERS diff --git a/api/server/MAINTAINERS b/api/server/MAINTAINERS new file mode 100644 index 0000000000..c92a061143 --- /dev/null +++ b/api/server/MAINTAINERS @@ -0,0 +1,2 @@ +Victor Vieux (@vieux) +Johan Euphrosine (@proppy) -- cgit v1.2.1 From e02cf69789d12e8d44c8168e1515f43f39be6461 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Sat, 14 Jun 2014 01:59:52 -0600 Subject: Fix contrib/man/md/docker-import.1.md warning ("macro `tar.gz,' not defined") Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- contrib/man/md/docker-import.1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/man/md/docker-import.1.md b/contrib/man/md/docker-import.1.md index a0db89eef4..6b76d191fa 100644 --- a/contrib/man/md/docker-import.1.md +++ b/contrib/man/md/docker-import.1.md @@ -9,8 +9,8 @@ of the tarball into it. **docker import** URL|- [REPOSITORY[:TAG]] # DESCRIPTION -Create a new filesystem image from the contents of a tarball (.tar, -.tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it. +Create a new filesystem image from the contents of a tarball (`.tar`, +`.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it. # EXAMPLES -- cgit v1.2.1 From 06248d745a6a69b14595a699e0e5b3e883d8ea3a Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 5 Jun 2014 18:05:49 +0000 Subject: update MAINTAINERS files Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- daemon/execdriver/MAINTAINERS | 1 + pkg/mflag/MAINTAINERS | 2 +- pkg/networkfs/MAINTAINERS | 2 +- pkg/sysinfo/MAINTAINERS | 1 + pkg/system/MAINTAINERS | 1 + server/MAINTAINERS | 2 +- 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/daemon/execdriver/MAINTAINERS b/daemon/execdriver/MAINTAINERS index 1e998f8ac1..68a97d2fc2 100644 --- a/daemon/execdriver/MAINTAINERS +++ b/daemon/execdriver/MAINTAINERS @@ -1 +1,2 @@ Michael Crosby (@crosbymichael) +Victor Vieux (@vieux) diff --git a/pkg/mflag/MAINTAINERS b/pkg/mflag/MAINTAINERS index ceeb0cfd18..e0f18f14f1 100644 --- a/pkg/mflag/MAINTAINERS +++ b/pkg/mflag/MAINTAINERS @@ -1 +1 @@ -Victor Vieux (@vieux) +Victor Vieux (@vieux) diff --git a/pkg/networkfs/MAINTAINERS b/pkg/networkfs/MAINTAINERS index ceeb0cfd18..e0f18f14f1 100644 --- a/pkg/networkfs/MAINTAINERS +++ b/pkg/networkfs/MAINTAINERS @@ -1 +1 @@ -Victor Vieux (@vieux) +Victor Vieux (@vieux) diff --git a/pkg/sysinfo/MAINTAINERS b/pkg/sysinfo/MAINTAINERS index 1e998f8ac1..68a97d2fc2 100644 --- a/pkg/sysinfo/MAINTAINERS +++ b/pkg/sysinfo/MAINTAINERS @@ -1 +1,2 @@ Michael Crosby (@crosbymichael) +Victor Vieux (@vieux) diff --git a/pkg/system/MAINTAINERS b/pkg/system/MAINTAINERS index 1e998f8ac1..68a97d2fc2 100644 --- a/pkg/system/MAINTAINERS +++ b/pkg/system/MAINTAINERS @@ -1 +1,2 @@ Michael Crosby (@crosbymichael) +Victor Vieux (@vieux) diff --git a/server/MAINTAINERS b/server/MAINTAINERS index 3564d3db47..e35518a6de 100644 --- a/server/MAINTAINERS +++ b/server/MAINTAINERS @@ -1,2 +1,2 @@ Solomon Hykes (@shykes) -Victor Vieux (@vieux) \ No newline at end of file +Victor Vieux (@vieux) -- cgit v1.2.1 From 3e4e8636c1b05626cae720b47ef99109077e1d3a Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 17 Jun 2014 00:06:21 +0000 Subject: do not alter json in docker save Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/server/server.go | 4 ++-- daemon/inspect.go | 2 +- graph/service.go | 2 +- server/server.go | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api/server/server.go b/api/server/server.go index 61407b2648..c6275177bc 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -855,7 +855,7 @@ func getContainersByName(eng *engine.Engine, version version.Version, w http.Res } var job = eng.Job("container_inspect", vars["name"]) if version.LessThan("1.12") { - job.SetenvBool("dirty", true) + job.SetenvBool("raw", true) } streamJSON(job, w, false) return job.Run() @@ -867,7 +867,7 @@ func getImagesByName(eng *engine.Engine, version version.Version, w http.Respons } var job = eng.Job("image_inspect", vars["name"]) if version.LessThan("1.12") { - job.SetenvBool("dirty", true) + job.SetenvBool("raw", true) } streamJSON(job, w, false) return job.Run() diff --git a/daemon/inspect.go b/daemon/inspect.go index af6d4520fb..6c4b74d6f2 100644 --- a/daemon/inspect.go +++ b/daemon/inspect.go @@ -15,7 +15,7 @@ func (daemon *Daemon) ContainerInspect(job *engine.Job) engine.Status { if container := daemon.Get(name); container != nil { container.Lock() defer container.Unlock() - if job.GetenvBool("dirty") { + if job.GetenvBool("raw") { b, err := json.Marshal(&struct { *Container HostConfig *runconfig.HostConfig diff --git a/graph/service.go b/graph/service.go index 4bce6b5645..ebdb881603 100644 --- a/graph/service.go +++ b/graph/service.go @@ -135,7 +135,7 @@ func (s *TagStore) CmdLookup(job *engine.Job) engine.Status { } name := job.Args[0] if image, err := s.LookupImage(name); err == nil && image != nil { - if job.GetenvBool("dirty") { + if job.GetenvBool("raw") { b, err := json.Marshal(image) if err != nil { return job.Error(err) diff --git a/server/server.go b/server/server.go index 76a51e796f..b054911ed8 100644 --- a/server/server.go +++ b/server/server.go @@ -433,6 +433,7 @@ func (srv *Server) exportImage(eng *engine.Engine, name, tempdir string) error { return err } job := eng.Job("image_inspect", n) + job.SetenvBool("raw", true) job.Stdout.Add(json) if err := job.Run(); err != nil { return err -- cgit v1.2.1 From 614c57c52161c0440247a4e4e36808116214770e Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 17 Jun 2014 00:59:51 +0000 Subject: improve test Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- integration-cli/docker_cli_save_load_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go index d728c7de95..3dc5b8d010 100644 --- a/integration-cli/docker_cli_save_load_test.go +++ b/integration-cli/docker_cli_save_load_test.go @@ -25,6 +25,10 @@ func TestSaveAndLoadRepo(t *testing.T) { out, _, err = runCommandWithOutput(commitCmd) errorOut(err, t, fmt.Sprintf("failed to commit container: %v %v", out, err)) + inspectCmd = exec.Command(dockerBinary, "inspect", repoName) + before, _, err := runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("the repo should exist before saving it: %v %v", before, err)) + saveCmdTemplate := `%v save %v > /tmp/foobar-save-load-test.tar` saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName) saveCmd := exec.Command("bash", "-c", saveCmdFinal) @@ -39,8 +43,12 @@ func TestSaveAndLoadRepo(t *testing.T) { errorOut(err, t, fmt.Sprintf("failed to load repo: %v %v", out, err)) inspectCmd = exec.Command(dockerBinary, "inspect", repoName) - out, _, err = runCommandWithOutput(inspectCmd) - errorOut(err, t, fmt.Sprintf("the repo should exist after loading it: %v %v", out, err)) + after, _, err := runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("the repo should exist after loading it: %v %v", after, err)) + + if before != after { + t.Fatalf("inspect is not the same after a save / load") + } deleteContainer(cleanedContainerID) deleteImages(repoName) -- cgit v1.2.1 From 6228761f67bb5f2af6c3105de556fa3fedb12069 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 17 Jun 2014 01:01:38 +0000 Subject: add a test using the flags Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- integration-cli/docker_cli_save_load_test.go | 60 ++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go index 3dc5b8d010..fb94cad9d8 100644 --- a/integration-cli/docker_cli_save_load_test.go +++ b/integration-cli/docker_cli_save_load_test.go @@ -7,8 +7,8 @@ import ( "testing" ) -// save a repo and try to load it -func TestSaveAndLoadRepo(t *testing.T) { +// save a repo and try to load it using stdout +func TestSaveAndLoadRepoStdout(t *testing.T) { runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") out, _, err := runCommandWithOutput(runCmd) errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err)) @@ -55,6 +55,58 @@ func TestSaveAndLoadRepo(t *testing.T) { os.Remove("/tmp/foobar-save-load-test.tar") - logDone("save - save a repo") - logDone("load - load a repo") + logDone("save - save a repo using stdout") + logDone("load - load a repo using stdout") +} + +// save a repo and try to load it using flags +func TestSaveAndLoadRepoFlags(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") + out, _, err := runCommandWithOutput(runCmd) + errorOut(err, t, fmt.Sprintf("failed to create a container: %v %v", out, err)) + + cleanedContainerID := stripTrailingCharacters(out) + + repoName := "foobar-save-load-test" + + inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) + out, _, err = runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("output should've been a container id: %v %v", cleanedContainerID, err)) + + commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName) + out, _, err = runCommandWithOutput(commitCmd) + errorOut(err, t, fmt.Sprintf("failed to commit container: %v %v", out, err)) + + inspectCmd = exec.Command(dockerBinary, "inspect", repoName) + before, _, err := runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("the repo should exist before saving it: %v %v", before, err)) + + saveCmdTemplate := `%v save -o /tmp/foobar-save-load-test.tar %v` + saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName) + saveCmd := exec.Command("bash", "-c", saveCmdFinal) + out, _, err = runCommandWithOutput(saveCmd) + errorOut(err, t, fmt.Sprintf("failed to save repo: %v %v", out, err)) + + deleteImages(repoName) + + loadCmdFinal := `docker load -i /tmp/foobar-save-load-test.tar` + loadCmd := exec.Command("bash", "-c", loadCmdFinal) + out, _, err = runCommandWithOutput(loadCmd) + errorOut(err, t, fmt.Sprintf("failed to load repo: %v %v", out, err)) + + inspectCmd = exec.Command(dockerBinary, "inspect", repoName) + after, _, err := runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("the repo should exist after loading it: %v %v", after, err)) + + if before != after { + t.Fatalf("inspect is not the same after a save / load") + } + + deleteContainer(cleanedContainerID) + deleteImages(repoName) + + os.Remove("/tmp/foobar-save-load-test.tar") + + logDone("save - save a repo using -o") + logDone("load - load a repo using -i") } -- cgit v1.2.1 From 962e1186f9a0a43344e19dcf70bac159f0eafb4e Mon Sep 17 00:00:00 2001 From: NikolaMandic Date: Wed, 18 Jun 2014 19:23:39 +0200 Subject: removed expect from mkimage-arch since it was not working Docker-DCO-1.1-Signed-off-by: NikolaMandic (github: NikolaMandic) --- contrib/mkimage-arch.sh | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/contrib/mkimage-arch.sh b/contrib/mkimage-arch.sh index dc21067473..0a77a11796 100755 --- a/contrib/mkimage-arch.sh +++ b/contrib/mkimage-arch.sh @@ -9,31 +9,13 @@ hash pacstrap &>/dev/null || { exit 1 } -hash expect &>/dev/null || { - echo "Could not find expect. Run pacman -S expect" - exit 1 -} - ROOTFS=$(mktemp -d /tmp/rootfs-archlinux-XXXXXXXXXX) chmod 755 $ROOTFS # packages to ignore for space savings PKGIGNORE=linux,jfsutils,lvm2,cryptsetup,groff,man-db,man-pages,mdadm,pciutils,pcmciautils,reiserfsprogs,s-nail,xfsprogs -expect < Date: Wed, 18 Jun 2014 15:08:33 +0400 Subject: More verbose error for parallel pull Partially fixes #6484 Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- server/server.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/server.go b/server/server.go index 620c8b20b8..66c2d7a289 100644 --- a/server/server.go +++ b/server/server.go @@ -1238,9 +1238,10 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, localName break } if !success { - out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, %s", img.Tag, localName, lastErr), nil)) + err := fmt.Errorf("Error pulling image (%s) from %s, %v", img.Tag, localName, lastErr) + out.Write(sf.FormatProgress(utils.TruncateID(img.ID), err.Error(), nil)) if parallel { - errors <- fmt.Errorf("Could not find repository on any of the indexed registries.") + errors <- err return } } -- cgit v1.2.1 From 216b4c9cf6cbdc9cd620de4edfbcd754a2184559 Mon Sep 17 00:00:00 2001 From: LK4D4 Date: Wed, 18 Jun 2014 23:11:04 +0400 Subject: Validate that one of streams choosen in logs on api side Fixes #6506 There is the bug, that very hard to fix: When we return job.Errorf in "logs" job it writes to job.Stderr, to which connected ResponseWriter and on this write w.WriteHeader(http.StatusOK) is called. So, we get 200 on error from "logs" job. Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- api/server/server.go | 27 +++++++----- api/server/server_unit_test.go | 99 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 13 deletions(-) diff --git a/api/server/server.go b/api/server/server.go index ce1bdbd39e..5feeaf9229 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -370,13 +370,23 @@ func getContainersLogs(eng *engine.Engine, version version.Version, w http.Respo } var ( - job = eng.Job("container_inspect", vars["name"]) - c, err = job.Stdout.AddEnv() + inspectJob = eng.Job("container_inspect", vars["name"]) + logsJob = eng.Job("logs", vars["name"]) + c, err = inspectJob.Stdout.AddEnv() ) if err != nil { return err } - if err = job.Run(); err != nil { + logsJob.Setenv("follow", r.Form.Get("follow")) + logsJob.Setenv("stdout", r.Form.Get("stdout")) + logsJob.Setenv("stderr", r.Form.Get("stderr")) + logsJob.Setenv("timestamps", r.Form.Get("timestamps")) + // Validate args here, because we can't return not StatusOK after job.Run() call + stdout, stderr := logsJob.GetenvBool("stdout"), logsJob.GetenvBool("stderr") + if !(stdout || stderr) { + return fmt.Errorf("Bad parameters: you must choose at least one stream") + } + if err = inspectJob.Run(); err != nil { return err } @@ -390,14 +400,9 @@ func getContainersLogs(eng *engine.Engine, version version.Version, w http.Respo errStream = outStream } - job = eng.Job("logs", vars["name"]) - job.Setenv("follow", r.Form.Get("follow")) - job.Setenv("stdout", r.Form.Get("stdout")) - job.Setenv("stderr", r.Form.Get("stderr")) - job.Setenv("timestamps", r.Form.Get("timestamps")) - job.Stdout.Add(outStream) - job.Stderr.Set(errStream) - if err := job.Run(); err != nil { + logsJob.Stdout.Add(outStream) + logsJob.Stderr.Set(errStream) + if err := logsJob.Run(); err != nil { fmt.Fprintf(outStream, "Error running logs job: %s\n", err) } return nil diff --git a/api/server/server_unit_test.go b/api/server/server_unit_test.go index 32f8e42b18..1116a0e562 100644 --- a/api/server/server_unit_test.go +++ b/api/server/server_unit_test.go @@ -4,12 +4,14 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/dotcloud/docker/api" - "github.com/dotcloud/docker/engine" "io" "net/http" "net/http/httptest" + "strings" "testing" + + "github.com/dotcloud/docker/api" + "github.com/dotcloud/docker/engine" ) func TestGetBoolParam(t *testing.T) { @@ -151,6 +153,99 @@ func TestGetContainersByName(t *testing.T) { } } +func TestLogs(t *testing.T) { + eng := engine.New() + var inspect bool + var logs bool + eng.Register("container_inspect", func(job *engine.Job) engine.Status { + inspect = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != "test" { + t.Fatalf("Container name %s, must be test", job.Args[0]) + } + return engine.StatusOK + }) + expected := "logs" + eng.Register("logs", func(job *engine.Job) engine.Status { + logs = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != "test" { + t.Fatalf("Container name %s, must be test", job.Args[0]) + } + follow := job.Getenv("follow") + if follow != "1" { + t.Fatalf("follow: %s, must be 1", follow) + } + stdout := job.Getenv("stdout") + if stdout != "1" { + t.Fatalf("stdout %s, must be 1", stdout) + } + stderr := job.Getenv("stderr") + if stderr != "" { + t.Fatalf("stderr %s, must be empty", stderr) + } + timestamps := job.Getenv("timestamps") + if timestamps != "1" { + t.Fatalf("timestamps %s, must be 1", timestamps) + } + job.Stdout.Write([]byte(expected)) + return engine.StatusOK + }) + r := serveRequest("GET", "/containers/test/logs?follow=1&stdout=1×tamps=1", nil, eng, t) + if r.Code != http.StatusOK { + t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK) + } + if !inspect { + t.Fatal("container_inspect job was not called") + } + if !logs { + t.Fatal("logs job was not called") + } + res := r.Body.String() + if res != expected { + t.Fatalf("Output %s, expected %s", res, expected) + } +} + +func TestLogsNoStreams(t *testing.T) { + eng := engine.New() + var inspect bool + var logs bool + eng.Register("container_inspect", func(job *engine.Job) engine.Status { + inspect = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } + if job.Args[0] != "test" { + t.Fatalf("Container name %s, must be test", job.Args[0]) + } + return engine.StatusOK + }) + eng.Register("logs", func(job *engine.Job) engine.Status { + logs = true + return engine.StatusOK + }) + r := serveRequest("GET", "/containers/test/logs", nil, eng, t) + if r.Code != http.StatusBadRequest { + t.Fatalf("Got status %d, expected %d", r.Code, http.StatusBadRequest) + } + if inspect { + t.Fatal("container_inspect job was called, but it shouldn't") + } + if logs { + t.Fatal("logs job was called, but it shouldn't") + } + res := strings.TrimSpace(r.Body.String()) + expected := "Bad parameters: you must choose at least one stream" + if !strings.Contains(res, expected) { + t.Fatalf("Output %s, expected %s in it", res, expected) + } +} + func serveRequest(method, target string, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder { r := httptest.NewRecorder() req, err := http.NewRequest(method, target, body) -- cgit v1.2.1 From 80bc06f1cf0833479d59078dc2a73c40711f3980 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 19 Jun 2014 11:25:14 +0200 Subject: Fix flag names --- docs/sources/reference/run.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/reference/run.md b/docs/sources/reference/run.md index 5cb050c025..b379f24c0b 100644 --- a/docs/sources/reference/run.md +++ b/docs/sources/reference/run.md @@ -103,7 +103,7 @@ interactive cases. ## Container Identification -### Name (–name) +### Name (–-name) The operator can identify a container in three ways: @@ -190,7 +190,7 @@ localhost interface. $ # use the redis container's network stack to access localhost $ docker run --rm -ti --net container:redis example/redis-cli -h 127.0.0.1 -## Clean Up (–rm) +## Clean Up (–-rm) By default a container's file system persists even after the container exits. This makes debugging a lot easier (since you can inspect the -- cgit v1.2.1 From 40966fa0966b3acd1893852a5297526374b690f2 Mon Sep 17 00:00:00 2001 From: lalyos Date: Thu, 19 Jun 2014 13:00:45 +0200 Subject: Fix installation docs to use the new boot2docker command: ip Docker-DCO-1.1-Signed-off-by: Lajos Papp (github: lalyos) --- docs/sources/installation/mac.md | 4 ++-- docs/sources/installation/windows.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sources/installation/mac.md b/docs/sources/installation/mac.md index a982c59845..4677005ccd 100644 --- a/docs/sources/installation/mac.md +++ b/docs/sources/installation/mac.md @@ -78,7 +78,7 @@ If you run a container with an exposed port, then you should be able to access that Nginx server using the IP address reported by: - $ boot2docker ssh ip addr show dev eth1 + $ boot2docker ip Typically, it is 192.168.59.103, but it could get changed by Virtualbox's DHCP implementation. @@ -91,7 +91,7 @@ The Boot2Docker management tool provides several commands: $ ./boot2docker Usage: ./boot2docker [] - {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|delete|download|version} + {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|delete|download|version} [] Continue with the [User Guide](/userguide/). diff --git a/docs/sources/installation/windows.md b/docs/sources/installation/windows.md index 447d8b280f..a1c910ee6d 100644 --- a/docs/sources/installation/windows.md +++ b/docs/sources/installation/windows.md @@ -63,7 +63,7 @@ This will download the small busybox image and print "hello world". The Boot2Docker management tool provides several commands: $ ./boot2docker - Usage: ./boot2docker [] {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|delete|download|version} [] + Usage: ./boot2docker [] {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|delete|download|version} [] ## Container port redirection -- cgit v1.2.1 From 10eae16fa70ac04191401bf2872ffa6688f79b82 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Thu, 19 Jun 2014 07:44:41 -0500 Subject: Updated SSH example to ensure it continues working Docker-DCO-1.1-Signed-off-by: James Turnbull (github: jamtur01) --- docs/sources/examples/running_ssh_service.Dockerfile | 2 +- docs/sources/examples/running_ssh_service.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/examples/running_ssh_service.Dockerfile b/docs/sources/examples/running_ssh_service.Dockerfile index 978e610422..57baf88cef 100644 --- a/docs/sources/examples/running_ssh_service.Dockerfile +++ b/docs/sources/examples/running_ssh_service.Dockerfile @@ -2,7 +2,7 @@ # # VERSION 0.0.1 -FROM debian +FROM ubuntu:12.04 MAINTAINER Thatcher R. Peskens "thatcher@dotcloud.com" # make sure the package repository is up to date diff --git a/docs/sources/examples/running_ssh_service.md b/docs/sources/examples/running_ssh_service.md index 27439f998f..579d372ba7 100644 --- a/docs/sources/examples/running_ssh_service.md +++ b/docs/sources/examples/running_ssh_service.md @@ -12,7 +12,7 @@ quick access to a test container. # # VERSION 0.0.1 - FROM debian + FROM ubuntu:12.04 MAINTAINER Thatcher R. Peskens "thatcher@dotcloud.com" # make sure the package repository is up to date -- cgit v1.2.1 From d7e5fdfb58d5829344486b7a6171f7e866f0378b Mon Sep 17 00:00:00 2001 From: "Kevin \"qwazerty\" Houdebert" Date: Thu, 19 Jun 2014 09:11:26 +0200 Subject: Fix minor typo Docker-DCO-1.1-Signed-off-by: Kevin Houdebert kevin.houdebert@gmail.com (github: qwazerty) --- runconfig/parse.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runconfig/parse.go b/runconfig/parse.go index 5bb065421c..fd3e4a50a7 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -65,7 +65,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container") flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)") flCpuset = cmd.String([]string{"-cpuset"}, "", "CPUs in which to allow execution (0-3, 0,1)") - flNetMode = cmd.String([]string{"-net"}, "bridge", "Set the Network mode for the container\n'bridge': creates a new network stack for the container on the docker bridge\n'none': no networking for this container\n'container:': reuses another container network stack\n'host': use the host network stack inside the contaner. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.") + flNetMode = cmd.String([]string{"-net"}, "bridge", "Set the Network mode for the container\n'bridge': creates a new network stack for the container on the docker bridge\n'none': no networking for this container\n'container:': reuses another container network stack\n'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.") // For documentation purpose _ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)") _ = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container") -- cgit v1.2.1 From d17c92965937bbc3181b73bb8a4e21ecee217e5f Mon Sep 17 00:00:00 2001 From: LK4D4 Date: Thu, 19 Jun 2014 21:42:55 +0400 Subject: Fix stdcopy when reads large frame at once Fixes TestLogsContainerMuchBiggerThanPage with go 1.3(#6520) Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- utils/stdcopy.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/utils/stdcopy.go b/utils/stdcopy.go index ab8759f4ee..bb9d632661 100644 --- a/utils/stdcopy.go +++ b/utils/stdcopy.go @@ -82,13 +82,17 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) for nr < StdWriterPrefixLen { var nr2 int nr2, er = src.Read(buf[nr:]) - // Don't exit on EOF, because we can have some more input - if er != nil && er != io.EOF { - return 0, er - } nr += nr2 - if nr == 0 { - return written, nil + if er == io.EOF { + if nr < StdWriterPrefixLen { + Debugf("Corrupted prefix: %v", buf[:nr]) + return written, nil + } + break + } + if er != nil { + Debugf("Error reading header: %s", er) + return 0, er } } @@ -123,21 +127,22 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) for nr < frameSize+StdWriterPrefixLen { var nr2 int nr2, er = src.Read(buf[nr:]) + nr += nr2 if er == io.EOF { - return written, nil + if nr < frameSize+StdWriterPrefixLen { + Debugf("Corrupted frame: %v", buf[StdWriterPrefixLen:nr]) + return written, nil + } + break } if er != nil { Debugf("Error reading frame: %s", er) return 0, er } - nr += nr2 } // Write the retrieved frame (without header) nw, ew = out.Write(buf[StdWriterPrefixLen : frameSize+StdWriterPrefixLen]) - if nw > 0 { - written += int64(nw) - } if ew != nil { Debugf("Error writing frame: %s", ew) return 0, ew @@ -147,6 +152,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) Debugf("Error Short Write: (%d on %d)", nw, frameSize) return 0, io.ErrShortWrite } + written += int64(nw) // Move the rest of the buffer to the beginning copy(buf, buf[frameSize+StdWriterPrefixLen:]) -- cgit v1.2.1 From 3f7909e9967ded9740fdf951c6f7e95f4aa9c963 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 19 Jun 2014 14:35:30 -0600 Subject: Disable netgo for dynbinary builds It's not necessary to use the netgo implementation for non-static builds. :) Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- hack/make/dynbinary | 1 + 1 file changed, 1 insertion(+) diff --git a/hack/make/dynbinary b/hack/make/dynbinary index 426b9cb566..74bb0dd36e 100644 --- a/hack/make/dynbinary +++ b/hack/make/dynbinary @@ -40,5 +40,6 @@ fi ( export LDFLAGS_STATIC_DOCKER="-X github.com/dotcloud/docker/dockerversion.INITSHA1 \"$DOCKER_INITSHA1\" -X github.com/dotcloud/docker/dockerversion.INITPATH \"$DOCKER_INITPATH\"" + export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary source "$(dirname "$BASH_SOURCE")/binary" ) -- cgit v1.2.1 From bf69b773ec4c817dcc276e4471fc85f762f18f9f Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Thu, 19 Jun 2014 12:07:39 -0500 Subject: Fixed #6545 - Updated Security article Docker-DCO-1.1-Signed-off-by: James Turnbull (github: jamtur01) --- docs/sources/articles/security.md | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/docs/sources/articles/security.md b/docs/sources/articles/security.md index cdf5fdddd0..83704e434a 100644 --- a/docs/sources/articles/security.md +++ b/docs/sources/articles/security.md @@ -17,15 +17,10 @@ There are three major areas to consider when reviewing Docker security: ## Kernel Namespaces -Docker containers are essentially LXC containers, and they come with the -same security features. When you start a container with -`docker run`, behind the scenes Docker uses -`lxc-start` to execute the Docker container. This -creates a set of namespaces and control groups for the container. Those -namespaces and control groups are not created by Docker itself, but by -`lxc-start`. This means that as the LXC userland -tools evolve (and provide additional namespaces and isolation features), -Docker will automatically make use of them. +Docker containers are very similar to LXC containers, and they come with +the similar security features. When you start a container with `docker +run`, behind the scenes Docker creates a set of namespaces and control +groups for the container. **Namespaces provide the first and most straightforward form of isolation**: processes running within a container cannot see, and even @@ -55,10 +50,9 @@ ago), namespace code has been exercised and scrutinized on a large number of production systems. And there is more: the design and inspiration for the namespaces code are even older. Namespaces are actually an effort to reimplement the features of [OpenVZ]( -http://en.wikipedia.org/wiki/OpenVZ) in such a way that they -could be merged within the mainstream kernel. And OpenVZ was initially -released in 2005, so both the design and the implementation are pretty -mature. +http://en.wikipedia.org/wiki/OpenVZ) in such a way that they could be +merged within the mainstream kernel. And OpenVZ was initially released +in 2005, so both the design and the implementation are pretty mature. ## Control Groups @@ -82,7 +76,7 @@ started in 2006, and initially merged in kernel 2.6.24. ## Docker Daemon Attack Surface Running containers (and applications) with Docker implies running the -Docker daemon. This daemon currently requires root privileges, and you +Docker daemon. This daemon currently requires `root` privileges, and you should therefore be aware of some important details. First of all, **only trusted users should be allowed to control your @@ -114,8 +108,9 @@ socket. You can also expose the REST API over HTTP if you explicitly decide so. However, if you do that, being aware of the above mentioned security implication, you should ensure that it will be reachable only from a -trusted network or VPN; or protected with e.g. `stunnel` -and client SSL certificates. +trusted network or VPN; or protected with e.g. `stunnel` and client SSL +certificates. You can also secure them with [HTTPS and +certificates](/articles/https/). Recent improvements in Linux namespaces will soon allow to run full-featured containers without root privileges, thanks to the new user @@ -199,15 +194,18 @@ container, it will be much harder to do serious damage, or to escalate to the host. This won't affect regular web apps; but malicious users will find that -the arsenal at their disposal has shrunk considerably! You can see [the -list of dropped capabilities in the Docker -code](https://github.com/dotcloud/docker/blob/v0.5.0/lxc_template.go#L97), -and a full list of available capabilities in [Linux +the arsenal at their disposal has shrunk considerably! By default Docker +drops all capabilities except [those +needed](https://github.com/dotcloud/docker/blob/master/daemon/execdriver/native/template/default_template.go), +a whitelist instead of a blacklist approach. You can see a full list of +available capabilities in [Linux manpages](http://man7.org/linux/man-pages/man7/capabilities.7.html). Of course, you can always enable extra capabilities if you really need them (for instance, if you want to use a FUSE-based filesystem), but by -default, Docker containers will be locked down to ensure maximum safety. +default, Docker containers use only a +[whitelist](https://github.com/dotcloud/docker/blob/master/daemon/execdriver/native/template/default_template.go) +of kernel capabilities by default. ## Other Kernel Security Features @@ -222,17 +220,16 @@ harden a Docker host. Here are a few examples. - You can run a kernel with GRSEC and PAX. This will add many safety checks, both at compile-time and run-time; it will also defeat many - exploits, thanks to techniques like address randomization. It - doesn't require Docker-specific configuration, since those security - features apply system-wide, independently of containers. - - If your distribution comes with security model templates for LXC - containers, you can use them out of the box. For instance, Ubuntu - comes with AppArmor templates for LXC, and those templates provide - an extra safety net (even though it overlaps greatly with - capabilities). + exploits, thanks to techniques like address randomization. It doesn't + require Docker-specific configuration, since those security features + apply system-wide, independently of containers. + - If your distribution comes with security model templates for + Docker containers, you can use them out of the box. For instance, we + ship a template that works with AppArmor and Red Hat comes with SELinux + policies for Docker. These templates provide an extra safety net (even + though it overlaps greatly with capabilities). - You can define your own policies using your favorite access control - mechanism. Since Docker containers are standard LXC containers, - there is nothing “magic” or specific to Docker. + mechanism. Just like there are many third-party tools to augment Docker containers with e.g. special network topologies or shared filesystems, you can @@ -243,7 +240,7 @@ affecting Docker's core. Docker containers are, by default, quite secure; especially if you take care of running your processes inside the containers as non-privileged -users (i.e. non root). +users (i.e. non-`root`). You can add an extra layer of safety by enabling Apparmor, SELinux, GRSEC, or your favorite hardening solution. -- cgit v1.2.1 From 49376ec4483c241167f7623ccc0260486ce8d4a3 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 20 Jun 2014 01:06:48 +0000 Subject: Change version to 1.0.1-dev Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7dea76edb3..3f60217db9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 +1.0.1-dev -- cgit v1.2.1 From 4efe02b3df67af544d398e435fbe567502bf0dea Mon Sep 17 00:00:00 2001 From: Adam Singer Date: Thu, 19 Jun 2014 22:01:10 -0700 Subject: full url to GCE image Docker-DCO-1.1-Signed-off-by: Adam Singer (github: financeCoding) --- docs/sources/installation/google.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/installation/google.md b/docs/sources/installation/google.md index c91d13612f..79d40c07d9 100644 --- a/docs/sources/installation/google.md +++ b/docs/sources/installation/google.md @@ -21,7 +21,7 @@ page_keywords: Docker, Docker documentation, installation, google, Google Comput (select a zone close to you and the desired instance size) $ gcloud compute instances create docker-playground \ - --image projects/google-containers/global/images/container-vm-v20140522 \ + --image https://www.googleapis.com/compute/v1/projects/google-containers/global/images/container-vm-v20140522 \ --zone us-central1-a \ --machine-type f1-micro -- cgit v1.2.1 From db9bf744ab93f1e688bf986794c852abc40b873e Mon Sep 17 00:00:00 2001 From: shaunol Date: Fri, 20 Jun 2014 19:23:35 +1200 Subject: Update windows.md Update Program Files path description, the default install folder is "Boot2Docker", rather than "Docker" --- docs/sources/installation/windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/installation/windows.md b/docs/sources/installation/windows.md index 447d8b280f..ff987054ab 100644 --- a/docs/sources/installation/windows.md +++ b/docs/sources/installation/windows.md @@ -25,7 +25,7 @@ virtual machine and runs the Docker daemon. 2. Run the installer, which will install VirtualBox, MSYS-git, the boot2docker Linux ISO, and the Boot2Docker management tool. ![](/installation/images/windows-installer.png) -3. Run the `Boot2Docker Start` shell script from your Desktop or Program Files > Docker. +3. Run the `Boot2Docker Start` shell script from your Desktop or Program Files > Boot2Docker for Windows. The Start script will ask you to enter an ssh key passphrase - the simplest (but least secure) is to just hit [Enter]. -- cgit v1.2.1 From cbdce9912d9f904b237e29dd2a1196367337628b Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 20 Jun 2014 07:14:56 -0400 Subject: Fix typo in networking.md Minor typo fix --- docs/sources/articles/networking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/articles/networking.md b/docs/sources/articles/networking.md index 927cd80875..bf46b90ea2 100644 --- a/docs/sources/articles/networking.md +++ b/docs/sources/articles/networking.md @@ -26,7 +26,7 @@ bridge* that automatically forwards packets between any other network interfaces that are attached to it. This lets containers communicate both with the host machine and with each other. Every time Docker creates a container, it creates a pair of “peer” interfaces that are -like opposite ends of a pipe — a packet send on one will be received on +like opposite ends of a pipe — a packet sent on one will be received on the other. It gives one of the peers to the container to become its `eth0` interface and keeps the other peer, with a unique name like `vethAQI2QT`, out in the namespace of the host machine. By binding -- cgit v1.2.1 From 66bccf3064effd910e47405dc738ba08a8d14b12 Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 20 Jun 2014 07:49:22 -0400 Subject: Minor typo/format fixes This fixes a code block typo so it renders as a code block. Additionally synchronizes the variable prefix examples from 'DB' and 'DB1_' to 'DB_' and 'DB1_' --- docs/sources/userguide/dockerlinks.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockerlinks.md b/docs/sources/userguide/dockerlinks.md index 833f4aed98..5a81cd5738 100644 --- a/docs/sources/userguide/dockerlinks.md +++ b/docs/sources/userguide/dockerlinks.md @@ -173,6 +173,7 @@ child container in two ways: Let's look first at the environment variables Docker sets. Let's run the `env` command to list the container's environment variables. + $ sudo docker run --rm --name web2 --link db:db training/webapp env . . . DB_NAME=/web2/db @@ -190,7 +191,7 @@ command to list the container's environment variables. We can see that Docker has created a series of environment variables with useful information about our `db` container. Each variables is prefixed with -`DB` which is populated from the `alias` we specified above. If our `alias` +`DB_` which is populated from the `alias` we specified above. If our `alias` were `db1` the variables would be prefixed with `DB1_`. You can use these environment variables to configure your applications to connect to the database on the `db` container. The connection will be secure, private and only the -- cgit v1.2.1 From a206186f8427c74fbf9625e4140bf84461a67eec Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Fri, 20 Jun 2014 10:04:48 -0600 Subject: Add a ton of simple improvements to contrib/mkimage/debootstrap, especially comments in the extra files put inside the image This also adds support for squeeze-lts. :) Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- contrib/mkimage.sh | 2 +- contrib/mkimage/debootstrap | 81 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/contrib/mkimage.sh b/contrib/mkimage.sh index db4815c204..dc82145acf 100755 --- a/contrib/mkimage.sh +++ b/contrib/mkimage.sh @@ -6,7 +6,7 @@ mkimg="$(basename "$0")" usage() { echo >&2 "usage: $mkimg [-d dir] [-t tag] script [script-args]" echo >&2 " ie: $mkimg -t someuser/debian debootstrap --variant=minbase jessie" - echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal trusty" + echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal --components main,universe trusty" echo >&2 " $mkimg -t someuser/busybox busybox-static" echo >&2 " $mkimg -t someuser/centos:5 rinse --distribution centos-5" exit 1 diff --git a/contrib/mkimage/debootstrap b/contrib/mkimage/debootstrap index 4747a84d31..d5aeae2b99 100755 --- a/contrib/mkimage/debootstrap +++ b/contrib/mkimage/debootstrap @@ -23,9 +23,14 @@ shift # now for some Docker-specific tweaks # prevent init scripts from running during install/update -echo >&2 "+ cat > '$rootfsDir/usr/sbin/policy-rc.d'" +echo >&2 "+ echo exit 101 > '$rootfsDir/usr/sbin/policy-rc.d'" cat > "$rootfsDir/usr/sbin/policy-rc.d" <<'EOF' #!/bin/sh + +# For most Docker users, "apt-get install" only happens during "docker build", +# where starting services doesn't work and often fails in humorous ways. This +# prevents those failures by stopping the services from attempting to start. + exit 101 EOF chmod +x "$rootfsDir/usr/sbin/policy-rc.d" @@ -34,17 +39,25 @@ chmod +x "$rootfsDir/usr/sbin/policy-rc.d" ( set -x chroot "$rootfsDir" dpkg-divert --local --rename --add /sbin/initctl - ln -sf /bin/true "$rootfsDir/sbin/initctl" + cp -a "$rootfsDir/usr/sbin/policy-rc.d" "$rootfsDir/sbin/initctl" + sed -i 's/^exit.*/exit 0/' "$rootfsDir/sbin/initctl" ) -# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB) +# shrink a little, since apt makes us cache-fat (wheezy: ~157.5MB vs ~120MB) ( set -x; chroot "$rootfsDir" apt-get clean ) # Ubuntu 10.04 sucks... :) if strings "$rootfsDir/usr/bin/dpkg" | grep -q unsafe-io; then # force dpkg not to call sync() after package extraction (speeding up installs) echo >&2 "+ echo force-unsafe-io > '$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup'" - echo 'force-unsafe-io' > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" + cat > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" <<-'EOF' + # For most Docker users, package installs happen during "docker build", which + # doesn't survive power loss and gets restarted clean afterwards anyhow, so + # this minor tweak gives us a nice speedup (much nicer on spinning disks, + # obviously). + + force-unsafe-io + EOF fi if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then @@ -52,16 +65,36 @@ if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";' echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-clean'" cat > "$rootfsDir/etc/apt/apt.conf.d/docker-clean" <<-EOF + # Since for most Docker users, package installs happen in "docker build" steps, + # they essentially become individual layers due to the way Docker handles + # layering, especially using CoW filesystems. What this means for us is that + # the caches that APT keeps end up just wasting space in those layers, making + # our layers unnecessarily large (especially since we'll normally never use + # these caches again and will instead just "docker build" again and make a brand + # new image). + + # Ideally, these would just be invoking "apt-get clean", but in our testing, + # that ended up being cyclic and we got stuck on APT's lock, so we get this fun + # creation that's essentially just "apt-get clean". DPkg::Post-Invoke { ${aptGetClean} }; APT::Update::Post-Invoke { ${aptGetClean} }; Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache ""; + + # Note that we do realize this isn't the ideal way to do this, and are always + # open to better suggestions (https://github.com/dotcloud/docker/issues). EOF # remove apt-cache translations for fast "apt-get update" - echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" - echo 'Acquire::Languages "none";' > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" + echo >&2 "+ echo Acquire::Languages 'none' > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" + cat > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" <<-'EOF' + # In Docker, we don't often need the "Translations" files, so we're just wasting + # time and space by downloading them, and this inhibits that. For users that do + # need them, it's a simple matter to delete this file and "apt-get update". :) + + Acquire::Languages "none"; + EOF fi if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then @@ -76,39 +109,53 @@ if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then if [ -z "$lsbDist" -a -r "$rootfsDir/etc/debian_version" ]; then lsbDist='Debian' fi + # normalize to lowercase for easier matching + lsbDist="$(echo "$lsbDist" | tr '[:upper:]' '[:lower:]')" case "$lsbDist" in - debian|Debian) + debian) # updates and security! if [ "$suite" != 'sid' -a "$suite" != 'unstable' ]; then ( set -x - sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list" + sed -i " + p; + s/ $suite / ${suite}-updates / + " "$rootfsDir/etc/apt/sources.list" echo "deb http://security.debian.org $suite/updates main" >> "$rootfsDir/etc/apt/sources.list" + # LTS + if [ "$suite" = 'squeeze' ]; then + head -1 "$rootfsDir/etc/apt/sources.list" \ + | sed "s/ $suite / ${suite}-lts /" \ + >> "$rootfsDir/etc/apt/sources.list" + fi ) fi ;; - ubuntu|Ubuntu) - # add the universe, updates, and security repositories + ubuntu) + # add the updates and security repositories ( set -x sed -i " - s/ $suite main$/ $suite main universe/; p; - s/ $suite main/ ${suite}-updates main/; p; - s/ $suite-updates main/ ${suite}-security main/ + p; + s/ $suite / ${suite}-updates /; p; + s/ $suite-updates / ${suite}-security / " "$rootfsDir/etc/apt/sources.list" ) ;; - tanglu|Tanglu) + tanglu) # add the updates repository if [ "$suite" != 'devel' ]; then ( set -x - sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list" + sed -i " + p; + s/ $suite / ${suite}-updates / + " "$rootfsDir/etc/apt/sources.list" ) fi ;; - steamos|SteamOS) - # add contrib and non-free + steamos) + # add contrib and non-free if "main" is the only component ( set -x sed -i "s/ $suite main$/ $suite main contrib non-free/" "$rootfsDir/etc/apt/sources.list" -- cgit v1.2.1 From d3bc787bca62edff384e06a12224be2d982353da Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Tue, 17 Jun 2014 09:05:29 -0400 Subject: docker save: raw json Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- graph/service.go | 3 +-- image/image.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/graph/service.go b/graph/service.go index ebdb881603..3201d6b994 100644 --- a/graph/service.go +++ b/graph/service.go @@ -1,7 +1,6 @@ package graph import ( - "encoding/json" "io" "github.com/dotcloud/docker/engine" @@ -136,7 +135,7 @@ func (s *TagStore) CmdLookup(job *engine.Job) engine.Status { name := job.Args[0] if image, err := s.LookupImage(name); err == nil && image != nil { if job.GetenvBool("raw") { - b, err := json.Marshal(image) + b, err := image.RawJson() if err != nil { return job.Error(err) } diff --git a/image/image.go b/image/image.go index b56cbf08ee..5c250947ce 100644 --- a/image/image.go +++ b/image/image.go @@ -149,6 +149,22 @@ func jsonPath(root string) string { return path.Join(root, "json") } +func (img *Image) RawJson() ([]byte, error) { + root, err := img.root() + if err != nil { + return nil, fmt.Errorf("Failed to get root for image %s: %s", img.ID, err) + } + fh, err := os.Open(jsonPath(root)) + if err != nil { + return nil, fmt.Errorf("Failed to open json for image %s: %s", img.ID, err) + } + buf, err := ioutil.ReadAll(fh) + if err != nil { + return nil, fmt.Errorf("Failed to read json for image %s: %s", img.ID, err) + } + return buf, nil +} + // TarLayer returns a tar archive of the image's filesystem layer. func (img *Image) TarLayer() (arch archive.Archive, err error) { if img.graph == nil { -- cgit v1.2.1 From 6d14e9f1acc3d5927cbd4f4b3c7ea0c691dea7bc Mon Sep 17 00:00:00 2001 From: Jonathan Boulle Date: Thu, 19 Jun 2014 01:29:40 -0700 Subject: be consistent in capitalization of Docker Docker-DCO-1.1-Signed-off-by: Jonathan Boulle (github: jonboulle) --- docker/docker.go | 10 +++++----- docs/sources/reference/commandline/cli.md | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docker/docker.go b/docker/docker.go index 56bcb04e41..a89eff454f 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -47,7 +47,7 @@ func main() { bridgeName = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking") bridgeIp = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b") pidfile = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file") - flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the docker runtime") + flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime") flSocketGroup = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group") flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") flDns = opts.NewListOpts(opts.ValidateIp4Address) @@ -56,8 +56,8 @@ func main() { flEnableIpForward = flag.Bool([]string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward") flDefaultIp = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports") flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication") - flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the docker runtime to use a specific storage driver") - flExecDriver = flag.String([]string{"e", "-exec-driver"}, "native", "Force the docker runtime to use a specific exec driver") + flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver") + flExecDriver = flag.String([]string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver") flHosts = opts.NewListOpts(api.ValidateHost) flMtu = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU\nif no value is provided: default to the default route MTU or 1500 if no default route is available") flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags") @@ -67,7 +67,7 @@ func main() { flKey = flag.String([]string{"-tlskey"}, dockerConfDir+defaultKeyFile, "Path to TLS key file") flSelinuxEnabled = flag.Bool([]string{"-selinux-enabled"}, false, "Enable selinux support") ) - flag.Var(&flDns, []string{"#dns", "-dns"}, "Force docker to use specific DNS servers") + flag.Var(&flDns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers") flag.Var(&flDnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains") flag.Var(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.") flag.Var(&flGraphOpts, []string{"-storage-opt"}, "Set storage driver options") @@ -259,7 +259,7 @@ func showVersion() { func checkKernelAndArch() error { // Check for unsupported architectures if runtime.GOARCH != "amd64" { - return fmt.Errorf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH) + return fmt.Errorf("The Docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH) } // Check for unsupported kernel versions // FIXME: it would be cleaner to not test for specific versions, but rather diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index e496ce425f..b92eeb3fbc 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -58,10 +58,10 @@ expect an integer, and they can only be specified once. -D, --debug=false Enable debug mode --dns=[] Force docker to use specific DNS servers --dns-search=[] Force Docker to use specific DNS search domains - -e, --exec-driver="native" Force the docker runtime to use a specific exec driver + -e, --exec-driver="native" Force the Docker runtime to use a specific exec driver -G, --group="docker" Group to assign the unix socket specified by -H when running in daemon mode use '' (the empty string) to disable setting of a group - -g, --graph="/var/lib/docker" Path to use as the root of the docker runtime + -g, --graph="/var/lib/docker" Path to use as the root of the Docker runtime -H, --host=[] The socket(s) to bind to in daemon mode specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd. --icc=true Enable inter-container communication @@ -72,7 +72,7 @@ expect an integer, and they can only be specified once. if no value is provided: default to the default route MTU or 1500 if no default route is available -p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file -r, --restart=true Restart previously running containers - -s, --storage-driver="" Force the docker runtime to use a specific storage driver + -s, --storage-driver="" Force the Docker runtime to use a specific storage driver --storage-opt=[] Set storage driver options --selinux-enabled=false Enable selinux support --tls=false Use TLS; implied by tls-verify flags -- cgit v1.2.1 From 1bcc37caec07c01ab385f562ffa56d2b2bb0a7d8 Mon Sep 17 00:00:00 2001 From: Paul Weaver Date: Fri, 20 Jun 2014 22:18:37 +0100 Subject: Fix minor typo and improve wording --- docs/sources/reference/builder.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/reference/builder.md b/docs/sources/reference/builder.md index 8717eb7bfc..a10cac00ea 100644 --- a/docs/sources/reference/builder.md +++ b/docs/sources/reference/builder.md @@ -15,7 +15,7 @@ To [*build*](../commandline/cli/#cli-build) an image from a source repository, create a description file called Dockerfile at the root of your repository. This file will describe the steps to assemble the image. -Then call `docker build` with the path of you source repository as argument +Then call `docker build` with the path of your source repository as the argument (for example, `.`): $ sudo docker build . -- cgit v1.2.1 From 5266d6fa7bc367ac4c7472550b7220c4eb06731f Mon Sep 17 00:00:00 2001 From: Paul Weaver Date: Fri, 20 Jun 2014 22:36:31 +0100 Subject: Clean up some uses on 'an' in builder docs --- docs/sources/reference/builder.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sources/reference/builder.md b/docs/sources/reference/builder.md index a10cac00ea..82b91a5b41 100644 --- a/docs/sources/reference/builder.md +++ b/docs/sources/reference/builder.md @@ -239,13 +239,13 @@ In the case where `` is a remote file URL, the destination will have permis > **Note**: > If you build using STDIN (`docker build - < somefile`), there is no -> build context, so the Dockerfile can only contain an URL based ADD +> build context, so the Dockerfile can only contain a URL based ADD > statement. > **Note**: > If your URL files are protected using authentication, you will need to -> use an `RUN wget` , `RUN curl` -> or other tool from within the container as ADD does not support +> use `RUN wget` , `RUN curl` +> or use another tool from within the container as ADD does not support > authentication. The copy obeys the following rules: -- cgit v1.2.1 From c70fbae3ed44090fffc9e5b81d2a6410e6008fcc Mon Sep 17 00:00:00 2001 From: Fred Lifton Date: Fri, 20 Jun 2014 17:10:20 -0700 Subject: Revised and fixed links on dockerrepo.md Docker-DCO-1.1-Signed-off-by: Fred Lifton (github: fredlf) --- docs/sources/userguide/dockerrepos.md | 136 ++++++++++++++++------------------ 1 file changed, 63 insertions(+), 73 deletions(-) diff --git a/docs/sources/userguide/dockerrepos.md b/docs/sources/userguide/dockerrepos.md index 5babfc76f4..2e5abbba15 100644 --- a/docs/sources/userguide/dockerrepos.md +++ b/docs/sources/userguide/dockerrepos.md @@ -1,37 +1,49 @@ page_title: Working with Docker Hub -page_description: Learning how to use Docker Hub to manage images and work flow +page_description: Learn how to use the Docker Hub to manage Docker images and work flow page_keywords: repo, Docker Hub, Docker Hub, registry, index, repositories, usage, pull image, push image, image, documentation # Working with Docker Hub -So far we've seen a lot about how to use Docker on the command line and -your local host. We've seen [how to pull down -images](/userguide/usingdocker/) that you can run your containers from -and we've seen how to [create your own images](/userguide/dockerimages). +So far you've learned how to use the command line to run Docker on your local host. +You've learned how to [pull down images](/userguide/usingdocker/) to build containers +from existing images and you've learned how to [create your own images](/userguide/dockerimages). -Now we're going to learn a bit more about -[Docker Hub](https://hub.docker.com) and how you can use it to enhance -your Docker work flows. +Next, you're going to learn how to use the [Docker Hub](https://hub.docker.com) to +simplify and enhance your Docker workflows. -[Docker Hub](https://hub.docker.com) is the public registry that Docker -Inc maintains. It contains a huge collection of images, over 15,000, -that you can download and use to build your containers. It also provides -authentication, structure (you can setup teams and organizations), work -flow tools like webhooks and build triggers as well as privacy features -like private repositories for storing images you don't want to publicly -share. +The [Docker Hub](https://hub.docker.com) is a public registry maintained by Docker, +Inc. It contains over 15,000 images you can download and use to build containers. It also +provides authentication, work group structure, workflow tools like webhooks and build +triggers, and privacy tools like private repositories for storing images you don't want +to share publicly. ## Docker commands and Docker Hub -Docker acts as a client for these services via the `docker search`, -`pull`, `login` and `push` commands. +Docker itself provides access to Docker Hub services via the `docker search`, +`pull`, `login`, and `push` commands. This page will show you how these commands work. + +### Account creation and login +Typically, you'll want to start by creating an account on Docker Hub (if you haven't +already) and logging in. You can create your account directly on +[Docker Hub](https://hub.docker.com/account/signup/), or by running: + + $ sudo docker login + +This will prompt you for a user name, which will become the public namespace for your +public repositories. +If your user name is available, Docker will prompt you to enter a password and your +e-mail address. It will then automatically log you in. You can now commit and +push your own images up to your repos on Docker Hub. + +> **Note:** +> Your authentication credentials will be stored in the [`.dockercfg` +> authentication file](#authentication-file) in your home directory. ## Searching for images -As we've already seen we can search the -[Docker Hub](https://hub.docker.com) registry via it's search interface -or using the command line interface. Searching can find images by name, -user name or description: +You can search the [Docker Hub](https://hub.docker.com) registry via it's search +interface or by using the command line interface. Searching can find images by image +name, user name, or description: $ sudo docker search centos NAME DESCRIPTION STARS OFFICIAL TRUSTED @@ -41,12 +53,12 @@ user name or description: There you can see two example results: `centos` and `tianon/centos`. The second result shows that it comes from -the public repository of a user, `tianon/`, while the first result, -`centos`, doesn't explicitly list a repository so it comes from the +the public repository of a user, named `tianon/`, while the first result, +`centos`, doesn't explicitly list a repository which means that it comes from the trusted top-level namespace. The `/` character separates a user's -repository and the image name. +repository from the image name. -Once you have found the image you want, you can download it: +Once you've found the image you want, you can download it with `docker pull `: $ sudo docker pull centos Pulling repository centos @@ -55,84 +67,63 @@ Once you have found the image you want, you can download it: 511136ea3c5a: Download complete 7064731afe90: Download complete -The image is now available to run a container from. +You now have an image from which you can run containers. ## Contributing to Docker Hub Anyone can pull public images from the [Docker Hub](https://hub.docker.com) registry, but if you would like to share your own images, then you must -register a user first as we saw in the [first section of the Docker User +register first, as we saw in the [first section of the Docker User Guide](/userguide/dockerhub/). -To refresh your memory, you can create your user name and login to -[Docker Hub](https://hub.docker.com/account/signup/), or by running: - - $ sudo docker login - -This will prompt you for a user name, which will become a public -namespace for your public repositories, for example: - - training/webapp - -Here `training` is the user name and `webapp` is a repository owned by -that user. - -If your user name is available then `docker` will also prompt you to -enter a password and your e-mail address. It will then automatically log -you in. Now you're ready to commit and push your own images! - -> **Note:** -> Your authentication credentials will be stored in the [`.dockercfg` -> authentication file](#authentication-file) in your home directory. - ## Pushing a repository to Docker Hub -In order to push an repository to its registry you need to have named an image, +In order to push a repository to its registry, you need to have named an image or committed your container to a named image as we saw [here](/userguide/dockerimages). -Now you can push this repository to the registry designated by its name -or tag. +Now you can push this repository to the registry designated by its name or tag. $ sudo docker push yourname/newimage -The image will then be uploaded and available for use. +The image will then be uploaded and available for use by your team-mates and/or the +community. ## Features of Docker Hub -Now let's look at some of the features of Docker Hub. You can find more -information [here](/docker-io/). +Let's take a closer look at some of the features of Docker Hub. You can find more +information [here](http://docs.docker.com/docker-hub/). * Private repositories * Organizations and teams * Automated Builds * Webhooks -## Private Repositories +### Private Repositories Sometimes you have images you don't want to make public and share with everyone. So Docker Hub allows you to have private repositories. You can sign up for a plan [here](https://registry.hub.docker.com/plans/). -## Organizations and teams +### Organizations and teams One of the useful aspects of private repositories is that you can share them only with members of your organization or team. Docker Hub lets you create organizations where you can collaborate with your colleagues and -manage private repositories. You can create and manage an organization +manage private repositories. You can learn how to create and manage an organization [here](https://registry.hub.docker.com/account/organizations/). -## Automated Builds +### Automated Builds -Automated Builds automate the building and updating of images from [GitHub](https://www.github.com) -or [BitBucket](http://bitbucket.com), directly on Docker Hub. It works by adding a commit hook to -your selected GitHub or BitBucket repository, triggering a build and update when you push a -commit. +Automated Builds automate the building and updating of images from +[GitHub](https://www.github.com) or [BitBucket](http://bitbucket.com), directly on Docker +Hub. It works by adding a commit hook to your selected GitHub or BitBucket repository, +triggering a build and update when you push a commit. -### To setup an Automated Build +#### To setup an Automated Build 1. Create a [Docker Hub account](https://hub.docker.com/) and login. -2. Link your GitHub or BitBucket account through the [`Link Accounts`](https://registry.hub.docker.com/account/accounts/) menu. +2. Link your GitHub or BitBucket account through the ["Link Accounts"](https://registry.hub.docker.com/account/accounts/) menu. 3. [Configure an Automated Build](https://registry.hub.docker.com/builds/). 4. Pick a GitHub or BitBucket project that has a `Dockerfile` that you want to build. 5. Pick the branch you want to build (the default is the `master` branch). @@ -141,33 +132,32 @@ commit. 8. Specify where the `Dockerfile` is located. The default is `/`. Once the Automated Build is configured it will automatically trigger a -build, and in a few minutes, if there are no errors, you will see your -new Automated Build on the [Docker Hub](https://hub.docker.com) Registry. -It will stay in sync with your GitHub and BitBucket repository until you +build and, in a few minutes, you should see your new Automated Build on the [Docker Hub](https://hub.docker.com) +Registry. It will stay in sync with your GitHub and BitBucket repository until you deactivate the Automated Build. -If you want to see the status of your Automated Builds you can go to your +If you want to see the status of your Automated Builds, you can go to your [Automated Builds page](https://registry.hub.docker.com/builds/) on the Docker Hub, -and it will show you the status of your builds, and the build history. +and it will show you the status of your builds and their build history. Once you've created an Automated Build you can deactivate or delete it. You -cannot however push to an Automated Build with the `docker push` command. +cannot, however, push to an Automated Build with the `docker push` command. You can only manage it by committing code to your GitHub or BitBucket repository. You can create multiple Automated Builds per repository and configure them to point to specific `Dockerfile`'s or Git branches. -### Build Triggers +#### Build Triggers Automated Builds can also be triggered via a URL on Docker Hub. This allows you to rebuild an Automated build image on demand. -## Webhooks +### Webhooks Webhooks are attached to your repositories and allow you to trigger an event when an image or updated image is pushed to the repository. With -a webhook you can specify a target URL and a JSON payload will be +a webhook you can specify a target URL and a JSON payload that will be delivered when the image is pushed. ## Next steps -- cgit v1.2.1 From ab0fc77ebe73e0dededad1d47dc3788191cb966c Mon Sep 17 00:00:00 2001 From: Fred Lifton Date: Fri, 20 Jun 2014 17:52:30 -0700 Subject: Fixed a typo Docker-DCO-1.1-Signed-off-by: Fred Lifton (github: fredlf) --- docs/sources/userguide/dockerrepos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockerrepos.md b/docs/sources/userguide/dockerrepos.md index 2e5abbba15..a73c4b7834 100644 --- a/docs/sources/userguide/dockerrepos.md +++ b/docs/sources/userguide/dockerrepos.md @@ -41,7 +41,7 @@ push your own images up to your repos on Docker Hub. ## Searching for images -You can search the [Docker Hub](https://hub.docker.com) registry via it's search +You can search the [Docker Hub](https://hub.docker.com) registry via its search interface or by using the command line interface. Searching can find images by image name, user name, or description: -- cgit v1.2.1 From 00469957ad0e17adf60a486740f4132a503e7309 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Sat, 21 Jun 2014 17:32:39 +0900 Subject: Fatal() doesn't take a format string like Fatalf() Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi (github: kzys) --- runconfig/parse_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runconfig/parse_test.go b/runconfig/parse_test.go index 88fa0dd542..94cea493f0 100644 --- a/runconfig/parse_test.go +++ b/runconfig/parse_test.go @@ -25,26 +25,26 @@ func TestParseLxcConfOpt(t *testing.T) { func TestNetHostname(t *testing.T) { if _, _, _, err := Parse([]string{"-h=name", "img", "cmd"}, nil); err != nil { - t.Fatal("Unexpected error: %s", err) + t.Fatalf("Unexpected error: %s", err) } if _, _, _, err := Parse([]string{"--net=host", "img", "cmd"}, nil); err != nil { - t.Fatal("Unexpected error: %s", err) + t.Fatalf("Unexpected error: %s", err) } if _, _, _, err := Parse([]string{"-h=name", "--net=bridge", "img", "cmd"}, nil); err != nil { - t.Fatal("Unexpected error: %s", err) + t.Fatalf("Unexpected error: %s", err) } if _, _, _, err := Parse([]string{"-h=name", "--net=none", "img", "cmd"}, nil); err != nil { - t.Fatal("Unexpected error: %s", err) + t.Fatalf("Unexpected error: %s", err) } if _, _, _, err := Parse([]string{"-h=name", "--net=host", "img", "cmd"}, nil); err != ErrConflictNetworkHostname { - t.Fatal("Expected error ErrConflictNetworkHostname, got: %s", err) + t.Fatalf("Expected error ErrConflictNetworkHostname, got: %s", err) } if _, _, _, err := Parse([]string{"-h=name", "--net=container:other", "img", "cmd"}, nil); err != ErrConflictNetworkHostname { - t.Fatal("Expected error ErrConflictNetworkHostname, got: %s", err) + t.Fatalf("Expected error ErrConflictNetworkHostname, got: %s", err) } } -- cgit v1.2.1 From ba7245f07271d5ccba70ef659b3e88424cf36887 Mon Sep 17 00:00:00 2001 From: Robert Bachmann Date: Sat, 21 Jun 2014 23:12:10 +0200 Subject: Windows needs hardware virtualization VirtualBox needs hardware virtualization for 64-bit guests. Docker-DCO-1.1-Signed-off-by: Robert Bachmann (github: robertbachmann) --- docs/sources/installation/windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/installation/windows.md b/docs/sources/installation/windows.md index 7cc2b991d1..9908c053d0 100644 --- a/docs/sources/installation/windows.md +++ b/docs/sources/installation/windows.md @@ -5,7 +5,7 @@ page_keywords: Docker, Docker documentation, Windows, requirements, virtualbox, # Windows > **Note:** > Docker has been tested on Windows 7.1 and 8; it may also run on older versions. - +> Your processor needs to support hardware virtualization. The Docker Engine uses Linux-specific kernel features, so to run it on Windows we need to use a lightweight virtual machine (vm). You use the Windows Docker client to -- cgit v1.2.1 From 51d032737c812347c766bf7a3df43c18ec708b9e Mon Sep 17 00:00:00 2001 From: Sven Dowideit Date: Sun, 22 Jun 2014 15:59:47 -0700 Subject: one last missing redirect Docker-DCO-1.1-Signed-off-by: Sven Dowideit (github: SvenDowideit) --- docs/s3_website.json | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/s3_website.json b/docs/s3_website.json index 8a6f99beb7..224ba816e2 100644 --- a/docs/s3_website.json +++ b/docs/s3_website.json @@ -27,6 +27,7 @@ { "Condition": { "KeyPrefixEquals": "docker-io/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/" } }, { "Condition": { "KeyPrefixEquals": "examples/cfengine_process_management/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/cfengine_process_management/" } }, { "Condition": { "KeyPrefixEquals": "examples/https/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/https/" } }, + { "Condition": { "KeyPrefixEquals": "examples/ambassador_pattern_linking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/ambassador_pattern_linking/" } }, { "Condition": { "KeyPrefixEquals": "examples/using_supervisord/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/using_supervisord/" } }, { "Condition": { "KeyPrefixEquals": "reference/api/registry_index_spec/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "reference/api/hub_registry_spec/" } }, { "Condition": { "KeyPrefixEquals": "use/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "examples/" } } -- cgit v1.2.1 From 1e847bff7af8ae722318cc7d448f46be955496c3 Mon Sep 17 00:00:00 2001 From: Sven Dowideit Date: Sun, 22 Jun 2014 17:34:04 -0700 Subject: Remove mention of SSH passphrase, it was only present in v0.12 Docker-DCO-1.1-Signed-off-by: Sven Dowideit (github: SvenDowideit) --- docs/sources/installation/mac.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/sources/installation/mac.md b/docs/sources/installation/mac.md index 4677005ccd..b6253de12d 100644 --- a/docs/sources/installation/mac.md +++ b/docs/sources/installation/mac.md @@ -31,16 +31,12 @@ virtual machine and runs the Docker daemon. 3. Run the `Boot2Docker` app in the `Applications` folder: ![](/installation/images/osx-Boot2Docker-Start-app.png) - Or, to initiate Boot2Docker manually, open a terminal and run: + Or, to initialize Boot2Docker manually, open a terminal and run: $ boot2docker init $ boot2docker start $ export DOCKER_HOST=tcp://$(boot2docker ip 2>/dev/null):2375 - The `boot2docker init` command will ask you to enter an SSH key passphrase - the simplest - (but least secure) is to just hit [Enter]. This passphrase is used by the - `boot2docker ssh` command. - Once you have an initialized virtual machine, you can control it with `boot2docker stop` and `boot2docker start`. -- cgit v1.2.1 From 9559f57463f8cd4c1af726514ae744a646fdd462 Mon Sep 17 00:00:00 2001 From: Alexander Shopov Date: Tue, 17 Jun 2014 14:52:52 +0300 Subject: Update fedora.md Docker-DCO-1.1-Signed-off-by: Alexander Shopov (github: alshopov) Squashed by Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) replaces #6478 Docker-DCO-1.1-Signed-off-by: Alexander Shopov (github: ) --- docs/sources/installation/fedora.md | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/sources/installation/fedora.md b/docs/sources/installation/fedora.md index bcd54e6bd6..a230aa6cf5 100644 --- a/docs/sources/installation/fedora.md +++ b/docs/sources/installation/fedora.md @@ -48,6 +48,44 @@ Now let's verify that Docker is working. $ sudo docker run -i -t fedora /bin/bash +## Granting rights to users to use Docker + +Fedora 19 and 20 shipped with Docker 0.11. The package has already been updated +to 1.0 in Fedora 20. If you are still using the 0.11 version you will need to +grant rights to users of Docker. + +The `docker` command line tool contacts the `docker` daemon process via a +socket file `/var/run/docker.sock` owned by group `docker`. One must be +member of that group in order to contact the `docker -d` process. + + $ usermod -a -G docker login_name + +Adding users to the `docker` group is *not* necessary for Docker versions 1.0 +and above. + +## HTTP Proxy + +If you are behind a HTTP proxy server, for example in corporate settings, +you will need to add this configuration in the Docker *systemd service file*. + +Edit file `/lib/systemd/system/docker.service`. Add the following to +section `[Service]` : + + Environment="HTTP_PROXY=http://proxy.example.com:80/" + +If you have internal Docker registries that you need to contact without +proxying you can specify them via the `NO_PROXY` environment variable: + + Environment="HTTP_PROXY=http://proxy.example.com:80/" "NO_PROXY=localhost,127.0.0.0/8,docker-registry.somecorporation.com" + +Flush changes: + + $ systemctl daemon-reload + +Restart Docker: + + $ systemctl start docker + ## What next? Continue with the [User Guide](/userguide/). -- cgit v1.2.1 From 4d7e28a7d701c3c3ee331f2d6f4fce62fdd20d93 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Mon, 23 Jun 2014 14:50:11 +1000 Subject: Remove `$` leaders from examples of editing text in a file not everything that is indented is a commandline example Closes #6591 Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/sources/installation/ubuntulinux.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/sources/installation/ubuntulinux.md b/docs/sources/installation/ubuntulinux.md index f1ba4971eb..5d1b6c3fbf 100644 --- a/docs/sources/installation/ubuntulinux.md +++ b/docs/sources/installation/ubuntulinux.md @@ -244,18 +244,18 @@ To install the latest version of docker, use the standard If you want to enable memory and swap accounting, you must add the following command-line parameters to your kernel: - $ cgroup_enable=memory swapaccount=1 + cgroup_enable=memory swapaccount=1 On systems using GRUB (which is the default for Ubuntu), you can add those parameters by editing `/etc/default/grub` and extending `GRUB_CMDLINE_LINUX`. Look for the following line: - $ GRUB_CMDLINE_LINUX="" + GRUB_CMDLINE_LINUX="" And replace it by the following one: - $ GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1" + GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1" Then run `sudo update-grub`, and reboot. @@ -283,7 +283,7 @@ forwarding: # Change: # DEFAULT_FORWARD_POLICY="DROP" # to - $ DEFAULT_FORWARD_POLICY="ACCEPT" + DEFAULT_FORWARD_POLICY="ACCEPT" Then reload UFW: @@ -316,7 +316,7 @@ Docker daemon for the containers: $ sudo nano /etc/default/docker --- # Add: - $ DOCKER_OPTS="--dns 8.8.8.8" + DOCKER_OPTS="--dns 8.8.8.8" # 8.8.8.8 could be replaced with a local DNS server, such as 192.168.1.1 # multiple DNS servers can be specified: --dns 8.8.8.8 --dns 192.168.1.1 -- cgit v1.2.1 From 3ce5fde7ab86bb5307129b77fa09225ca07b1128 Mon Sep 17 00:00:00 2001 From: Ivan Fraixedes Date: Mon, 23 Jun 2014 16:08:34 +0100 Subject: Update dockervolumes.md Missed double hyphen in `--volumes-from` option --- docs/sources/userguide/dockervolumes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockervolumes.md b/docs/sources/userguide/dockervolumes.md index 0c2f6cfac6..7b3494920e 100644 --- a/docs/sources/userguide/dockervolumes.md +++ b/docs/sources/userguide/dockervolumes.md @@ -90,7 +90,7 @@ And another: $ docker run -d --volumes-from dbdata --name db2 training/postgres -You can use multiple `-volumes-from` parameters to bring together multiple data +You can use multiple `--volumes-from` parameters to bring together multiple data volumes from multiple containers. You can also extend the chain by mounting the volume that came from the -- cgit v1.2.1 From 8228d0e2bbd3a42755a84e11455b51a5caf61a94 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 23 Jun 2014 17:52:03 +0000 Subject: Remove old tag format Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/client/commands.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 0cdf3f1acb..08ca0495a2 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1829,21 +1829,15 @@ func (cli *DockerCli) CmdTag(args ...string) error { if err := cmd.Parse(args); err != nil { return nil } - if cmd.NArg() != 2 && cmd.NArg() != 3 { + if cmd.NArg() != 2 { cmd.Usage() return nil } - var repository, tag string - - if cmd.NArg() == 3 { - fmt.Fprintf(cli.err, "[DEPRECATED] The format 'IMAGE [REPOSITORY [TAG]]' as been deprecated. Please use IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG]]\n") - repository, tag = cmd.Arg(1), cmd.Arg(2) - } else { + var ( repository, tag = utils.ParseRepositoryTag(cmd.Arg(1)) - } - - v := url.Values{} + v = url.Values{} + ) //Check if the given image name can be resolved if _, _, err := registry.ResolveRepositoryName(repository); err != nil { -- cgit v1.2.1 From 386d1ecc6e2489401aac685eb11da15d21c4b0a7 Mon Sep 17 00:00:00 2001 From: LK4D4 Date: Mon, 23 Jun 2014 22:19:52 +0400 Subject: Move sorter_test from integration to integration-cli TestServerListOrderedImagesByCreationDateAndTag was redundant and broken Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- integration-cli/docker_cli_images_test.go | 42 +++++++++++++++++++++++ integration/sorter_test.go | 56 ------------------------------- 2 files changed, 42 insertions(+), 56 deletions(-) delete mode 100644 integration/sorter_test.go diff --git a/integration-cli/docker_cli_images_test.go b/integration-cli/docker_cli_images_test.go index b27bc870fe..2cf2bbfcf5 100644 --- a/integration-cli/docker_cli_images_test.go +++ b/integration-cli/docker_cli_images_test.go @@ -5,6 +5,7 @@ import ( "os/exec" "strings" "testing" + "time" ) func TestImagesEnsureImageIsListed(t *testing.T) { @@ -56,3 +57,44 @@ func TestCLIImageTagRemove(t *testing.T) { } logDone("tag,rmi- tagging the same images multiple times then removing tags") } + +func TestImagesOrderedByCreationDate(t *testing.T) { + defer deleteImages("order:test_a") + defer deleteImages("order:test_c") + defer deleteImages("order:test_b") + id1, err := buildImage("order:test_a", + `FROM scratch + MAINTAINER dockerio1`, true) + if err != nil { + t.Fatal(err) + } + time.Sleep(time.Second) + id2, err := buildImage("order:test_c", + `FROM scratch + MAINTAINER dockerio2`, true) + if err != nil { + t.Fatal(err) + } + time.Sleep(time.Second) + id3, err := buildImage("order:test_b", + `FROM scratch + MAINTAINER dockerio3`, true) + if err != nil { + t.Fatal(err) + } + + out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "images", "-q", "--no-trunc")) + errorOut(err, t, fmt.Sprintf("listing images failed with errors: %v", err)) + imgs := strings.Split(out, "\n") + if imgs[0] != id3 { + t.Fatalf("First image must be %s, got %s", id3, imgs[0]) + } + if imgs[1] != id2 { + t.Fatalf("Second image must be %s, got %s", id2, imgs[1]) + } + if imgs[2] != id1 { + t.Fatalf("Third image must be %s, got %s", id1, imgs[2]) + } + + logDone("images - ordering by creation date") +} diff --git a/integration/sorter_test.go b/integration/sorter_test.go deleted file mode 100644 index 610fe9b3ab..0000000000 --- a/integration/sorter_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package docker - -import ( - "github.com/dotcloud/docker/engine" - "testing" - "time" -) - -func TestServerListOrderedImagesByCreationDate(t *testing.T) { - eng := NewTestEngine(t) - defer mkDaemonFromEngine(eng, t).Nuke() - - if err := generateImage("", eng); err != nil { - t.Fatal(err) - } - - images := getImages(eng, t, true, "") - - if images.Data[0].GetInt("Created") < images.Data[1].GetInt("Created") { - t.Error("Expected images to be ordered by most recent creation date.") - } -} - -func TestServerListOrderedImagesByCreationDateAndTag(t *testing.T) { - eng := NewTestEngine(t) - defer mkDaemonFromEngine(eng, t).Nuke() - - err := generateImage("bar", eng) - if err != nil { - t.Fatal(err) - } - - time.Sleep(time.Second) - - err = generateImage("zed", eng) - if err != nil { - t.Fatal(err) - } - - images := getImages(eng, t, true, "") - - if repoTags := images.Data[0].GetList("RepoTags"); repoTags[0] != "repo:zed" && repoTags[0] != "repo:bar" { - t.Errorf("Expected Images to be ordered by most recent creation date.") - } -} - -func generateImage(name string, eng *engine.Engine) error { - archive, err := fakeTar() - if err != nil { - return err - } - job := eng.Job("import", "-", "repo", name) - job.Stdin.Add(archive) - job.SetenvBool("json", true) - return job.Run() -} -- cgit v1.2.1 From edf16383c60c8c05549a97a0fb909c2387f69bce Mon Sep 17 00:00:00 2001 From: "Roberto G. Hashioka" Date: Mon, 23 Jun 2014 18:35:15 +0000 Subject: Fix header and about Docker links --- docs/sources/index.md | 2 +- docs/theme/mkdocs/header.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sources/index.md b/docs/sources/index.md index 06e1ac6d57..ef5fe2c2c0 100644 --- a/docs/sources/index.md +++ b/docs/sources/index.md @@ -6,7 +6,7 @@ page_keywords: docker, introduction, documentation, about, technology, understan **Develop, Ship and Run Any Application, Anywhere** -[**Docker**](https://www.docker.io) is a platform for developers and sysadmins +[**Docker**](https://www.docker.com) is a platform for developers and sysadmins to develop, ship, and run applications. Docker lets you quickly assemble applications from components and eliminates the friction that can come when shipping code. Docker lets you get your code tested and deployed into production diff --git a/docs/theme/mkdocs/header.html b/docs/theme/mkdocs/header.html index 785797f0dc..351c1583ed 100644 --- a/docs/theme/mkdocs/header.html +++ b/docs/theme/mkdocs/header.html @@ -25,8 +25,8 @@
- {% include "version.html" %} + {% include "beta_warning.html" %} {{ content }}
-- cgit v1.2.1 From 3fcb0d880aad65690cac304c30f72d0688a801d2 Mon Sep 17 00:00:00 2001 From: Trent Ogren Date: Mon, 9 Jun 2014 13:33:55 -0500 Subject: Add missing parenthesis in docs for -author switch Docker-DCO-1.1-Signed-off-by: Trent Ogren (github: misfo) Docker-DCO-1.1-Signed-off-by: Trent Ogren (github: SvenDowideit) --- api/client/commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client/commands.go b/api/client/commands.go index 46a465f69a..83bf09a7ee 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1520,7 +1520,7 @@ func (cli *DockerCli) CmdPs(args ...string) error { func (cli *DockerCli) CmdCommit(args ...string) error { cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes") flComment := cmd.String([]string{"m", "-message"}, "", "Commit message") - flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith \"") + flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith \")") // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. flConfig := cmd.String([]string{"#run", "#-run"}, "", "this option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") if err := cmd.Parse(args); err != nil { -- cgit v1.2.1 From 389916bf9ae62ded0e497512da22faba75d0cf2d Mon Sep 17 00:00:00 2001 From: Sven Dowideit Date: Wed, 25 Jun 2014 16:50:35 -0700 Subject: Add the missing paren to the documentation for docker commit too Docker-DCO-1.1-Signed-off-by: Sven Dowideit (github: SvenDowideit) --- docs/sources/reference/commandline/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 47dd0a992d..1b67b216f4 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -306,7 +306,7 @@ schema. Create a new image from a container's changes - -a, --author="" Author (eg. "John Hannibal Smith " + -a, --author="" Author (eg. "John Hannibal Smith ") -m, --message="" Commit message It can be useful to commit a container's file changes or settings into a -- cgit v1.2.1 From c42b5575e5dff5b3a117462e32eda0095528e3b2 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Wed, 25 Jun 2014 19:07:39 -0600 Subject: Update contrib/mkimage/debootstrap to remove /var/lib/apt/lists (trimming at least 40MB and forcing "apt-get update" in dependent images before packages can be installed) Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- contrib/mkimage/debootstrap | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/contrib/mkimage/debootstrap b/contrib/mkimage/debootstrap index d5aeae2b99..96d22ddddc 100755 --- a/contrib/mkimage/debootstrap +++ b/contrib/mkimage/debootstrap @@ -164,9 +164,13 @@ if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then esac fi -# make sure we're fully up-to-date, too ( set -x - chroot "$rootfsDir" apt-get update - chroot "$rootfsDir" apt-get dist-upgrade -y + + # make sure we're fully up-to-date + chroot "$rootfsDir" bash -c 'apt-get update && apt-get dist-upgrade -y' + + # delete all the apt list files since they're big and get stale quickly + rm -rf "$rootfsDir/var/lib/apt/lists"/* + # this forces "apt-get update" in dependent images, which is also good ) -- cgit v1.2.1 From 5e256799ddd6a297e22756363fc5eb079af0f07e Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Wed, 25 Jun 2014 22:12:25 -0600 Subject: Add bash completion for "docker rm -f" and complete on all containers instead of just stopped containers when "-f" is specified Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- contrib/completion/bash/docker | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index f75b85ca8c..89395560f9 100755 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -458,10 +458,21 @@ _docker_rm() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "-v --volumes -l --link" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "-f --force -l --link -v --volumes" -- "$cur" ) ) + return ;; *) + local force= + for arg in "${COMP_WORDS[@]}"; do + case "$arg" in + -f|--force) + __docker_containers_all + return + ;; + esac + done __docker_containers_stopped + return ;; esac } -- cgit v1.2.1 From 6bb6e422b5cd9e9ee97c5855a94b5776323a5626 Mon Sep 17 00:00:00 2001 From: leeplay Date: Thu, 26 Jun 2014 15:14:18 +0900 Subject: Update examples/nodejs_web_app Docker-DCO-1.1-Signed-off-by: Hyeongkyu Lee (github: leeplay) --- docs/sources/examples/nodejs_web_app.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sources/examples/nodejs_web_app.md b/docs/sources/examples/nodejs_web_app.md index cf00e88bed..cc3ea061af 100644 --- a/docs/sources/examples/nodejs_web_app.md +++ b/docs/sources/examples/nodejs_web_app.md @@ -137,9 +137,9 @@ Your image will now be listed by Docker: $ sudo docker images # Example - REPOSITORY TAG ID CREATED - centos 6.4 539c0211cd76 8 weeks ago - gasi/centos-node-hello latest d64d3505b0d2 2 hours ago + REPOSITORY TAG ID CREATED + centos 6.4 539c0211cd76 8 weeks ago + /centos-node-hello latest d64d3505b0d2 2 hours ago ## Run the image -- cgit v1.2.1 From 714c1bd8ca49c6fc5e7939d6a7abf6a54d56b06a Mon Sep 17 00:00:00 2001 From: "O.S. Tezer" Date: Sun, 22 Jun 2014 22:15:26 -0700 Subject: Anglicanisms: Grammatical correction (pos. adj. apost.) Docker-DCO-1.1-Signed-off-by: O.S. Tezer (github: ostezer) --- api/client/commands.go | 2 +- contrib/completion/fish/docker.fish | 2 +- docs/man/docker-cp.1.md | 2 +- docs/man/docker.1.md | 2 +- docs/sources/reference/commandline/cli.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 46a465f69a..2c03a6d020 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -55,7 +55,7 @@ func (cli *DockerCli) CmdHelp(args ...string) error { {"attach", "Attach to a running container"}, {"build", "Build an image from a Dockerfile"}, {"commit", "Create a new image from a container's changes"}, - {"cp", "Copy files/folders from the containers filesystem to the host path"}, + {"cp", "Copy files/folders from a container's filesystem to the host path"}, {"diff", "Inspect changes on a container's filesystem"}, {"events", "Get real time events from the server"}, {"export", "Stream the contents of a container as a tar archive"}, diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index 00255bc0ae..a1eac31df7 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -85,7 +85,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -l run -d 'Conf complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -a '(__fish_print_docker_containers all)' -d "Container" # cp -complete -c docker -f -n '__fish_docker_no_subcommand' -a cp -d 'Copy files/folders from the containers filesystem to the host path' +complete -c docker -f -n '__fish_docker_no_subcommand' -a cp -d 'Copy files/folders from a container's filesystem to the host path' # diff complete -c docker -f -n '__fish_docker_no_subcommand' -a diff -d "Inspect changes on a container's filesystem" diff --git a/docs/man/docker-cp.1.md b/docs/man/docker-cp.1.md index f787198669..1801e7318d 100644 --- a/docs/man/docker-cp.1.md +++ b/docs/man/docker-cp.1.md @@ -8,7 +8,7 @@ docker-cp - Copy files/folders from the PATH to the HOSTPATH **docker cp** CONTAINER:PATH HOSTPATH # DESCRIPTION -Copy files/folders from the containers filesystem to the host +Copy files/folders from a container's filesystem to the host path. Paths are relative to the root of the filesystem. Files can be copied from a running or stopped container. diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index ab5b67d11f..ae5efff87e 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -87,7 +87,7 @@ unix://[/path/to/socket] to use. Create a new image from a container's changes **docker-cp(1)** - Copy files/folders from the containers filesystem to the host at path + Copy files/folders from a container's filesystem to the host at path **docker-diff(1)** Inspect changes on a container's filesystem diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 47dd0a992d..77f868e975 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -329,7 +329,7 @@ maintainable way. ## cp -Copy files/folders from the containers filesystem to the host +Copy files/folders from a container's filesystem to the host path. Paths are relative to the root of the filesystem. Usage: docker cp CONTAINER:PATH HOSTPATH -- cgit v1.2.1 From e0dad305791a7406cf819a27fa5a079a46a62acc Mon Sep 17 00:00:00 2001 From: unclejack Date: Wed, 25 Jun 2014 01:24:02 +0300 Subject: refactor TruncIndex to use a trie & vendor deps Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- daemon/daemon.go | 8 +- hack/vendor.sh | 2 + pkg/truncindex/truncindex.go | 96 ++- pkg/truncindex/truncindex_test.go | 15 +- vendor/src/github.com/tchap/go-patricia/.gitignore | 25 + .../src/github.com/tchap/go-patricia/.travis.yml | 9 + vendor/src/github.com/tchap/go-patricia/AUTHORS | 3 + vendor/src/github.com/tchap/go-patricia/LICENSE | 20 + vendor/src/github.com/tchap/go-patricia/README.md | 112 ++++ .../tchap/go-patricia/patricia/children.go | 231 ++++++++ .../tchap/go-patricia/patricia/patricia.go | 432 ++++++++++++++ .../go-patricia/patricia/patricia_dense_test.go | 161 +++++ .../go-patricia/patricia/patricia_sparse_test.go | 659 +++++++++++++++++++++ .../tchap/go-patricia/patricia/patricia_test.go | 78 +++ 14 files changed, 1794 insertions(+), 57 deletions(-) create mode 100644 vendor/src/github.com/tchap/go-patricia/.gitignore create mode 100644 vendor/src/github.com/tchap/go-patricia/.travis.yml create mode 100644 vendor/src/github.com/tchap/go-patricia/AUTHORS create mode 100644 vendor/src/github.com/tchap/go-patricia/LICENSE create mode 100644 vendor/src/github.com/tchap/go-patricia/README.md create mode 100644 vendor/src/github.com/tchap/go-patricia/patricia/children.go create mode 100644 vendor/src/github.com/tchap/go-patricia/patricia/patricia.go create mode 100644 vendor/src/github.com/tchap/go-patricia/patricia/patricia_dense_test.go create mode 100644 vendor/src/github.com/tchap/go-patricia/patricia/patricia_sparse_test.go create mode 100644 vendor/src/github.com/tchap/go-patricia/patricia/patricia_test.go diff --git a/daemon/daemon.go b/daemon/daemon.go index e4078fdfeb..3536678d22 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -182,11 +182,7 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool, con // don't update the Suffixarray if we're starting up // we'll waste time if we update it for every container - if updateSuffixarray { - daemon.idIndex.Add(container.ID) - } else { - daemon.idIndex.AddWithoutSuffixarrayUpdate(container.ID) - } + daemon.idIndex.Add(container.ID) // FIXME: if the container is supposed to be running but is not, auto restart it? // if so, then we need to restart monitor and init a new lock @@ -377,8 +373,6 @@ func (daemon *Daemon) restore() error { } } - daemon.idIndex.UpdateSuffixarray() - for _, container := range containersToStart { utils.Debugf("Starting container %d", container.ID) if err := container.Start(); err != nil { diff --git a/hack/vendor.sh b/hack/vendor.sh index c4494ffa72..630998e206 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -47,6 +47,8 @@ clone git github.com/gorilla/mux 136d54f81f clone git github.com/syndtr/gocapability 3c85049eae +clone git github.com/tchap/go-patricia v1.0.0 + clone hg code.google.com/p/go.net 84a4013f96e0 clone hg code.google.com/p/gosqlite 74691fb6f837 diff --git a/pkg/truncindex/truncindex.go b/pkg/truncindex/truncindex.go index 78512047a4..811f606661 100644 --- a/pkg/truncindex/truncindex.go +++ b/pkg/truncindex/truncindex.go @@ -1,31 +1,34 @@ package truncindex import ( + "errors" "fmt" - "index/suffixarray" "strings" "sync" + + "github.com/tchap/go-patricia/patricia" +) + +var ( + ErrNoID = errors.New("prefix can't be empty") ) // TruncIndex allows the retrieval of string identifiers by any of their unique prefixes. // This is used to retrieve image and container IDs by more convenient shorthand prefixes. type TruncIndex struct { sync.RWMutex - index *suffixarray.Index - ids map[string]bool - bytes []byte + trie *patricia.Trie + ids map[string]struct{} } func NewTruncIndex(ids []string) (idx *TruncIndex) { idx = &TruncIndex{ - ids: make(map[string]bool), - bytes: []byte{' '}, + ids: make(map[string]struct{}), + trie: patricia.NewTrie(), } for _, id := range ids { - idx.ids[id] = true - idx.bytes = append(idx.bytes, []byte(id+" ")...) + idx.addId(id) } - idx.index = suffixarray.New(idx.bytes) return } @@ -33,11 +36,16 @@ func (idx *TruncIndex) addId(id string) error { if strings.Contains(id, " ") { return fmt.Errorf("Illegal character: ' '") } + if id == "" { + return ErrNoID + } if _, exists := idx.ids[id]; exists { - return fmt.Errorf("Id already exists: %s", id) + return fmt.Errorf("Id already exists: '%s'", id) + } + idx.ids[id] = struct{}{} + if inserted := idx.trie.Insert(patricia.Prefix(id), struct{}{}); !inserted { + return fmt.Errorf("Failed to insert id: %s", id) } - idx.ids[id] = true - idx.bytes = append(idx.bytes, []byte(id+" ")...) return nil } @@ -47,56 +55,46 @@ func (idx *TruncIndex) Add(id string) error { if err := idx.addId(id); err != nil { return err } - idx.index = suffixarray.New(idx.bytes) return nil } -func (idx *TruncIndex) AddWithoutSuffixarrayUpdate(id string) error { - idx.Lock() - defer idx.Unlock() - return idx.addId(id) -} - -func (idx *TruncIndex) UpdateSuffixarray() { - idx.Lock() - defer idx.Unlock() - idx.index = suffixarray.New(idx.bytes) -} - func (idx *TruncIndex) Delete(id string) error { idx.Lock() defer idx.Unlock() - if _, exists := idx.ids[id]; !exists { - return fmt.Errorf("No such id: %s", id) - } - before, after, err := idx.lookup(id) - if err != nil { - return err + if _, exists := idx.ids[id]; !exists || id == "" { + return fmt.Errorf("No such id: '%s'", id) } delete(idx.ids, id) - idx.bytes = append(idx.bytes[:before], idx.bytes[after:]...) - idx.index = suffixarray.New(idx.bytes) - return nil -} - -func (idx *TruncIndex) lookup(s string) (int, int, error) { - offsets := idx.index.Lookup([]byte(" "+s), -1) - //log.Printf("lookup(%s): %v (index bytes: '%s')\n", s, offsets, idx.index.Bytes()) - if offsets == nil || len(offsets) == 0 || len(offsets) > 1 { - return -1, -1, fmt.Errorf("No such id: %s", s) + if deleted := idx.trie.Delete(patricia.Prefix(id)); !deleted { + return fmt.Errorf("No such id: '%s'", id) } - offsetBefore := offsets[0] + 1 - offsetAfter := offsetBefore + strings.Index(string(idx.bytes[offsetBefore:]), " ") - return offsetBefore, offsetAfter, nil + return nil } func (idx *TruncIndex) Get(s string) (string, error) { idx.RLock() defer idx.RUnlock() - before, after, err := idx.lookup(s) - //log.Printf("Get(%s) bytes=|%s| before=|%d| after=|%d|\n", s, idx.bytes, before, after) - if err != nil { - return "", err + var ( + id string + ) + if s == "" { + return "", ErrNoID + } + subTreeVisitFunc := func(prefix patricia.Prefix, item patricia.Item) error { + if id != "" { + // we haven't found the ID if there are two or more IDs + id = "" + return fmt.Errorf("we've found two entries") + } + id = string(prefix) + return nil + } + + if err := idx.trie.VisitSubtree(patricia.Prefix(s), subTreeVisitFunc); err != nil { + return "", fmt.Errorf("No such id: %s", s) + } + if id != "" { + return id, nil } - return string(idx.bytes[before:after]), err + return "", fmt.Errorf("No such id: %s", s) } diff --git a/pkg/truncindex/truncindex_test.go b/pkg/truncindex/truncindex_test.go index 5e2a386d74..f88d667d5a 100644 --- a/pkg/truncindex/truncindex_test.go +++ b/pkg/truncindex/truncindex_test.go @@ -26,8 +26,16 @@ func TestTruncIndex(t *testing.T) { if err := index.Add(id); err != nil { t.Fatal(err) } + + // Add an empty id (should fail) + if err := index.Add(""); err == nil { + t.Fatalf("Adding an empty id should return an error") + } + // Get a non-existing id assertIndexGet(t, index, "abracadabra", "", true) + // Get an empty id + assertIndexGet(t, index, "", "", true) // Get the exact id assertIndexGet(t, index, id, id, false) // The first letter should match @@ -60,6 +68,11 @@ func TestTruncIndex(t *testing.T) { t.Fatalf("Deleting a non-existing id should return an error") } + // Deleting an empty id should return an error + if err := index.Delete(""); err == nil { + t.Fatal("Deleting an empty id should return an error") + } + // Deleting id2 should remove conflicts if err := index.Delete(id2); err != nil { t.Fatal(err) @@ -84,7 +97,7 @@ func assertIndexGet(t *testing.T, index *TruncIndex, input, expectedResult strin if result, err := index.Get(input); err != nil && !expectError { t.Fatalf("Unexpected error getting '%s': %s", input, err) } else if err == nil && expectError { - t.Fatalf("Getting '%s' should return an error", input) + t.Fatalf("Getting '%s' should return an error, not '%s'", input, result) } else if result != expectedResult { t.Fatalf("Getting '%s' returned '%s' instead of '%s'", input, result, expectedResult) } diff --git a/vendor/src/github.com/tchap/go-patricia/.gitignore b/vendor/src/github.com/tchap/go-patricia/.gitignore new file mode 100644 index 0000000000..b3971c067a --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/.gitignore @@ -0,0 +1,25 @@ +# Swap files. +*.swp + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/src/github.com/tchap/go-patricia/.travis.yml b/vendor/src/github.com/tchap/go-patricia/.travis.yml new file mode 100644 index 0000000000..66183e2ad4 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.2 + - tip + +branches: + exclude: + - wip diff --git a/vendor/src/github.com/tchap/go-patricia/AUTHORS b/vendor/src/github.com/tchap/go-patricia/AUTHORS new file mode 100644 index 0000000000..e640b0bf51 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/AUTHORS @@ -0,0 +1,3 @@ +This is the complete list of go-patricia copyright holders: + +Ondřej Kupka diff --git a/vendor/src/github.com/tchap/go-patricia/LICENSE b/vendor/src/github.com/tchap/go-patricia/LICENSE new file mode 100644 index 0000000000..e50d398e98 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 The AUTHORS + +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/vendor/src/github.com/tchap/go-patricia/README.md b/vendor/src/github.com/tchap/go-patricia/README.md new file mode 100644 index 0000000000..635e2b8ea7 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/README.md @@ -0,0 +1,112 @@ +# go-patricia # + +**Documentation**: [GoDoc](http://godoc.org/github.com/tchap/go-patricia/patricia)
+**Build Status**: [![Build Status](https://travis-ci.org/tchap/go-patricia.png?branch=master)](https://travis-ci.org/tchap/go-patricia)
+**Test Coverage**: Comming as soon as Drone.io people update their Go. + +## About ## + +A generic patricia trie (also called radix tree) implemented in Go (Golang). + +The patricia trie as implemented in this library enables fast visiting of items +in some particular ways: + +1. visit all items saved in the tree, +2. visit all items matching particular prefix (visit subtree), or +3. given a string, visit all items matching some prefix of that string. + +`[]byte` type is used for keys, `interface{}` for values. + +`Trie` is not thread safe. Synchronize the access yourself. + +### State of the Project ### + +Apparently some people are using this, so the API should not change often. +Any ideas on how to make the library better are still welcome. + +More (unit) testing would be cool as well... + +## Usage ## + +Import the package from GitHub first. + +```go +import "github.com/tchap/go-patricia/patricia" +``` + +Then you can start having fun. + +```go +printItem := func(prefix patricia.Prefix, item patricia.Item) error { + fmt.Printf("%q: %v\n", prefix, item) + return nil +} + +// Create a new tree. +trie := NewTrie() + +// Insert some items. +trie.Insert(Prefix("Pepa Novak"), 1) +trie.Insert(Prefix("Pepa Sindelar"), 2) +trie.Insert(Prefix("Karel Macha"), 3) +trie.Insert(Prefix("Karel Hynek Macha"), 4) + +// Just check if some things are present in the tree. +key := Prefix("Pepa Novak") +fmt.Printf("%q present? %v\n", key, trie.Match(key)) +// "Pepa Novak" present? true +key = Prefix("Karel") +fmt.Printf("Anybody called %q here? %v\n", key, trie.MatchSubtree(key)) +// Anybody called "Karel" here? true + +// Walk the tree. +trie.Visit(printItem) +// "Pepa Novak": 1 +// "Pepa Sindelar": 2 +// "Karel Macha": 3 +// "Karel Hynek Macha": 4 + +// Walk a subtree. +trie.VisitSubtree(Prefix("Pepa"), printItem) +// "Pepa Novak": 1 +// "Pepa Sindelar": 2 + +// Modify an item, then fetch it from the tree. +trie.Set(Prefix("Karel Hynek Macha"), 10) +key = Prefix("Karel Hynek Macha") +fmt.Printf("%q: %v\n", key, trie.Get(key)) +// "Karel Hynek Macha": 10 + +// Walk prefixes. +prefix := Prefix("Karel Hynek Macha je kouzelnik") +trie.VisitPrefixes(prefix, printItem) +// "Karel Hynek Macha": 10 + +// Delete some items. +trie.Delete(Prefix("Pepa Novak")) +trie.Delete(Prefix("Karel Macha")) + +// Walk again. +trie.Visit(printItem) +// "Pepa Sindelar": 2 +// "Karel Hynek Macha": 10 + +// Delete a subtree. +trie.DeleteSubtree(Prefix("Pepa")) + +// Print what is left. +trie.Visit(printItem) +// "Karel Hynek Macha": 10 +``` + +## License ## + +MIT, check the `LICENSE` file. + +[![Gittip +Badge](http://img.shields.io/gittip/alanhamlett.png)](https://www.gittip.com/tchap/ +"Gittip Badge") + +[![Bitdeli +Badge](https://d2weczhvl823v0.cloudfront.net/tchap/go-patricia/trend.png)](https://bitdeli.com/free +"Bitdeli Badge") diff --git a/vendor/src/github.com/tchap/go-patricia/patricia/children.go b/vendor/src/github.com/tchap/go-patricia/patricia/children.go new file mode 100644 index 0000000000..42b0547de6 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/patricia/children.go @@ -0,0 +1,231 @@ +// Copyright (c) 2014 The go-patricia AUTHORS +// +// Use of this source code is governed by The MIT License +// that can be found in the LICENSE file. + +package patricia + +const ( + // Max prefix length that is kept in a single trie node. + MaxPrefixPerNode = 10 + // Max children to keep in a node in the sparse mode. + MaxChildrenPerSparseNode = 8 +) + +type childList interface { + length() int + head() *Trie + add(child *Trie) childList + replace(b byte, child *Trie) + remove(child *Trie) + next(b byte) *Trie + walk(prefix *Prefix, visitor VisitorFunc) error +} + +type sparseChildList struct { + children []*Trie +} + +func newSparseChildList() childList { + return &sparseChildList{ + children: make([]*Trie, 0, MaxChildrenPerSparseNode), + } +} + +func (list *sparseChildList) length() int { + return len(list.children) +} + +func (list *sparseChildList) head() *Trie { + return list.children[0] +} + +func (list *sparseChildList) add(child *Trie) childList { + // Search for an empty spot and insert the child if possible. + if len(list.children) != cap(list.children) { + list.children = append(list.children, child) + return list + } + + // Otherwise we have to transform to the dense list type. + return newDenseChildList(list, child) +} + +func (list *sparseChildList) replace(b byte, child *Trie) { + // Seek the child and replace it. + for i, node := range list.children { + if node.prefix[0] == b { + list.children[i] = child + return + } + } +} + +func (list *sparseChildList) remove(child *Trie) { + for i, node := range list.children { + if node.prefix[0] == child.prefix[0] { + list.children = append(list.children[:i], list.children[i+1:]...) + return + } + } + + // This is not supposed to be reached. + panic("removing non-existent child") +} + +func (list *sparseChildList) next(b byte) *Trie { + for _, child := range list.children { + if child.prefix[0] == b { + return child + } + } + return nil +} + +func (list *sparseChildList) walk(prefix *Prefix, visitor VisitorFunc) error { + for _, child := range list.children { + *prefix = append(*prefix, child.prefix...) + if child.item != nil { + err := visitor(*prefix, child.item) + if err != nil { + if err == SkipSubtree { + *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] + continue + } + *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] + return err + } + } + + err := child.children.walk(prefix, visitor) + *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] + if err != nil { + return err + } + } + + return nil +} + +type denseChildList struct { + min int + max int + children []*Trie +} + +func newDenseChildList(list *sparseChildList, child *Trie) childList { + var ( + min int = 255 + max int = 0 + ) + for _, child := range list.children { + b := int(child.prefix[0]) + if b < min { + min = b + } + if b > max { + max = b + } + } + + b := int(child.prefix[0]) + if b < min { + min = b + } + if b > max { + max = b + } + + children := make([]*Trie, max-min+1) + for _, child := range list.children { + children[int(child.prefix[0])-min] = child + } + children[int(child.prefix[0])-min] = child + + return &denseChildList{min, max, children} +} + +func (list *denseChildList) length() int { + return list.max - list.min + 1 +} + +func (list *denseChildList) head() *Trie { + return list.children[0] +} + +func (list *denseChildList) add(child *Trie) childList { + b := int(child.prefix[0]) + + switch { + case list.min <= b && b <= list.max: + if list.children[b-list.min] != nil { + panic("dense child list collision detected") + } + list.children[b-list.min] = child + + case b < list.min: + children := make([]*Trie, list.max-b+1) + children[0] = child + copy(children[list.min-b:], list.children) + list.children = children + list.min = b + + default: // b > list.max + children := make([]*Trie, b-list.min+1) + children[b-list.min] = child + copy(children, list.children) + list.children = children + list.max = b + } + + return list +} + +func (list *denseChildList) replace(b byte, child *Trie) { + list.children[int(b)-list.min] = nil + list.children[int(child.prefix[0])-list.min] = child +} + +func (list *denseChildList) remove(child *Trie) { + i := int(child.prefix[0]) - list.min + if list.children[i] == nil { + // This is not supposed to be reached. + panic("removing non-existent child") + } + list.children[i] = nil +} + +func (list *denseChildList) next(b byte) *Trie { + i := int(b) + if i < list.min || list.max < i { + return nil + } + return list.children[i-list.min] +} + +func (list *denseChildList) walk(prefix *Prefix, visitor VisitorFunc) error { + for _, child := range list.children { + if child == nil { + continue + } + *prefix = append(*prefix, child.prefix...) + if child.item != nil { + if err := visitor(*prefix, child.item); err != nil { + if err == SkipSubtree { + *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] + continue + } + *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] + return err + } + } + + err := child.children.walk(prefix, visitor) + *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/src/github.com/tchap/go-patricia/patricia/patricia.go b/vendor/src/github.com/tchap/go-patricia/patricia/patricia.go new file mode 100644 index 0000000000..8fcbcdf426 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/patricia/patricia.go @@ -0,0 +1,432 @@ +// Copyright (c) 2014 The go-patricia AUTHORS +// +// Use of this source code is governed by The MIT License +// that can be found in the LICENSE file. + +package patricia + +import ( + "errors" +) + +//------------------------------------------------------------------------------ +// Trie +//------------------------------------------------------------------------------ + +type ( + Prefix []byte + Item interface{} + VisitorFunc func(prefix Prefix, item Item) error +) + +// Trie is a generic patricia trie that allows fast retrieval of items by prefix. +// and other funky stuff. +// +// Trie is not thread-safe. +type Trie struct { + prefix Prefix + item Item + + children childList +} + +// Public API ------------------------------------------------------------------ + +// Trie constructor. +func NewTrie() *Trie { + return &Trie{ + children: newSparseChildList(), + } +} + +// Item returns the item stored in the root of this trie. +func (trie *Trie) Item() Item { + return trie.item +} + +// Insert inserts a new item into the trie using the given prefix. Insert does +// not replace existing items. It returns false if an item was already in place. +func (trie *Trie) Insert(key Prefix, item Item) (inserted bool) { + return trie.put(key, item, false) +} + +// Set works much like Insert, but it always sets the item, possibly replacing +// the item previously inserted. +func (trie *Trie) Set(key Prefix, item Item) { + trie.put(key, item, true) +} + +// Get returns the item located at key. +// +// This method is a bit dangerous, because Get can as well end up in an internal +// node that is not really representing any user-defined value. So when nil is +// a valid value being used, it is not possible to tell if the value was inserted +// into the tree by the user or not. A possible workaround for this is not to use +// nil interface as a valid value, even using zero value of any type is enough +// to prevent this bad behaviour. +func (trie *Trie) Get(key Prefix) (item Item) { + _, node, found, leftover := trie.findSubtree(key) + if !found || len(leftover) != 0 { + return nil + } + return node.item +} + +// Match returns what Get(prefix) != nil would return. The same warning as for +// Get applies here as well. +func (trie *Trie) Match(prefix Prefix) (matchedExactly bool) { + return trie.Get(prefix) != nil +} + +// MatchSubtree returns true when there is a subtree representing extensions +// to key, that is if there are any keys in the tree which have key as prefix. +func (trie *Trie) MatchSubtree(key Prefix) (matched bool) { + _, _, matched, _ = trie.findSubtree(key) + return +} + +// Visit calls visitor on every node containing a non-nil item. +// +// If an error is returned from visitor, the function stops visiting the tree +// and returns that error, unless it is a special error - SkipSubtree. In that +// case Visit skips the subtree represented by the current node and continues +// elsewhere. +func (trie *Trie) Visit(visitor VisitorFunc) error { + return trie.walk(nil, visitor) +} + +// VisitSubtree works much like Visit, but it only visits nodes matching prefix. +func (trie *Trie) VisitSubtree(prefix Prefix, visitor VisitorFunc) error { + // Nil prefix not allowed. + if prefix == nil { + panic(ErrNilPrefix) + } + + // Empty trie must be handled explicitly. + if trie.prefix == nil { + return nil + } + + // Locate the relevant subtree. + _, root, found, leftover := trie.findSubtree(prefix) + if !found { + return nil + } + prefix = append(prefix, leftover...) + + // Visit it. + return root.walk(prefix, visitor) +} + +// VisitPrefixes visits only nodes that represent prefixes of key. +// To say the obvious, returning SkipSubtree from visitor makes no sense here. +func (trie *Trie) VisitPrefixes(key Prefix, visitor VisitorFunc) error { + // Nil key not allowed. + if key == nil { + panic(ErrNilPrefix) + } + + // Empty trie must be handled explicitly. + if trie.prefix == nil { + return nil + } + + // Walk the path matching key prefixes. + node := trie + prefix := key + offset := 0 + for { + // Compute what part of prefix matches. + common := node.longestCommonPrefixLength(key) + key = key[common:] + offset += common + + // Partial match means that there is no subtree matching prefix. + if common < len(node.prefix) { + return nil + } + + // Call the visitor. + if item := node.item; item != nil { + if err := visitor(prefix[:offset], item); err != nil { + return err + } + } + + if len(key) == 0 { + // This node represents key, we are finished. + return nil + } + + // There is some key suffix left, move to the children. + child := node.children.next(key[0]) + if child == nil { + // There is nowhere to continue, return. + return nil + } + + node = child + } +} + +// Delete deletes the item represented by the given prefix. +// +// True is returned if the matching node was found and deleted. +func (trie *Trie) Delete(key Prefix) (deleted bool) { + // Nil prefix not allowed. + if key == nil { + panic(ErrNilPrefix) + } + + // Empty trie must be handled explicitly. + if trie.prefix == nil { + return false + } + + // Find the relevant node. + parent, node, _, leftover := trie.findSubtree(key) + if len(leftover) != 0 { + return false + } + + // If the item is already set to nil, there is nothing to do. + if node.item == nil { + return false + } + + // Delete the item. + node.item = nil + + // Compact since that might be possible now. + if compacted := node.compact(); compacted != node { + if parent == nil { + *node = *compacted + } else { + parent.children.replace(node.prefix[0], compacted) + *parent = *parent.compact() + } + } + + return true +} + +// DeleteSubtree finds the subtree exactly matching prefix and deletes it. +// +// True is returned if the subtree was found and deleted. +func (trie *Trie) DeleteSubtree(prefix Prefix) (deleted bool) { + // Nil prefix not allowed. + if prefix == nil { + panic(ErrNilPrefix) + } + + // Empty trie must be handled explicitly. + if trie.prefix == nil { + return false + } + + // Locate the relevant subtree. + parent, root, found, _ := trie.findSubtree(prefix) + if !found { + return false + } + + // If we are in the root of the trie, reset the trie. + if parent == nil { + root.prefix = nil + root.children = newSparseChildList() + return true + } + + // Otherwise remove the root node from its parent. + parent.children.remove(root) + return true +} + +// Internal helper methods ----------------------------------------------------- + +func (trie *Trie) put(key Prefix, item Item, replace bool) (inserted bool) { + // Nil prefix not allowed. + if key == nil { + panic(ErrNilPrefix) + } + + var ( + common int + node *Trie = trie + child *Trie + ) + + if node.prefix == nil { + if len(key) <= MaxPrefixPerNode { + node.prefix = key + goto InsertItem + } + node.prefix = key[:MaxPrefixPerNode] + key = key[MaxPrefixPerNode:] + goto AppendChild + } + + for { + // Compute the longest common prefix length. + common = node.longestCommonPrefixLength(key) + key = key[common:] + + // Only a part matches, split. + if common < len(node.prefix) { + goto SplitPrefix + } + + // common == len(node.prefix) since never (common > len(node.prefix)) + // common == len(former key) <-> 0 == len(key) + // -> former key == node.prefix + if len(key) == 0 { + goto InsertItem + } + + // Check children for matching prefix. + child = node.children.next(key[0]) + if child == nil { + goto AppendChild + } + node = child + } + +SplitPrefix: + // Split the prefix if necessary. + child = new(Trie) + *child = *node + *node = *NewTrie() + node.prefix = child.prefix[:common] + child.prefix = child.prefix[common:] + child = child.compact() + node.children = node.children.add(child) + +AppendChild: + // Keep appending children until whole prefix is inserted. + // This loop starts with empty node.prefix that needs to be filled. + for len(key) != 0 { + child := NewTrie() + if len(key) <= MaxPrefixPerNode { + child.prefix = key + node.children = node.children.add(child) + node = child + goto InsertItem + } else { + child.prefix = key[:MaxPrefixPerNode] + key = key[MaxPrefixPerNode:] + node.children = node.children.add(child) + node = child + } + } + +InsertItem: + // Try to insert the item if possible. + if replace || node.item == nil { + node.item = item + return true + } + return false +} + +func (trie *Trie) compact() *Trie { + // Only a node with a single child can be compacted. + if trie.children.length() != 1 { + return trie + } + + child := trie.children.head() + + // If any item is set, we cannot compact since we want to retain + // the ability to do searching by key. This makes compaction less usable, + // but that simply cannot be avoided. + if trie.item != nil || child.item != nil { + return trie + } + + // Make sure the combined prefixes fit into a single node. + if len(trie.prefix)+len(child.prefix) > MaxPrefixPerNode { + return trie + } + + // Concatenate the prefixes, move the items. + child.prefix = append(trie.prefix, child.prefix...) + if trie.item != nil { + child.item = trie.item + } + + return child +} + +func (trie *Trie) findSubtree(prefix Prefix) (parent *Trie, root *Trie, found bool, leftover Prefix) { + // Find the subtree matching prefix. + root = trie + for { + // Compute what part of prefix matches. + common := root.longestCommonPrefixLength(prefix) + prefix = prefix[common:] + + // We used up the whole prefix, subtree found. + if len(prefix) == 0 { + found = true + leftover = root.prefix[common:] + return + } + + // Partial match means that there is no subtree matching prefix. + if common < len(root.prefix) { + leftover = root.prefix[common:] + return + } + + // There is some prefix left, move to the children. + child := root.children.next(prefix[0]) + if child == nil { + // There is nowhere to continue, there is no subtree matching prefix. + return + } + + parent = root + root = child + } +} + +func (trie *Trie) walk(actualRootPrefix Prefix, visitor VisitorFunc) error { + var prefix Prefix + // Allocate a bit more space for prefix at the beginning. + if actualRootPrefix == nil { + prefix = make(Prefix, 32+len(trie.prefix)) + copy(prefix, trie.prefix) + prefix = prefix[:len(trie.prefix)] + } else { + prefix = make(Prefix, 32+len(actualRootPrefix)) + copy(prefix, actualRootPrefix) + prefix = prefix[:len(actualRootPrefix)] + } + + // Visit the root first. Not that this works for empty trie as well since + // in that case item == nil && len(children) == 0. + if trie.item != nil { + if err := visitor(prefix, trie.item); err != nil { + if err == SkipSubtree { + return nil + } + return err + } + } + + // Then continue to the children. + return trie.children.walk(&prefix, visitor) +} + +func (trie *Trie) longestCommonPrefixLength(prefix Prefix) (i int) { + for ; i < len(prefix) && i < len(trie.prefix) && prefix[i] == trie.prefix[i]; i++ { + } + return +} + +// Errors ---------------------------------------------------------------------- + +var ( + SkipSubtree = errors.New("Skip this subtree") + ErrNilPrefix = errors.New("Nil prefix passed into a method call") +) diff --git a/vendor/src/github.com/tchap/go-patricia/patricia/patricia_dense_test.go b/vendor/src/github.com/tchap/go-patricia/patricia/patricia_dense_test.go new file mode 100644 index 0000000000..346e9a66cb --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/patricia/patricia_dense_test.go @@ -0,0 +1,161 @@ +// Copyright (c) 2014 The go-patricia AUTHORS +// +// Use of this source code is governed by The MIT License +// that can be found in the LICENSE file. + +package patricia + +import ( + "testing" +) + +// Tests ----------------------------------------------------------------------- + +func TestTrie_InsertDense(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"aba", 0, success}, + {"abb", 1, success}, + {"abc", 2, success}, + {"abd", 3, success}, + {"abe", 4, success}, + {"abf", 5, success}, + {"abg", 6, success}, + {"abh", 7, success}, + {"abi", 8, success}, + {"abj", 9, success}, + {"abk", 0, success}, + {"abl", 1, success}, + {"abm", 2, success}, + {"abn", 3, success}, + {"abo", 4, success}, + {"abp", 5, success}, + {"abq", 6, success}, + {"abr", 7, success}, + {"abs", 8, success}, + {"abt", 9, success}, + {"abu", 0, success}, + {"abv", 1, success}, + {"abw", 2, success}, + {"abx", 3, success}, + {"aby", 4, success}, + {"abz", 5, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestTrie_InsertDensePreceeding(t *testing.T) { + trie := NewTrie() + start := byte(70) + // create a dense node + for i := byte(0); i <= MaxChildrenPerSparseNode; i++ { + if !trie.Insert(Prefix([]byte{start + i}), true) { + t.Errorf("insert failed, prefix=%v", start+i) + } + } + // insert some preceeding keys + for i := byte(1); i < start; i *= i + 1 { + if !trie.Insert(Prefix([]byte{start - i}), true) { + t.Errorf("insert failed, prefix=%v", start-i) + } + } +} + +func TestTrie_InsertDenseDuplicatePrefixes(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"aba", 0, success}, + {"abb", 1, success}, + {"abc", 2, success}, + {"abd", 3, success}, + {"abe", 4, success}, + {"abf", 5, success}, + {"abg", 6, success}, + {"abh", 7, success}, + {"abi", 8, success}, + {"abj", 9, success}, + {"abk", 0, success}, + {"abl", 1, success}, + {"abm", 2, success}, + {"abn", 3, success}, + {"abo", 4, success}, + {"abp", 5, success}, + {"abq", 6, success}, + {"abr", 7, success}, + {"abs", 8, success}, + {"abt", 9, success}, + {"abu", 0, success}, + {"abv", 1, success}, + {"abw", 2, success}, + {"abx", 3, success}, + {"aby", 4, success}, + {"abz", 5, success}, + {"aba", 0, failure}, + {"abb", 1, failure}, + {"abc", 2, failure}, + {"abd", 3, failure}, + {"abe", 4, failure}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestTrie_DeleteDense(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"aba", 0, success}, + {"abb", 1, success}, + {"abc", 2, success}, + {"abd", 3, success}, + {"abe", 4, success}, + {"abf", 5, success}, + {"abg", 6, success}, + {"abh", 7, success}, + {"abi", 8, success}, + {"abj", 9, success}, + {"abk", 0, success}, + {"abl", 1, success}, + {"abm", 2, success}, + {"abn", 3, success}, + {"abo", 4, success}, + {"abp", 5, success}, + {"abq", 6, success}, + {"abr", 7, success}, + {"abs", 8, success}, + {"abt", 9, success}, + {"abu", 0, success}, + {"abv", 1, success}, + {"abw", 2, success}, + {"abx", 3, success}, + {"aby", 4, success}, + {"abz", 5, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range data { + t.Logf("DELETE word=%v, success=%v", v.key, v.retVal) + if ok := trie.Delete([]byte(v.key)); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} diff --git a/vendor/src/github.com/tchap/go-patricia/patricia/patricia_sparse_test.go b/vendor/src/github.com/tchap/go-patricia/patricia/patricia_sparse_test.go new file mode 100644 index 0000000000..27f3c878b5 --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/patricia/patricia_sparse_test.go @@ -0,0 +1,659 @@ +// Copyright (c) 2014 The go-patricia AUTHORS +// +// Use of this source code is governed by The MIT License +// that can be found in the LICENSE file. + +package patricia + +import ( + "bytes" + "errors" + "fmt" + "strings" + "testing" +) + +const ( + success = true + failure = false +) + +type testData struct { + key string + value interface{} + retVal bool +} + +// Tests ----------------------------------------------------------------------- + +func TestTrie_InsertDifferentPrefixes(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepaneeeeeeeeeeeeee", "Pepan Zdepan", success}, + {"Honzooooooooooooooo", "Honza Novak", success}, + {"Jenikuuuuuuuuuuuuuu", "Jenik Poustevnicek", success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestTrie_InsertDuplicatePrefixes(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Pepan", "Pepan Zdepan", failure}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestTrie_InsertVariousPrefixes(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Pepin", "Pepin Omacka", success}, + {"Honza", "Honza Novak", success}, + {"Jenik", "Jenik Poustevnicek", success}, + {"Pepan", "Pepan Dupan", failure}, + {"Karel", "Karel Pekar", success}, + {"Jenik", "Jenik Poustevnicek", failure}, + {"Pepanek", "Pepanek Zemlicka", success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestTrie_InsertAndMatchPrefix(t *testing.T) { + trie := NewTrie() + t.Log("INSERT prefix=by week") + trie.Insert(Prefix("by week"), 2) + t.Log("INSERT prefix=by") + trie.Insert(Prefix("by"), 1) + + if !trie.Match(Prefix("by")) { + t.Error("MATCH prefix=by, expected=true, got=false") + } +} + +func TestTrie_SetGet(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Pepin", "Pepin Omacka", success}, + {"Honza", "Honza Novak", success}, + {"Jenik", "Jenik Poustevnicek", success}, + {"Pepan", "Pepan Dupan", failure}, + {"Karel", "Karel Pekar", success}, + {"Jenik", "Jenik Poustevnicek", failure}, + {"Pepanek", "Pepanek Zemlicka", success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range data { + t.Logf("SET %q to 10", v.key) + trie.Set(Prefix(v.key), 10) + } + + for _, v := range data { + value := trie.Get(Prefix(v.key)) + t.Logf("GET %q => %v", v.key, value) + if value.(int) != 10 { + t.Errorf("Unexpected return value, != 10", value) + } + } + + if value := trie.Get(Prefix("random crap")); value != nil { + t.Errorf("Unexpected return value, %v != ", value) + } +} + +func TestTrie_Match(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Pepin", "Pepin Omacka", success}, + {"Honza", "Honza Novak", success}, + {"Jenik", "Jenik Poustevnicek", success}, + {"Pepan", "Pepan Dupan", failure}, + {"Karel", "Karel Pekar", success}, + {"Jenik", "Jenik Poustevnicek", failure}, + {"Pepanek", "Pepanek Zemlicka", success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range data { + matched := trie.Match(Prefix(v.key)) + t.Logf("MATCH %q => %v", v.key, matched) + if !matched { + t.Errorf("Inserted key %q was not matched", v.key) + } + } + + if trie.Match(Prefix("random crap")) { + t.Errorf("Key that was not inserted matched: %q", "random crap") + } +} + +func TestTrie_MatchFalsePositive(t *testing.T) { + trie := NewTrie() + + if ok := trie.Insert(Prefix("A"), 1); !ok { + t.Fatal("INSERT prefix=A, item=1 not ok") + } + + resultMatchSubtree := trie.MatchSubtree(Prefix("A extra")) + resultMatch := trie.Match(Prefix("A extra")) + + if resultMatchSubtree != false { + t.Error("MatchSubtree returned false positive") + } + + if resultMatch != false { + t.Error("Match returned false positive") + } +} + +func TestTrie_MatchSubtree(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Pepin", "Pepin Omacka", success}, + {"Honza", "Honza Novak", success}, + {"Jenik", "Jenik Poustevnicek", success}, + {"Pepan", "Pepan Dupan", failure}, + {"Karel", "Karel Pekar", success}, + {"Jenik", "Jenik Poustevnicek", failure}, + {"Pepanek", "Pepanek Zemlicka", success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range data { + key := Prefix(v.key[:3]) + matched := trie.MatchSubtree(key) + t.Logf("MATCH_SUBTREE %q => %v", key, matched) + if !matched { + t.Errorf("Subtree %q was not matched", v.key) + } + } +} + +func TestTrie_Visit(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepa", 0, success}, + {"Pepa Zdepa", 1, success}, + {"Pepa Kuchar", 2, success}, + {"Honza", 3, success}, + {"Jenik", 4, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + if err := trie.Visit(func(prefix Prefix, item Item) error { + name := data[item.(int)].key + t.Logf("VISITING prefix=%q, item=%v", prefix, item) + if !strings.HasPrefix(string(prefix), name) { + t.Errorf("Unexpected prefix encountered, %q not a prefix of %q", prefix, name) + } + return nil + }); err != nil { + t.Fatal(err) + } +} + +func TestTrie_VisitSkipSubtree(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepa", 0, success}, + {"Pepa Zdepa", 1, success}, + {"Pepa Kuchar", 2, success}, + {"Honza", 3, success}, + {"Jenik", 4, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + if err := trie.Visit(func(prefix Prefix, item Item) error { + t.Logf("VISITING prefix=%q, item=%v", prefix, item) + if item.(int) == 0 { + t.Logf("SKIP %q", prefix) + return SkipSubtree + } + if strings.HasPrefix(string(prefix), "Pepa") { + t.Errorf("Unexpected prefix encountered, %q", prefix) + } + return nil + }); err != nil { + t.Fatal(err) + } +} + +func TestTrie_VisitReturnError(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepa", 0, success}, + {"Pepa Zdepa", 1, success}, + {"Pepa Kuchar", 2, success}, + {"Honza", 3, success}, + {"Jenik", 4, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + someErr := errors.New("Something exploded") + if err := trie.Visit(func(prefix Prefix, item Item) error { + t.Logf("VISITING prefix=%q, item=%v", prefix, item) + if item.(int) == 0 { + return someErr + } + if item.(int) != 0 { + t.Errorf("Unexpected prefix encountered, %q", prefix) + } + return nil + }); err != nil && err != someErr { + t.Fatal(err) + } +} + +func TestTrie_VisitSubtree(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepa", 0, success}, + {"Pepa Zdepa", 1, success}, + {"Pepa Kuchar", 2, success}, + {"Honza", 3, success}, + {"Jenik", 4, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + var counter int + subtreePrefix := []byte("Pep") + t.Log("VISIT Pep") + if err := trie.VisitSubtree(subtreePrefix, func(prefix Prefix, item Item) error { + t.Logf("VISITING prefix=%q, item=%v", prefix, item) + if !bytes.HasPrefix(prefix, subtreePrefix) { + t.Errorf("Unexpected prefix encountered, %q does not extend %q", + prefix, subtreePrefix) + } + if len(prefix) > len(data[item.(int)].key) { + t.Fatalf("Something is rather fishy here, prefix=%q", prefix) + } + counter++ + return nil + }); err != nil { + t.Fatal(err) + } + + if counter != 3 { + t.Error("Unexpected number of nodes visited") + } +} + +func TestTrie_VisitPrefixes(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"P", 0, success}, + {"Pe", 1, success}, + {"Pep", 2, success}, + {"Pepa", 3, success}, + {"Pepa Zdepa", 4, success}, + {"Pepa Kuchar", 5, success}, + {"Honza", 6, success}, + {"Jenik", 7, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + var counter int + word := []byte("Pepa") + if err := trie.VisitPrefixes(word, func(prefix Prefix, item Item) error { + t.Logf("VISITING prefix=%q, item=%v", prefix, item) + if !bytes.HasPrefix(word, prefix) { + t.Errorf("Unexpected prefix encountered, %q is not a prefix of %q", + prefix, word) + } + counter++ + return nil + }); err != nil { + t.Fatal(err) + } + + if counter != 4 { + t.Error("Unexpected number of nodes visited") + } +} + +func TestParticiaTrie_Delete(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Honza", "Honza Novak", success}, + {"Jenik", "Jenik Poustevnicek", success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range data { + t.Logf("DELETE word=%v, success=%v", v.key, v.retVal) + if ok := trie.Delete([]byte(v.key)); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestParticiaTrie_DeleteNonExistent(t *testing.T) { + trie := NewTrie() + + insertData := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Honza", "Honza Novak", success}, + {"Jenik", "Jenik Poustevnicek", success}, + } + deleteData := []testData{ + {"Pepan", "Pepan Zdepan", success}, + {"Honza", "Honza Novak", success}, + {"Pepan", "Pepan Zdepan", failure}, + {"Jenik", "Jenik Poustevnicek", success}, + {"Honza", "Honza Novak", failure}, + } + + for _, v := range insertData { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range deleteData { + t.Logf("DELETE word=%v, success=%v", v.key, v.retVal) + if ok := trie.Delete([]byte(v.key)); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +func TestParticiaTrie_DeleteSubtree(t *testing.T) { + trie := NewTrie() + + insertData := []testData{ + {"P", 0, success}, + {"Pe", 1, success}, + {"Pep", 2, success}, + {"Pepa", 3, success}, + {"Pepa Zdepa", 4, success}, + {"Pepa Kuchar", 5, success}, + {"Honza", 6, success}, + {"Jenik", 7, success}, + } + deleteData := []testData{ + {"Pe", -1, success}, + {"Pe", -1, failure}, + {"Honzik", -1, failure}, + {"Honza", -1, success}, + {"Honza", -1, failure}, + {"Pep", -1, failure}, + {"P", -1, success}, + {"Nobody", -1, failure}, + {"", -1, success}, + } + + for _, v := range insertData { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + for _, v := range deleteData { + t.Logf("DELETE_SUBTREE prefix=%v, success=%v", v.key, v.retVal) + if ok := trie.DeleteSubtree([]byte(v.key)); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } +} + +/* +func TestTrie_Dump(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"Honda", nil, success}, + {"Honza", nil, success}, + {"Jenik", nil, success}, + {"Pepan", nil, success}, + {"Pepin", nil, success}, + } + + for i, v := range data { + if _, ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { + t.Logf("INSERT %v %v", v.key, v.value) + t.Fatalf("Unexpected return value, expected=%v, got=%v", i, ok) + } + } + + dump := ` ++--+--+ Hon +--+--+ da + | | + | +--+ za + | + +--+ Jenik + | + +--+ Pep +--+--+ an + | + +--+ in +` + + var buf bytes.Buffer + trie.Dump(buf) + + if !bytes.Equal(buf.Bytes(), dump) { + t.Logf("DUMP") + t.Fatalf("Unexpected dump generated, expected\n\n%v\ngot\n\n%v", dump, buf.String()) + } +} +*/ + +func TestTrie_compact(t *testing.T) { + trie := NewTrie() + + trie.Insert(Prefix("a"), 0) + trie.Insert(Prefix("ab"), 0) + trie.Insert(Prefix("abc"), 0) + trie.Insert(Prefix("abcd"), 0) + trie.Insert(Prefix("abcde"), 0) + trie.Insert(Prefix("abcdef"), 0) + trie.Insert(Prefix("abcdefg"), 0) + trie.Insert(Prefix("abcdefgi"), 0) + trie.Insert(Prefix("abcdefgij"), 0) + trie.Insert(Prefix("abcdefgijk"), 0) + + trie.Delete(Prefix("abcdef")) + trie.Delete(Prefix("abcde")) + trie.Delete(Prefix("abcdefg")) + + trie.Delete(Prefix("a")) + trie.Delete(Prefix("abc")) + trie.Delete(Prefix("ab")) + + trie.Visit(func(prefix Prefix, item Item) error { + // 97 ~~ 'a', + for ch := byte(97); ch <= 107; ch++ { + if c := bytes.Count(prefix, []byte{ch}); c > 1 { + t.Errorf("%q appeared in %q %v times", ch, prefix, c) + } + } + return nil + }) +} + +func TestTrie_longestCommonPrefixLenght(t *testing.T) { + trie := NewTrie() + trie.prefix = []byte("1234567890") + + switch { + case trie.longestCommonPrefixLength([]byte("")) != 0: + t.Fail() + case trie.longestCommonPrefixLength([]byte("12345")) != 5: + t.Fail() + case trie.longestCommonPrefixLength([]byte("123789")) != 3: + t.Fail() + case trie.longestCommonPrefixLength([]byte("12345678901")) != 10: + t.Fail() + } +} + +// Examples -------------------------------------------------------------------- + +func ExampleTrie() { + // Create a new tree. + trie := NewTrie() + + // Insert some items. + trie.Insert(Prefix("Pepa Novak"), 1) + trie.Insert(Prefix("Pepa Sindelar"), 2) + trie.Insert(Prefix("Karel Macha"), 3) + trie.Insert(Prefix("Karel Hynek Macha"), 4) + + // Just check if some things are present in the tree. + key := Prefix("Pepa Novak") + fmt.Printf("%q present? %v\n", key, trie.Match(key)) + key = Prefix("Karel") + fmt.Printf("Anybody called %q here? %v\n", key, trie.MatchSubtree(key)) + + // Walk the tree. + trie.Visit(printItem) + // "Pepa Novak": 1 + // "Pepa Sindelar": 2 + // "Karel Macha": 3 + // "Karel Hynek Macha": 4 + + // Walk a subtree. + trie.VisitSubtree(Prefix("Pepa"), printItem) + // "Pepa Novak": 1 + // "Pepa Sindelar": 2 + + // Modify an item, then fetch it from the tree. + trie.Set(Prefix("Karel Hynek Macha"), 10) + key = Prefix("Karel Hynek Macha") + fmt.Printf("%q: %v\n", key, trie.Get(key)) + // "Karel Hynek Macha": 10 + + // Walk prefixes. + prefix := Prefix("Karel Hynek Macha je kouzelnik") + trie.VisitPrefixes(prefix, printItem) + // "Karel Hynek Macha": 10 + + // Delete some items. + trie.Delete(Prefix("Pepa Novak")) + trie.Delete(Prefix("Karel Macha")) + + // Walk again. + trie.Visit(printItem) + // "Pepa Sindelar": 2 + // "Karel Hynek Macha": 10 + + // Delete a subtree. + trie.DeleteSubtree(Prefix("Pepa")) + + // Print what is left. + trie.Visit(printItem) + // "Karel Hynek Macha": 10 + + // Output: + // "Pepa Novak" present? true + // Anybody called "Karel" here? true + // "Pepa Novak": 1 + // "Pepa Sindelar": 2 + // "Karel Macha": 3 + // "Karel Hynek Macha": 4 + // "Pepa Novak": 1 + // "Pepa Sindelar": 2 + // "Karel Hynek Macha": 10 + // "Karel Hynek Macha": 10 + // "Pepa Sindelar": 2 + // "Karel Hynek Macha": 10 + // "Karel Hynek Macha": 10 +} + +// Helpers --------------------------------------------------------------------- + +func printItem(prefix Prefix, item Item) error { + fmt.Printf("%q: %v\n", prefix, item) + return nil +} diff --git a/vendor/src/github.com/tchap/go-patricia/patricia/patricia_test.go b/vendor/src/github.com/tchap/go-patricia/patricia/patricia_test.go new file mode 100644 index 0000000000..ce5ae378fa --- /dev/null +++ b/vendor/src/github.com/tchap/go-patricia/patricia/patricia_test.go @@ -0,0 +1,78 @@ +// Copyright (c) 2014 The go-patricia AUTHORS +// +// Use of this source code is governed by The MIT License +// that can be found in the LICENSE file. + +package patricia + +import ( + "crypto/rand" + "reflect" + "testing" +) + +// Tests ----------------------------------------------------------------------- + +func TestTrie_GetNonexistentPrefix(t *testing.T) { + trie := NewTrie() + + data := []testData{ + {"aba", 0, success}, + } + + for _, v := range data { + t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) + if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { + t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) + } + } + + t.Logf("GET prefix=baa, expect item=nil") + if item := trie.Get(Prefix("baa")); item != nil { + t.Errorf("Unexpected return value, expected=, got=%v", item) + } +} + +func TestTrie_RandomKitchenSink(t *testing.T) { + if testing.Short() { + t.Skip() + } + const count, size = 750000, 16 + b := make([]byte, count+size+1) + if _, err := rand.Read(b); err != nil { + t.Fatal("error generating random bytes", err) + } + m := make(map[string]string) + for i := 0; i < count; i++ { + m[string(b[i:i+size])] = string(b[i+1 : i+size+1]) + } + trie := NewTrie() + getAndDelete := func(k, v string) { + i := trie.Get(Prefix(k)) + if i == nil { + t.Fatalf("item not found, prefix=%v", []byte(k)) + } else if s, ok := i.(string); !ok { + t.Fatalf("unexpected item type, expecting=%v, got=%v", reflect.TypeOf(k), reflect.TypeOf(i)) + } else if s != v { + t.Fatalf("unexpected item, expecting=%v, got=%v", []byte(k), []byte(s)) + } else if !trie.Delete(Prefix(k)) { + t.Fatalf("delete failed, prefix=%v", []byte(k)) + } else if i = trie.Get(Prefix(k)); i != nil { + t.Fatalf("unexpected item, expecting=, got=%v", i) + } else if trie.Delete(Prefix(k)) { + t.Fatalf("extra delete succeeded, prefix=%v", []byte(k)) + } + } + for k, v := range m { + if !trie.Insert(Prefix(k), v) { + t.Fatalf("insert failed, prefix=%v", []byte(k)) + } + if byte(k[size/2]) < 128 { + getAndDelete(k, v) + delete(m, k) + } + } + for k, v := range m { + getAndDelete(k, v) + } +} -- cgit v1.2.1 From 7606412d53b522774b2b7cea93fa2618b784e886 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Thu, 26 Jun 2014 09:54:12 -0400 Subject: Remove integration tests moved to integration-cli(dups) integration/commands_test.go/TestRunHostname == integration-cli/docker_cli_run_tests.go/TestModeHostname integration/commands_test.go/TestRunWorkdir == integration-cli/docker_cli_run_tests.go/TestDockerRunWorkingDirectory integration/commands_test.go/TestRunWorkdirExists == integration-cli/docker_cli_run_tests.go/TestDockerRunWorkingDirectory integration/commands_test.go/TestAttachstdIn == integration-cli/docker_cli_run_tests.go/TestRunStdinPipe integration/commands_test.go/TestCmdLogs == integration-cli/docker_cli_logs_tests.go integration/commands_test.go/TestCmdKill == integration-cli/docker_cli_kill_test.go Docker-DCO-1.1-Signed-off-by: Brian Goff (github: cpuguy83) --- integration/commands_test.go | 292 +------------------------------------------ 1 file changed, 2 insertions(+), 290 deletions(-) diff --git a/integration/commands_test.go b/integration/commands_test.go index 4ad225bb43..55c822bbeb 100644 --- a/integration/commands_test.go +++ b/integration/commands_test.go @@ -8,9 +8,7 @@ import ( "os" "path" "regexp" - "strconv" "strings" - "syscall" "testing" "time" @@ -118,141 +116,6 @@ func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error return nil } -// TestRunHostname checks that 'docker run -h' correctly sets a custom hostname -func TestRunHostname(t *testing.T) { - stdout, stdoutPipe := io.Pipe() - - cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - defer cleanup(globalEngine, t) - - c := make(chan struct{}) - go func() { - defer close(c) - if err := cli.CmdRun("-h", "foobar", unitTestImageID, "hostname"); err != nil { - t.Fatal(err) - } - }() - - setTimeout(t, "Reading command output time out", 2*time.Second, func() { - cmdOutput, err := bufio.NewReader(stdout).ReadString('\n') - if err != nil { - t.Fatal(err) - } - if cmdOutput != "foobar\n" { - t.Fatalf("'hostname' should display '%s', not '%s'", "foobar\n", cmdOutput) - } - }) - - container := globalDaemon.List()[0] - - setTimeout(t, "CmdRun timed out", 10*time.Second, func() { - <-c - - go func() { - cli.CmdWait(container.ID) - }() - - if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil { - t.Fatal(err) - } - }) - - // Cleanup pipes - if err := closeWrap(stdout, stdoutPipe); err != nil { - t.Fatal(err) - } -} - -// TestRunWorkdir checks that 'docker run -w' correctly sets a custom working directory -func TestRunWorkdir(t *testing.T) { - stdout, stdoutPipe := io.Pipe() - - cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - defer cleanup(globalEngine, t) - - c := make(chan struct{}) - go func() { - defer close(c) - if err := cli.CmdRun("-w", "/foo/bar", unitTestImageID, "pwd"); err != nil { - t.Fatal(err) - } - }() - - setTimeout(t, "Reading command output time out", 2*time.Second, func() { - cmdOutput, err := bufio.NewReader(stdout).ReadString('\n') - if err != nil { - t.Fatal(err) - } - if cmdOutput != "/foo/bar\n" { - t.Fatalf("'pwd' should display '%s', not '%s'", "/foo/bar\n", cmdOutput) - } - }) - - container := globalDaemon.List()[0] - - setTimeout(t, "CmdRun timed out", 10*time.Second, func() { - <-c - - go func() { - cli.CmdWait(container.ID) - }() - - if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil { - t.Fatal(err) - } - }) - - // Cleanup pipes - if err := closeWrap(stdout, stdoutPipe); err != nil { - t.Fatal(err) - } -} - -// TestRunWorkdirExists checks that 'docker run -w' correctly sets a custom working directory, even if it exists -func TestRunWorkdirExists(t *testing.T) { - stdout, stdoutPipe := io.Pipe() - - cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - defer cleanup(globalEngine, t) - - c := make(chan struct{}) - go func() { - defer close(c) - if err := cli.CmdRun("-w", "/proc", unitTestImageID, "pwd"); err != nil { - t.Fatal(err) - } - }() - - setTimeout(t, "Reading command output time out", 2*time.Second, func() { - cmdOutput, err := bufio.NewReader(stdout).ReadString('\n') - if err != nil { - t.Fatal(err) - } - if cmdOutput != "/proc\n" { - t.Fatalf("'pwd' should display '%s', not '%s'", "/proc\n", cmdOutput) - } - }) - - container := globalDaemon.List()[0] - - setTimeout(t, "CmdRun timed out", 5*time.Second, func() { - <-c - - go func() { - cli.CmdWait(container.ID) - }() - - if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil { - t.Fatal(err) - } - }) - - // Cleanup pipes - if err := closeWrap(stdout, stdoutPipe); err != nil { - t.Fatal(err) - } -} - // TestRunWorkdirExistsAndIsFile checks that if 'docker run -w' with existing file can be detected func TestRunWorkdirExistsAndIsFile(t *testing.T) { @@ -419,72 +282,6 @@ func TestRunDisconnectTty(t *testing.T) { } } -// TestAttachStdin checks attaching to stdin without stdout and stderr. -// 'docker run -i -a stdin' should sends the client's stdin to the command, -// then detach from it and print the container id. -func TestRunAttachStdin(t *testing.T) { - - stdin, stdinPipe := io.Pipe() - stdout, stdoutPipe := io.Pipe() - - cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - defer cleanup(globalEngine, t) - - ch := make(chan struct{}) - go func() { - defer close(ch) - cli.CmdRun("-i", "-a", "stdin", unitTestImageID, "sh", "-c", "echo hello && cat && sleep 5") - }() - - // Send input to the command, close stdin - setTimeout(t, "Write timed out", 10*time.Second, func() { - if _, err := stdinPipe.Write([]byte("hi there\n")); err != nil { - t.Fatal(err) - } - if err := stdinPipe.Close(); err != nil { - t.Fatal(err) - } - }) - - container := globalDaemon.List()[0] - - // Check output - setTimeout(t, "Reading command output time out", 10*time.Second, func() { - cmdOutput, err := bufio.NewReader(stdout).ReadString('\n') - if err != nil { - t.Fatal(err) - } - if cmdOutput != container.ID+"\n" { - t.Fatalf("Wrong output: should be '%s', not '%s'\n", container.ID+"\n", cmdOutput) - } - }) - - // wait for CmdRun to return - setTimeout(t, "Waiting for CmdRun timed out", 5*time.Second, func() { - <-ch - }) - - setTimeout(t, "Waiting for command to exit timed out", 10*time.Second, func() { - container.Wait() - }) - - // Check logs - if cmdLogs, err := container.ReadLog("json"); err != nil { - t.Fatal(err) - } else { - if output, err := ioutil.ReadAll(cmdLogs); err != nil { - t.Fatal(err) - } else { - expectedLogs := []string{"{\"log\":\"hello\\n\",\"stream\":\"stdout\"", "{\"log\":\"hi there\\n\",\"stream\":\"stdout\""} - for _, expectedLog := range expectedLogs { - if !strings.Contains(string(output), expectedLog) { - t.Fatalf("Unexpected logs: should contains '%s', it is not '%s'\n", expectedLog, output) - } - } - } - } -} - // TestRunDetach checks attaching and detaching with the escape sequence. func TestRunDetach(t *testing.T) { @@ -787,23 +584,6 @@ func TestRunAutoRemove(t *testing.T) { } } -func TestCmdLogs(t *testing.T) { - t.Skip("Test not impemented") - cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - defer cleanup(globalEngine, t) - - if err := cli.CmdRun(unitTestImageID, "sh", "-c", "ls -l"); err != nil { - t.Fatal(err) - } - if err := cli.CmdRun("-t", unitTestImageID, "sh", "-c", "ls -l"); err != nil { - t.Fatal(err) - } - - if err := cli.CmdLogs(globalDaemon.List()[0].ID); err != nil { - t.Fatal(err) - } -} - // Expected behaviour: error out when attempting to bind mount non-existing source paths func TestRunErrorBindNonExistingSource(t *testing.T) { @@ -825,6 +605,7 @@ func TestRunErrorBindNonExistingSource(t *testing.T) { } func TestImagesViz(t *testing.T) { + t.Skip("Image viz is deprecated") stdout, stdoutPipe := io.Pipe() cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) @@ -875,6 +656,7 @@ func TestImagesViz(t *testing.T) { } func TestImagesTree(t *testing.T) { + t.Skip("Image tree is deprecated") stdout, stdoutPipe := io.Pipe() cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) @@ -1095,73 +877,3 @@ func TestContainerOrphaning(t *testing.T) { } } - -func TestCmdKill(t *testing.T) { - var ( - stdin, stdinPipe = io.Pipe() - stdout, stdoutPipe = io.Pipe() - cli = client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - cli2 = client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil) - ) - defer cleanup(globalEngine, t) - - ch := make(chan struct{}) - go func() { - defer close(ch) - cli.CmdRun("-i", "-t", unitTestImageID, "sh", "-c", "trap 'echo SIGUSR1' USR1; trap 'echo SIGUSR2' USR2; echo Ready; while true; do read; done") - }() - - container := waitContainerStart(t, 10*time.Second) - - setTimeout(t, "Read Ready timed out", 3*time.Second, func() { - if err := expectPipe("Ready", stdout); err != nil { - t.Fatal(err) - } - }) - - setTimeout(t, "SIGUSR1 timed out", 2*time.Second, func() { - for i := 0; i < 10; i++ { - if err := cli2.CmdKill("-s", strconv.Itoa(int(syscall.SIGUSR1)), container.ID); err != nil { - t.Fatal(err) - } - if err := expectPipe("SIGUSR1", stdout); err != nil { - t.Fatal(err) - } - } - }) - - setTimeout(t, "SIGUSR2 timed out", 2*time.Second, func() { - for i := 0; i < 20; i++ { - sig := "USR2" - if i%2 != 0 { - // Swap to testing "SIGUSR2" for every odd iteration - sig = "SIGUSR2" - } - if err := cli2.CmdKill("--signal="+sig, container.ID); err != nil { - t.Fatal(err) - } - if err := expectPipe("SIGUSR2", stdout); err != nil { - t.Fatal(err) - } - } - }) - - stdout.Close() - time.Sleep(500 * time.Millisecond) - if !container.State.IsRunning() { - t.Fatal("The container should be still running") - } - - setTimeout(t, "Waiting for container timedout", 5*time.Second, func() { - if err := cli2.CmdKill(container.ID); err != nil { - t.Fatal(err) - } - - <-ch - if err := cli2.CmdWait(container.ID); err != nil { - t.Fatal(err) - } - }) - - closeWrap(stdin, stdinPipe, stdout, stdoutPipe) -} -- cgit v1.2.1 From e39b8eade1f42503b6b7217e72eff4c8fdc13cb6 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 26 Jun 2014 10:50:18 -0700 Subject: Allow / as source of -v We discussed this at the docker plumbers meetup and for tools and working on the system for things like boot2docker and coreos this is needed. You can already bypass this check so we felt it is ok to start allowing this feature. Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- integration-cli/docker_cli_run_test.go | 11 +++++++++++ runconfig/parse.go | 4 ++-- server/server.go | 10 +--------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 9e5a90bedf..a0c3903064 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -960,3 +960,14 @@ func TestRootWorkdir(t *testing.T) { logDone("run - workdir /") } + +func TestAllowBindMountingRoot(t *testing.T) { + s, _, err := cmd(t, "run", "-v", "/:/host", "busybox", "ls", "/host") + if err != nil { + t.Fatal(s, err) + } + + deleteAllContainers() + + logDone("run - bind mount / as volume") +} diff --git a/runconfig/parse.go b/runconfig/parse.go index fd3e4a50a7..f057f311cc 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -132,8 +132,8 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf // add any bind targets to the list of container volumes for bind := range flVolumes.GetMap() { if arr := strings.Split(bind, ":"); len(arr) > 1 { - if arr[0] == "/" { - return nil, nil, cmd, fmt.Errorf("Invalid bind mount: source can't be '/'") + if arr[1] == "/" { + return nil, nil, cmd, fmt.Errorf("Invalid bind mount: desination can't be '/'") } // after creating the bind mount we want to delete it from the flVolumes values because // we do not want bind mounts being committed to image configs diff --git a/server/server.go b/server/server.go index fa695adfe2..76b3a83971 100644 --- a/server/server.go +++ b/server/server.go @@ -2055,19 +2055,11 @@ func (srv *Server) ContainerStart(job *engine.Job) engine.Status { if len(job.Environ()) > 0 { hostConfig := runconfig.ContainerHostConfigFromJob(job) // Validate the HostConfig binds. Make sure that: - // 1) the source of a bind mount isn't / - // The bind mount "/:/foo" isn't allowed. - // 2) Check that the source exists - // The source to be bind mounted must exist. + // the source exists for _, bind := range hostConfig.Binds { splitBind := strings.Split(bind, ":") source := splitBind[0] - // refuse to bind mount "/" to the container - if source == "/" { - return job.Errorf("Invalid bind mount '%s' : source can't be '/'", bind) - } - // ensure the source exists on the host _, err := os.Stat(source) if err != nil && os.IsNotExist(err) { -- cgit v1.2.1 From fa3ac2d37032583a7c1171c24d71fbf93e330acc Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Wed, 25 Jun 2014 12:04:59 -0400 Subject: Fixed manpage generation script and README Update md2man script to generate manpages inside docs/man/ directory. Update usage documentation in the readme to point to the new docs/man path. Update Ubuntu makefile to use new path to manpages Docker-DCO-1.1-Signed-off-by: Matthew Heon (github: mheon) --- docs/man/README.md | 8 ++++---- docs/man/md2man-all.sh | 4 ++-- hack/make/ubuntu | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/man/README.md b/docs/man/README.md index d49b39b7a2..d04d82454f 100644 --- a/docs/man/README.md +++ b/docs/man/README.md @@ -51,7 +51,7 @@ saving you from dealing with Pandoc and dependencies on your own computer. ## Building the Fedora / Pandoc image -There is a Dockerfile provided in the `docker/contrib/man/md` directory. +There is a Dockerfile provided in the `docker/docs/man` directory. Using this Dockerfile, create a Docker image tagged `fedora/pandoc`: @@ -61,11 +61,11 @@ Using this Dockerfile, create a Docker image tagged `fedora/pandoc`: Once the image is built, run a container using the image with *volumes*: - docker run -v //docker/contrib/man:/pandoc:rw \ - -w /pandoc -i fedora/pandoc /pandoc/md/md2man-all.sh + docker run -v //docker/docs/man:/pandoc:rw \ + -w /pandoc -i fedora/pandoc /pandoc/md2man-all.sh The Pandoc Docker container will process the Markdown files and generate -the man pages inside the `docker/contrib/man/man1` directory using +the man pages inside the `docker/docs/man/man1` directory using Docker volumes. For more information on Docker volumes see the man page for `docker run` and also look at the article [Sharing Directories via Volumes] (http://docs.docker.io/use/working_with_volumes/). diff --git a/docs/man/md2man-all.sh b/docs/man/md2man-all.sh index def876f47a..12d84de232 100755 --- a/docs/man/md2man-all.sh +++ b/docs/man/md2man-all.sh @@ -17,6 +17,6 @@ for FILE in *.md; do # skip files that aren't of the format xxxx.N.md (like README.md) continue fi - mkdir -p "../man${num}" - pandoc -s -t man "$FILE" -o "../man${num}/${name}" + mkdir -p "./man${num}" + pandoc -s -t man "$FILE" -o "./man${num}/${name}" done diff --git a/hack/make/ubuntu b/hack/make/ubuntu index 75202eace6..c55123fb7a 100644 --- a/hack/make/ubuntu +++ b/hack/make/ubuntu @@ -50,7 +50,7 @@ bundle_ubuntu() { docs/man/md2man-all.sh -q manRoot="$DIR/usr/share/man" mkdir -p "$manRoot" - for manDir in docs/man?; do + for manDir in docs/man/man?; do manBase="$(basename "$manDir")" # "man1" for manFile in "$manDir"/*; do manName="$(basename "$manFile")" # "docker-build.1" -- cgit v1.2.1 From 55691e5fdc78b5c3015c7a481371e482878c14d2 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 25 Jun 2014 22:24:14 +0000 Subject: add links to inspect for 'linking' containers Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- daemon/inspect.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/daemon/inspect.go b/daemon/inspect.go index 6c4b74d6f2..b93aec5059 100644 --- a/daemon/inspect.go +++ b/daemon/inspect.go @@ -2,6 +2,7 @@ package daemon import ( "encoding/json" + "fmt" "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/runconfig" @@ -46,7 +47,16 @@ func (daemon *Daemon) ContainerInspect(job *engine.Job) engine.Status { out.Set("ProcessLabel", container.ProcessLabel) out.SetJson("Volumes", container.Volumes) out.SetJson("VolumesRW", container.VolumesRW) + + if children, err := daemon.Children(container.Name); err == nil { + for linkAlias, child := range children { + container.hostConfig.Links = append(container.hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias)) + } + } + out.SetJson("HostConfig", container.hostConfig) + + container.hostConfig.Links = nil if _, err := out.WriteTo(job.Stdout); err != nil { return job.Error(err) } -- cgit v1.2.1 From af025f2a95090974eaaf3d8792d5f467d0a637be Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 26 Jun 2014 15:39:45 -0700 Subject: Remove api test for bind mount / Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- integration/api_test.go | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/integration/api_test.go b/integration/api_test.go index 620d6ecaa4..2d1b803682 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -672,42 +672,6 @@ func TestPostContainersStart(t *testing.T) { containerKill(eng, containerID, t) } -// Expected behaviour: using / as a bind mount source should throw an error -func TestRunErrorBindMountRootSource(t *testing.T) { - eng := NewTestEngine(t) - defer mkDaemonFromEngine(eng, t).Nuke() - - containerID := createTestContainer( - eng, - &runconfig.Config{ - Image: unitTestImageID, - Cmd: []string{"/bin/cat"}, - OpenStdin: true, - }, - t, - ) - - hostConfigJSON, err := json.Marshal(&runconfig.HostConfig{ - Binds: []string{"/:/tmp"}, - }) - - req, err := http.NewRequest("POST", "/containers/"+containerID+"/start", bytes.NewReader(hostConfigJSON)) - if err != nil { - t.Fatal(err) - } - - req.Header.Set("Content-Type", "application/json") - - r := httptest.NewRecorder() - if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil { - t.Fatal(err) - } - if r.Code != http.StatusInternalServerError { - containerKill(eng, containerID, t) - t.Fatal("should have failed to run when using / as a source for the bind mount") - } -} - func TestPostContainersStop(t *testing.T) { eng := NewTestEngine(t) defer mkDaemonFromEngine(eng, t).Nuke() -- cgit v1.2.1 From 111ab125b954c8d28503e1922e742eb271cc5d04 Mon Sep 17 00:00:00 2001 From: Travis Cline Date: Thu, 13 Feb 2014 16:05:36 -0800 Subject: Change misnamed TarFilter to TarWithOptions Docker-DCO-1.1-Signed-off-by: Travis Cline (github: tmc) --- archive/archive.go | 29 +++++++++++++----- archive/archive_test.go | 68 ++++++++++++++++++++++++++++++----------- daemon/container.go | 2 +- daemon/graphdriver/aufs/aufs.go | 2 +- 4 files changed, 73 insertions(+), 28 deletions(-) diff --git a/archive/archive.go b/archive/archive.go index 628d425ea1..65a5b495eb 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -27,6 +27,7 @@ type ( Compression int TarOptions struct { Includes []string + Excludes []string Compression Compression NoLchown bool } @@ -286,7 +287,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L // Tar creates an archive from the directory at `path`, and returns it as a // stream of bytes. func Tar(path string, compression Compression) (io.ReadCloser, error) { - return TarFilter(path, &TarOptions{Compression: compression}) + return TarWithOptions(path, &TarOptions{Compression: compression}) } func escapeName(name string) string { @@ -305,12 +306,9 @@ func escapeName(name string) string { return string(escaped) } -// TarFilter creates an archive from the directory at `srcPath` with `options`, and returns it as a -// stream of bytes. -// -// Files are included according to `options.Includes`, default to including all files. -// Stream is compressed according to `options.Compression', default to Uncompressed. -func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { +// TarWithOptions creates an archive from the directory at `path`, only including files whose relative +// paths are included in `options.Includes` (if non-nil) or not in `options.Excludes`. +func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { pipeReader, pipeWriter := io.Pipe() compressWriter, err := CompressStream(pipeWriter, options.Compression) @@ -342,6 +340,21 @@ func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { return nil } + for _, exclude := range options.Excludes { + matched, err := filepath.Match(exclude, relFilePath) + if err != nil { + utils.Errorf("Error matching: %s (pattern: %s)\n", relFilePath, exclude) + return err + } + if matched { + utils.Debugf("Skipping excluded path: %s\n", relFilePath) + if f.IsDir() { + return filepath.SkipDir + } + return nil + } + } + if err := addTarFile(filePath, relFilePath, tw); err != nil { utils.Debugf("Can't add file %s to tar: %s\n", srcPath, err) } @@ -482,7 +495,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { // TarUntar aborts and returns the error. func TarUntar(src string, dst string) error { utils.Debugf("TarUntar(%s %s)", src, dst) - archive, err := TarFilter(src, &TarOptions{Compression: Uncompressed}) + archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed}) if err != nil { return err } diff --git a/archive/archive_test.go b/archive/archive_test.go index 8c9ed6e552..b9051fe6ae 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -63,8 +63,8 @@ func TestCmdStreamGood(t *testing.T) { } } -func tarUntar(t *testing.T, origin string, compression Compression) error { - archive, err := Tar(origin, compression) +func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error) { + archive, err := TarWithOptions(origin, options) if err != nil { t.Fatal(err) } @@ -72,37 +72,29 @@ func tarUntar(t *testing.T, origin string, compression Compression) error { buf := make([]byte, 10) if _, err := archive.Read(buf); err != nil { - return err + return nil, err } wrap := io.MultiReader(bytes.NewReader(buf), archive) detectedCompression := DetectCompression(buf) + compression := options.Compression if detectedCompression.Extension() != compression.Extension() { - return fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) + return nil, fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) } tmp, err := ioutil.TempDir("", "docker-test-untar") if err != nil { - return err + return nil, err } defer os.RemoveAll(tmp) if err := Untar(wrap, tmp, nil); err != nil { - return err + return nil, err } if _, err := os.Stat(tmp); err != nil { - return err + return nil, err } - changes, err := ChangesDirs(origin, tmp) - if err != nil { - return err - } - - if len(changes) != 0 { - t.Fatalf("Unexpected differences after tarUntar: %v", changes) - } - - return nil + return ChangesDirs(origin, tmp) } func TestTarUntar(t *testing.T) { @@ -122,9 +114,49 @@ func TestTarUntar(t *testing.T) { Uncompressed, Gzip, } { - if err := tarUntar(t, origin, c); err != nil { + changes, err := tarUntar(t, origin, &TarOptions{ + Compression: c, + }) + + if err != nil { t.Fatalf("Error tar/untar for compression %s: %s", c.Extension(), err) } + + if len(changes) != 0 { + t.Fatalf("Unexpected differences after tarUntar: %v", changes) + } + } +} + +func TestTarWithOptions(t *testing.T) { + origin, err := ioutil.TempDir("", "docker-test-untar-origin") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(origin) + if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { + t.Fatal(err) + } + + cases := []struct { + opts *TarOptions + numChanges int + }{ + {&TarOptions{Includes: []string{"1"}}, 1}, + {&TarOptions{Excludes: []string{"2"}}, 1}, + } + for _, testCase := range cases { + changes, err := tarUntar(t, origin, testCase.opts) + if err != nil { + t.Fatalf("Error tar/untar when testing inclusion/exclusion: %s", err) + } + if len(changes) != testCase.numChanges { + t.Errorf("Expected %d changes, got %d for %+v:", + testCase.numChanges, len(changes), testCase.opts) + } } } diff --git a/daemon/container.go b/daemon/container.go index 2fd827eb9c..d9c809cee5 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -813,7 +813,7 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) { basePath = path.Dir(basePath) } - archive, err := archive.TarFilter(basePath, &archive.TarOptions{ + archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{ Compression: archive.Uncompressed, Includes: filter, }) diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index eb8ff77cde..0206b92e17 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/daemon/graphdriver/aufs/aufs.go @@ -295,7 +295,7 @@ func (a *Driver) Put(id string) { // Returns an archive of the contents for the id func (a *Driver) Diff(id string) (archive.Archive, error) { - return archive.TarFilter(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ + return archive.TarWithOptions(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ Compression: archive.Uncompressed, }) } -- cgit v1.2.1 From 9189db3aff3e9d72b215b5e204cfac018b2acc5d Mon Sep 17 00:00:00 2001 From: Travis Cline Date: Sat, 15 Feb 2014 10:38:48 -0800 Subject: Add .dockerignore support Fixes #2224 Docker-DCO-1.1-Signed-off-by: Travis Cline (github: tmc) --- .dockerignore | 2 ++ api/client/commands.go | 20 ++++++++++++- docs/sources/reference/commandline/cli.md | 30 +++++++++++++++++++ integration-cli/docker_cli_build_test.go | 50 +++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..37abdef44f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +bundles +.gopath diff --git a/api/client/commands.go b/api/client/commands.go index dcd882470c..c386e7a09c 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -13,6 +13,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "runtime" "strconv" "strings" @@ -163,7 +164,24 @@ func (cli *DockerCli) CmdBuild(args ...string) error { if err = utils.ValidateContextDirectory(root); err != nil { return fmt.Errorf("Error checking context is accessible: '%s'. Please check permissions and try again.", err) } - context, err = archive.Tar(root, archive.Uncompressed) + options := &archive.TarOptions{ + Compression: archive.Uncompressed, + } + ignoreFile := path.Join(root, ".dockerignore") + if ignore, err := ioutil.ReadFile(ignoreFile); err == nil { + for _, pattern := range strings.Split(string(ignore), "\n") { + ok, err := filepath.Match(pattern, "Dockerfile") + if err != nil { + utils.Errorf("Bad .dockerignore pattern: '%s', error: %s", pattern, err) + continue + } + if ok { + return fmt.Errorf("Dockerfile was excluded by .dockerignore pattern '%s'", pattern) + } + options.Excludes = append(options.Excludes, pattern) + } + } + context, err = archive.TarWithOptions(root, options) } var body io.Reader // Setup an upload progress bar diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 600a89b68a..cb5d39d93a 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -215,6 +215,12 @@ temporary directory on your local host, and then this is sent to the Docker daemon as the context. This way, your local user credentials and vpn's etc can be used to access private repositories. +If a file named ``.dockerignore`` exists in the root of ``PATH`` then it is +interpreted as a newline-separated list of exclusion patterns. Exclusion +patterns match files or directories relative to ``PATH`` that will be excluded +from the context. Globbing is done using Go's +[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. + See also: [*Dockerfile Reference*](/reference/builder/#dockerbuilder). @@ -266,6 +272,30 @@ If you wish to keep the intermediate containers after the build is complete, you must use `--rm=false`. This does not affect the build cache. + $ docker build . + Uploading context 18.829 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello World + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + $ echo ".git" > .dockerignore + $ docker build . + Uploading context 6.76 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello World + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + +This example shows the use of the ``.dockerignore`` file to exclude the ``.git`` +directory the context. Its effect can be seen in the changed size of the +uploaded context. + $ sudo docker build -t vieux/apache:2.0 . This will build like the previous example, but it will then tag the diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 6086258d10..2f2f2b6e0c 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -1514,3 +1514,53 @@ docker.com>" logDone("build - validate escaping whitespace") } + +func TestDockerignore(t *testing.T) { + name := "testbuilddockerignore" + defer deleteImages(name) + dockerfile := ` + FROM busybox + ADD . /bla + RUN [[ -f /bla/src/x.go ]] + RUN [[ -f /bla/Makefile ]] + RUN [[ ! -e /bla/src/_vendor ]] + RUN [[ ! -e /bla/.gitignore ]] + RUN [[ ! -e /bla/README.md ]] + RUN [[ ! -e /bla/.git ]]` + ctx, err := fakeContext(dockerfile, map[string]string{ + "Makefile": "all:", + ".git/HEAD": "ref: foo", + "src/x.go": "package main", + "src/_vendor/v.go": "package main", + ".gitignore": "", + "README.md": "readme", + ".dockerignore": ".git\npkg\n.gitignore\nsrc/_vendor\n*.md", + }) + defer ctx.Close() + if err != nil { + t.Fatal(err) + } + if _, err := buildImageFromContext(name, ctx, true); err != nil { + t.Fatal(err) + } + logDone("build - test .dockerignore") +} + +func TestDockerignoringDockerfile(t *testing.T) { + name := "testbuilddockerignoredockerfile" + defer deleteImages(name) + dockerfile := ` + FROM scratch` + ctx, err := fakeContext(dockerfile, map[string]string{ + "Dockerfile": "FROM scratch", + ".dockerignore": "Dockerfile\n", + }) + defer ctx.Close() + if err != nil { + t.Fatal(err) + } + if _, err = buildImageFromContext(name, ctx, true); err == nil { + t.Fatalf("Didn't get expected error from ignoring Dockerfile") + } + logDone("build - test .dockerignore of Dockerfile") +} -- cgit v1.2.1 From 42ca8a064b0e315c983997dbdb2560c40397eb0e Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 20 Jun 2014 23:08:27 +0000 Subject: add @tianon as maintainer of .dockerignore Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 059ff79f09..2947eb355e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6,3 +6,4 @@ Michael Crosby (@crosbymichael) AUTHORS: Tianon Gravi (@tianon) Dockerfile: Tianon Gravi (@tianon) Makefile: Tianon Gravi (@tianon) +.dockerignore: Tianon Gravi (@tianon) -- cgit v1.2.1 From 0098360726e3df99e8f76dce9221a85dd89c2065 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 26 Jun 2014 02:12:18 +0000 Subject: abort on error and fix debug Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/client/commands.go | 5 +++-- archive/archive.go | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index c386e7a09c..61ef426387 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -167,8 +167,9 @@ func (cli *DockerCli) CmdBuild(args ...string) error { options := &archive.TarOptions{ Compression: archive.Uncompressed, } - ignoreFile := path.Join(root, ".dockerignore") - if ignore, err := ioutil.ReadFile(ignoreFile); err == nil { + if ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore")); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("Error reading .dockerignore: '%s'", err) + } else if err == nil { for _, pattern := range strings.Split(string(ignore), "\n") { ok, err := filepath.Match(pattern, "Dockerfile") if err != nil { diff --git a/archive/archive.go b/archive/archive.go index 65a5b495eb..b9701b58af 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -343,11 +343,11 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) for _, exclude := range options.Excludes { matched, err := filepath.Match(exclude, relFilePath) if err != nil { - utils.Errorf("Error matching: %s (pattern: %s)\n", relFilePath, exclude) + utils.Errorf("Error matching: %s (pattern: %s)", relFilePath, exclude) return err } if matched { - utils.Debugf("Skipping excluded path: %s\n", relFilePath) + utils.Debugf("Skipping excluded path: %s", relFilePath) if f.IsDir() { return filepath.SkipDir } -- cgit v1.2.1 From 8162dc031246c55e34530d2b35ff7087f143d1c2 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 26 Jun 2014 22:51:47 +0000 Subject: fix rebase Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- archive/archive_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archive/archive_test.go b/archive/archive_test.go index b9051fe6ae..e05cd72e49 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -177,7 +177,7 @@ func TestTarUntarFile(t *testing.T) { t.Fatal(err) } - tar, err := TarFilter(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) + tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) if err != nil { t.Fatal(err) } -- cgit v1.2.1 From 250b0d070c7d8fce3d75bafc02c31ab3e356ba2e Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 26 Jun 2014 23:36:29 +0000 Subject: add doc Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- docs/sources/reference/api/docker_remote_api.md | 5 +++++ docs/sources/reference/api/docker_remote_api_v1.13.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/sources/reference/api/docker_remote_api.md b/docs/sources/reference/api/docker_remote_api.md index b623167c4a..ff337b379a 100644 --- a/docs/sources/reference/api/docker_remote_api.md +++ b/docs/sources/reference/api/docker_remote_api.md @@ -34,6 +34,11 @@ You can still call an old version of the API using ### What's new +`GET /containers/(name)/json` + +**New!** +The `HostConfig.Links` field is now filled correctly + **New!** `Sockets` parameter added to the `/info` endpoint listing all the sockets the daemon is configured to listen on. diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md index e92b130faa..286c7e1852 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.13.md +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -240,7 +240,7 @@ Return low-level information on the container `id` } ] }, - "Links": null, + "Links": ["/name:alias"], "PublishAllPorts": false } } -- cgit v1.2.1 From 41e75232914df5f5075d5d04cc2891fee9417067 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 26 Jun 2014 15:18:50 -0700 Subject: Update libcontainer to 53cfe0a1eba9145bf5329abbb52 Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- hack/vendor.sh | 2 +- .../src/github.com/docker/libcontainer/README.md | 41 +++-- vendor/src/github.com/docker/libcontainer/api.go | 23 +++ .../docker/libcontainer/cgroups/fs/notify_linux.go | 82 +++++++++ .../libcontainer/cgroups/fs/notify_linux_test.go | 86 +++++++++ .../github.com/docker/libcontainer/container.go | 17 +- .../docker/libcontainer/container_test.go | 52 +++++- .../github.com/docker/libcontainer/mount/init.go | 4 +- .../github.com/docker/libcontainer/mount/types.go | 1 + .../docker/libcontainer/namespaces/exec.go | 49 +++-- .../docker/libcontainer/namespaces/execin.go | 8 +- .../docker/libcontainer/namespaces/init.go | 30 ++-- .../docker/libcontainer/namespaces/pid.go | 28 --- .../docker/libcontainer/namespaces/sync_pipe.go | 60 +++++-- .../libcontainer/namespaces/sync_pipe_linux.go | 20 +++ .../libcontainer/namespaces/sync_pipe_test.go | 61 +++++++ .../docker/libcontainer/network/loopback.go | 4 +- .../docker/libcontainer/network/netns.go | 13 +- .../docker/libcontainer/network/stats.go | 68 +++++++ .../docker/libcontainer/network/strategy.go | 4 +- .../docker/libcontainer/network/types.go | 11 ++ .../github.com/docker/libcontainer/network/veth.go | 18 +- .../github.com/docker/libcontainer/nsinit/exec.go | 11 +- .../github.com/docker/libcontainer/nsinit/stats.go | 12 +- .../github.com/docker/libcontainer/nsinit/utils.go | 16 -- .../libcontainer/sample_configs/apparmor.json | 196 ++++++++++++++++++++ .../sample_configs/attach_to_bridge.json | 6 +- .../libcontainer/sample_configs/minimal.json | 6 +- .../libcontainer/sample_configs/selinux.json | 197 +++++++++++++++++++++ vendor/src/github.com/docker/libcontainer/state.go | 55 ++++++ vendor/src/github.com/docker/libcontainer/types.go | 11 ++ 31 files changed, 1026 insertions(+), 166 deletions(-) create mode 100644 vendor/src/github.com/docker/libcontainer/api.go create mode 100644 vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux.go create mode 100644 vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux_test.go delete mode 100644 vendor/src/github.com/docker/libcontainer/namespaces/pid.go create mode 100644 vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_linux.go create mode 100644 vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_test.go create mode 100644 vendor/src/github.com/docker/libcontainer/network/stats.go create mode 100644 vendor/src/github.com/docker/libcontainer/sample_configs/apparmor.json create mode 100644 vendor/src/github.com/docker/libcontainer/sample_configs/selinux.json create mode 100644 vendor/src/github.com/docker/libcontainer/state.go create mode 100644 vendor/src/github.com/docker/libcontainer/types.go diff --git a/hack/vendor.sh b/hack/vendor.sh index 630998e206..b17ea0b3ab 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -63,4 +63,4 @@ mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar clone git github.com/godbus/dbus v1 clone git github.com/coreos/go-systemd v2 -clone git github.com/docker/libcontainer 5210a236b92a8022a673108f3471fed0a046bd05 +clone git github.com/docker/libcontainer 53cfe0a1eba9145bf5329abbb52b0072ccab8a00 diff --git a/vendor/src/github.com/docker/libcontainer/README.md b/vendor/src/github.com/docker/libcontainer/README.md index e4cf36f37a..ee14a57ce1 100644 --- a/vendor/src/github.com/docker/libcontainer/README.md +++ b/vendor/src/github.com/docker/libcontainer/README.md @@ -6,39 +6,44 @@ Please bear with us while we work on making the libcontainer API stable and some #### 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. +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 directory that is able to run one or more processes without -affecting the host system. The directory is usually a full system tree. Inside the directory -a `container.json` file is placed with the runtime configuration for how the processes -should be contained and run. Environment, networking, and different capabilities for the -process are specified in this file. The configuration is used for each process executed inside the 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. -See the `sample_configs` folder for examples of what the container configuration should look like. -Using this configuration and the current directory holding the rootfs for a process, one can use libcontainer to exec the container. Running the life of the namespace, a `pid` file -is written to the current directory with the pid of the namespaced process to the external world. A client can use this pid to wait, kill, or perform other operation with the container. If a user tries to run a new process inside an existing container with a live namespace, the namespace will be joined by the new process. +#### Configuration + +A container is initially configured by supplying configuration data when the container is created. -You may also specify an alternate root place where the `container.json` file is read and where the `pid` file will be saved. #### nsinit -`nsinit` is a cli application used as the reference implementation of libcontainer. It is able to -spawn or join new containers giving the current directory. To use `nsinit` cd into a Linux -rootfs and copy a `container.json` file into the directory with your specified configuration. +`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: +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 just run the exact same command again to get another bash shell or change the command. If the original process dies, PID 1, all other processes spawned inside the container will also be killed and the namespace will be removed. +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. -You can identify if a process is running in a container by looking to see if `pid` is in the root of the directory. #### Future See the [roadmap](ROADMAP.md). diff --git a/vendor/src/github.com/docker/libcontainer/api.go b/vendor/src/github.com/docker/libcontainer/api.go new file mode 100644 index 0000000000..310f06e810 --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/api.go @@ -0,0 +1,23 @@ +package libcontainer + +import ( + "github.com/docker/libcontainer/cgroups/fs" + "github.com/docker/libcontainer/network" +) + +// Returns all available stats for the given container. +func GetStats(container *Config, state *State) (*ContainerStats, error) { + var containerStats ContainerStats + stats, err := fs.GetStats(container.Cgroups) + if err != nil { + return &containerStats, err + } + containerStats.CgroupStats = stats + networkStats, err := network.GetStats(&state.NetworkState) + if err != nil { + return &containerStats, err + } + containerStats.NetworkStats = networkStats + + return &containerStats, nil +} diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux.go new file mode 100644 index 0000000000..d92063bade --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux.go @@ -0,0 +1,82 @@ +// +build linux + +package fs + +import ( + "fmt" + "os" + "path/filepath" + "syscall" + + "github.com/docker/libcontainer/cgroups" +) + +// NotifyOnOOM sends signals on the returned channel when the cgroup reaches +// its memory limit. The channel is closed when the cgroup is removed. +func NotifyOnOOM(c *cgroups.Cgroup) (<-chan struct{}, error) { + d, err := getCgroupData(c, 0) + if err != nil { + return nil, err + } + + return notifyOnOOM(d) +} + +func notifyOnOOM(d *data) (<-chan struct{}, error) { + dir, err := d.path("memory") + 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") + + oomControl, err := os.Open(filepath.Join(dir, "memory.oom_control")) + if err != nil { + eventfd.Close() + return nil, err + } + + var ( + eventControlPath = filepath.Join(dir, "cgroup.event_control") + data = fmt.Sprintf("%d %d", eventfd.Fd(), oomControl.Fd()) + ) + + if err := writeFile(dir, "cgroup.event_control", data); 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/vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux_test.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux_test.go new file mode 100644 index 0000000000..a11880cb66 --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/notify_linux_test.go @@ -0,0 +1,86 @@ +// +build linux + +package fs + +import ( + "encoding/binary" + "fmt" + "syscall" + "testing" + "time" +) + +func TestNotifyOnOOM(t *testing.T) { + helper := NewCgroupTestUtil("memory", t) + defer helper.cleanup() + + helper.writeFileContents(map[string]string{ + "memory.oom_control": "", + "cgroup.event_control": "", + }) + + var eventFd, oomControlFd int + + ooms, err := notifyOnOOM(helper.CgroupData) + if err != nil { + t.Fatal("expected no error, got:", err) + } + + memoryPath, _ := helper.CgroupData.path("memory") + data, err := readFile(memoryPath, "cgroup.event_control") + if err != nil { + t.Fatal("couldn't read event control file:", err) + } + + if _, err := fmt.Sscanf(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. + helper.cleanup() + 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/vendor/src/github.com/docker/libcontainer/container.go b/vendor/src/github.com/docker/libcontainer/container.go index 95be4f9ec9..8fe95c24f7 100644 --- a/vendor/src/github.com/docker/libcontainer/container.go +++ b/vendor/src/github.com/docker/libcontainer/container.go @@ -51,12 +51,17 @@ type Config struct { // placed into to limit the resources the container has available Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"` - // Context is a generic key value format that allows for additional settings to be passed - // on the container's creation - // This is commonly used to specify apparmor profiles, selinux labels, and different restrictions - // placed on the container's processes - // TODO(vishh): Avoid overloading this field with params for different subsystems. Strongtype this. - Context map[string]string `json:"context,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"` } // Routes can be specified to create entries in the route table as the container is started diff --git a/vendor/src/github.com/docker/libcontainer/container_test.go b/vendor/src/github.com/docker/libcontainer/container_test.go index e98b38febb..5981281153 100644 --- a/vendor/src/github.com/docker/libcontainer/container_test.go +++ b/vendor/src/github.com/docker/libcontainer/container_test.go @@ -3,6 +3,7 @@ package libcontainer import ( "encoding/json" "os" + "path/filepath" "testing" "github.com/docker/libcontainer/devices" @@ -32,17 +33,27 @@ func containsDevice(expected *devices.Device, values []*devices.Device) bool { return false } -func TestConfigJsonFormat(t *testing.T) { - f, err := os.Open("sample_configs/attach_to_bridge.json") +func loadConfig(name string) (*Config, error) { + f, err := os.Open(filepath.Join("sample_configs", name)) if err != nil { - t.Fatal("Unable to open container.json") + return nil, err } defer f.Close() var container *Config if err := json.NewDecoder(f).Decode(&container); err != nil { - t.Fatalf("failed to decode container config: %s", err) + 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() @@ -111,8 +122,39 @@ func TestConfigJsonFormat(t *testing.T) { for _, d := range devices.DefaultSimpleDevices { if !containsDevice(d, container.MountConfig.DeviceNodes) { - t.Logf("expected defice configuration for %s", d.Path) + 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) + } } diff --git a/vendor/src/github.com/docker/libcontainer/mount/init.go b/vendor/src/github.com/docker/libcontainer/mount/init.go index bc839e3253..34fad6dd19 100644 --- a/vendor/src/github.com/docker/libcontainer/mount/init.go +++ b/vendor/src/github.com/docker/libcontainer/mount/init.go @@ -25,8 +25,8 @@ type mount struct { data string } -// InitializeMountNamespace setups up the devices, mount points, and filesystems for use inside a -// new mount namepsace +// InitializeMountNamespace sets up the devices, mount points, and filesystems for use inside a +// new mount namespace. func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) error { var ( err error diff --git a/vendor/src/github.com/docker/libcontainer/mount/types.go b/vendor/src/github.com/docker/libcontainer/mount/types.go index 9a0083705f..a2659e582e 100644 --- a/vendor/src/github.com/docker/libcontainer/mount/types.go +++ b/vendor/src/github.com/docker/libcontainer/mount/types.go @@ -2,6 +2,7 @@ package mount import ( "errors" + "github.com/docker/libcontainer/devices" ) diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/exec.go b/vendor/src/github.com/docker/libcontainer/namespaces/exec.go index 10238536e2..0aa2bb9c7a 100644 --- a/vendor/src/github.com/docker/libcontainer/namespaces/exec.go +++ b/vendor/src/github.com/docker/libcontainer/namespaces/exec.go @@ -17,7 +17,7 @@ import ( // 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 performes setup outside of a namespace so that a container can be +// 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, term Terminal, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) { var ( @@ -32,6 +32,7 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string if err != nil { return -1, err } + defer syncPipe.Close() if container.Tty { master, console, err = system.CreateMasterAndConsole() @@ -52,16 +53,13 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string return -1, err } + // Now we passed the pipe to the child, close our side + syncPipe.CloseChild() + started, err := system.GetProcessStartTime(command.Process.Pid) if err != nil { return -1, err } - if err := WritePid(dataPath, command.Process.Pid, started); err != nil { - command.Process.Kill() - command.Wait() - return -1, err - } - defer DeletePid(dataPath) // Do this before syncing with child so that no children // can escape the cgroup @@ -75,14 +73,32 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string defer cleaner.Cleanup() } - if err := InitializeNetworking(container, command.Process.Pid, syncPipe); err != nil { + var networkState network.NetworkState + if err := InitializeNetworking(container, command.Process.Pid, syncPipe, &networkState); err != nil { + command.Process.Kill() + command.Wait() + return -1, err + } + + state := &libcontainer.State{ + InitPid: command.Process.Pid, + InitStartTime: started, + NetworkState: networkState, + } + + if err := libcontainer.SaveState(dataPath, state); err != nil { command.Process.Kill() command.Wait() return -1, err } + defer libcontainer.DeleteState(dataPath) // Sync with child - syncPipe.Close() + if err := syncPipe.ReadFromChild(); err != nil { + command.Process.Kill() + command.Wait() + return -1, err + } if startCallback != nil { startCallback() @@ -101,10 +117,10 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string // args provided // // console: the /dev/console to setup inside the container -// init: the progam executed inside the namespaces +// init: the program executed inside the namespaces // root: the path to the container json file and information -// pipe: sync pipe to syncronize the parent and child processes -// args: the arguemnts to pass to the container to run as the user's program +// 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, rootfs, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { // get our binary name from arg0 so we can always reexec ourself env := []string{ @@ -135,7 +151,7 @@ func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataP return command } -// SetupCgroups applies the cgroup restrictions to the process running in the contaienr based +// 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) (cgroups.ActiveCgroup, error) { if container.Cgroups != nil { @@ -150,18 +166,17 @@ func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgro // 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, pipe *SyncPipe) error { - context := map[string]string{} +func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *SyncPipe, 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, context); err != nil { + if err := strategy.Create((*network.Network)(config), nspid, networkState); err != nil { return err } } - return pipe.SendToChild(context) + return pipe.SendToChild(networkState) } // GetNamespaceFlags parses the container's Namespaces options to set the correct diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/execin.go b/vendor/src/github.com/docker/libcontainer/namespaces/execin.go index cd33025af7..d349282e84 100644 --- a/vendor/src/github.com/docker/libcontainer/namespaces/execin.go +++ b/vendor/src/github.com/docker/libcontainer/namespaces/execin.go @@ -13,7 +13,7 @@ import ( ) // ExecIn uses an existing pid and joins the pid's namespaces with the new command. -func ExecIn(container *libcontainer.Config, nspid int, args []string) error { +func ExecIn(container *libcontainer.Config, state *libcontainer.State, args []string) error { // TODO(vmarmol): If this gets too long, send it over a pipe to the child. // Marshall the container into JSON since it won't be available in the namespace. containerJson, err := json.Marshal(container) @@ -22,7 +22,7 @@ func ExecIn(container *libcontainer.Config, nspid int, args []string) error { } // Enter the namespace and then finish setup - finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(nspid), "--containerjson", string(containerJson), "--"} + finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(state.InitPid), "--containerjson", string(containerJson), "--"} finalArgs = append(finalArgs, args...) if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil { return err @@ -41,8 +41,8 @@ func NsEnter(container *libcontainer.Config, nspid int, args []string) error { return err } - if process_label, ok := container.Context["process_label"]; ok { - if err := label.SetProcessLabel(process_label); err != nil { + if container.ProcessLabel != "" { + if err := label.SetProcessLabel(container.ProcessLabel); err != nil { return err } } diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/init.go b/vendor/src/github.com/docker/libcontainer/namespaces/init.go index e916ca289c..53d2611b89 100644 --- a/vendor/src/github.com/docker/libcontainer/namespaces/init.go +++ b/vendor/src/github.com/docker/libcontainer/namespaces/init.go @@ -27,7 +27,13 @@ import ( // 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. -func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syncPipe *SyncPipe, args []string) error { +func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syncPipe *SyncPipe, args []string) (err error) { + defer func() { + if err != nil { + syncPipe.ReportChildError(err) + } + }() + rootfs, err := utils.ResolveRootfs(uncleanRootfs) if err != nil { return err @@ -40,12 +46,10 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn } // We always read this as it is a way to sync with the parent as well - context, err := syncPipe.ReadFromParent() + networkState, err := syncPipe.ReadFromParent() if err != nil { - syncPipe.Close() return err } - syncPipe.Close() if consolePath != "" { if err := console.OpenAndDup(consolePath); err != nil { @@ -60,7 +64,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn return fmt.Errorf("setctty %s", err) } } - if err := setupNetwork(container, context); err != nil { + if err := setupNetwork(container, networkState); err != nil { return fmt.Errorf("setup networking %s", err) } if err := setupRoute(container); err != nil { @@ -74,6 +78,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn (*mount.MountConfig)(container.MountConfig)); err != nil { return fmt.Errorf("setup mount namespace %s", err) } + if container.Hostname != "" { if err := system.Sethostname(container.Hostname); err != nil { return fmt.Errorf("sethostname %s", err) @@ -82,13 +87,16 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn runtime.LockOSThread() - if err := apparmor.ApplyProfile(container.Context["apparmor_profile"]); err != nil { - return fmt.Errorf("set apparmor profile %s: %s", container.Context["apparmor_profile"], 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.Context["process_label"]); err != nil { + + if err := label.SetProcessLabel(container.ProcessLabel); err != nil { return fmt.Errorf("set process label %s", err) } - if container.Context["restrictions"] != "" { + + // TODO: (crosbymichael) make this configurable at the Config level + if container.RestrictSys { if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus", "sys"); err != nil { return err } @@ -161,14 +169,14 @@ func SetupUser(u string) error { // 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, context map[string]string) error { +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), context) + err1 := strategy.Initialize((*network.Network)(config), networkState) if err1 != nil { return err1 } diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/pid.go b/vendor/src/github.com/docker/libcontainer/namespaces/pid.go deleted file mode 100644 index 8d97ec1463..0000000000 --- a/vendor/src/github.com/docker/libcontainer/namespaces/pid.go +++ /dev/null @@ -1,28 +0,0 @@ -package namespaces - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" -) - -// WritePid writes the namespaced processes pid to pid and it's start time -// to the path specified -func WritePid(path string, pid int, startTime string) error { - err := ioutil.WriteFile(filepath.Join(path, "pid"), []byte(fmt.Sprint(pid)), 0655) - if err != nil { - return err - } - return ioutil.WriteFile(filepath.Join(path, "start"), []byte(startTime), 0655) -} - -// DeletePid removes the pid and started file from disk when the container's process -// dies and the container is cleanly removed -func DeletePid(path string) error { - err := os.Remove(filepath.Join(path, "pid")) - if serr := os.Remove(filepath.Join(path, "start")); err == nil { - err = serr - } - return err -} diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe.go b/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe.go index 210ee5fbd6..dcb5d9749d 100644 --- a/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe.go +++ b/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe.go @@ -5,6 +5,9 @@ import ( "fmt" "io/ioutil" "os" + "syscall" + + "github.com/docker/libcontainer/network" ) // SyncPipe allows communication to and from the child processes @@ -14,24 +17,17 @@ type SyncPipe struct { parent, child *os.File } -func NewSyncPipe() (s *SyncPipe, err error) { - s = &SyncPipe{} - s.child, s.parent, err = os.Pipe() - if err != nil { - return nil, err - } - return s, nil -} - -func NewSyncPipeFromFd(parendFd, childFd uintptr) (*SyncPipe, error) { +func NewSyncPipeFromFd(parentFd, childFd uintptr) (*SyncPipe, error) { s := &SyncPipe{} - if parendFd > 0 { - s.parent = os.NewFile(parendFd, "parendPipe") + + if parentFd > 0 { + s.parent = os.NewFile(parentFd, "parentPipe") } else if childFd > 0 { s.child = os.NewFile(childFd, "childPipe") } else { return nil, fmt.Errorf("no valid sync pipe fd specified") } + return s, nil } @@ -43,36 +39,64 @@ func (s *SyncPipe) Parent() *os.File { return s.parent } -func (s *SyncPipe) SendToChild(context map[string]string) error { - data, err := json.Marshal(context) +func (s *SyncPipe) SendToChild(networkState *network.NetworkState) error { + data, err := json.Marshal(networkState) if err != nil { return err } + s.parent.Write(data) + + return syscall.Shutdown(int(s.parent.Fd()), syscall.SHUT_WR) +} + +func (s *SyncPipe) ReadFromChild() error { + data, err := ioutil.ReadAll(s.parent) + if err != nil { + return err + } + + if len(data) > 0 { + return fmt.Errorf("%s", data) + } + return nil } -func (s *SyncPipe) ReadFromParent() (map[string]string, error) { +func (s *SyncPipe) ReadFromParent() (*network.NetworkState, error) { data, err := ioutil.ReadAll(s.child) if err != nil { return nil, fmt.Errorf("error reading from sync pipe %s", err) } - var context map[string]string + var networkState *network.NetworkState if len(data) > 0 { - if err := json.Unmarshal(data, &context); err != nil { + if err := json.Unmarshal(data, &networkState); err != nil { return nil, err } } - return context, nil + return networkState, nil +} +func (s *SyncPipe) ReportChildError(err error) { + s.child.Write([]byte(err.Error())) + s.CloseChild() } func (s *SyncPipe) Close() error { if s.parent != nil { s.parent.Close() } + if s.child != nil { s.child.Close() } + return nil } + +func (s *SyncPipe) CloseChild() { + if s.child != nil { + s.child.Close() + s.child = nil + } +} diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_linux.go b/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_linux.go new file mode 100644 index 0000000000..ad61e75d29 --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_linux.go @@ -0,0 +1,20 @@ +package namespaces + +import ( + "os" + "syscall" +) + +func NewSyncPipe() (s *SyncPipe, err error) { + s = &SyncPipe{} + + fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) + if err != nil { + return nil, err + } + + s.child = os.NewFile(uintptr(fds[0]), "child syncpipe") + s.parent = os.NewFile(uintptr(fds[1]), "parent syncpipe") + + return s, nil +} diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_test.go b/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_test.go new file mode 100644 index 0000000000..69bd0abbfb --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/namespaces/sync_pipe_test.go @@ -0,0 +1,61 @@ +package namespaces + +import ( + "fmt" + "testing" + + "github.com/docker/libcontainer/network" +) + +func TestSendErrorFromChild(t *testing.T) { + pipe, err := NewSyncPipe() + if err != nil { + t.Fatal(err) + } + defer func() { + if err := pipe.Close(); err != nil { + t.Fatal(err) + } + }() + + expected := "something bad happened" + + pipe.ReportChildError(fmt.Errorf(expected)) + + childError := pipe.ReadFromChild() + if childError == nil { + t.Fatal("expected an error to be returned but did not receive anything") + } + + if childError.Error() != expected { + t.Fatalf("expected %q but received error message %q", expected, childError.Error()) + } +} + +func TestSendPayloadToChild(t *testing.T) { + pipe, err := NewSyncPipe() + if err != nil { + t.Fatal(err) + } + + defer func() { + if err := pipe.Close(); err != nil { + t.Fatal(err) + } + }() + + expected := "libcontainer" + + if err := pipe.SendToChild(&network.NetworkState{VethHost: expected}); err != nil { + t.Fatal(err) + } + + payload, err := pipe.ReadFromParent() + if err != nil { + t.Fatal(err) + } + + if payload.VethHost != expected { + t.Fatalf("expected veth host %q but received %q", expected, payload.VethHost) + } +} diff --git a/vendor/src/github.com/docker/libcontainer/network/loopback.go b/vendor/src/github.com/docker/libcontainer/network/loopback.go index 0d36c4f8c6..46a1fa8c86 100644 --- a/vendor/src/github.com/docker/libcontainer/network/loopback.go +++ b/vendor/src/github.com/docker/libcontainer/network/loopback.go @@ -10,11 +10,11 @@ import ( type Loopback struct { } -func (l *Loopback) Create(n *Network, nspid int, context map[string]string) error { +func (l *Loopback) Create(n *Network, nspid int, networkState *NetworkState) error { return nil } -func (l *Loopback) Initialize(config *Network, context map[string]string) error { +func (l *Loopback) Initialize(config *Network, networkState *NetworkState) error { if err := SetMtu("lo", config.Mtu); err != nil { return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err) } diff --git a/vendor/src/github.com/docker/libcontainer/network/netns.go b/vendor/src/github.com/docker/libcontainer/network/netns.go index e2121cb08a..64544476b8 100644 --- a/vendor/src/github.com/docker/libcontainer/network/netns.go +++ b/vendor/src/github.com/docker/libcontainer/network/netns.go @@ -14,17 +14,16 @@ import ( type NetNS struct { } -func (v *NetNS) Create(n *Network, nspid int, context map[string]string) error { - context["nspath"] = n.NsPath +func (v *NetNS) Create(n *Network, nspid int, networkState *NetworkState) error { + networkState.NsPath = n.NsPath return nil } -func (v *NetNS) Initialize(config *Network, context map[string]string) error { - nspath, exists := context["nspath"] - if !exists { - return fmt.Errorf("nspath does not exist in network context") +func (v *NetNS) Initialize(config *Network, networkState *NetworkState) error { + if networkState.NsPath == "" { + return fmt.Errorf("nspath does is not specified in NetworkState") } - f, err := os.OpenFile(nspath, os.O_RDONLY, 0) + f, err := os.OpenFile(networkState.NsPath, os.O_RDONLY, 0) if err != nil { return fmt.Errorf("failed get network namespace fd: %v", err) } diff --git a/vendor/src/github.com/docker/libcontainer/network/stats.go b/vendor/src/github.com/docker/libcontainer/network/stats.go new file mode 100644 index 0000000000..b69fa91851 --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/network/stats.go @@ -0,0 +1,68 @@ +package network + +import ( + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" +) + +type NetworkStats struct { + RxBytes uint64 `json:"rx_bytes,omitempty"` + RxPackets uint64 `json:"rx_packets,omitempty"` + RxErrors uint64 `json:"rx_errors,omitempty"` + RxDropped uint64 `json:"rx_dropped,omitempty"` + TxBytes uint64 `json:"tx_bytes,omitempty"` + TxPackets uint64 `json:"tx_packets,omitempty"` + TxErrors uint64 `json:"tx_errors,omitempty"` + TxDropped uint64 `json:"tx_dropped,omitempty"` +} + +// 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 + } + data, err := readSysfsNetworkStats(networkState.VethHost) + if err != nil { + return NetworkStats{}, err + } + + return NetworkStats{ + RxBytes: data["rx_bytes"], + RxPackets: data["rx_packets"], + RxErrors: data["rx_errors"], + RxDropped: data["rx_dropped"], + TxBytes: data["tx_bytes"], + TxPackets: data["tx_packets"], + TxErrors: data["tx_errors"], + TxDropped: data["tx_dropped"], + }, nil +} + +// Reads all the statistics available under /sys/class/net//statistics as a map with file name as key and data as integers. +func readSysfsNetworkStats(ethInterface string) (map[string]uint64, error) { + out := make(map[string]uint64) + + fullPath := filepath.Join("/sys/class/net", ethInterface, "statistics/") + err := filepath.Walk(fullPath, func(path string, _ os.FileInfo, _ error) error { + // skip fullPath. + if path == fullPath { + return nil + } + base := filepath.Base(path) + data, err := ioutil.ReadFile(path) + if err != nil { + return err + } + value, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) + if err != nil { + return err + } + out[base] = value + return nil + }) + return out, err +} diff --git a/vendor/src/github.com/docker/libcontainer/network/strategy.go b/vendor/src/github.com/docker/libcontainer/network/strategy.go index 358fb4152b..be5ec93b71 100644 --- a/vendor/src/github.com/docker/libcontainer/network/strategy.go +++ b/vendor/src/github.com/docker/libcontainer/network/strategy.go @@ -19,8 +19,8 @@ var strategies = map[string]NetworkStrategy{ // NetworkStrategy represents a specific network configuration for // a container's networking stack type NetworkStrategy interface { - Create(*Network, int, map[string]string) error - Initialize(*Network, map[string]string) error + Create(*Network, int, *NetworkState) error + Initialize(*Network, *NetworkState) error } // GetStrategy returns the specific network strategy for the diff --git a/vendor/src/github.com/docker/libcontainer/network/types.go b/vendor/src/github.com/docker/libcontainer/network/types.go index 14463ab712..0f1df30e85 100644 --- a/vendor/src/github.com/docker/libcontainer/network/types.go +++ b/vendor/src/github.com/docker/libcontainer/network/types.go @@ -27,3 +27,14 @@ type Network struct { // container's interfaces if a pair is created, specifically in the case of type veth Mtu int `json:"mtu,omitempty"` } + +// 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"` + // Net namespace path. + NsPath string `json:"ns_path,omitempty"` +} diff --git a/vendor/src/github.com/docker/libcontainer/network/veth.go b/vendor/src/github.com/docker/libcontainer/network/veth.go index 20bc9e5067..fcafd85ccf 100644 --- a/vendor/src/github.com/docker/libcontainer/network/veth.go +++ b/vendor/src/github.com/docker/libcontainer/network/veth.go @@ -16,7 +16,7 @@ type Veth struct { const defaultDevice = "eth0" -func (v *Veth) Create(n *Network, nspid int, context map[string]string) error { +func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error { var ( bridge = n.Bridge prefix = n.VethPrefix @@ -31,8 +31,6 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string) error { if err != nil { return err } - context["veth-host"] = name1 - context["veth-child"] = name2 if err := SetInterfaceMaster(name1, bridge); err != nil { return err } @@ -45,16 +43,16 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string) error { if err := SetInterfaceInNamespacePid(name2, nspid); err != nil { return err } + networkState.VethHost = name1 + networkState.VethChild = name2 + return nil } -func (v *Veth) Initialize(config *Network, context map[string]string) error { - var ( - vethChild string - exists bool - ) - if vethChild, exists = context["veth-child"]; !exists { - return fmt.Errorf("vethChild does not exist in network context") +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) diff --git a/vendor/src/github.com/docker/libcontainer/nsinit/exec.go b/vendor/src/github.com/docker/libcontainer/nsinit/exec.go index deaf963fdf..c58c30664e 100644 --- a/vendor/src/github.com/docker/libcontainer/nsinit/exec.go +++ b/vendor/src/github.com/docker/libcontainer/nsinit/exec.go @@ -19,19 +19,20 @@ var execCommand = cli.Command{ } func execAction(context *cli.Context) { - var nspid, exitCode int + var exitCode int container, err := loadContainer() if err != nil { log.Fatal(err) } - if nspid, err = readPid(); err != nil && !os.IsNotExist(err) { - log.Fatalf("unable to read pid: %s", err) + state, err := libcontainer.GetState(dataPath) + if err != nil && !os.IsNotExist(err) { + log.Fatalf("unable to read state.json: %s", err) } - if nspid > 0 { - err = namespaces.ExecIn(container, nspid, []string(context.Args())) + if state != nil { + err = namespaces.ExecIn(container, state, []string(context.Args())) } else { term := namespaces.NewTerminal(os.Stdin, os.Stdout, os.Stderr, container.Tty) exitCode, err = startContainer(container, term, dataPath, []string(context.Args())) diff --git a/vendor/src/github.com/docker/libcontainer/nsinit/stats.go b/vendor/src/github.com/docker/libcontainer/nsinit/stats.go index 41301bedfa..eae9833808 100644 --- a/vendor/src/github.com/docker/libcontainer/nsinit/stats.go +++ b/vendor/src/github.com/docker/libcontainer/nsinit/stats.go @@ -7,7 +7,6 @@ import ( "github.com/codegangsta/cli" "github.com/docker/libcontainer" - "github.com/docker/libcontainer/cgroups/fs" ) var statsCommand = cli.Command{ @@ -22,7 +21,12 @@ func statsAction(context *cli.Context) { log.Fatal(err) } - stats, err := getContainerStats(container) + runtimeCkpt, err := libcontainer.GetState(dataPath) + if err != nil { + log.Fatal(err) + } + + stats, err := getStats(container, runtimeCkpt) if err != nil { log.Fatalf("Failed to get stats - %v\n", err) } @@ -31,8 +35,8 @@ func statsAction(context *cli.Context) { } // returns the container stats in json format. -func getContainerStats(container *libcontainer.Config) (string, error) { - stats, err := fs.GetStats(container.Cgroups) +func getStats(container *libcontainer.Config, state *libcontainer.State) (string, error) { + stats, err := libcontainer.GetStats(container, state) if err != nil { return "", err } diff --git a/vendor/src/github.com/docker/libcontainer/nsinit/utils.go b/vendor/src/github.com/docker/libcontainer/nsinit/utils.go index fb672521f0..44194d885b 100644 --- a/vendor/src/github.com/docker/libcontainer/nsinit/utils.go +++ b/vendor/src/github.com/docker/libcontainer/nsinit/utils.go @@ -2,11 +2,9 @@ package main import ( "encoding/json" - "io/ioutil" "log" "os" "path/filepath" - "strconv" "github.com/docker/libcontainer" ) @@ -26,20 +24,6 @@ func loadContainer() (*libcontainer.Config, error) { return container, nil } -func readPid() (int, error) { - data, err := ioutil.ReadFile(filepath.Join(dataPath, "pid")) - if err != nil { - return -1, err - } - - pid, err := strconv.Atoi(string(data)) - if err != nil { - return -1, err - } - - return pid, nil -} - func openLog(name string) error { f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0755) if err != nil { diff --git a/vendor/src/github.com/docker/libcontainer/sample_configs/apparmor.json b/vendor/src/github.com/docker/libcontainer/sample_configs/apparmor.json new file mode 100644 index 0000000000..f739df1006 --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/sample_configs/apparmor.json @@ -0,0 +1,196 @@ +{ + "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": { + "NEWIPC": true, + "NEWNET": true, + "NEWNS": true, + "NEWPID": true, + "NEWUTS": true + }, + "networks": [ + { + "address": "127.0.0.1/0", + "gateway": "localhost", + "mtu": 1500, + "type": "loopback" + } + ], + "tty": true, + "user": "daemon" +} diff --git a/vendor/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json b/vendor/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json index 9b1e627d94..0795e6c143 100644 --- a/vendor/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json +++ b/vendor/src/github.com/docker/libcontainer/sample_configs/attach_to_bridge.json @@ -116,11 +116,7 @@ "name": "docker-koye", "parent": "docker" }, - "context": { - "mount_label": "", - "process_label": "", - "restrictions": "true" - }, + "restrict_sys": true, "mount_config": { "device_nodes": [ { diff --git a/vendor/src/github.com/docker/libcontainer/sample_configs/minimal.json b/vendor/src/github.com/docker/libcontainer/sample_configs/minimal.json index 3e1a01ad0e..c08c996797 100644 --- a/vendor/src/github.com/docker/libcontainer/sample_configs/minimal.json +++ b/vendor/src/github.com/docker/libcontainer/sample_configs/minimal.json @@ -116,11 +116,7 @@ "name": "docker-koye", "parent": "docker" }, - "context": { - "mount_label": "", - "process_label": "", - "restrictions": "true" - }, + "restrict_sys": true, "mount_config": { "device_nodes": [ { diff --git a/vendor/src/github.com/docker/libcontainer/sample_configs/selinux.json b/vendor/src/github.com/docker/libcontainer/sample_configs/selinux.json new file mode 100644 index 0000000000..ce383e2cc2 --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/sample_configs/selinux.json @@ -0,0 +1,197 @@ +{ + "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": { + "NEWIPC": true, + "NEWNET": true, + "NEWNS": true, + "NEWPID": true, + "NEWUTS": true + }, + "networks": [ + { + "address": "127.0.0.1/0", + "gateway": "localhost", + "mtu": 1500, + "type": "loopback" + } + ], + "tty": true, + "user": "daemon" +} diff --git a/vendor/src/github.com/docker/libcontainer/state.go b/vendor/src/github.com/docker/libcontainer/state.go new file mode 100644 index 0000000000..a055bb0ffe --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/state.go @@ -0,0 +1,55 @@ +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"` +} + +// The name of the runtime state file +const stateFile = "state.json" + +// 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/vendor/src/github.com/docker/libcontainer/types.go b/vendor/src/github.com/docker/libcontainer/types.go new file mode 100644 index 0000000000..5095dca66a --- /dev/null +++ b/vendor/src/github.com/docker/libcontainer/types.go @@ -0,0 +1,11 @@ +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"` +} -- cgit v1.2.1 From c9fdb08bdafb90b76cfa804b079d2e446a3503e4 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 26 Jun 2014 12:23:53 -0700 Subject: Update libcontainer Context changes Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- daemon/execdriver/native/configuration/parse.go | 2 +- daemon/execdriver/native/configuration/parse_test.go | 5 +++-- daemon/execdriver/native/create.go | 10 +++++----- daemon/execdriver/native/template/default_template.go | 3 +-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/daemon/execdriver/native/configuration/parse.go b/daemon/execdriver/native/configuration/parse.go index a923f2a3c8..8fb1b452b9 100644 --- a/daemon/execdriver/native/configuration/parse.go +++ b/daemon/execdriver/native/configuration/parse.go @@ -54,7 +54,7 @@ func systemdSlice(container *libcontainer.Config, context interface{}, value str } func apparmorProfile(container *libcontainer.Config, context interface{}, value string) error { - container.Context["apparmor_profile"] = value + container.AppArmorProfile = value return nil } diff --git a/daemon/execdriver/native/configuration/parse_test.go b/daemon/execdriver/native/configuration/parse_test.go index 886a42cf8b..0401d7b37e 100644 --- a/daemon/execdriver/native/configuration/parse_test.go +++ b/daemon/execdriver/native/configuration/parse_test.go @@ -84,8 +84,9 @@ func TestAppArmorProfile(t *testing.T) { if err := ParseConfiguration(container, nil, opts); err != nil { t.Fatal(err) } - if expected := "koye-the-protector"; container.Context["apparmor_profile"] != expected { - t.Fatalf("expected profile %s got %s", expected, container.Context["apparmor_profile"]) + + if expected := "koye-the-protector"; container.AppArmorProfile != expected { + t.Fatalf("expected profile %s got %s", expected, container.AppArmorProfile) } } diff --git a/daemon/execdriver/native/create.go b/daemon/execdriver/native/create.go index e577bd2b87..f28507b046 100644 --- a/daemon/execdriver/native/create.go +++ b/daemon/execdriver/native/create.go @@ -32,7 +32,7 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, e // check to see if we are running in ramdisk to disable pivot root container.MountConfig.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != "" - container.Context["restrictions"] = "true" + container.RestrictSys = true if err := d.createNetwork(container, c); err != nil { return nil, err @@ -127,10 +127,10 @@ func (d *driver) setPrivileged(container *libcontainer.Config) (err error) { } container.MountConfig.DeviceNodes = hostDeviceNodes - delete(container.Context, "restrictions") + container.RestrictSys = false if apparmor.IsEnabled() { - container.Context["apparmor_profile"] = "unconfined" + container.AppArmorProfile = "unconfined" } return nil @@ -163,8 +163,8 @@ func (d *driver) setupMounts(container *libcontainer.Config, c *execdriver.Comma } func (d *driver) setupLabels(container *libcontainer.Config, c *execdriver.Command) error { - container.Context["process_label"] = c.Config["process_label"][0] - container.Context["mount_label"] = c.Config["mount_label"][0] + container.ProcessLabel = c.Config["process_label"][0] + container.MountConfig.MountLabel = c.Config["mount_label"][0] return nil } diff --git a/daemon/execdriver/native/template/default_template.go b/daemon/execdriver/native/template/default_template.go index 5dbcbb5589..d0894a0c9f 100644 --- a/daemon/execdriver/native/template/default_template.go +++ b/daemon/execdriver/native/template/default_template.go @@ -35,11 +35,10 @@ func New() *libcontainer.Config { AllowAllDevices: false, }, MountConfig: &libcontainer.MountConfig{}, - Context: make(map[string]string), } if apparmor.IsEnabled() { - container.Context["apparmor_profile"] = "docker-default" + container.AppArmorProfile = "docker-default" } return container -- cgit v1.2.1 From 012091a28f8c2a96ad937f8c84992687e804ab71 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 26 Jun 2014 17:09:41 -0700 Subject: Fix sleep command in tests Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- integration-cli/docker_cli_diff_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_diff_test.go b/integration-cli/docker_cli_diff_test.go index 478ebd2df1..416f9421b7 100644 --- a/integration-cli/docker_cli_diff_test.go +++ b/integration-cli/docker_cli_diff_test.go @@ -66,7 +66,7 @@ func TestDiffEnsureDockerinitFilesAreIgnored(t *testing.T) { } func TestDiffEnsureOnlyKmsgAndPtmx(t *testing.T) { - runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sleep 0") + runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sleep", "0") cid, _, err := runCommandWithOutput(runCmd) errorOut(err, t, fmt.Sprintf("%s", err)) cleanCID := stripTrailingCharacters(cid) -- cgit v1.2.1 From e817681581f433b37a8ab214a73edf5fb2a35473 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Fri, 27 Jun 2014 11:10:20 +1000 Subject: Yes, ok, not-Sam Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/sources/docker-hub/accounts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/docker-hub/accounts.md b/docs/sources/docker-hub/accounts.md index 7e951448d3..304010fb5a 100644 --- a/docs/sources/docker-hub/accounts.md +++ b/docs/sources/docker-hub/accounts.md @@ -36,8 +36,8 @@ page. Also available on the Docker Hub are organizations and groups that allow you to collaborate across your organization or team. You can see what -organizations [you belong to and add new organizations](Sam Alba -) from the Account +organizations [you belong to and add new organizations]( +https://hub.docker.com/account/organizations/) from the Account tab. ![organizations](/docker-hub/orgs.png) -- cgit v1.2.1 From 748aaf3530b943449d61952e06eb9aeab4a455ac Mon Sep 17 00:00:00 2001 From: Paul Weaver Date: Thu, 26 Jun 2014 11:49:29 +0100 Subject: Remove superfluous reptition from usingdocker.md Clarify wording about default docker ps options Fix typo in dockerlinks.md Docker-DCO-1.1-Signed-off-by: Paul Weaver (github: ch3pjw) --- docs/sources/userguide/dockerlinks.md | 2 +- docs/sources/userguide/usingdocker.md | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/sources/userguide/dockerlinks.md b/docs/sources/userguide/dockerlinks.md index d928cc1401..711fd979c8 100644 --- a/docs/sources/userguide/dockerlinks.md +++ b/docs/sources/userguide/dockerlinks.md @@ -192,7 +192,7 @@ command to list the container's environment variables. > will scrub them when spawning shells for connection. We can see that Docker has created a series of environment variables with -useful information about our `db` container. Each variables is prefixed with +useful information about our `db` container. Each variable is prefixed with `DB_` which is populated from the `alias` we specified above. If our `alias` were `db1` the variables would be prefixed with `DB1_`. You can use these environment variables to configure your applications to connect to the database diff --git a/docs/sources/userguide/usingdocker.md b/docs/sources/userguide/usingdocker.md index 54c094bfa9..c1f524f89a 100644 --- a/docs/sources/userguide/usingdocker.md +++ b/docs/sources/userguide/usingdocker.md @@ -87,11 +87,6 @@ This will display the help text and all available flags: --no-stdin=false: Do not attach stdin --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode) - -None of the containers we've run did anything particularly useful -though. So let's build on that experience by running an example web -application in Docker. - > **Note:** > You can see a full list of Docker's commands > [here](/reference/commandline/cli/). @@ -140,8 +135,8 @@ command. This tells the `docker ps` command to return the details of the *last* container started. > **Note:** -> The `docker ps` command only shows running containers. If you want to -> see stopped containers too use the `-a` flag. +> By default, the `docker ps` command only shows information about running +> containers. If you want to see stopped containers too use the `-a` flag. We can see the same details we saw [when we first Dockerized a container](/userguide/dockerizing) with one important addition in the `PORTS` -- cgit v1.2.1 From d14cfc8d435dbef0d70b6444b275a025e60ac171 Mon Sep 17 00:00:00 2001 From: Jonathan Boulle Date: Fri, 16 May 2014 16:40:27 -0700 Subject: sort flags with the same name in a consistent order Docker-DCO-1.1-Signed-off-by: Jonathan Boulle (github: jonboulle) --- pkg/mflag/flag.go | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/pkg/mflag/flag.go b/pkg/mflag/flag.go index ad23e540fb..52f786e451 100644 --- a/pkg/mflag/flag.go +++ b/pkg/mflag/flag.go @@ -305,12 +305,10 @@ type flagSlice []string func (p flagSlice) Len() int { return len(p) } func (p flagSlice) Less(i, j int) bool { - pi, pj := strings.ToLower(p[i]), strings.ToLower(p[j]) - if pi[0] == '-' { - pi = pi[1:] - } - if pj[0] == '-' { - pj = pj[1:] + pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-") + lpi, lpj := strings.ToLower(pi), strings.ToLower(pj) + if lpi != lpj { + return lpi < lpj } return pi < pj } @@ -443,8 +441,6 @@ func (f *FlagSet) PrintDefaults() { } fmt.Fprintln(writer, "\t", line) } - // start := fmt.Sprintf(format, strings.Join(names, ", -"), flag.DefValue) - // fmt.Fprintln(f.out(), start, strings.Replace(flag.Usage, "\n", "\n"+strings.Repeat(" ", len(start)+1), -1)) } }) writer.Flush() @@ -833,14 +829,12 @@ func (f *FlagSet) parseOne() (bool, string, error) { f.args = f.args[1:] has_value := false value := "" - for i := 1; i < len(name); i++ { // equals cannot be first - if name[i] == '=' { - value = trimQuotes(name[i+1:]) - has_value = true - name = name[0:i] - break - } + if i := strings.Index(name, "="); i != -1 { + value = trimQuotes(name[i+1:]) + has_value = true + name = name[:i] } + m := f.formal flag, alreadythere := m[name] // BUG if !alreadythere { -- cgit v1.2.1 From 15ea1ca1f0d5190645b2ec0c0971daa3cdee30df Mon Sep 17 00:00:00 2001 From: leeplay Date: Fri, 27 Jun 2014 11:39:58 +0900 Subject: Update nodejs_web_app.md Docker-DCO-1.1-Signed-off-by: Hyeongkyu Lee (github: leeplay) --- docs/sources/examples/nodejs_web_app.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/examples/nodejs_web_app.md b/docs/sources/examples/nodejs_web_app.md index cc3ea061af..5fb0300f56 100644 --- a/docs/sources/examples/nodejs_web_app.md +++ b/docs/sources/examples/nodejs_web_app.md @@ -167,8 +167,8 @@ To test your app, get the the port of your app that Docker mapped: $ sudo docker ps # Example - ID IMAGE COMMAND ... PORTS - ecce33b30ebf gasi/centos-node-hello:latest node /src/index.js 49160->8080 + ID IMAGE COMMAND ... PORTS + ecce33b30ebf /centos-node-hello:latest node /src/index.js 49160->8080 In the example above, Docker mapped the `8080` port of the container to `49160`. -- cgit v1.2.1 From 0bfa14a70aa7dda06d769c5dd55354b13b417c94 Mon Sep 17 00:00:00 2001 From: Mike Chelen Date: Fri, 27 Jun 2014 02:34:47 -0400 Subject: Update dockerizing.md fix typo --- docs/sources/userguide/dockerizing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockerizing.md b/docs/sources/userguide/dockerizing.md index afe18ce8df..ed927df08a 100644 --- a/docs/sources/userguide/dockerizing.md +++ b/docs/sources/userguide/dockerizing.md @@ -131,7 +131,7 @@ world` daemon. Firstly let's make sure our container is running. We can do that with the `docker ps` command. The `docker ps` command queries -the Docker daemon for information about all the container it knows +the Docker daemon for information about all the containers it knows about. $ sudo docker ps -- cgit v1.2.1 From 47065b904559f36e83b924007c375f2de0f31af0 Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Fri, 6 Jun 2014 15:28:12 +0400 Subject: State refactoring and add waiting functions Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- daemon/state.go | 115 ++++++++++++++++++++++++++++++++++++++++----------- daemon/state_test.go | 102 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 23 deletions(-) create mode 100644 daemon/state_test.go diff --git a/daemon/state.go b/daemon/state.go index 7ee8fc48c3..b9ef350568 100644 --- a/daemon/state.go +++ b/daemon/state.go @@ -16,6 +16,13 @@ type State struct { ExitCode int StartedAt time.Time FinishedAt time.Time + waitChan chan struct{} +} + +func NewState() *State { + return &State{ + waitChan: make(chan struct{}), + } } // String returns a human-readable description of the state @@ -35,56 +42,118 @@ func (s *State) String() string { return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt))) } +func wait(waitChan <-chan struct{}, timeout time.Duration) error { + if timeout < 0 { + <-waitChan + return nil + } + select { + case <-time.After(timeout): + return fmt.Errorf("Timed out: %v", timeout) + case <-waitChan: + return nil + } +} + +// WaitRunning waits until state is running. If state already running it returns +// immediatly. If you want wait forever you must supply negative timeout. +// Returns pid, that was passed to SetRunning +func (s *State) WaitRunning(timeout time.Duration) (int, error) { + s.RLock() + if s.IsRunning() { + pid := s.Pid + s.RUnlock() + return pid, nil + } + waitChan := s.waitChan + s.RUnlock() + if err := wait(waitChan, timeout); err != nil { + return -1, err + } + return s.GetPid(), nil +} + +// WaitStop waits until state is stopped. If state already stopped it returns +// immediatly. If you want wait forever you must supply negative timeout. +// Returns exit code, that was passed to SetRunning +func (s *State) WaitStop(timeout time.Duration) (int, error) { + s.RLock() + if !s.Running { + exitCode := s.ExitCode + s.RUnlock() + return exitCode, nil + } + waitChan := s.waitChan + s.RUnlock() + if err := wait(waitChan, timeout); err != nil { + return -1, err + } + return s.GetExitCode(), nil +} + func (s *State) IsRunning() bool { s.RLock() - defer s.RUnlock() + res := s.Running + s.RUnlock() + return res +} - return s.Running +func (s *State) GetPid() int { + s.RLock() + res := s.Pid + s.RUnlock() + return res } func (s *State) GetExitCode() int { s.RLock() - defer s.RUnlock() - - return s.ExitCode + res := s.ExitCode + s.RUnlock() + return res } func (s *State) SetRunning(pid int) { s.Lock() - defer s.Unlock() - - s.Running = true - s.Paused = false - s.ExitCode = 0 - s.Pid = pid - s.StartedAt = time.Now().UTC() + if !s.Running { + s.Running = true + s.Paused = false + s.ExitCode = 0 + s.Pid = pid + s.StartedAt = time.Now().UTC() + close(s.waitChan) // fire waiters for start + s.waitChan = make(chan struct{}) + } + s.Unlock() } func (s *State) SetStopped(exitCode int) { s.Lock() - defer s.Unlock() - - s.Running = false - s.Pid = 0 - s.FinishedAt = time.Now().UTC() - s.ExitCode = exitCode + if s.Running { + s.Running = false + s.Pid = 0 + s.FinishedAt = time.Now().UTC() + s.ExitCode = exitCode + close(s.waitChan) // fire waiters for stop + s.waitChan = make(chan struct{}) + } + s.Unlock() } func (s *State) SetPaused() { s.Lock() - defer s.Unlock() s.Paused = true + s.Unlock() } func (s *State) SetUnpaused() { s.Lock() - defer s.Unlock() s.Paused = false + s.Unlock() } func (s *State) IsPaused() bool { s.RLock() - defer s.RUnlock() - - return s.Paused + res := s.Paused + s.RUnlock() + return res } diff --git a/daemon/state_test.go b/daemon/state_test.go new file mode 100644 index 0000000000..7b02f3aeac --- /dev/null +++ b/daemon/state_test.go @@ -0,0 +1,102 @@ +package daemon + +import ( + "sync/atomic" + "testing" + "time" +) + +func TestStateRunStop(t *testing.T) { + s := NewState() + for i := 1; i < 3; i++ { // full lifecycle two times + started := make(chan struct{}) + var pid int64 + go func() { + runPid, _ := s.WaitRunning(-1 * time.Second) + atomic.StoreInt64(&pid, int64(runPid)) + close(started) + }() + s.SetRunning(i + 100) + if !s.IsRunning() { + t.Fatal("State not running") + } + if s.Pid != i+100 { + t.Fatalf("Pid %v, expected %v", s.Pid, i+100) + } + if s.ExitCode != 0 { + t.Fatalf("ExitCode %v, expected 0", s.ExitCode) + } + select { + case <-time.After(100 * time.Millisecond): + t.Fatal("Start callback doesn't fire in 100 milliseconds") + case <-started: + t.Log("Start callback fired") + } + runPid := int(atomic.LoadInt64(&pid)) + if runPid != i+100 { + t.Fatalf("Pid %v, expected %v", runPid, i+100) + } + if pid, err := s.WaitRunning(-1 * time.Second); err != nil || pid != i+100 { + t.Fatal("WaitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil) + } + + stopped := make(chan struct{}) + var exit int64 + go func() { + exitCode, _ := s.WaitStop(-1 * time.Second) + atomic.StoreInt64(&exit, int64(exitCode)) + close(stopped) + }() + s.SetStopped(i) + if s.IsRunning() { + t.Fatal("State is running") + } + if s.ExitCode != i { + t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i) + } + if s.Pid != 0 { + t.Fatalf("Pid %v, expected 0", s.Pid) + } + select { + case <-time.After(100 * time.Millisecond): + t.Fatal("Stop callback doesn't fire in 100 milliseconds") + case <-stopped: + t.Log("Stop callback fired") + } + exitCode := int(atomic.LoadInt64(&exit)) + if exitCode != i { + t.Fatalf("ExitCode %v, expected %v", exitCode, i) + } + if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i { + t.Fatal("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil) + } + } +} + +func TestStateTimeoutWait(t *testing.T) { + s := NewState() + started := make(chan struct{}) + go func() { + s.WaitRunning(100 * time.Millisecond) + close(started) + }() + select { + case <-time.After(200 * time.Millisecond): + t.Fatal("Start callback doesn't fire in 100 milliseconds") + case <-started: + t.Log("Start callback fired") + } + s.SetRunning(42) + stopped := make(chan struct{}) + go func() { + s.WaitRunning(100 * time.Millisecond) + close(stopped) + }() + select { + case <-time.After(200 * time.Millisecond): + t.Fatal("Start callback doesn't fire in 100 milliseconds") + case <-stopped: + t.Log("Start callback fired") + } + +} -- cgit v1.2.1 From 57d86a5619adae5e08e0e28fba99f6a7c2f5ee54 Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Fri, 6 Jun 2014 15:30:04 +0400 Subject: Use State waiting functions Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- daemon/container.go | 75 ++++++++++++++----------------------------- daemon/daemon.go | 11 ++----- daemon/state.go | 2 +- integration/commands_test.go | 8 ++--- integration/container_test.go | 15 +++++---- integration/runtime_test.go | 4 +-- integration/utils_test.go | 8 +++-- server/buildfile.go | 3 +- server/server.go | 4 +-- 9 files changed, 51 insertions(+), 79 deletions(-) diff --git a/daemon/container.go b/daemon/container.go index d9c809cee5..5b41438680 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -53,7 +53,7 @@ type Container struct { Args []string Config *runconfig.Config - State State + State *State Image string NetworkSettings *NetworkSettings @@ -74,8 +74,7 @@ type Container struct { daemon *Daemon MountLabel, ProcessLabel string - waitLock chan struct{} - Volumes map[string]string + Volumes map[string]string // Store rw/ro in a separate structure to preserve reverse-compatibility on-disk. // Easier than migrating older container configs :) VolumesRW map[string]bool @@ -284,7 +283,6 @@ func (container *Container) Start() (err error) { if err := container.startLoggingToDisk(); err != nil { return err } - container.waitLock = make(chan struct{}) return container.waitForStart() } @@ -293,7 +291,7 @@ func (container *Container) Run() error { if err := container.Start(); err != nil { return err } - container.Wait() + container.State.WaitStop(-1 * time.Second) return nil } @@ -307,7 +305,7 @@ func (container *Container) Output() (output []byte, err error) { return nil, err } output, err = ioutil.ReadAll(pipe) - container.Wait() + container.State.WaitStop(-1 * time.Second) return output, err } @@ -467,6 +465,7 @@ func (container *Container) monitor(callback execdriver.StartCallback) error { if err != nil { utils.Errorf("Error running container: %s", err) } + container.State.SetStopped(exitCode) // Cleanup container.cleanup() @@ -475,28 +474,17 @@ func (container *Container) monitor(callback execdriver.StartCallback) error { if container.Config.OpenStdin { container.stdin, container.stdinPipe = io.Pipe() } - if container.daemon != nil && container.daemon.srv != nil { container.daemon.srv.LogEvent("die", container.ID, container.daemon.repositories.ImageName(container.Image)) } - - close(container.waitLock) - if container.daemon != nil && container.daemon.srv != nil && container.daemon.srv.IsRunning() { - container.State.SetStopped(exitCode) - - // FIXME: there is a race condition here which causes this to fail during the unit tests. - // If another goroutine was waiting for Wait() to return before removing the container's root - // from the filesystem... At this point it may already have done so. - // This is because State.setStopped() has already been called, and has caused Wait() - // to return. - // FIXME: why are we serializing running state to disk in the first place? - //log.Printf("%s: Failed to dump configuration to the disk: %s", container.ID, err) + // FIXME: here is race condition between two RUN instructions in Dockerfile + // because they share same runconfig and change image. Must be fixed + // in server/buildfile.go if err := container.ToDisk(); err != nil { - utils.Errorf("Error dumping container state to disk: %s\n", err) + utils.Errorf("Error dumping container %s state to disk: %s\n", container.ID, err) } } - return err } @@ -532,6 +520,7 @@ func (container *Container) cleanup() { } func (container *Container) KillSig(sig int) error { + utils.Debugf("Sending %d to %s", sig, container.ID) container.Lock() defer container.Unlock() @@ -577,9 +566,9 @@ func (container *Container) Kill() error { } // 2. Wait for the process to die, in last resort, try to kill the process directly - if err := container.WaitTimeout(10 * time.Second); err != nil { + if _, err := container.State.WaitStop(10 * time.Second); err != nil { // Ensure that we don't kill ourselves - if pid := container.State.Pid; pid != 0 { + if pid := container.State.GetPid(); pid != 0 { log.Printf("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", utils.TruncateID(container.ID)) if err := syscall.Kill(pid, 9); err != nil { return err @@ -587,7 +576,7 @@ func (container *Container) Kill() error { } } - container.Wait() + container.State.WaitStop(-1 * time.Second) return nil } @@ -605,11 +594,11 @@ func (container *Container) Stop(seconds int) error { } // 2. Wait for the process to exit on its own - if err := container.WaitTimeout(time.Duration(seconds) * time.Second); err != nil { + if _, err := container.State.WaitStop(time.Duration(seconds) * time.Second); err != nil { log.Printf("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds) // 3. If it doesn't, then send SIGKILL if err := container.Kill(); err != nil { - container.Wait() + container.State.WaitStop(-1 * time.Second) return err } } @@ -630,12 +619,6 @@ func (container *Container) Restart(seconds int) error { return container.Start() } -// Wait blocks until the container stops running, then returns its exit code. -func (container *Container) Wait() int { - <-container.waitLock - return container.State.GetExitCode() -} - func (container *Container) Resize(h, w int) error { return container.command.Terminal.Resize(h, w) } @@ -678,21 +661,6 @@ func (container *Container) Export() (archive.Archive, error) { nil } -func (container *Container) WaitTimeout(timeout time.Duration) error { - done := make(chan bool, 1) - go func() { - container.Wait() - done <- true - }() - - select { - case <-time.After(timeout): - return fmt.Errorf("Timed Out") - case <-done: - return nil - } -} - func (container *Container) Mount() error { return container.daemon.Mount(container) } @@ -1103,9 +1071,7 @@ func (container *Container) startLoggingToDisk() error { } func (container *Container) waitForStart() error { - callbackLock := make(chan struct{}) callback := func(command *execdriver.Command) { - container.State.SetRunning(command.Pid()) if command.Tty { // The callback is called after the process Start() // so we are in the parent process. In TTY mode, stdin/out/err is the PtySlace @@ -1117,16 +1083,23 @@ func (container *Container) waitForStart() error { if err := container.ToDisk(); err != nil { utils.Debugf("%s", err) } - close(callbackLock) + container.State.SetRunning(command.Pid()) } // We use a callback here instead of a goroutine and an chan for // syncronization purposes cErr := utils.Go(func() error { return container.monitor(callback) }) + waitStart := make(chan struct{}) + + go func() { + container.State.WaitRunning(-1 * time.Second) + close(waitStart) + }() + // Start should not return until the process is actually running select { - case <-callbackLock: + case <-waitStart: case err := <-cErr: return err } diff --git a/daemon/daemon.go b/daemon/daemon.go index 3536678d22..aa8d2bad3f 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -138,7 +138,7 @@ func (daemon *Daemon) containerRoot(id string) string { // Load reads the contents of a container from disk // This is typically done at startup. func (daemon *Daemon) load(id string) (*Container, error) { - container := &Container{root: daemon.containerRoot(id)} + container := &Container{root: daemon.containerRoot(id), State: NewState()} if err := container.FromDisk(); err != nil { return nil, err } @@ -236,12 +236,6 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool, con } } } - } else { - // When the container is not running, we still initialize the waitLock - // chan and close it. Receiving on nil chan blocks whereas receiving on a - // closed chan does not. In this case we do not want to block. - container.waitLock = make(chan struct{}) - close(container.waitLock) } return nil } @@ -588,6 +582,7 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, img *i Name: name, Driver: daemon.driver.String(), ExecDriver: daemon.execDriver.Name(), + State: NewState(), } container.root = daemon.containerRoot(container.ID) @@ -900,7 +895,7 @@ func (daemon *Daemon) shutdown() error { if err := c.KillSig(15); err != nil { utils.Debugf("kill 15 error for %s - %s", c.ID, err) } - c.Wait() + c.State.WaitStop(-1 * time.Second) utils.Debugf("container stopped %s", c.ID) }() } diff --git a/daemon/state.go b/daemon/state.go index b9ef350568..3f904d7829 100644 --- a/daemon/state.go +++ b/daemon/state.go @@ -75,7 +75,7 @@ func (s *State) WaitRunning(timeout time.Duration) (int, error) { // WaitStop waits until state is stopped. If state already stopped it returns // immediatly. If you want wait forever you must supply negative timeout. -// Returns exit code, that was passed to SetRunning +// Returns exit code, that was passed to SetStopped func (s *State) WaitStop(timeout time.Duration) (int, error) { s.RLock() if !s.Running { diff --git a/integration/commands_test.go b/integration/commands_test.go index 55c822bbeb..47e9860052 100644 --- a/integration/commands_test.go +++ b/integration/commands_test.go @@ -224,7 +224,7 @@ func TestRunDisconnect(t *testing.T) { // cause /bin/cat to exit. setTimeout(t, "Waiting for /bin/cat to exit timed out", 2*time.Second, func() { container := globalDaemon.List()[0] - container.Wait() + container.State.WaitStop(-1 * time.Second) if container.State.IsRunning() { t.Fatalf("/bin/cat is still running after closing stdin") } @@ -276,7 +276,7 @@ func TestRunDisconnectTty(t *testing.T) { // In tty mode, we expect the process to stay alive even after client's stdin closes. // Give some time to monitor to do his thing - container.WaitTimeout(500 * time.Millisecond) + container.State.WaitStop(500 * time.Millisecond) if !container.State.IsRunning() { t.Fatalf("/bin/cat should still be running after closing stdin (tty mode)") } @@ -535,7 +535,7 @@ func TestAttachDisconnect(t *testing.T) { // We closed stdin, expect /bin/cat to still be running // Wait a little bit to make sure container.monitor() did his thing - err := container.WaitTimeout(500 * time.Millisecond) + _, err := container.State.WaitStop(500 * time.Millisecond) if err == nil || !container.State.IsRunning() { t.Fatalf("/bin/cat is not running after closing stdin") } @@ -543,7 +543,7 @@ func TestAttachDisconnect(t *testing.T) { // Try to avoid the timeout in destroy. Best effort, don't check error cStdin, _ := container.StdinPipe() cStdin.Close() - container.Wait() + container.State.WaitStop(-1 * time.Second) } // Expected behaviour: container gets deleted automatically after exit diff --git a/integration/container_test.go b/integration/container_test.go index 8fe52a3cd6..31a57df77b 100644 --- a/integration/container_test.go +++ b/integration/container_test.go @@ -2,7 +2,6 @@ package docker import ( "fmt" - "github.com/dotcloud/docker/runconfig" "io" "io/ioutil" "os" @@ -10,6 +9,8 @@ import ( "strings" "testing" "time" + + "github.com/dotcloud/docker/runconfig" ) func TestKillDifferentUser(t *testing.T) { @@ -60,7 +61,7 @@ func TestKillDifferentUser(t *testing.T) { if container.State.IsRunning() { t.Errorf("Container shouldn't be running") } - container.Wait() + container.State.WaitStop(-1 * time.Second) if container.State.IsRunning() { t.Errorf("Container shouldn't be running") } @@ -134,7 +135,7 @@ func TestRestartStdin(t *testing.T) { if err := stdin.Close(); err != nil { t.Fatal(err) } - container.Wait() + container.State.WaitStop(-1 * time.Second) output, err := ioutil.ReadAll(stdout) if err != nil { t.Fatal(err) @@ -164,7 +165,7 @@ func TestRestartStdin(t *testing.T) { if err := stdin.Close(); err != nil { t.Fatal(err) } - container.Wait() + container.State.WaitStop(-1 * time.Second) output, err = ioutil.ReadAll(stdout) if err != nil { t.Fatal(err) @@ -212,7 +213,7 @@ func TestStdin(t *testing.T) { if err := stdin.Close(); err != nil { t.Fatal(err) } - container.Wait() + container.State.WaitStop(-1 * time.Second) output, err := ioutil.ReadAll(stdout) if err != nil { t.Fatal(err) @@ -257,7 +258,7 @@ func TestTty(t *testing.T) { if err := stdin.Close(); err != nil { t.Fatal(err) } - container.Wait() + container.State.WaitStop(-1 * time.Second) output, err := ioutil.ReadAll(stdout) if err != nil { t.Fatal(err) @@ -366,7 +367,7 @@ func BenchmarkRunParallel(b *testing.B) { complete <- err return } - if err := container.WaitTimeout(15 * time.Second); err != nil { + if _, err := container.State.WaitStop(15 * time.Second); err != nil { complete <- err return } diff --git a/integration/runtime_test.go b/integration/runtime_test.go index 96df15be60..754146c5f8 100644 --- a/integration/runtime_test.go +++ b/integration/runtime_test.go @@ -496,7 +496,7 @@ func startEchoServerContainer(t *testing.T, proto string) (*daemon.Daemon, *daem }) // Even if the state is running, lets give some time to lxc to spawn the process - container.WaitTimeout(500 * time.Millisecond) + container.State.WaitStop(500 * time.Millisecond) strPort = container.NetworkSettings.Ports[p][0].HostPort return daemon, container, strPort @@ -611,7 +611,7 @@ func TestRestore(t *testing.T) { // Simulate a crash/manual quit of dockerd: process dies, states stays 'Running' cStdin, _ := container2.StdinPipe() cStdin.Close() - if err := container2.WaitTimeout(2 * time.Second); err != nil { + if _, err := container2.State.WaitStop(2 * time.Second); err != nil { t.Fatal(err) } container2.State.SetRunning(42) diff --git a/integration/utils_test.go b/integration/utils_test.go index d8101dfb1d..7be7f13eee 100644 --- a/integration/utils_test.go +++ b/integration/utils_test.go @@ -96,11 +96,13 @@ func containerAttach(eng *engine.Engine, id string, t utils.Fataler) (io.WriteCl } func containerWait(eng *engine.Engine, id string, t utils.Fataler) int { - return getContainer(eng, id, t).Wait() + ex, _ := getContainer(eng, id, t).State.WaitStop(-1 * time.Second) + return ex } func containerWaitTimeout(eng *engine.Engine, id string, t utils.Fataler) error { - return getContainer(eng, id, t).WaitTimeout(500 * time.Millisecond) + _, err := getContainer(eng, id, t).State.WaitStop(500 * time.Millisecond) + return err } func containerKill(eng *engine.Engine, id string, t utils.Fataler) { @@ -307,7 +309,7 @@ func runContainer(eng *engine.Engine, r *daemon.Daemon, args []string, t *testin return "", err } - container.Wait() + container.State.WaitStop(-1 * time.Second) data, err := ioutil.ReadAll(stdout) if err != nil { return "", err diff --git a/server/buildfile.go b/server/buildfile.go index f10cc0dbc5..f5ef6e0d2a 100644 --- a/server/buildfile.go +++ b/server/buildfile.go @@ -17,6 +17,7 @@ import ( "sort" "strings" "syscall" + "time" "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/daemon" @@ -696,7 +697,7 @@ func (b *buildFile) run(c *daemon.Container) error { } // Wait for it to finish - if ret := c.Wait(); ret != 0 { + if ret, _ := c.State.WaitStop(-1 * time.Second); ret != 0 { err := &utils.JSONError{ Message: fmt.Sprintf("The command %v returned a non-zero code: %d", b.config.Cmd, ret), Code: ret, diff --git a/server/server.go b/server/server.go index fa695adfe2..1641023170 100644 --- a/server/server.go +++ b/server/server.go @@ -2123,7 +2123,7 @@ func (srv *Server) ContainerWait(job *engine.Job) engine.Status { } name := job.Args[0] if container := srv.daemon.Get(name); container != nil { - status := container.Wait() + status, _ := container.State.WaitStop(-1 * time.Second) job.Printf("%d\n", status) return engine.StatusOK } @@ -2336,7 +2336,7 @@ func (srv *Server) ContainerAttach(job *engine.Job) engine.Status { // If we are in stdinonce mode, wait for the process to end // otherwise, simply return if container.Config.StdinOnce && !container.Config.Tty { - container.Wait() + container.State.WaitStop(-1 * time.Second) } } return engine.StatusOK -- cgit v1.2.1 From 287e604a8f53e569d355b1b6c75f6736f4927281 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Fri, 27 Jun 2014 14:43:12 +0200 Subject: mkimage: use /var/tmp by default instead of /tmp Additionally, this can be overridden by setting the TMPDIR variable, like this was already the case for the generic `mkimage.sh` script. As explained in #6456, the rationale to use `/var/tmp` instead of `/tmp` is that `/tmp` is often a small tmpfs filesystem with more restricted rights. Docker-DCO-1.1-Signed-off-by: Vincent Bernat (github: vincentbernat) --- contrib/mkimage-alpine.sh | 4 ++-- contrib/mkimage-arch.sh | 2 +- contrib/mkimage-busybox.sh | 2 +- contrib/mkimage-crux.sh | 6 +++--- contrib/mkimage-debootstrap.sh | 2 +- contrib/mkimage-rinse.sh | 2 +- contrib/mkimage-unittest.sh | 2 +- contrib/mkimage.sh | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contrib/mkimage-alpine.sh b/contrib/mkimage-alpine.sh index 7444ffafb9..0bf328efa9 100755 --- a/contrib/mkimage-alpine.sh +++ b/contrib/mkimage-alpine.sh @@ -13,8 +13,8 @@ usage() { } tmp() { - TMP=$(mktemp -d /tmp/alpine-docker-XXXXXXXXXX) - ROOTFS=$(mktemp -d /tmp/alpine-docker-rootfs-XXXXXXXXXX) + TMP=$(mktemp -d ${TMPDIR:-/var/tmp}/alpine-docker-XXXXXXXXXX) + ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/alpine-docker-rootfs-XXXXXXXXXX) trap "rm -rf $TMP $ROOTFS" EXIT TERM INT } diff --git a/contrib/mkimage-arch.sh b/contrib/mkimage-arch.sh index dc21067473..27c6ac6a3e 100755 --- a/contrib/mkimage-arch.sh +++ b/contrib/mkimage-arch.sh @@ -14,7 +14,7 @@ hash expect &>/dev/null || { exit 1 } -ROOTFS=$(mktemp -d /tmp/rootfs-archlinux-XXXXXXXXXX) +ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/rootfs-archlinux-XXXXXXXXXX) chmod 755 $ROOTFS # packages to ignore for space savings diff --git a/contrib/mkimage-busybox.sh b/contrib/mkimage-busybox.sh index cbaa567834..b11a6bb265 100755 --- a/contrib/mkimage-busybox.sh +++ b/contrib/mkimage-busybox.sh @@ -14,7 +14,7 @@ BUSYBOX=$(which busybox) } set -e -ROOTFS=/tmp/rootfs-busybox-$$-$RANDOM +ROOTFS=${TMPDIR:-/var/tmp}/rootfs-busybox-$$-$RANDOM mkdir $ROOTFS cd $ROOTFS diff --git a/contrib/mkimage-crux.sh b/contrib/mkimage-crux.sh index 074c334bba..3f0bdcae3c 100755 --- a/contrib/mkimage-crux.sh +++ b/contrib/mkimage-crux.sh @@ -14,9 +14,9 @@ die () { ISO=${1} -ROOTFS=$(mktemp -d /tmp/rootfs-crux-XXXXXXXXXX) -CRUX=$(mktemp -d /tmp/crux-XXXXXXXXXX) -TMP=$(mktemp -d /tmp/XXXXXXXXXX) +ROOTFS=$(mktemp -d ${TMPDIR:-/var/tmp}/rootfs-crux-XXXXXXXXXX) +CRUX=$(mktemp -d ${TMPDIR:-/var/tmp}/crux-XXXXXXXXXX) +TMP=$(mktemp -d ${TMPDIR:-/var/tmp}/XXXXXXXXXX) VERSION=$(basename --suffix=.iso $ISO | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') diff --git a/contrib/mkimage-debootstrap.sh b/contrib/mkimage-debootstrap.sh index 808f393549..0a3df140db 100755 --- a/contrib/mkimage-debootstrap.sh +++ b/contrib/mkimage-debootstrap.sh @@ -118,7 +118,7 @@ fi # will be filled in later, if [ -z "$skipDetection" ] lsbDist='' -target="/tmp/docker-rootfs-debootstrap-$suite-$$-$RANDOM" +target="${TMPDIR:-/var/tmp}/docker-rootfs-debootstrap-$suite-$$-$RANDOM" cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" returnTo="$(pwd -P)" diff --git a/contrib/mkimage-rinse.sh b/contrib/mkimage-rinse.sh index 0692ae1794..69a8bc8fe6 100755 --- a/contrib/mkimage-rinse.sh +++ b/contrib/mkimage-rinse.sh @@ -39,7 +39,7 @@ if [ ! "$repo" ] || [ ! "$distro" ]; then exit 1 fi -target="/tmp/docker-rootfs-rinse-$distro-$$-$RANDOM" +target="${TMPDIR:-/var/tmp}/docker-rootfs-rinse-$distro-$$-$RANDOM" cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" returnTo="$(pwd -P)" diff --git a/contrib/mkimage-unittest.sh b/contrib/mkimage-unittest.sh index a33f238845..feebb17b0e 100755 --- a/contrib/mkimage-unittest.sh +++ b/contrib/mkimage-unittest.sh @@ -15,7 +15,7 @@ SOCAT=$(which socat) shopt -s extglob set -ex -ROOTFS=`mktemp -d /tmp/rootfs-busybox.XXXXXXXXXX` +ROOTFS=`mktemp -d ${TMPDIR:-/var/tmp}/rootfs-busybox.XXXXXXXXXX` trap "rm -rf $ROOTFS" INT QUIT TERM cd $ROOTFS diff --git a/contrib/mkimage.sh b/contrib/mkimage.sh index 522e9a2840..803d1627df 100755 --- a/contrib/mkimage.sh +++ b/contrib/mkimage.sh @@ -50,7 +50,7 @@ fi delDir= if [ -z "$dir" ]; then - dir="$(mktemp -d ${TMPDIR:-/tmp}/docker-mkimage.XXXXXXXXXX)" + dir="$(mktemp -d ${TMPDIR:-/var/tmp}/docker-mkimage.XXXXXXXXXX)" delDir=1 fi -- cgit v1.2.1 From 2fcbfb5a66249739ef04d414307be01371190bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=BDupka?= Date: Fri, 27 Jun 2014 15:55:20 +0200 Subject: Adds check if default ip address is correct format. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It avoids hidden error when ports are redirected from container to host using -p host_port:guest_port. Docker-DCO-1.1-Signed-off-by: Jiří Župka (github: jzupka) --- docker/docker.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker/docker.go b/docker/docker.go index 6932d32776..30d43bc6a8 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "log" + "net" "os" "runtime" "strings" @@ -99,6 +100,10 @@ func main() { log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.") } + if net.ParseIP(*flDefaultIp) == nil { + log.Fatalf("Specified --ip=%s is not in correct format \"0.0.0.0\".", *flDefaultIp) + } + if *flDebug { os.Setenv("DEBUG", "1") } -- cgit v1.2.1 From 4361366783bbb4c9e4bd87e1c16da5a0988ed0bd Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Wed, 25 Jun 2014 11:25:54 -0400 Subject: Document memory limit sizing in manpages The -m flag permits the setting of a memory limit when running a Docker container. The actual limit set must be a multiple of page size on Linux, so whatever number the uses passes in will be rounded up if needed. Document this behavior to prevent confusion. Also fixed several small formatting and grammar issues in the docker run manpage. Docker-DCO-1.1-Signed-off-by: Matthew Heon (github: mheon) --- docs/man/docker-run.1.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/man/docker-run.1.md b/docs/man/docker-run.1.md index 447d9e13c3..2ef7f50489 100644 --- a/docs/man/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -103,8 +103,10 @@ container can be started with the **--link**. **-m**, **-memory**=*memory-limit* Allows you to constrain the memory available to a container. If the host supports swap memory, then the -m memory setting can be larger than physical -RAM. If a limit of 0 is specified, the container's memory is not limited. The -memory limit format: , where unit = b, k, m or g. +RAM. If a limit of 0 is specified, the container's memory is not limited. The +actual limit may be rounded up to a multiple of the operating system's page +size, if it is not already. The memory limit should be formatted as follows: +``, where unit = b, k, m or g. **-P**, **-publish-all**=*true*|*false* When set to true publish all exposed ports to the host interfaces. The -- cgit v1.2.1 From 815279c240e27478aa7ddde349761546a5c474fc Mon Sep 17 00:00:00 2001 From: Mike Chelen Date: Fri, 27 Jun 2014 11:09:09 -0400 Subject: Update dockerimages.md fix typo --- docs/sources/userguide/dockerimages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockerimages.md b/docs/sources/userguide/dockerimages.md index b58be90449..ffcc39ddba 100644 --- a/docs/sources/userguide/dockerimages.md +++ b/docs/sources/userguide/dockerimages.md @@ -239,7 +239,7 @@ Let's create a directory and a `Dockerfile` first. $ cd sinatra $ touch Dockerfile -Each instructions creates a new layer of the image. Let's look at a simple +Each instruction creates a new layer of the image. Let's look at a simple example now for building our own Sinatra image for our development team. # This is a comment -- cgit v1.2.1 From a1b6f350e806c43225b724530e563d6ff66e6b8a Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 27 Jun 2014 19:49:40 +0300 Subject: correct typo - desination -> destination Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- runconfig/parse.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runconfig/parse.go b/runconfig/parse.go index f057f311cc..01662fd010 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -133,7 +133,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf for bind := range flVolumes.GetMap() { if arr := strings.Split(bind, ":"); len(arr) > 1 { if arr[1] == "/" { - return nil, nil, cmd, fmt.Errorf("Invalid bind mount: desination can't be '/'") + return nil, nil, cmd, fmt.Errorf("Invalid bind mount: destination can't be '/'") } // after creating the bind mount we want to delete it from the flVolumes values because // we do not want bind mounts being committed to image configs -- cgit v1.2.1 From 38b005ec69e62d93453ac4013fe6bfa2fccebc5d Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 27 Jun 2014 19:51:24 +0300 Subject: integcli: add test to ensure -v /:/ isn't allowed Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- integration-cli/docker_cli_run_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index a0c3903064..eda1b3f0a5 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -971,3 +971,15 @@ func TestAllowBindMountingRoot(t *testing.T) { logDone("run - bind mount / as volume") } + +func TestDisallowBindMountingRootToRoot(t *testing.T) { + cmd := exec.Command(dockerBinary, "run", "-v", "/:/", "busybox", "ls", "/host") + out, _, err := runCommandWithOutput(cmd) + if err == nil { + t.Fatal(out, err) + } + + deleteAllContainers() + + logDone("run - bind mount /:/ as volume should fail") +} -- cgit v1.2.1 From dafddf461eeabd792d9ced6caced75ad6961c1d7 Mon Sep 17 00:00:00 2001 From: Arnaud Porterie Date: Thu, 19 Jun 2014 23:33:51 +0200 Subject: Restrict portallocator to Docker allocated ports Port allocation status is stored in a global map: a port detected in use will remain as such for the lifetime of the daemon. Change the behavior to only mark as allocated ports which are claimed by Docker itself (which we can trust to properly remove from the allocation map once released). Ports allocated by other applications will always be retried to account for the eventually of the port having been released. Docker-DCO-1.1-Signed-off-by: Arnaud Porterie (github: icecrime) --- daemon/networkdriver/bridge/driver.go | 74 +++++++---------- daemon/networkdriver/bridge/driver_test.go | 106 +++++++++++++++++++++++++ daemon/networkdriver/portmapper/mapper.go | 84 ++++++++++++++++---- daemon/networkdriver/portmapper/mapper_test.go | 24 +++++- 4 files changed, 225 insertions(+), 63 deletions(-) create mode 100644 daemon/networkdriver/bridge/driver_test.go diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 8c5db9f843..8da7a0457a 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -11,7 +11,6 @@ import ( "github.com/docker/libcontainer/netlink" "github.com/dotcloud/docker/daemon/networkdriver" "github.com/dotcloud/docker/daemon/networkdriver/ipallocator" - "github.com/dotcloud/docker/daemon/networkdriver/portallocator" "github.com/dotcloud/docker/daemon/networkdriver/portmapper" "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/pkg/iptables" @@ -354,9 +353,6 @@ func Release(job *engine.Job) engine.Status { var ( id = job.Args[0] containerInterface = currentInterfaces.Get(id) - ip net.IP - port int - proto string ) if containerInterface == nil { @@ -367,22 +363,6 @@ func Release(job *engine.Job) engine.Status { if err := portmapper.Unmap(nat); err != nil { log.Printf("Unable to unmap port %s: %s", nat, err) } - - // this is host mappings - switch a := nat.(type) { - case *net.TCPAddr: - proto = "tcp" - ip = a.IP - port = a.Port - case *net.UDPAddr: - proto = "udp" - ip = a.IP - port = a.Port - } - - if err := portallocator.ReleasePort(ip, proto, port); err != nil { - log.Printf("Unable to release port %s", nat) - } } if err := ipallocator.ReleaseIP(bridgeNetwork, &containerInterface.IP); err != nil { @@ -399,7 +379,7 @@ func AllocatePort(job *engine.Job) engine.Status { ip = defaultBindingIP id = job.Args[0] hostIP = job.Getenv("HostIP") - origHostPort = job.GetenvInt("HostPort") + hostPort = job.GetenvInt("HostPort") containerPort = job.GetenvInt("ContainerPort") proto = job.Getenv("Proto") network = currentInterfaces.Get(id) @@ -409,11 +389,16 @@ func AllocatePort(job *engine.Job) engine.Status { ip = net.ParseIP(hostIP) } - var ( - hostPort int - container net.Addr - host net.Addr - ) + // host ip, proto, and host port + var container net.Addr + switch proto { + case "tcp": + container = &net.TCPAddr{IP: network.IP, Port: containerPort} + case "udp": + container = &net.UDPAddr{IP: network.IP, Port: containerPort} + default: + return job.Errorf("unsupported address type %s", proto) + } /* Try up to 10 times to get a port that's not already allocated. @@ -421,27 +406,22 @@ func AllocatePort(job *engine.Job) engine.Status { In the event of failure to bind, return the error that portmapper.Map yields. */ - for i := 0; i < 10; i++ { - // host ip, proto, and host port - hostPort, err = portallocator.RequestPort(ip, proto, origHostPort) - if err != nil { - return job.Error(err) - } - - if proto == "tcp" { - host = &net.TCPAddr{IP: ip, Port: hostPort} - container = &net.TCPAddr{IP: network.IP, Port: containerPort} - } else { - host = &net.UDPAddr{IP: ip, Port: hostPort} - container = &net.UDPAddr{IP: network.IP, Port: containerPort} + var host net.Addr + for i := 0; i < 10; i++ { + if host, err = portmapper.Map(container, ip, hostPort); err == nil { + break } - if err = portmapper.Map(container, ip, hostPort); err == nil { + // There is no point in immediately retrying to map an explicitely + // chosen port. + if hostPort != 0 { + job.Logf("Failed to bind %s for container address %s", host.String(), container.String()) break } - job.Logf("Failed to bind %s:%d for container address %s:%d. Trying another port.", ip.String(), hostPort, network.IP.String(), containerPort) + // Automatically chosen 'free' port failed to bind: move on the next. + job.Logf("Failed to bind %s for container address %s. Trying another port.", host.String(), container.String()) } if err != nil { @@ -451,12 +431,18 @@ func AllocatePort(job *engine.Job) engine.Status { network.PortMappings = append(network.PortMappings, host) out := engine.Env{} - out.Set("HostIP", ip.String()) - out.SetInt("HostPort", hostPort) - + switch netAddr := host.(type) { + case *net.TCPAddr: + out.Set("HostIP", netAddr.IP.String()) + out.SetInt("HostPort", netAddr.Port) + case *net.UDPAddr: + out.Set("HostIP", netAddr.IP.String()) + out.SetInt("HostPort", netAddr.Port) + } if _, err := out.WriteTo(job.Stdout); err != nil { return job.Error(err) } + return engine.StatusOK } diff --git a/daemon/networkdriver/bridge/driver_test.go b/daemon/networkdriver/bridge/driver_test.go new file mode 100644 index 0000000000..f8ddd4c64e --- /dev/null +++ b/daemon/networkdriver/bridge/driver_test.go @@ -0,0 +1,106 @@ +package bridge + +import ( + "fmt" + "net" + "strconv" + "testing" + + "github.com/dotcloud/docker/engine" +) + +func findFreePort(t *testing.T) int { + l, err := net.Listen("tcp", ":0") + if err != nil { + t.Fatal("Failed to find a free port") + } + defer l.Close() + + result, err := net.ResolveTCPAddr("tcp", l.Addr().String()) + if err != nil { + t.Fatal("Failed to resolve address to identify free port") + } + return result.Port +} + +func newPortAllocationJob(eng *engine.Engine, port int) (job *engine.Job) { + strPort := strconv.Itoa(port) + + job = eng.Job("allocate_port", "container_id") + job.Setenv("HostIP", "127.0.0.1") + job.Setenv("HostPort", strPort) + job.Setenv("Proto", "tcp") + job.Setenv("ContainerPort", strPort) + return +} + +func TestAllocatePortDetection(t *testing.T) { + eng := engine.New() + eng.Logging = false + + freePort := findFreePort(t) + + // Init driver + job := eng.Job("initdriver") + if res := InitDriver(job); res != engine.StatusOK { + t.Fatal("Failed to initialize network driver") + } + + // Allocate interface + job = eng.Job("allocate_interface", "container_id") + if res := Allocate(job); res != engine.StatusOK { + t.Fatal("Failed to allocate network interface") + } + + // Allocate same port twice, expect failure on second call + job = newPortAllocationJob(eng, freePort) + if res := AllocatePort(job); res != engine.StatusOK { + t.Fatal("Failed to find a free port to allocate") + } + if res := AllocatePort(job); res == engine.StatusOK { + t.Fatal("Duplicate port allocation granted by AllocatePort") + } +} + +func TestAllocatePortReclaim(t *testing.T) { + eng := engine.New() + eng.Logging = false + + freePort := findFreePort(t) + + // Init driver + job := eng.Job("initdriver") + if res := InitDriver(job); res != engine.StatusOK { + t.Fatal("Failed to initialize network driver") + } + + // Allocate interface + job = eng.Job("allocate_interface", "container_id") + if res := Allocate(job); res != engine.StatusOK { + t.Fatal("Failed to allocate network interface") + } + + // Occupy port + listenAddr := fmt.Sprintf(":%d", freePort) + tcpListenAddr, err := net.ResolveTCPAddr("tcp", listenAddr) + if err != nil { + t.Fatalf("Failed to resolve TCP address '%s'", listenAddr) + } + + l, err := net.ListenTCP("tcp", tcpListenAddr) + if err != nil { + t.Fatalf("Fail to listen on port %d", freePort) + } + + // Allocate port, expect failure + job = newPortAllocationJob(eng, freePort) + if res := AllocatePort(job); res == engine.StatusOK { + t.Fatal("Successfully allocated currently used port") + } + + // Reclaim port, retry allocation + l.Close() + if res := AllocatePort(job); res != engine.StatusOK { + t.Fatal("Failed to allocate previously reclaimed port") + } +} diff --git a/daemon/networkdriver/portmapper/mapper.go b/daemon/networkdriver/portmapper/mapper.go index e29959a245..880cfb2986 100644 --- a/daemon/networkdriver/portmapper/mapper.go +++ b/daemon/networkdriver/portmapper/mapper.go @@ -3,10 +3,12 @@ package portmapper import ( "errors" "fmt" - "github.com/dotcloud/docker/pkg/iptables" - "github.com/dotcloud/docker/pkg/proxy" "net" "sync" + + "github.com/dotcloud/docker/daemon/networkdriver/portallocator" + "github.com/dotcloud/docker/pkg/iptables" + "github.com/dotcloud/docker/pkg/proxy" ) type mapping struct { @@ -31,47 +33,87 @@ var ( ErrPortNotMapped = errors.New("port is not mapped") ) +type genericAddr struct { + IP net.IP + Port int +} + +func (g *genericAddr) Network() string { + return "" +} + +func (g *genericAddr) String() string { + return fmt.Sprintf("%s:%d", g.IP.String(), g.Port) +} + func SetIptablesChain(c *iptables.Chain) { chain = c } -func Map(container net.Addr, hostIP net.IP, hostPort int) error { +func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { lock.Lock() defer lock.Unlock() - var m *mapping + var ( + m *mapping + err error + proto string + allocatedHostPort int + ) + switch container.(type) { case *net.TCPAddr: + proto = "tcp" + if allocatedHostPort, err = portallocator.RequestPort(hostIP, proto, hostPort); err != nil { + return &net.TCPAddr{IP: hostIP, Port: hostPort}, err + } m = &mapping{ - proto: "tcp", - host: &net.TCPAddr{IP: hostIP, Port: hostPort}, + proto: proto, + host: &net.TCPAddr{IP: hostIP, Port: allocatedHostPort}, container: container, } case *net.UDPAddr: + proto = "udp" + if allocatedHostPort, err = portallocator.RequestPort(hostIP, proto, hostPort); err != nil { + return &net.UDPAddr{IP: hostIP, Port: hostPort}, err + } m = &mapping{ - proto: "udp", - host: &net.UDPAddr{IP: hostIP, Port: hostPort}, + proto: proto, + host: &net.UDPAddr{IP: hostIP, Port: allocatedHostPort}, container: container, } default: - return ErrUnknownBackendAddressType + // Always return a proper net.Addr for proper reporting. + return &genericAddr{IP: hostIP, Port: hostPort}, ErrUnknownBackendAddressType } + // When binding fails: + // - for a specifically requested port: it might be locked by some other + // process, so we want to allow for an ulterior retry + // - for an automatically allocated port: it falls in the Docker range of + // ports, so we'll just remember it as used and try the next free one + defer func() { + if err != nil && hostPort != 0 { + portallocator.ReleasePort(hostIP, proto, allocatedHostPort) + } + }() + key := getKey(m.host) if _, exists := currentMappings[key]; exists { - return ErrPortMappedForIP + err = ErrPortMappedForIP + return m.host, err } containerIP, containerPort := getIPAndPort(m.container) - if err := forward(iptables.Add, m.proto, hostIP, hostPort, containerIP.String(), containerPort); err != nil { - return err + if err := forward(iptables.Add, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort); err != nil { + return m.host, err } p, err := newProxy(m.host, m.container) if err != nil { // need to undo the iptables rules before we reutrn - forward(iptables.Delete, m.proto, hostIP, hostPort, containerIP.String(), containerPort) - return err + forward(iptables.Delete, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort) + return m.host, err } m.userlandProxy = p @@ -79,7 +121,7 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) error { go p.Run() - return nil + return m.host, nil } func Unmap(host net.Addr) error { @@ -100,6 +142,18 @@ func Unmap(host net.Addr) error { if err := forward(iptables.Delete, data.proto, hostIP, hostPort, containerIP.String(), containerPort); err != nil { return err } + + switch a := host.(type) { + case *net.TCPAddr: + if err := portallocator.ReleasePort(a.IP, "tcp", a.Port); err != nil { + return err + } + case *net.UDPAddr: + if err := portallocator.ReleasePort(a.IP, "udp", a.Port); err != nil { + return err + } + } + return nil } diff --git a/daemon/networkdriver/portmapper/mapper_test.go b/daemon/networkdriver/portmapper/mapper_test.go index 4c09f3c651..881ea028f3 100644 --- a/daemon/networkdriver/portmapper/mapper_test.go +++ b/daemon/networkdriver/portmapper/mapper_test.go @@ -44,20 +44,36 @@ func TestMapPorts(t *testing.T) { srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")} srcAddr2 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.2")} - if err := Map(srcAddr1, dstIp1, 80); err != nil { + addrEqual := func(addr1, addr2 net.Addr) bool { + return (addr1.Network() == addr2.Network()) && (addr1.String() == addr2.String()) + } + + if host, err := Map(srcAddr1, dstIp1, 80); err != nil { t.Fatalf("Failed to allocate port: %s", err) + } else if !addrEqual(dstAddr1, host) { + t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", + dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if Map(srcAddr1, dstIp1, 80) == nil { + if host, err := Map(srcAddr1, dstIp1, 80); err == nil { t.Fatalf("Port is in use - mapping should have failed") + } else if !addrEqual(dstAddr1, host) { + t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", + dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if Map(srcAddr2, dstIp1, 80) == nil { + if host, err := Map(srcAddr2, dstIp1, 80); err == nil { t.Fatalf("Port is in use - mapping should have failed") + } else if !addrEqual(dstAddr1, host) { + t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", + dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if err := Map(srcAddr2, dstIp2, 80); err != nil { + if host, err := Map(srcAddr2, dstIp2, 80); err != nil { t.Fatalf("Failed to allocate port: %s", err) + } else if !addrEqual(dstAddr2, host) { + t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", + dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } if Unmap(dstAddr1) != nil { -- cgit v1.2.1 From ffd68badc0a3d70fbd063903702355a387621b10 Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Wed, 25 Jun 2014 13:17:20 -0700 Subject: Make ErrPortAlreadyAllocated an error interface with a few extras, adjust tests to fit. Docker-DCO-1.1-Signed-off-by: Erik Hollensbe (github: erikh) --- daemon/networkdriver/bridge/driver.go | 22 ++++++++----- .../networkdriver/portallocator/portallocator.go | 36 +++++++++++++++++++--- .../portallocator/portallocator_test.go | 7 +++-- daemon/networkdriver/portmapper/mapper.go | 23 +++----------- daemon/networkdriver/portmapper/mapper_test.go | 15 ++------- 5 files changed, 60 insertions(+), 43 deletions(-) diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 8da7a0457a..16439d2aca 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -11,6 +11,7 @@ import ( "github.com/docker/libcontainer/netlink" "github.com/dotcloud/docker/daemon/networkdriver" "github.com/dotcloud/docker/daemon/networkdriver/ipallocator" + "github.com/dotcloud/docker/daemon/networkdriver/portallocator" "github.com/dotcloud/docker/daemon/networkdriver/portmapper" "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/pkg/iptables" @@ -413,15 +414,22 @@ func AllocatePort(job *engine.Job) engine.Status { break } - // There is no point in immediately retrying to map an explicitely - // chosen port. - if hostPort != 0 { - job.Logf("Failed to bind %s for container address %s", host.String(), container.String()) + switch allocerr := err.(type) { + case portallocator.ErrPortAlreadyAllocated: + // There is no point in immediately retrying to map an explicitly + // chosen port. + if hostPort != 0 { + job.Logf("Failed to bind %s for container address %s: %s", allocerr.IPPort(), container.String(), allocerr.Error()) + break + } + + // Automatically chosen 'free' port failed to bind: move on the next. + job.Logf("Failed to bind %s for container address %s. Trying another port.", allocerr.IPPort(), container.String()) + default: + // some other error during mapping + job.Logf("Received an unexpected error during port allocation: %s", err.Error()) break } - - // Automatically chosen 'free' port failed to bind: move on the next. - job.Logf("Failed to bind %s for container address %s. Trying another port.", host.String(), container.String()) } if err != nil { diff --git a/daemon/networkdriver/portallocator/portallocator.go b/daemon/networkdriver/portallocator/portallocator.go index 251ab94473..3b01e28a30 100644 --- a/daemon/networkdriver/portallocator/portallocator.go +++ b/daemon/networkdriver/portallocator/portallocator.go @@ -2,6 +2,7 @@ package portallocator import ( "errors" + "fmt" "net" "sync" ) @@ -18,9 +19,8 @@ const ( ) var ( - ErrAllPortsAllocated = errors.New("all ports are allocated") - ErrPortAlreadyAllocated = errors.New("port has already been allocated") - ErrUnknownProtocol = errors.New("unknown protocol") + ErrAllPortsAllocated = errors.New("all ports are allocated") + ErrUnknownProtocol = errors.New("unknown protocol") ) var ( @@ -30,6 +30,34 @@ var ( globalMap = ipMapping{} ) +type ErrPortAlreadyAllocated struct { + ip string + port int +} + +func NewErrPortAlreadyAllocated(ip string, port int) ErrPortAlreadyAllocated { + return ErrPortAlreadyAllocated{ + ip: ip, + port: port, + } +} + +func (e ErrPortAlreadyAllocated) IP() string { + return e.ip +} + +func (e ErrPortAlreadyAllocated) Port() int { + return e.port +} + +func (e ErrPortAlreadyAllocated) IPPort() string { + return fmt.Sprintf("%s:%d", e.ip, e.port) +} + +func (e ErrPortAlreadyAllocated) Error() string { + return fmt.Sprintf("Bind for %s:%d failed: port is already allocated", e.ip, e.port) +} + func RequestPort(ip net.IP, proto string, port int) (int, error) { mutex.Lock() defer mutex.Unlock() @@ -47,7 +75,7 @@ func RequestPort(ip net.IP, proto string, port int) (int, error) { mapping[proto][port] = true return port, nil } else { - return 0, ErrPortAlreadyAllocated + return 0, NewErrPortAlreadyAllocated(ip.String(), port) } } else { port, err := findPort(ip, proto) diff --git a/daemon/networkdriver/portallocator/portallocator_test.go b/daemon/networkdriver/portallocator/portallocator_test.go index 5a4765ddd4..9869c332e9 100644 --- a/daemon/networkdriver/portallocator/portallocator_test.go +++ b/daemon/networkdriver/portallocator/portallocator_test.go @@ -83,8 +83,11 @@ func TestReleaseUnreadledPort(t *testing.T) { } port, err = RequestPort(defaultIP, "tcp", 5000) - if err != ErrPortAlreadyAllocated { - t.Fatalf("Expected error %s got %s", ErrPortAlreadyAllocated, err) + + switch err.(type) { + case ErrPortAlreadyAllocated: + default: + t.Fatalf("Expected port allocation error got %s", err) } } diff --git a/daemon/networkdriver/portmapper/mapper.go b/daemon/networkdriver/portmapper/mapper.go index 880cfb2986..d4469cd6d0 100644 --- a/daemon/networkdriver/portmapper/mapper.go +++ b/daemon/networkdriver/portmapper/mapper.go @@ -33,19 +33,6 @@ var ( ErrPortNotMapped = errors.New("port is not mapped") ) -type genericAddr struct { - IP net.IP - Port int -} - -func (g *genericAddr) Network() string { - return "" -} - -func (g *genericAddr) String() string { - return fmt.Sprintf("%s:%d", g.IP.String(), g.Port) -} - func SetIptablesChain(c *iptables.Chain) { chain = c } @@ -65,7 +52,7 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { case *net.TCPAddr: proto = "tcp" if allocatedHostPort, err = portallocator.RequestPort(hostIP, proto, hostPort); err != nil { - return &net.TCPAddr{IP: hostIP, Port: hostPort}, err + return nil, err } m = &mapping{ proto: proto, @@ -75,7 +62,7 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { case *net.UDPAddr: proto = "udp" if allocatedHostPort, err = portallocator.RequestPort(hostIP, proto, hostPort); err != nil { - return &net.UDPAddr{IP: hostIP, Port: hostPort}, err + return nil, err } m = &mapping{ proto: proto, @@ -83,8 +70,8 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { container: container, } default: - // Always return a proper net.Addr for proper reporting. - return &genericAddr{IP: hostIP, Port: hostPort}, ErrUnknownBackendAddressType + err = ErrUnknownBackendAddressType + return nil, err } // When binding fails: @@ -111,7 +98,7 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { p, err := newProxy(m.host, m.container) if err != nil { - // need to undo the iptables rules before we reutrn + // need to undo the iptables rules before we return forward(iptables.Delete, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort) return m.host, err } diff --git a/daemon/networkdriver/portmapper/mapper_test.go b/daemon/networkdriver/portmapper/mapper_test.go index 881ea028f3..cae74ebb8b 100644 --- a/daemon/networkdriver/portmapper/mapper_test.go +++ b/daemon/networkdriver/portmapper/mapper_test.go @@ -55,25 +55,16 @@ func TestMapPorts(t *testing.T) { dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if host, err := Map(srcAddr1, dstIp1, 80); err == nil { + if _, err := Map(srcAddr1, dstIp1, 80); err == nil { t.Fatalf("Port is in use - mapping should have failed") - } else if !addrEqual(dstAddr1, host) { - t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", - dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if host, err := Map(srcAddr2, dstIp1, 80); err == nil { + if _, err := Map(srcAddr2, dstIp1, 80); err == nil { t.Fatalf("Port is in use - mapping should have failed") - } else if !addrEqual(dstAddr1, host) { - t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", - dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } - if host, err := Map(srcAddr2, dstIp2, 80); err != nil { + if _, err := Map(srcAddr2, dstIp2, 80); err != nil { t.Fatalf("Failed to allocate port: %s", err) - } else if !addrEqual(dstAddr2, host) { - t.Fatalf("Incorrect mapping result: expected %s:%s, got %s:%s", - dstAddr1.String(), dstAddr1.Network(), host.String(), host.Network()) } if Unmap(dstAddr1) != nil { -- cgit v1.2.1 From e77729c2e081c5ce55aa1d4f316b7c7703e5de96 Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Thu, 26 Jun 2014 00:09:19 -0700 Subject: Use last allocated port logic in port allocator Docker-DCO-1.1-Signed-off-by: Erik Hollensbe (github: erikh) --- daemon/networkdriver/bridge/driver.go | 17 ++++---- .../networkdriver/portallocator/portallocator.go | 45 ++++++++++++++-------- daemon/networkdriver/portmapper/mapper.go | 24 +++++------- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 16439d2aca..a843da0499 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -20,7 +20,8 @@ import ( ) const ( - DefaultNetworkBridge = "docker0" + DefaultNetworkBridge = "docker0" + MaxAllocatedPortAttempts = 10 ) // Network interface represents the networking stack of a container @@ -401,15 +402,15 @@ func AllocatePort(job *engine.Job) engine.Status { return job.Errorf("unsupported address type %s", proto) } - /* - Try up to 10 times to get a port that's not already allocated. - - In the event of failure to bind, return the error that portmapper.Map - yields. - */ + // + // Try up to 10 times to get a port that's not already allocated. + // + // In the event of failure to bind, return the error that portmapper.Map + // yields. + // var host net.Addr - for i := 0; i < 10; i++ { + for i := 0; i < MaxAllocatedPortAttempts; i++ { if host, err = portmapper.Map(container, ip, hostPort); err == nil { break } diff --git a/daemon/networkdriver/portallocator/portallocator.go b/daemon/networkdriver/portallocator/portallocator.go index 3b01e28a30..c722ba98ba 100644 --- a/daemon/networkdriver/portallocator/portallocator.go +++ b/daemon/networkdriver/portallocator/portallocator.go @@ -7,9 +7,13 @@ import ( "sync" ) +type portMap struct { + p map[int]struct{} + last int +} + type ( - portMap map[int]bool - protocolMap map[string]portMap + protocolMap map[string]*portMap ipMapping map[string]protocolMap ) @@ -71,8 +75,8 @@ func RequestPort(ip net.IP, proto string, port int) (int, error) { mapping := getOrCreate(ip) if port > 0 { - if !mapping[proto][port] { - mapping[proto][port] = true + if _, ok := mapping[proto].p[port]; !ok { + mapping[proto].p[port] = struct{}{} return port, nil } else { return 0, NewErrPortAlreadyAllocated(ip.String(), port) @@ -94,8 +98,8 @@ func ReleasePort(ip net.IP, proto string, port int) error { ip = getDefault(ip) - mapping := getOrCreate(ip) - delete(mapping[proto], port) + mapping := getOrCreate(ip)[proto] + delete(mapping.p, port) return nil } @@ -114,8 +118,8 @@ func getOrCreate(ip net.IP) protocolMap { if _, ok := globalMap[ipstr]; !ok { globalMap[ipstr] = protocolMap{ - "tcp": portMap{}, - "udp": portMap{}, + "tcp": &portMap{p: map[int]struct{}{}, last: 0}, + "udp": &portMap{p: map[int]struct{}{}, last: 0}, } } @@ -123,21 +127,28 @@ func getOrCreate(ip net.IP) protocolMap { } func findPort(ip net.IP, proto string) (int, error) { - port := BeginPortRange + mapping := getOrCreate(ip)[proto] - mapping := getOrCreate(ip) - - for mapping[proto][port] { - port++ + if mapping.last == 0 { + mapping.p[BeginPortRange] = struct{}{} + mapping.last = BeginPortRange + return BeginPortRange, nil + } + for port := mapping.last + 1; port != mapping.last; port++ { if port > EndPortRange { - return 0, ErrAllPortsAllocated + port = BeginPortRange } - } - mapping[proto][port] = true + if _, ok := mapping.p[port]; !ok { + mapping.p[port] = struct{}{} + mapping.last = port + return port, nil + } + + } - return port, nil + return 0, ErrAllPortsAllocated } func getDefault(ip net.IP) net.IP { diff --git a/daemon/networkdriver/portmapper/mapper.go b/daemon/networkdriver/portmapper/mapper.go index d4469cd6d0..1bd332271f 100644 --- a/daemon/networkdriver/portmapper/mapper.go +++ b/daemon/networkdriver/portmapper/mapper.go @@ -48,6 +48,13 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { allocatedHostPort int ) + // release the port on any error during return. + defer func() { + if err != nil { + portallocator.ReleasePort(hostIP, proto, allocatedHostPort) + } + }() + switch container.(type) { case *net.TCPAddr: proto = "tcp" @@ -74,33 +81,22 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) (net.Addr, error) { return nil, err } - // When binding fails: - // - for a specifically requested port: it might be locked by some other - // process, so we want to allow for an ulterior retry - // - for an automatically allocated port: it falls in the Docker range of - // ports, so we'll just remember it as used and try the next free one - defer func() { - if err != nil && hostPort != 0 { - portallocator.ReleasePort(hostIP, proto, allocatedHostPort) - } - }() - key := getKey(m.host) if _, exists := currentMappings[key]; exists { err = ErrPortMappedForIP - return m.host, err + return nil, err } containerIP, containerPort := getIPAndPort(m.container) if err := forward(iptables.Add, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort); err != nil { - return m.host, err + return nil, err } p, err := newProxy(m.host, m.container) if err != nil { // need to undo the iptables rules before we return forward(iptables.Delete, m.proto, hostIP, allocatedHostPort, containerIP.String(), containerPort) - return m.host, err + return nil, err } m.userlandProxy = p -- cgit v1.2.1 From 08182da5d829762366b9bff9cb27b25a010ad1dd Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Fri, 27 Jun 2014 12:26:02 +0400 Subject: Integration cli tests on Links in inspect Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- integration-cli/docker_cli_links_test.go | 33 +++++++++++++++++++++++++++++++- integration-cli/docker_utils.go | 4 ++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_links_test.go b/integration-cli/docker_cli_links_test.go index 0480183bc7..d2616475c9 100644 --- a/integration-cli/docker_cli_links_test.go +++ b/integration-cli/docker_cli_links_test.go @@ -2,12 +2,13 @@ package main import ( "fmt" - "github.com/dotcloud/docker/pkg/iptables" "io/ioutil" "os" "os/exec" "strings" "testing" + + "github.com/dotcloud/docker/pkg/iptables" ) func TestEtcHostsRegularFile(t *testing.T) { @@ -90,3 +91,33 @@ func TestIpTablesRulesWhenLinkAndUnlink(t *testing.T) { logDone("link - verify iptables when link and unlink") } + +func TestInspectLinksStarted(t *testing.T) { + defer deleteAllContainers() + cmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10") + cmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10") + cmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sleep", "10") + links, err := inspectField("testinspectlink", "HostConfig.Links") + if err != nil { + t.Fatal(err) + } + if expected := "[/container1:/testinspectlink/alias1 /container2:/testinspectlink/alias2]"; links != expected { + t.Fatalf("Links %s, but expected %s", links, expected) + } + logDone("link - links in started container inspect") +} + +func TestInspectLinksStopped(t *testing.T) { + defer deleteAllContainers() + cmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10") + cmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10") + cmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true") + links, err := inspectField("testinspectlink", "HostConfig.Links") + if err != nil { + t.Fatal(err) + } + if expected := "[/container1:/testinspectlink/alias1 /container2:/testinspectlink/alias2]"; links != expected { + t.Fatalf("Links %s, but expected %s", links, expected) + } + logDone("link - links in stopped container inspect") +} diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index c1e306f2ee..cc45012437 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -16,6 +16,10 @@ import ( func deleteContainer(container string) error { container = strings.Replace(container, "\n", " ", -1) container = strings.Trim(container, " ") + killArgs := fmt.Sprintf("kill %v", container) + killSplitArgs := strings.Split(killArgs, " ") + killCmd := exec.Command(dockerBinary, killSplitArgs...) + runCommand(killCmd) rmArgs := fmt.Sprintf("rm %v", container) rmSplitArgs := strings.Split(rmArgs, " ") rmCmd := exec.Command(dockerBinary, rmSplitArgs...) -- cgit v1.2.1 From 0acec443745a917fb8e97d50609ff01b03888512 Mon Sep 17 00:00:00 2001 From: Fred Lifton Date: Fri, 27 Jun 2014 12:45:55 -0700 Subject: Changed add to group command to include -a (append) flag, for safety. In response to customer email. Docker-DCO-1.1-Signed-off-by: Fred Lifton (github: fredlf) --- docs/sources/installation/openSUSE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/installation/openSUSE.md b/docs/sources/installation/openSUSE.md index 165f953b06..b8d9122225 100644 --- a/docs/sources/installation/openSUSE.md +++ b/docs/sources/installation/openSUSE.md @@ -45,9 +45,9 @@ If we want Docker to start at boot, we should also: The docker package creates a new group named docker. Users, other than root user, need to be part of this group in order to interact with the -Docker daemon. +Docker daemon. You can add users with: - $ sudo usermod -G docker + $ sudo usermod -a -G docker **Done!** -- cgit v1.2.1 From 5a3d774e5651da772a065282a1fb1a31e19e911c Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Fri, 27 Jun 2014 14:53:35 -0400 Subject: allow overwrite in untar Docker-DCO-1.1-Signed-off-by: Tibor Vass (github: tiborvass) --- archive/archive.go | 15 +++++++++------ archive/archive_test.go | 3 +++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/archive/archive.go b/archive/archive.go index b9701b58af..8d8b7412cc 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -383,7 +383,8 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) // identity (uncompressed), gzip, bzip2, xz. // If `dest` does not exist, it is created unless there are multiple entries in `archive`. // In the latter case, an error is returned. -// An other error is returned if `dest` exists but is not a directory, to prevent overwriting. +// If `dest` is an existing file, it gets overwritten. +// If `dest` is an existing directory, its files get merged (with overwrite for conflicting files). func Untar(archive io.Reader, dest string, options *TarOptions) error { if archive == nil { return fmt.Errorf("Empty archive") @@ -399,7 +400,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { var ( dirs []*tar.Header - destNotExist bool + create bool multipleEntries bool ) @@ -408,9 +409,10 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { return err } // destination does not exist, so it is assumed it has to be created. - destNotExist = true + create = true } else if !fi.IsDir() { - return fmt.Errorf("Trying to untar to `%s`: exists but not a directory", dest) + // destination exists and is not a directory, so it will be overwritten. + create = true } // Iterate through the files in the archive. @@ -425,7 +427,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } // Return an error if destination needs to be created and there is more than 1 entry in the tar stream. - if destNotExist && multipleEntries { + if create && multipleEntries { return fmt.Errorf("Trying to untar an archive with multiple entries to an inexistant target `%s`: did you mean `%s` instead?", dest, filepath.Dir(dest)) } @@ -445,7 +447,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } var path string - if destNotExist { + if create { path = dest // we are renaming hdr.Name to dest } else { path = filepath.Join(dest, hdr.Name) @@ -465,6 +467,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } } } + if err := createTarFile(path, dest, hdr, tr, options == nil || !options.NoLchown); err != nil { return err } diff --git a/archive/archive_test.go b/archive/archive_test.go index e05cd72e49..1b5e146965 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -176,6 +176,9 @@ func TestTarUntarFile(t *testing.T) { if err := ioutil.WriteFile(path.Join(origin, "before", "file"), []byte("hello world"), 0700); err != nil { t.Fatal(err) } + if err := ioutil.WriteFile(path.Join(origin, "after", "file2"), []byte("please overwrite me"), 0700); err != nil { + t.Fatal(err) + } tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) if err != nil { -- cgit v1.2.1 From 2cdcfc0c57e375955d3ed7c8e1487f9d4751b255 Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Fri, 27 Jun 2014 15:57:20 -0700 Subject: portmapper: unit tests for remap problem Docker-DCO-1.1-Signed-off-by: Erik Hollensbe (github: erikh) --- daemon/networkdriver/portmapper/mapper_test.go | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/daemon/networkdriver/portmapper/mapper_test.go b/daemon/networkdriver/portmapper/mapper_test.go index cae74ebb8b..6affdc5445 100644 --- a/daemon/networkdriver/portmapper/mapper_test.go +++ b/daemon/networkdriver/portmapper/mapper_test.go @@ -1,6 +1,7 @@ package portmapper import ( + "github.com/dotcloud/docker/daemon/networkdriver/portallocator" "github.com/dotcloud/docker/pkg/iptables" "github.com/dotcloud/docker/pkg/proxy" "net" @@ -112,3 +113,40 @@ func TestGetUDPIPAndPort(t *testing.T) { t.Fatalf("expected port %d got %d", ep, port) } } + +func TestMapAllPortsSingleInterface(t *testing.T) { + dstIp1 := net.ParseIP("0.0.0.0") + srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")} + + hosts := []net.Addr{} + var host net.Addr + var err error + + defer func() { + for _, val := range hosts { + Unmap(val) + } + }() + + for i := 0; i < 10; i++ { + for i := portallocator.BeginPortRange; i < portallocator.EndPortRange; i++ { + if host, err = Map(srcAddr1, dstIp1, 0); err != nil { + t.Fatal(err) + } + + hosts = append(hosts, host) + } + + if _, err := Map(srcAddr1, dstIp1, portallocator.BeginPortRange); err == nil { + t.Fatal("Port %d should be bound but is not", portallocator.BeginPortRange) + } + + for _, val := range hosts { + if err := Unmap(val); err != nil { + t.Fatal(err) + } + } + + hosts = []net.Addr{} + } +} -- cgit v1.2.1 From a0b229071394e6534808f16c4570ed8fd9ff3a1c Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 27 Jun 2014 20:22:18 +0000 Subject: remove deprecated syntax for docker commit Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/client/commands.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 61ef426387..76d079fc30 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1546,17 +1546,12 @@ func (cli *DockerCli) CmdCommit(args ...string) error { return nil } - var name, repository, tag string - - if cmd.NArg() == 3 { - fmt.Fprintf(cli.err, "[DEPRECATED] The format 'CONTAINER [REPOSITORY [TAG]]' as been deprecated. Please use CONTAINER [REPOSITORY[:TAG]]\n") - name, repository, tag = cmd.Arg(0), cmd.Arg(1), cmd.Arg(2) - } else { - name = cmd.Arg(0) + var ( + name = cmd.Arg(0) repository, tag = utils.ParseRepositoryTag(cmd.Arg(1)) - } + ) - if name == "" { + if name == "" || len(cmd.Args()) > 2 { cmd.Usage() return nil } -- cgit v1.2.1 From 2edfb1e696d8f46ea4276b3952078b1553ea42eb Mon Sep 17 00:00:00 2001 From: LK4D4 Date: Sat, 28 Jun 2014 12:20:31 +0400 Subject: Update go-patricia to v1.0.1 Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- hack/vendor.sh | 2 +- vendor/src/github.com/tchap/go-patricia/.travis.yml | 9 --------- vendor/src/github.com/tchap/go-patricia/README.md | 12 ++++++++++-- vendor/src/github.com/tchap/go-patricia/patricia/children.go | 11 +++++------ 4 files changed, 16 insertions(+), 18 deletions(-) delete mode 100644 vendor/src/github.com/tchap/go-patricia/.travis.yml diff --git a/hack/vendor.sh b/hack/vendor.sh index b17ea0b3ab..e444a01c40 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -47,7 +47,7 @@ clone git github.com/gorilla/mux 136d54f81f clone git github.com/syndtr/gocapability 3c85049eae -clone git github.com/tchap/go-patricia v1.0.0 +clone git github.com/tchap/go-patricia v1.0.1 clone hg code.google.com/p/go.net 84a4013f96e0 diff --git a/vendor/src/github.com/tchap/go-patricia/.travis.yml b/vendor/src/github.com/tchap/go-patricia/.travis.yml deleted file mode 100644 index 66183e2ad4..0000000000 --- a/vendor/src/github.com/tchap/go-patricia/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.2 - - tip - -branches: - exclude: - - wip diff --git a/vendor/src/github.com/tchap/go-patricia/README.md b/vendor/src/github.com/tchap/go-patricia/README.md index 635e2b8ea7..11ee4612d3 100644 --- a/vendor/src/github.com/tchap/go-patricia/README.md +++ b/vendor/src/github.com/tchap/go-patricia/README.md @@ -1,8 +1,10 @@ # go-patricia # **Documentation**: [GoDoc](http://godoc.org/github.com/tchap/go-patricia/patricia)
-**Build Status**: [![Build Status](https://travis-ci.org/tchap/go-patricia.png?branch=master)](https://travis-ci.org/tchap/go-patricia)
-**Test Coverage**: Comming as soon as Drone.io people update their Go. +**Build Status**: [![Build +Status](https://drone.io/github.com/tchap/go-patricia/status.png)](https://drone.io/github.com/tchap/go-patricia/latest)
+**Test Coverage**: [![Coverage +Status](https://coveralls.io/repos/tchap/go-patricia/badge.png)](https://coveralls.io/r/tchap/go-patricia) ## About ## @@ -34,6 +36,12 @@ Import the package from GitHub first. import "github.com/tchap/go-patricia/patricia" ``` +You can as well use gopkg.in thingie: + +```go +import "gopkg.in/tchap/go-patricia.v1/patricia" +``` + Then you can start having fun. ```go diff --git a/vendor/src/github.com/tchap/go-patricia/patricia/children.go b/vendor/src/github.com/tchap/go-patricia/patricia/children.go index 42b0547de6..07d3326335 100644 --- a/vendor/src/github.com/tchap/go-patricia/patricia/children.go +++ b/vendor/src/github.com/tchap/go-patricia/patricia/children.go @@ -5,12 +5,11 @@ package patricia -const ( - // Max prefix length that is kept in a single trie node. - MaxPrefixPerNode = 10 - // Max children to keep in a node in the sparse mode. - MaxChildrenPerSparseNode = 8 -) +// Max prefix length that is kept in a single trie node. +var MaxPrefixPerNode = 10 + +// Max children to keep in a node in the sparse mode. +const MaxChildrenPerSparseNode = 8 type childList interface { length() int -- cgit v1.2.1 From 095cb7a81800512b99474aec7245bddddd1b2278 Mon Sep 17 00:00:00 2001 From: LK4D4 Date: Sat, 28 Jun 2014 12:27:44 +0400 Subject: Increase patricia.MaxPrefixPerNode It allows to avoid redundant prefix splits Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- pkg/truncindex/truncindex.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/truncindex/truncindex.go b/pkg/truncindex/truncindex.go index 811f606661..89aa88d6b7 100644 --- a/pkg/truncindex/truncindex.go +++ b/pkg/truncindex/truncindex.go @@ -13,6 +13,12 @@ var ( ErrNoID = errors.New("prefix can't be empty") ) +func init() { + // Change patricia max prefix per node length, + // because our len(ID) always 64 + patricia.MaxPrefixPerNode = 64 +} + // TruncIndex allows the retrieval of string identifiers by any of their unique prefixes. // This is used to retrieve image and container IDs by more convenient shorthand prefixes. type TruncIndex struct { -- cgit v1.2.1 From ea464ea212aa584dd0aa50820c78f7f60a77450d Mon Sep 17 00:00:00 2001 From: LK4D4 Date: Sat, 28 Jun 2014 12:38:29 +0400 Subject: Update gorilla/context Race condition was fixed recently Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- hack/vendor.sh | 2 +- vendor/src/github.com/gorilla/context/context.go | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/hack/vendor.sh b/hack/vendor.sh index b17ea0b3ab..fd7ca5ef71 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -41,7 +41,7 @@ clone() { clone git github.com/kr/pty 67e2db24c8 -clone git github.com/gorilla/context b06ed15e1c +clone git github.com/gorilla/context 14f550f51a clone git github.com/gorilla/mux 136d54f81f diff --git a/vendor/src/github.com/gorilla/context/context.go b/vendor/src/github.com/gorilla/context/context.go index a7f7d85bb4..81cb128b19 100644 --- a/vendor/src/github.com/gorilla/context/context.go +++ b/vendor/src/github.com/gorilla/context/context.go @@ -30,9 +30,10 @@ func Set(r *http.Request, key, val interface{}) { // Get returns a value stored for a given key in a given request. func Get(r *http.Request, key interface{}) interface{} { mutex.RLock() - if data[r] != nil { + if ctx := data[r]; ctx != nil { + value := ctx[key] mutex.RUnlock() - return data[r][key] + return value } mutex.RUnlock() return nil @@ -54,20 +55,28 @@ func GetOk(r *http.Request, key interface{}) (interface{}, bool) { func GetAll(r *http.Request) map[interface{}]interface{} { mutex.RLock() if context, ok := data[r]; ok { + result := make(map[interface{}]interface{}, len(context)) + for k, v := range context { + result[k] = v + } mutex.RUnlock() - return context + return result } mutex.RUnlock() return nil } -// GetAllOk returns all stored values for the request as a map. It returns not -// ok if the request was never registered. +// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if +// the request was registered. func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) { mutex.RLock() context, ok := data[r] + result := make(map[interface{}]interface{}, len(context)) + for k, v := range context { + result[k] = v + } mutex.RUnlock() - return context, ok + return result, ok } // Delete removes a value stored for a given key in a given request. -- cgit v1.2.1 From 4a5f09387e17860ba748d94028cb2a307c9e0b11 Mon Sep 17 00:00:00 2001 From: Mike Chelen Date: Sat, 28 Jun 2014 12:01:16 -0400 Subject: missing `sudo` --- docs/sources/userguide/dockerimages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockerimages.md b/docs/sources/userguide/dockerimages.md index ffcc39ddba..c3f5461c2f 100644 --- a/docs/sources/userguide/dockerimages.md +++ b/docs/sources/userguide/dockerimages.md @@ -380,7 +380,7 @@ containers]( Let's delete the `training/sinatra` image as we don't need it anymore. - $ docker rmi training/sinatra + $ sudo docker rmi training/sinatra Untagged: training/sinatra:latest Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f -- cgit v1.2.1 From 0d2656ce6e8536fcdb6d68b5899febe867f59c70 Mon Sep 17 00:00:00 2001 From: Mike Chelen Date: Sat, 28 Jun 2014 12:26:36 -0400 Subject: fix typo --- docs/sources/userguide/dockerlinks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/dockerlinks.md b/docs/sources/userguide/dockerlinks.md index 711fd979c8..20a5c1a179 100644 --- a/docs/sources/userguide/dockerlinks.md +++ b/docs/sources/userguide/dockerlinks.md @@ -94,7 +94,7 @@ yourself. This naming provides two useful functions: that makes it easier for you to remember them, for example naming a container with a web application in it `web`. -2. It provides Docker with reference point that allows it to refer to other +2. It provides Docker with a reference point that allows it to refer to other containers, for example link container `web` to container `db`. You can name your container by using the `--name` flag, for example: -- cgit v1.2.1 From 5c0819a0464624eba12b6a37462d549d7fed3be4 Mon Sep 17 00:00:00 2001 From: doug tangren Date: Sat, 28 Jun 2014 01:38:54 -0400 Subject: added linkage to tugboat, a scala client Docker-DCO-1.1-Signed-off-by: Doug Tangren (github: softprops) --- docs/sources/reference/api/remote_api_client_libraries.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/sources/reference/api/remote_api_client_libraries.md b/docs/sources/reference/api/remote_api_client_libraries.md index e299e6ed81..d1d26a1ddf 100644 --- a/docs/sources/reference/api/remote_api_client_libraries.md +++ b/docs/sources/reference/api/remote_api_client_libraries.md @@ -123,12 +123,18 @@ will add the libraries here. Active + Scala + tugboat + https://github.com/softprops/tugboat + Active + + Scala reactive-docker https://github.com/almoehi/reactive-docker Active - + Java docker-client https://github.com/spotify/docker-client -- cgit v1.2.1 From 3be683a0bbf25f41e9f4b1652f8f0784cafbd05b Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sun, 29 Jun 2014 19:45:08 -0300 Subject: Remove extra "Docker" from docs index --- docs/sources/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/index.md b/docs/sources/index.md index ef5fe2c2c0..57b9712238 100644 --- a/docs/sources/index.md +++ b/docs/sources/index.md @@ -46,7 +46,7 @@ Docker consists of: * Since Docker runs on so many platforms, it's easy to move your applications around. You can easily move an application from a testing environment into the cloud and back whenever you need. - * Docker's lightweight containers Docker also make scaling up and + * Docker's lightweight containers also make scaling up and down fast and easy. You can quickly launch more containers when needed and then shut them down easily when they're no longer needed. -- cgit v1.2.1 From 9a2771eac22950fce43702896052f5187944de6d Mon Sep 17 00:00:00 2001 From: Adrien Folie Date: Mon, 30 Jun 2014 01:31:16 +0200 Subject: Migrate TestGetImagesHistory into unit and CLI test Docker-DCO-1.1-Signed-off-by: Adrien Folie (github: folieadrien) --- api/server/server_unit_test.go | 27 +++++++++++++++++++++++++++ integration-cli/docker_cli_history_test.go | 18 ++++++++++++++++++ integration/api_test.go | 25 ------------------------- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/api/server/server_unit_test.go b/api/server/server_unit_test.go index 914cb7c0dc..4840a2526c 100644 --- a/api/server/server_unit_test.go +++ b/api/server/server_unit_test.go @@ -289,6 +289,33 @@ func TestLogsNoStreams(t *testing.T) { } } +func TestGetImagesHistory(t *testing.T) { + eng := engine.New() + imageName := "docker-test-image" + var called bool + eng.Register("history", func(job *engine.Job) engine.Status { + called = true + if job.Args[0] != imageName { + t.Fatalf("name != '%s': %#v", imageName, job.Args[0]) + } + v := &engine.Env{} + if _, err := v.WriteTo(job.Stdout); err != nil { + return job.Error(err) + } + return engine.StatusOK + }) + r := serveRequest("GET", "/images/"+imageName+"/history", nil, eng, t) + if !called { + t.Fatalf("handler was not called") + } + if r.Code != http.StatusOK { + t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK) + } + if r.HeaderMap.Get("Content-Type") != "application/json" { + t.Fatalf("%#v\n", r) + } +} + func serveRequest(method, target string, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder { r := httptest.NewRecorder() req, err := http.NewRequest(method, target, body) diff --git a/integration-cli/docker_cli_history_test.go b/integration-cli/docker_cli_history_test.go index 42edec2fd6..59ad117128 100644 --- a/integration-cli/docker_cli_history_test.go +++ b/integration-cli/docker_cli_history_test.go @@ -41,3 +41,21 @@ func TestBuildHistory(t *testing.T) { deleteImages("testbuildhistory") } + +func TestHistoryExistentImage(t *testing.T) { + historyCmd := exec.Command(dockerBinary, "history", "busybox") + _, exitCode, err := runCommandWithOutput(historyCmd) + if err != nil || exitCode != 0 { + t.Fatal("failed to get image history") + } + logDone("history - history on existent image must not fail") +} + +func TestHistoryNonExistentImage(t *testing.T) { + historyCmd := exec.Command(dockerBinary, "history", "testHistoryNonExistentImage") + _, exitCode, err := runCommandWithOutput(historyCmd) + if err == nil || exitCode == 0 { + t.Fatal("history on a non-existent image didn't result in a non-zero exit status") + } + logDone("history - history on non-existent image must fail") +} diff --git a/integration/api_test.go b/integration/api_test.go index 2d1b803682..b2e44717a5 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -4,7 +4,6 @@ import ( "bufio" "bytes" "encoding/json" - "fmt" "io" "io/ioutil" "net" @@ -125,30 +124,6 @@ func TestGetImagesJSON(t *testing.T) { } } -func TestGetImagesHistory(t *testing.T) { - eng := NewTestEngine(t) - defer mkDaemonFromEngine(eng, t).Nuke() - - r := httptest.NewRecorder() - - req, err := http.NewRequest("GET", fmt.Sprintf("/images/%s/history", unitTestImageName), nil) - if err != nil { - t.Fatal(err) - } - if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil { - t.Fatal(err) - } - assertHttpNotError(r, t) - - outs := engine.NewTable("Created", 0) - if _, err := outs.ReadListFrom(r.Body.Bytes()); err != nil { - t.Fatal(err) - } - if len(outs.Data) != 1 { - t.Errorf("Expected 1 line, %d found", len(outs.Data)) - } -} - func TestGetImagesByName(t *testing.T) { eng := NewTestEngine(t) defer mkDaemonFromEngine(eng, t).Nuke() -- cgit v1.2.1 From 24bf8faa99ef7c80aca3ee3a6eac485f74e521ef Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Mon, 30 Jun 2014 11:46:09 +1000 Subject: use the official image for now - there's an opensuse image on its way Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/sources/installation/openSUSE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/installation/openSUSE.md b/docs/sources/installation/openSUSE.md index 2affa81ef1..f714790205 100644 --- a/docs/sources/installation/openSUSE.md +++ b/docs/sources/installation/openSUSE.md @@ -49,9 +49,9 @@ Docker daemon. To verify that everything has worked as expected: - $ sudo docker run -i -t b1systems/opensuse /bin/bash + $ sudo docker run --rm -i -t ubuntu /bin/bash -This should download and import the `opensuse` image, and then start `bash` in a container. To exit the container type `exit`. +This should download and import the `ubuntu` image, and then start `bash` in a container. To exit the container type `exit`. **Done!** -- cgit v1.2.1 From 8c765ae68a4a9aceb9886f4d92f2ded7af144e22 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Sun, 29 Jun 2014 22:25:12 -0400 Subject: Formatting and consistency fixes to CLI and RUN references * Removed double backticks. * Reformatted paragraphs. * Fixed consistent STDOUT/STDIN/STDERR references. * Fixed several broken URLs. * Fixed backtick mismatches. Docker-DCO-1.1-Signed-off-by: James Turnbull (github: jamtur01) --- docs/sources/reference/commandline/cli.md | 84 ++++++----- docs/sources/reference/run.md | 223 +++++++++++++++--------------- 2 files changed, 154 insertions(+), 153 deletions(-) diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index cb5d39d93a..7277b4c978 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -199,26 +199,26 @@ To kill the container, use `docker kill`. --rm=true Remove intermediate containers after a successful build -t, --tag="" Repository name (and optionally a tag) to be applied to the resulting image in case of success -Use this command to build Docker images from a Dockerfile -and a "context". - -The files at `PATH` or `URL` are called the "context" of the build. The build -process may refer to any of the files in the context, for example when using an -[*ADD*](/reference/builder/#dockerfile-add) instruction. When a single Dockerfile is -given as `URL` or is piped through STDIN (`docker build - < Dockerfile`), then -no context is set. - -When a Git repository is set as `URL`, then the -repository is used as the context. The Git repository is cloned with its -submodules (git clone –recursive). A fresh git clone occurs in a -temporary directory on your local host, and then this is sent to the -Docker daemon as the context. This way, your local user credentials and -vpn's etc can be used to access private repositories. - -If a file named ``.dockerignore`` exists in the root of ``PATH`` then it is -interpreted as a newline-separated list of exclusion patterns. Exclusion -patterns match files or directories relative to ``PATH`` that will be excluded -from the context. Globbing is done using Go's +Use this command to build Docker images from a Dockerfile and a +"context". + +The files at `PATH` or `URL` are called the "context" of the build. The +build process may refer to any of the files in the context, for example +when using an [*ADD*](/reference/builder/#dockerfile-add) instruction. +When a single Dockerfile is given as `URL` or is piped through `STDIN` +(`docker build - < Dockerfile`), then no context is set. + +When a Git repository is set as `URL`, then the repository is used as +the context. The Git repository is cloned with its submodules (`git +clone -recursive`). A fresh `git clone` occurs in a temporary directory +on your local host, and then this is sent to the Docker daemon as the +context. This way, your local user credentials and VPN's etc can be +used to access private repositories. + +If a file named `.dockerignore` exists in the root of `PATH` then it +is interpreted as a newline-separated list of exclusion patterns. +Exclusion patterns match files or directories relative to `PATH` that +will be excluded from the context. Globbing is done using Go's [filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. See also: @@ -304,15 +304,14 @@ and the tag will be `2.0` $ sudo docker build - < Dockerfile -This will read a Dockerfile from STDIN without -context. Due to the lack of a context, no contents of any local -directory will be sent to the `docker` daemon. Since -there is no context, a Dockerfile `ADD` -only works if it refers to a remote URL. +This will read a Dockerfile from `STDIN` without context. Due to the +lack of a context, no contents of any local directory will be sent to +the Docker daemon. Since there is no context, a Dockerfile `ADD` only +works if it refers to a remote URL. $ sudo docker build - < context.tar.gz -This will build an image for a compressed context read from STDIN. +This will build an image for a compressed context read from `STDIN`. Supported formats are: bzip2, gzip and xz. $ sudo docker build github.com/creack/docker-firefox @@ -518,7 +517,7 @@ by default. ### Filtering -The filtering flag (-f or --filter) format is of "key=value". If there are more +The filtering flag (`-f` or `--filter`) format is of "key=value". If there are more than one filter, then pass multiple flags (e.g. `--filter "foo=bar" --filter "bif=baz"`) Current filters: @@ -562,11 +561,10 @@ NOTE: Docker will warn you if any containers exist that are using these untagged Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it. -URLs must start with `http` and point to a single -file archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, or .txz) containing a -root filesystem. If you would like to import from a local directory or -archive, you can use the `-` parameter to take the -data from STDIN. +URLs must start with `http` and point to a single file archive (.tar, +.tar.gz, .tgz, .bzip, .tar.xz, or .txz) containing a root filesystem. If +you would like to import from a local directory or archive, you can use +the `-` parameter to take the data from `STDIN`. ### Examples @@ -578,7 +576,7 @@ This will create a new untagged image. **Import from a local file:** -Import to docker via pipe and STDIN. +Import to docker via pipe and `STDIN`. $ cat exampleimage.tgz | sudo docker import - exampleimagelocal:new @@ -681,7 +679,7 @@ contains complex json object, so to grab it as JSON, you use -s, --signal="KILL" Signal to send to the container -The main process inside the container will be sent SIGKILL, or any +The main process inside the container will be sent `SIGKILL`, or any signal specified with option `--signal`. ## load @@ -739,8 +737,8 @@ The `docker logs` command batch-retrieves all logs present at the time of execution. The ``docker logs --follow`` command will first return all logs from the -beginning and then continue streaming new output from the container's stdout -and stderr. +beginning and then continue streaming new output from the container's `STDOUT` +and `STDERR`. ## port @@ -1074,7 +1072,7 @@ This will create and run a new container with the container name being The `--link` flag will link the container named `/redis` into the newly created container with the alias `redis`. The new container can access the -network and environment of the redis container via environment variables. +network and environment of the `redis` container via environment variables. The `--name` flag will assign the name `console` to the newly created container. @@ -1087,19 +1085,19 @@ optionally suffixed with `:ro` or `:rw` to mount the volumes in read-only or read-write mode, respectively. By default, the volumes are mounted in the same mode (read write or read only) as the reference container. -The `-a` flag tells `docker run` to bind to the container's stdin, stdout or -stderr. This makes it possible to manipulate the output and input as needed. +The `-a` flag tells `docker run` to bind to the container's `STDIN`, `STDOUT` or +`STDERR`. This makes it possible to manipulate the output and input as needed. $ echo "test" | sudo docker run -i -a stdin ubuntu cat - This pipes data into a container and prints the container's ID by attaching -only to the container'sstdin. +only to the container's `STDIN`. $ sudo docker run -a stderr ubuntu echo test -This isn't going to print anything unless there's an error because We've -only attached to the stderr of the container. The container's logs still - store what's been written to stderr and stdout. +This isn't going to print anything unless there's an error because we've +only attached to the `STDERR` of the container. The container's logs +still store what's been written to `STDERR` and `STDOUT`. $ cat somefile | sudo docker run -i -a stdin mybuilder dobuild diff --git a/docs/sources/reference/run.md b/docs/sources/reference/run.md index 80429d7e2e..37dba587b6 100644 --- a/docs/sources/reference/run.md +++ b/docs/sources/reference/run.md @@ -5,13 +5,13 @@ page_keywords: docker, run, configure, runtime # Docker Run Reference **Docker runs processes in isolated containers**. When an operator -executes `docker run`, she starts a process with its -own file system, its own networking, and its own isolated process tree. -The [*Image*](/terms/image/#image-def) which starts the process may -define defaults related to the binary to run, the networking to expose, -and more, but `docker run` gives final control to -the operator who starts the container from the image. That's the main -reason [*run*](/reference/commandline/cli/#cli-run) has more options than any +executes `docker run`, she starts a process with its own file system, +its own networking, and its own isolated process tree. The +[*Image*](/terms/image/#image-def) which starts the process may define +defaults related to the binary to run, the networking to expose, and +more, but `docker run` gives final control to the operator who starts +the container from the image. That's the main reason +[*run*](/reference/commandline/cli/#cli-run) has more options than any other `docker` command. ## General Form @@ -36,10 +36,10 @@ The list of `[OPTIONS]` breaks down into two groups: 2. Setting shared between operators and developers, where operators can override defaults developers set in images at build time. -Together, the `docker run [OPTIONS]` give complete -control over runtime behavior to the operator, allowing them to override -all defaults set by the developer during `docker build` -and nearly all the defaults set by the Docker runtime itself. +Together, the `docker run [OPTIONS]` give complete control over runtime +behavior to the operator, allowing them to override all defaults set by +the developer during `docker build` and nearly all the defaults set by +the Docker runtime itself. ## Operator Exclusive Options @@ -54,10 +54,8 @@ following options. - [PID Equivalent](#pid-equivalent) - [Network Settings](#network-settings) - [Clean Up (--rm)](#clean-up-rm) - - [Runtime Constraints on CPU and - Memory](#runtime-constraints-on-cpu-and-memory) - - [Runtime Privilege and LXC - Configuration](#runtime-privilege-and-lxc-configuration) + - [Runtime Constraints on CPU and Memory](#runtime-constraints-on-cpu-and-memory) + - [Runtime Privilege and LXC Configuration](#runtime-privilege-and-lxc-configuration) ## Detached vs Foreground @@ -78,28 +76,28 @@ container in the detached mode, then you cannot use the `--rm` option. ### Foreground -In foreground mode (the default when `-d` is not specified), `docker run` -can start the process in the container and attach the console to the process's -standard input, output, and standard error. It can even pretend to be a TTY -(this is what most command line executables expect) and pass along signals. All -of that is configurable: +In foreground mode (the default when `-d` is not specified), `docker +run` can start the process in the container and attach the console to +the process's standard input, output, and standard error. It can even +pretend to be a TTY (this is what most command line executables expect) +and pass along signals. All of that is configurable: - -a=[] : Attach to ``stdin``, ``stdout`` and/or ``stderr`` + -a=[] : Attach to `STDIN`, `STDOUT` and/or `STDERR` -t=false : Allocate a pseudo-tty --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode) -i=false : Keep STDIN open even if not attached -If you do not specify `-a` then Docker will [attach everything (stdin,stdout,stderr)]( -https://github.com/dotcloud/docker/blob/ -75a7f4d90cde0295bcfb7213004abce8d4779b75/commands.go#L1797). You can specify to which -of the three standard streams (`stdin`, `stdout`, `stderr`) you'd like to connect -instead, as in: +If you do not specify `-a` then Docker will [attach all standard +streams]( https://github.com/dotcloud/docker/blob/ +75a7f4d90cde0295bcfb7213004abce8d4779b75/commands.go#L1797). You can +specify to which of the three standard streams (`STDIN`, `STDOUT`, +`STDERR`) you'd like to connect instead, as in: $ docker run -a stdin -a stdout -i -t ubuntu /bin/bash -For interactive processes (like a shell) you will typically want a tty as well as -persistent standard input (`stdin`), so you'll use `-i -t` together in most -interactive cases. +For interactive processes (like a shell) you will typically want a tty +as well as persistent standard input (`STDIN`), so you'll use `-i -t` +together in most interactive cases. ## Container Identification @@ -113,19 +111,18 @@ The operator can identify a container in three ways: - Name ("evil_ptolemy") The UUID identifiers come from the Docker daemon, and if you do not -assign a name to the container with `--name` then -the daemon will also generate a random string name too. The name can -become a handy way to add meaning to a container since you can use this -name when defining -[*links*](/userguide/dockerlinks/#working-with-links-names) -(or any other place you need to identify a container). This works for -both background and foreground Docker containers. +assign a name to the container with `--name` then the daemon will also +generate a random string name too. The name can become a handy way to +add meaning to a container since you can use this name when defining +[*links*](/userguide/dockerlinks/#working-with-links-names) (or any +other place you need to identify a container). This works for both +background and foreground Docker containers. -### PID Equivalent +### PID Equivalent -And finally, to help with automation, you can have Docker write the +Finally, to help with automation, you can have Docker write the container ID out to a file of your choosing. This is similar to how some -programs might write out their process ID to a file (you`ve seen them as +programs might write out their process ID to a file (you've seen them as PID files): --cidfile="": Write the container ID to the file @@ -141,14 +138,14 @@ PID files): By default, all containers have networking enabled and they can make any outgoing connections. The operator can completely disable networking -with `docker run --net none` which disables all incoming and -outgoing networking. In cases like this, you would perform I/O through -files or STDIN/STDOUT only. +with `docker run --net none` which disables all incoming and outgoing +networking. In cases like this, you would perform I/O through files or +`STDIN` and `STDOUT` only. Your container will use the same DNS servers as the host by default, but you can override this with `--dns`. -Supported networking modes are: +Supported networking modes are: * none - no networking in the container * bridge - (default) connect the container to the bridge via veth interfaces @@ -156,35 +153,40 @@ Supported networking modes are: * container - use another container's network stack #### Mode: none -With the networking mode set to `none` a container will not have a access to -any external routes. The container will still have a `loopback` interface -enabled in the container but it does not have any routes to external traffic. + +With the networking mode set to `none` a container will not have a +access to any external routes. The container will still have a +`loopback` interface enabled in the container but it does not have any +routes to external traffic. #### Mode: bridge -With the networking mode set to `bridge` a container will use docker's default -networking setup. A bridge is setup on the host, commonly named `docker0`, -and a pair of veth interfaces will be created for the container. One side of -the veth pair will remain on the host attached to the bridge while the other -side of the pair will be placed inside the container's namespaces in addition -to the `loopback` interface. An IP address will be allocated for containers -on the bridge's network and trafic will be routed though this bridge to the -container. + +With the networking mode set to `bridge` a container will use docker's +default networking setup. A bridge is setup on the host, commonly named +`docker0`, and a pair of `veth` interfaces will be created for the +container. One side of the `veth` pair will remain on the host attached +to the bridge while the other side of the pair will be placed inside the +container's namespaces in addition to the `loopback` interface. An IP +address will be allocated for containers on the bridge's network and +traffic will be routed though this bridge to the container. #### Mode: host + With the networking mode set to `host` a container will share the host's -network stack and all interfaces from the host will be available to the -container. The container's hostname will match the hostname on the host -system. Publishing ports and linking to other containers will not work -when sharing the host's network stack. +network stack and all interfaces from the host will be available to the +container. The container's hostname will match the hostname on the host +system. Publishing ports and linking to other containers will not work +when sharing the host's network stack. #### Mode: container -With the networking mode set to `container` a container will share the -network stack of another container. The other container's name must be + +With the networking mode set to `container` a container will share the +network stack of another container. The other container's name must be provided in the format of `--net container:`. -Example running a redis container with redis binding to localhost then -running the redis-cli and connecting to the redis server over the -localhost interface. +Example running a Redis container with Redis binding to `localhost` then +running the `redis-cli` command and connecting to the Redis server over the +`localhost` interface. $ docker run -d --name redis example/redis --bind 127.0.0.1 $ # use the redis container's network stack to access localhost @@ -211,15 +213,14 @@ container: -c=0 : CPU shares (relative weight) The operator can constrain the memory available to a container easily -with `docker run -m`. If the host supports swap -memory, then the `-m` memory setting can be larger -than physical RAM. +with `docker run -m`. If the host supports swap memory, then the `-m` +memory setting can be larger than physical RAM. Similarly the operator can increase the priority of this container with -the `-c` option. By default, all containers run at -the same priority and get the same proportion of CPU cycles, but you can -tell the kernel to give more shares of CPU time to one or more -containers when you start them via Docker. +the `-c` option. By default, all containers run at the same priority and +get the same proportion of CPU cycles, but you can tell the kernel to +give more shares of CPU time to one or more containers when you start +them via Docker. ## Runtime Privilege and LXC Configuration @@ -277,19 +278,20 @@ commandline: $ docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...] -This command is optional because the person who created the `IMAGE` may have -already provided a default `COMMAND` using the Dockerfile `CMD`. As the -operator (the person running a container from the image), you can override that -`CMD` just by specifying a new `COMMAND`. +This command is optional because the person who created the `IMAGE` may +have already provided a default `COMMAND` using the Dockerfile `CMD` +instruction. As the operator (the person running a container from the +image), you can override that `CMD` instruction just by specifying a new +`COMMAND`. -If the image also specifies an `ENTRYPOINT` then the `CMD` or `COMMAND` get -appended as arguments to the `ENTRYPOINT`. +If the image also specifies an `ENTRYPOINT` then the `CMD` or `COMMAND` +get appended as arguments to the `ENTRYPOINT`. ## ENTRYPOINT (Default Command to Execute at Runtime) --entrypoint="": Overwrite the default entrypoint set by the image -The ENTRYPOINT of an image is similar to a `COMMAND` because it +The `ENTRYPOINT` of an image is similar to a `COMMAND` because it specifies what executable to run when the container starts, but it is (purposely) more difficult to override. The `ENTRYPOINT` gives a container its default nature or behavior, so that when you set an @@ -310,10 +312,10 @@ or two examples of how to pass more parameters to that ENTRYPOINT: ## EXPOSE (Incoming Ports) -The Dockerfile doesn't give much control over networking, only providing the -`EXPOSE` instruction to give a hint to the operator about what incoming ports -might provide services. The following options work with or override the -Dockerfile's exposed defaults: +The Dockerfile doesn't give much control over networking, only providing +the `EXPOSE` instruction to give a hint to the operator about what +incoming ports might provide services. The following options work with +or override the Dockerfile's exposed defaults: --expose=[]: Expose a port from the container without publishing it to your host @@ -324,34 +326,34 @@ Dockerfile's exposed defaults: (use 'docker port' to see the actual mapping) --link="" : Add link to another container (name:alias) -As mentioned previously, `EXPOSE` (and `--expose`) make a port available **in** -a container for incoming connections. The port number on the inside of the -container (where the service listens) does not need to be the same number as the -port exposed on the outside of the container (where clients connect), so inside -the container you might have an HTTP service listening on port 80 (and so you -`EXPOSE 80` in the Dockerfile), but outside the container the port might be -42800. +As mentioned previously, `EXPOSE` (and `--expose`) make a port available +**in** a container for incoming connections. The port number on the +inside of the container (where the service listens) does not need to be +the same number as the port exposed on the outside of the container +(where clients connect), so inside the container you might have an HTTP +service listening on port 80 (and so you `EXPOSE 80` in the Dockerfile), +but outside the container the port might be 42800. -To help a new client container reach the server container's internal port -operator `--expose`'d by the operator or `EXPOSE`'d by the developer, the -operator has three choices: start the server container with `-P` or `-p,` or -start the client container with `--link`. +To help a new client container reach the server container's internal +port operator `--expose`'d by the operator or `EXPOSE`'d by the +developer, the operator has three choices: start the server container +with `-P` or `-p,` or start the client container with `--link`. If the operator uses `-P` or `-p` then Docker will make the exposed port -accessible on the host and the ports will be available to any client that -can reach the host. To find the map between the host ports and the exposed -ports, use `docker port`) +accessible on the host and the ports will be available to any client +that can reach the host. To find the map between the host ports and the +exposed ports, use `docker port`) -If the operator uses `--link` when starting the new client container, then the -client container can access the exposed port via a private networking interface. -Docker will set some environment variables in the client container to help -indicate which interface and port to use. +If the operator uses `--link` when starting the new client container, +then the client container can access the exposed port via a private +networking interface. Docker will set some environment variables in the +client container to help indicate which interface and port to use. ## ENV (Environment Variables) -The operator can **set any environment variable** in the container by using one -or more `-e` flags, even overriding those already defined by the developer with -a Dockerfile `ENV`: +The operator can **set any environment variable** in the container by +using one or more `-e` flags, even overriding those already defined by +the developer with a Dockerfile `ENV`: $ docker run -e "deep=purple" --rm ubuntu /bin/bash -c export declare -x HOME="/" @@ -420,18 +422,19 @@ mechanism to communicate with a linked container by its alias: If "container-dir" is missing, then docker creates a new volume. --volumes-from="": Mount all volumes from the given container(s) -The volumes commands are complex enough to have their own documentation in -section [*Share Directories via Volumes*](/userguide/dockervolumes/#volume-def). -A developer can define one or more `VOLUME's associated with an image, but only the -operator can give access from one container to another (or from a container to a +The volumes commands are complex enough to have their own documentation +in section [*Share Directories via +Volumes*](/userguide/dockervolumes/#volume-def). A developer can define +one or more `VOLUME`'s associated with an image, but only the operator +can give access from one container to another (or from a container to a volume mounted on the host). ## USER -The default user within a container is `root` (id = 0), but if the developer -created additional users, those are accessible too. The developer can set a -default user to run the first process with the `Dockerfile USER` command, -but the operator can override it: +The default user within a container is `root` (id = 0), but if the +developer created additional users, those are accessible too. The +developer can set a default user to run the first process with the +Dockerfile `USER` instruction, but the operator can override it: -u="": Username or UID -- cgit v1.2.1 From 26332fe339d4d939d91fe00a0df849d564026005 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Mon, 30 Jun 2014 14:19:16 +1000 Subject: Add the 1.13 API docs to the menu Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 5c3147a285..21b334197e 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -103,6 +103,7 @@ pages: - ['reference/api/registry_api.md', 'Reference', 'Docker Registry API'] - ['reference/api/hub_registry_spec.md', 'Reference', 'Docker Hub and Registry Spec'] - ['reference/api/docker_remote_api.md', 'Reference', 'Docker Remote API'] +- ['reference/api/docker_remote_api_v1.13.md', 'Reference', 'Docker Remote API v1.13'] - ['reference/api/docker_remote_api_v1.12.md', 'Reference', 'Docker Remote API v1.12'] - ['reference/api/docker_remote_api_v1.11.md', 'Reference', 'Docker Remote API v1.11'] - ['reference/api/docker_remote_api_v1.10.md', '**HIDDEN**'] -- cgit v1.2.1 From c2699d8d896d592dc02276d76dfdf544fd26d0dd Mon Sep 17 00:00:00 2001 From: Adrien Folie Date: Mon, 30 Jun 2014 09:36:46 +0000 Subject: Add missing test for full coverage Docker-DCO-1.1-Signed-off-by: Adrien Folie (github: folieadrien) --- api/server/server_unit_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/server/server_unit_test.go b/api/server/server_unit_test.go index 4840a2526c..2d14f89551 100644 --- a/api/server/server_unit_test.go +++ b/api/server/server_unit_test.go @@ -295,6 +295,9 @@ func TestGetImagesHistory(t *testing.T) { var called bool eng.Register("history", func(job *engine.Job) engine.Status { called = true + if len(job.Args) == 0 { + t.Fatal("Job arguments is empty") + } if job.Args[0] != imageName { t.Fatalf("name != '%s': %#v", imageName, job.Args[0]) } -- cgit v1.2.1 From eb1e8e884d92a7086af96663d0c658d838315490 Mon Sep 17 00:00:00 2001 From: unclejack Date: Mon, 30 Jun 2014 22:22:29 +0300 Subject: integration cli: add imageExists to docker utils Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- integration-cli/docker_utils.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index cc45012437..22217e2f03 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -66,6 +66,15 @@ func deleteImages(images string) error { return err } +func imageExists(image string) error { + inspectCmd := exec.Command(dockerBinary, "inspect", image) + exitCode, err := runCommand(inspectCmd) + if exitCode != 0 && err == nil { + err = fmt.Errorf("couldn't find image '%s'", image) + } + return err +} + func cmd(t *testing.T, args ...string) (string, int, error) { out, status, err := runCommandWithOutput(exec.Command(dockerBinary, args...)) errorOut(err, t, fmt.Sprintf("'%s' failed with errors: %v (%v)", strings.Join(args, " "), err, out)) -- cgit v1.2.1 From 63e28cc363c5f13288335e811f075e2423375b05 Mon Sep 17 00:00:00 2001 From: unclejack Date: Mon, 30 Jun 2014 22:25:50 +0300 Subject: make TestRemoveContainerRunning handle signals This lowers the test execution time by about 5 seconds. Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- integration-cli/docker_cli_rm_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_rm_test.go b/integration-cli/docker_cli_rm_test.go index e25c9991de..34b5df0338 100644 --- a/integration-cli/docker_cli_rm_test.go +++ b/integration-cli/docker_cli_rm_test.go @@ -43,7 +43,7 @@ func TestRemoveContainerWithVolume(t *testing.T) { } func TestRemoveContainerRunning(t *testing.T) { - cmd := exec.Command(dockerBinary, "run", "-d", "--name", "foo", "busybox", "sleep", "300") + cmd := exec.Command(dockerBinary, "run", "-dt", "--name", "foo", "busybox", "top") if _, err := runCommand(cmd); err != nil { t.Fatal(err) } -- cgit v1.2.1 From 262d45e0fe483dbc6d27bc6af51590a8be42d55f Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Mon, 30 Jun 2014 18:27:15 -0400 Subject: Use new libcontainer.State API Docker-DCO-1.1-Signed-off-by: Tibor Vass (github: tiborvass) --- daemon/execdriver/native/driver.go | 12 ++---------- daemon/execdriver/native/info.go | 5 +++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index 7cbb563ea7..1f27ef77b3 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -171,7 +171,7 @@ func (d *driver) Unpause(c *execdriver.Command) error { func (d *driver) Terminate(p *execdriver.Command) error { // lets check the start time for the process - started, err := d.readStartTime(p) + state, err := libcontainer.GetState(filepath.Join(d.root, p.ID)) if err != nil { // if we don't have the data on disk then we can assume the process is gone // because this is only removed after we know the process has stopped @@ -185,7 +185,7 @@ func (d *driver) Terminate(p *execdriver.Command) error { if err != nil { return err } - if started == currentStartTime { + if state.InitStartTime == currentStartTime { err = syscall.Kill(p.Process.Pid, 9) syscall.Wait4(p.Process.Pid, nil, 0, nil) } @@ -194,14 +194,6 @@ func (d *driver) Terminate(p *execdriver.Command) error { } -func (d *driver) readStartTime(p *execdriver.Command) (string, error) { - data, err := ioutil.ReadFile(filepath.Join(d.root, p.ID, "start")) - if err != nil { - return "", err - } - return string(data), nil -} - func (d *driver) Info(id string) execdriver.Info { return &info{ ID: id, diff --git a/daemon/execdriver/native/info.go b/daemon/execdriver/native/info.go index aef2f85c6b..693a455a41 100644 --- a/daemon/execdriver/native/info.go +++ b/daemon/execdriver/native/info.go @@ -1,8 +1,9 @@ package native import ( - "os" "path/filepath" + + "github.com/docker/libcontainer" ) type info struct { @@ -14,7 +15,7 @@ type info struct { // pid file for a container. If the file exists then the // container is currently running func (i *info) IsRunning() bool { - if _, err := os.Stat(filepath.Join(i.driver.root, i.ID, "pid")); err == nil { + if _, err := libcontainer.GetState(filepath.Join(i.driver.root, i.ID)); err == nil { return true } return false -- cgit v1.2.1 From b44e13ae023816ed9d36b6dc6d74f089fc402cab Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Fri, 27 Jun 2014 13:32:01 +0200 Subject: Fixed typographical erros in the documentation Used the RETF rules provided by Wikipedia to fix some typographical errors in the Markdown files of the documentation with the following script: https://github.com/openstack/openstack-doc-tools/tree/master/cleanup/retf Docker-DCO-1.1-Signed-off-by: Christian Berendt (github: berendt) Docker-DCO-1.1-Signed-off-by: Christian Berendt (github: SvenDowideit) --- docs/man/Dockerfile.5.md | 2 +- docs/man/docker-commit.1.md | 2 +- docs/man/docker-run.1.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.0.md | 6 +++--- docs/sources/reference/api/docker_remote_api_v1.1.md | 6 +++--- docs/sources/reference/api/docker_remote_api_v1.10.md | 6 +++--- docs/sources/reference/api/docker_remote_api_v1.11.md | 10 +++++----- docs/sources/reference/api/docker_remote_api_v1.12.md | 10 +++++----- docs/sources/reference/api/docker_remote_api_v1.13.md | 10 +++++----- docs/sources/reference/api/docker_remote_api_v1.2.md | 6 +++--- docs/sources/reference/api/docker_remote_api_v1.3.md | 6 +++--- docs/sources/reference/api/docker_remote_api_v1.4.md | 8 ++++---- docs/sources/reference/api/docker_remote_api_v1.5.md | 8 ++++---- docs/sources/reference/api/docker_remote_api_v1.6.md | 10 +++++----- docs/sources/reference/api/docker_remote_api_v1.7.md | 10 +++++----- docs/sources/reference/api/docker_remote_api_v1.8.md | 10 +++++----- docs/sources/reference/api/docker_remote_api_v1.9.md | 10 +++++----- 17 files changed, 62 insertions(+), 62 deletions(-) diff --git a/docs/man/Dockerfile.5.md b/docs/man/Dockerfile.5.md index d669122107..73c1312b87 100644 --- a/docs/man/Dockerfile.5.md +++ b/docs/man/Dockerfile.5.md @@ -93,7 +93,7 @@ or they omit the executable, an ENTRYPOINT must be specified. When used in the shell or exec formats, the CMD instruction sets the command to be executed when running the image. - If you use the shell form of of the CMD, the executes in /bin/sh -c: + If you use the shell form of the CMD, the executes in /bin/sh -c: **FROM ubuntu** **CMD echo "This is a test." | wc -** If you run wihtout a shell, then you must express the command as a diff --git a/docs/man/docker-commit.1.md b/docs/man/docker-commit.1.md index 03bf17872d..b72c385bff 100644 --- a/docs/man/docker-commit.1.md +++ b/docs/man/docker-commit.1.md @@ -14,7 +14,7 @@ Using an existing container's name or ID you can create a new image. # OPTIONS **-a, --author**="" - Author name. (eg. "John Hannibal Smith " + Author name. (e.g. "John Hannibal Smith " **-m, --message**="" Commit message diff --git a/docs/man/docker-run.1.md b/docs/man/docker-run.1.md index 1abcf03f2d..bac64aa185 100644 --- a/docs/man/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -13,7 +13,7 @@ docker-run - Run a process in an isolated container [**--link**=*name*:*alias*] [**-e**|**--env**=*environment*] [**--entrypoint**=*command*] [**--expose**=*port*] [**-P**|**--publish-all**[=*false*]] -[**-p**|**--publish**=*port-mappping*] [**-h**|**--hostname**=*hostname*] +[**-p**|**--publish**=*port-mapping*] [**-h**|**--hostname**=*hostname*] [**--rm**[=*false*]] [**--privileged**[=*false*]] [**-i**|**--interactive**[=*false*]] [**-t**|**--tty**[=*false*]] [**--lxc-conf**=*options*] @@ -71,7 +71,7 @@ stopping the process by pressing the keys CTRL-P CTRL-Q. **--dns**=*IP-address* Set custom DNS servers. This option can be used to override the DNS configuration passed to the container. Typically this is necessary when the -host DNS configuration is invalid for the container (eg. 127.0.0.1). When this +host DNS configuration is invalid for the container (e.g. 127.0.0.1). When this is the case the **-dns** flags is necessary for every run. diff --git a/docs/sources/reference/api/docker_remote_api_v1.0.md b/docs/sources/reference/api/docker_remote_api_v1.0.md index 2f17b2a74d..b5ca1b5130 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.0.md +++ b/docs/sources/reference/api/docker_remote_api_v1.0.md @@ -605,8 +605,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -935,7 +935,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.1.md b/docs/sources/reference/api/docker_remote_api_v1.1.md index e777901c6c..70617a4a1f 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.1.md +++ b/docs/sources/reference/api/docker_remote_api_v1.1.md @@ -612,8 +612,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -946,7 +946,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.10.md b/docs/sources/reference/api/docker_remote_api_v1.10.md index 0292c1ab2f..01a176d86b 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.10.md +++ b/docs/sources/reference/api/docker_remote_api_v1.10.md @@ -286,7 +286,7 @@ List processes running inside the container `id`   - - **ps\_args** – ps arguments to use (eg. aux) + - **ps\_args** – ps arguments to use (e.g. aux) Status Codes: @@ -530,7 +530,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -1181,7 +1181,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.11.md b/docs/sources/reference/api/docker_remote_api_v1.11.md index 63444a83e0..35abd35fb1 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.11.md +++ b/docs/sources/reference/api/docker_remote_api_v1.11.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -570,7 +570,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -791,8 +791,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1223,7 +1223,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.12.md b/docs/sources/reference/api/docker_remote_api_v1.12.md index 51727be263..66408eb15e 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.12.md +++ b/docs/sources/reference/api/docker_remote_api_v1.12.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -611,7 +611,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -865,8 +865,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1301,7 +1301,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md index 117052aebe..454aec530c 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.13.md +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -613,7 +613,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -867,8 +867,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1304,7 +1304,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.2.md b/docs/sources/reference/api/docker_remote_api_v1.2.md index cecab5bb4e..82084606e6 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.2.md +++ b/docs/sources/reference/api/docker_remote_api_v1.2.md @@ -628,8 +628,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -959,7 +959,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.3.md b/docs/sources/reference/api/docker_remote_api_v1.3.md index 1d60b4300d..b28194d882 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.3.md +++ b/docs/sources/reference/api/docker_remote_api_v1.3.md @@ -678,8 +678,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"" @@ -1009,7 +1009,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.4.md b/docs/sources/reference/api/docker_remote_api_v1.4.md index f7d6e82c19..be5678d678 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.4.md +++ b/docs/sources/reference/api/docker_remote_api_v1.4.md @@ -264,7 +264,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -724,8 +724,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"", @@ -1055,7 +1055,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.5.md b/docs/sources/reference/api/docker_remote_api_v1.5.md index 53d970accd..08e7077c1f 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.5.md +++ b/docs/sources/reference/api/docker_remote_api_v1.5.md @@ -261,7 +261,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -725,8 +725,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"centos", "Volumes":null, "VolumesFrom":"", @@ -1067,7 +1067,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.6.md b/docs/sources/reference/api/docker_remote_api_v1.6.md index 9b7cded33f..e657252f19 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.6.md +++ b/docs/sources/reference/api/docker_remote_api_v1.6.md @@ -311,7 +311,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -558,7 +558,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -832,8 +832,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1163,7 +1163,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.7.md b/docs/sources/reference/api/docker_remote_api_v1.7.md index 3432e9bb21..66a93667a0 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.7.md +++ b/docs/sources/reference/api/docker_remote_api_v1.7.md @@ -267,7 +267,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -507,7 +507,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -751,8 +751,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1112,7 +1112,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") - **run** – config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) diff --git a/docs/sources/reference/api/docker_remote_api_v1.8.md b/docs/sources/reference/api/docker_remote_api_v1.8.md index 184e107cdc..4e1f02bed8 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.8.md +++ b/docs/sources/reference/api/docker_remote_api_v1.8.md @@ -303,7 +303,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -549,7 +549,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -793,8 +793,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1157,7 +1157,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") - **run** – config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) diff --git a/docs/sources/reference/api/docker_remote_api_v1.9.md b/docs/sources/reference/api/docker_remote_api_v1.9.md index fc9f9b8d5b..8551bed84e 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.9.md +++ b/docs/sources/reference/api/docker_remote_api_v1.9.md @@ -303,7 +303,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (eg. aux) + - **ps_args** – ps arguments to use (e.g. aux) Status Codes: @@ -553,7 +553,7 @@ Attach to the container `id` `STREAM_TYPE` can be: - - 0: stdin (will be writen on stdout) + - 0: stdin (will be written on stdout) - 1: stdout - 2: stderr @@ -797,8 +797,8 @@ Return low-level information on the image `name` "OpenStdin":true, "StdinOnce":false, "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, + "Cmd": ["/bin/bash"], + "Dns":null, "Image":"base", "Volumes":null, "VolumesFrom":"", @@ -1194,7 +1194,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (eg. "John Hannibal Smith + - **author** – author (e.g. "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: -- cgit v1.2.1 From fde10cf87b9f0df6d8aa8683721a6f9d71dda516 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Mon, 30 Jun 2014 11:31:15 +1000 Subject: blindly make all uses of e\.?g\.? into e.g., Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/README.md | 2 +- docs/man/docker-commit.1.md | 2 +- docs/man/docker-images.1.md | 2 +- docs/man/docker-inspect.1.md | 2 +- docs/man/docker-pull.1.md | 2 +- docs/man/docker-run.1.md | 2 +- docs/man/docker-tag.1.md | 2 +- docs/sources/articles/cfengine_process_management.md | 2 +- docs/sources/articles/https.md | 2 +- docs/sources/articles/runmetrics.md | 8 ++++---- docs/sources/articles/security.md | 14 +++++++------- docs/sources/contributing/devenvironment.md | 2 +- docs/sources/installation/rackspace.md | 2 +- docs/sources/reference/api/docker_remote_api.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.0.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.1.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.10.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.11.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.12.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.13.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.2.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.3.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.4.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.5.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.6.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.7.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.8.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.9.md | 4 ++-- docs/sources/reference/api/hub_registry_spec.md | 4 ++-- docs/sources/reference/api/registry_api.md | 4 ++-- docs/sources/reference/commandline/cli.md | 6 +++--- docs/sources/terms/repository.md | 6 +++--- 32 files changed, 57 insertions(+), 57 deletions(-) diff --git a/docs/README.md b/docs/README.md index d74ec4ee87..99dc8712c9 100755 --- a/docs/README.md +++ b/docs/README.md @@ -70,7 +70,7 @@ in their shell: ### Images -When you need to add images, try to make them as small as possible (e.g. as +When you need to add images, try to make them as small as possible (e.g., as gifs). Usually images should go in the same directory as the `.md` file which references them, or in a subdirectory if one already exists. diff --git a/docs/man/docker-commit.1.md b/docs/man/docker-commit.1.md index b72c385bff..e9f3393381 100644 --- a/docs/man/docker-commit.1.md +++ b/docs/man/docker-commit.1.md @@ -14,7 +14,7 @@ Using an existing container's name or ID you can create a new image. # OPTIONS **-a, --author**="" - Author name. (e.g. "John Hannibal Smith " + Author name. (e.g., "John Hannibal Smith " **-m, --message**="" Commit message diff --git a/docs/man/docker-images.1.md b/docs/man/docker-images.1.md index a466798096..602ccf7c90 100644 --- a/docs/man/docker-images.1.md +++ b/docs/man/docker-images.1.md @@ -17,7 +17,7 @@ docker-images - List the images in the local repository This command lists the images stored in the local Docker repository. By default, intermediate images, used during builds, are not listed. Some of the -output, e.g. image ID, is truncated, for space reasons. However the truncated +output, e.g., image ID, is truncated, for space reasons. However the truncated image ID, and often the first few characters, are enough to be used in other Docker commands that use the image ID. The output includes repository, tag, image ID, date created and the virtual size. diff --git a/docs/man/docker-inspect.1.md b/docs/man/docker-inspect.1.md index a49e42138f..a82c76a625 100644 --- a/docs/man/docker-inspect.1.md +++ b/docs/man/docker-inspect.1.md @@ -142,7 +142,7 @@ output: ## Getting information on an image -Use an image's ID or name (e.g. repository/name[:tag]) to get information +Use an image's ID or name (e.g., repository/name[:tag]) to get information on it. # docker inspect 58394af37342 diff --git a/docs/man/docker-pull.1.md b/docs/man/docker-pull.1.md index 40b7425f77..d8e177b2b2 100644 --- a/docs/man/docker-pull.1.md +++ b/docs/man/docker-pull.1.md @@ -10,7 +10,7 @@ docker-pull - Pull an image or a repository from the registry # DESCRIPTION This command pulls down an image or a repository from the registry. If -there is more than one image for a repository (e.g. fedora) then all +there is more than one image for a repository (e.g., fedora) then all images for that repository name are pulled down including any tags. It is also possible to specify a non-default registry to pull from. diff --git a/docs/man/docker-run.1.md b/docs/man/docker-run.1.md index bac64aa185..ec9db8fd08 100644 --- a/docs/man/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -71,7 +71,7 @@ stopping the process by pressing the keys CTRL-P CTRL-Q. **--dns**=*IP-address* Set custom DNS servers. This option can be used to override the DNS configuration passed to the container. Typically this is necessary when the -host DNS configuration is invalid for the container (e.g. 127.0.0.1). When this +host DNS configuration is invalid for the container (e.g., 127.0.0.1). When this is the case the **-dns** flags is necessary for every run. diff --git a/docs/man/docker-tag.1.md b/docs/man/docker-tag.1.md index 0c42769908..01b5b9137c 100644 --- a/docs/man/docker-tag.1.md +++ b/docs/man/docker-tag.1.md @@ -35,7 +35,7 @@ Note that here TAG is a part of the overall name or "tag". ## Giving an image a new alias -Here is an example of aliasing an image (e.g. 0e5574283393) as "httpd" and +Here is an example of aliasing an image (e.g., 0e5574283393) as "httpd" and tagging it into the "fedora" repository with "version1.0": docker tag 0e5574283393 fedora/httpd:version1.0 diff --git a/docs/sources/articles/cfengine_process_management.md b/docs/sources/articles/cfengine_process_management.md index ee5ba238a0..6bb4df66ae 100644 --- a/docs/sources/articles/cfengine_process_management.md +++ b/docs/sources/articles/cfengine_process_management.md @@ -87,7 +87,7 @@ The first two steps can be done as part of a Dockerfile, as follows. ENTRYPOINT ["/var/cfengine/bin/docker_processes_run.sh"] By saving this file as Dockerfile to a working directory, you can then build -your image with the docker build command, e.g. +your image with the docker build command, e.g., `docker build -t managed_image`. ### Testing the container diff --git a/docs/sources/articles/https.md b/docs/sources/articles/https.md index cc8c6a9761..b6ae4ef37d 100644 --- a/docs/sources/articles/https.md +++ b/docs/sources/articles/https.md @@ -29,7 +29,7 @@ keys: $ openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem Now that we have a CA, you can create a server key and certificate -signing request. Make sure that "Common Name (e.g. server FQDN or YOUR +signing request. Make sure that "Common Name (e.g., server FQDN or YOUR name)" matches the hostname you will use to connect to Docker or just use `\*` for a certificate valid for any hostname: diff --git a/docs/sources/articles/runmetrics.md b/docs/sources/articles/runmetrics.md index bf4fe21c4e..9c871a24f6 100644 --- a/docs/sources/articles/runmetrics.md +++ b/docs/sources/articles/runmetrics.md @@ -35,7 +35,7 @@ known to the system, the hierarchy they belong to, and how many groups they cont You can also look at `/proc//cgroup` to see which control groups a process belongs to. The control group will be shown as a path relative to the root of -the hierarchy mountpoint; e.g. `/` means “this process has not been assigned into +the hierarchy mountpoint; e.g., `/` means “this process has not been assigned into a particular group”, while `/lxc/pumpkin` means that the process is likely to be a member of a container named `pumpkin`. @@ -106,9 +106,9 @@ to the processes within the cgroup, excluding sub-cgroups. The second half (with the `total_` prefix) includes sub-cgroups as well. Some metrics are "gauges", i.e. values that can increase or decrease -(e.g. swap, the amount of swap space used by the members of the cgroup). +(e.g., swap, the amount of swap space used by the members of the cgroup). Some others are "counters", i.e. values that can only go up, because -they represent occurrences of a specific event (e.g. pgfault, which +they represent occurrences of a specific event (e.g., pgfault, which indicates the number of page faults which happened since the creation of the cgroup; this number can never decrease). @@ -410,7 +410,7 @@ used. Docker makes this difficult because it relies on `lxc-start`, which carefully cleans up after itself, but it is still possible. It is -usually easier to collect metrics at regular intervals (e.g. every +usually easier to collect metrics at regular intervals (e.g., every minute, with the collectd LXC plugin) and rely on that instead. But, if you'd still like to gather the stats when a container stops, diff --git a/docs/sources/articles/security.md b/docs/sources/articles/security.md index 83704e434a..4c39c18a69 100644 --- a/docs/sources/articles/security.md +++ b/docs/sources/articles/security.md @@ -91,8 +91,8 @@ without any restriction. This sounds crazy? Well, you have to know that same way**. Nothing prevents you from sharing your root filesystem (or even your root block device) with a virtual machine. -This has a strong security implication: if you instrument Docker from -e.g. a web server to provision containers through an API, you should be +This has a strong security implication: for example, if you instrument Docker +from a web server to provision containers through an API, you should be even more careful than usual with parameter checking, to make sure that a malicious user cannot pass crafted parameters causing Docker to create arbitrary containers. @@ -108,7 +108,7 @@ socket. You can also expose the REST API over HTTP if you explicitly decide so. However, if you do that, being aware of the above mentioned security implication, you should ensure that it will be reachable only from a -trusted network or VPN; or protected with e.g. `stunnel` and client SSL +trusted network or VPN; or protected with e.g., `stunnel` and client SSL certificates. You can also secure them with [HTTPS and certificates](/articles/https/). @@ -136,7 +136,7 @@ Finally, if you run Docker on a server, it is recommended to run exclusively Docker in the server, and move all other services within containers controlled by Docker. Of course, it is fine to keep your favorite admin tools (probably at least an SSH server), as well as -existing monitoring/supervision processes (e.g. NRPE, collectd, etc). +existing monitoring/supervision processes (e.g., NRPE, collectd, etc). ## Linux Kernel Capabilities @@ -154,8 +154,8 @@ This means a lot for container security; let's see why! Your average server (bare metal or virtual machine) needs to run a bunch of processes as root. Those typically include SSH, cron, syslogd; -hardware management tools (to e.g. load modules), network configuration -tools (to handle e.g. DHCP, WPA, or VPNs), and much more. A container is +hardware management tools (e.g., load modules), network configuration +tools (e.g., to handle DHCP, WPA, or VPNs), and much more. A container is very different, because almost all of those tasks are handled by the infrastructure around the container: @@ -232,7 +232,7 @@ harden a Docker host. Here are a few examples. mechanism. Just like there are many third-party tools to augment Docker containers -with e.g. special network topologies or shared filesystems, you can +with e.g., special network topologies or shared filesystems, you can expect to see tools to harden existing Docker containers without affecting Docker's core. diff --git a/docs/sources/contributing/devenvironment.md b/docs/sources/contributing/devenvironment.md index 54b867cf40..9188031e3f 100644 --- a/docs/sources/contributing/devenvironment.md +++ b/docs/sources/contributing/devenvironment.md @@ -113,7 +113,7 @@ something like this ok github.com/dotcloud/docker/utils 0.017s If $TESTFLAGS is set in the environment, it is passed as extra arguments -to `go test`. You can use this to select certain tests to run, e.g. +to `go test`. You can use this to select certain tests to run, e.g., $ TESTFLAGS=`-run \^TestBuild\$` make test diff --git a/docs/sources/installation/rackspace.md b/docs/sources/installation/rackspace.md index 1aa969d1e5..9fddf5e450 100644 --- a/docs/sources/installation/rackspace.md +++ b/docs/sources/installation/rackspace.md @@ -15,7 +15,7 @@ will need to install it. And this is a little more difficult on Rackspace. Rackspace boots their servers using grub's `menu.lst` -and does not like non `virtual` packages (e.g. Xen compatible) +and does not like non `virtual` packages (e.g., Xen compatible) kernels there, although they do work. This results in `update-grub` not having the expected result, and you will need to set the kernel manually. diff --git a/docs/sources/reference/api/docker_remote_api.md b/docs/sources/reference/api/docker_remote_api.md index 3f61db721c..c3cce3ea3e 100644 --- a/docs/sources/reference/api/docker_remote_api.md +++ b/docs/sources/reference/api/docker_remote_api.md @@ -373,7 +373,7 @@ List containers (/containers/json): Start containers (/containers//start): - - You can now pass host-specific configuration (e.g. bind mounts) in + - You can now pass host-specific configuration (e.g., bind mounts) in the POST body for start calls ## v1.2 diff --git a/docs/sources/reference/api/docker_remote_api_v1.0.md b/docs/sources/reference/api/docker_remote_api_v1.0.md index b5ca1b5130..b906298b85 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.0.md +++ b/docs/sources/reference/api/docker_remote_api_v1.0.md @@ -935,7 +935,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.1.md b/docs/sources/reference/api/docker_remote_api_v1.1.md index 70617a4a1f..4e449bccec 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.1.md +++ b/docs/sources/reference/api/docker_remote_api_v1.1.md @@ -946,7 +946,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.10.md b/docs/sources/reference/api/docker_remote_api_v1.10.md index 01a176d86b..264cdefc20 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.10.md +++ b/docs/sources/reference/api/docker_remote_api_v1.10.md @@ -286,7 +286,7 @@ List processes running inside the container `id`   - - **ps\_args** – ps arguments to use (e.g. aux) + - **ps\_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1181,7 +1181,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.11.md b/docs/sources/reference/api/docker_remote_api_v1.11.md index 35abd35fb1..ae2daae407 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.11.md +++ b/docs/sources/reference/api/docker_remote_api_v1.11.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1223,7 +1223,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.12.md b/docs/sources/reference/api/docker_remote_api_v1.12.md index 66408eb15e..19fb24fe48 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.12.md +++ b/docs/sources/reference/api/docker_remote_api_v1.12.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1301,7 +1301,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md index 454aec530c..9eddb21051 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.13.md +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -290,7 +290,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1304,7 +1304,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.2.md b/docs/sources/reference/api/docker_remote_api_v1.2.md index 82084606e6..37a8e1c012 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.2.md +++ b/docs/sources/reference/api/docker_remote_api_v1.2.md @@ -959,7 +959,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.3.md b/docs/sources/reference/api/docker_remote_api_v1.3.md index b28194d882..b510f660fd 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.3.md +++ b/docs/sources/reference/api/docker_remote_api_v1.3.md @@ -1009,7 +1009,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.4.md b/docs/sources/reference/api/docker_remote_api_v1.4.md index be5678d678..0e49402621 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.4.md +++ b/docs/sources/reference/api/docker_remote_api_v1.4.md @@ -264,7 +264,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1055,7 +1055,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.5.md b/docs/sources/reference/api/docker_remote_api_v1.5.md index 08e7077c1f..33c1aeca1e 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.5.md +++ b/docs/sources/reference/api/docker_remote_api_v1.5.md @@ -261,7 +261,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1067,7 +1067,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.6.md b/docs/sources/reference/api/docker_remote_api_v1.6.md index e657252f19..4500c1554c 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.6.md +++ b/docs/sources/reference/api/docker_remote_api_v1.6.md @@ -311,7 +311,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1163,7 +1163,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/docker_remote_api_v1.7.md b/docs/sources/reference/api/docker_remote_api_v1.7.md index 66a93667a0..402efa4262 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.7.md +++ b/docs/sources/reference/api/docker_remote_api_v1.7.md @@ -267,7 +267,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1112,7 +1112,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") - **run** – config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) diff --git a/docs/sources/reference/api/docker_remote_api_v1.8.md b/docs/sources/reference/api/docker_remote_api_v1.8.md index 4e1f02bed8..78fccaf281 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.8.md +++ b/docs/sources/reference/api/docker_remote_api_v1.8.md @@ -303,7 +303,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1157,7 +1157,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") - **run** – config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) diff --git a/docs/sources/reference/api/docker_remote_api_v1.9.md b/docs/sources/reference/api/docker_remote_api_v1.9.md index 8551bed84e..741a9ac955 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.9.md +++ b/docs/sources/reference/api/docker_remote_api_v1.9.md @@ -303,7 +303,7 @@ List processes running inside the container `id`   - - **ps_args** – ps arguments to use (e.g. aux) + - **ps_args** – ps arguments to use (e.g., aux) Status Codes: @@ -1194,7 +1194,7 @@ Create a new image from a container's changes - **repo** – repository - **tag** – tag - **m** – commit message - - **author** – author (e.g. "John Hannibal Smith + - **author** – author (e.g., "John Hannibal Smith <[hannibal@a-team.com](mailto:hannibal%40a-team.com)>") Status Codes: diff --git a/docs/sources/reference/api/hub_registry_spec.md b/docs/sources/reference/api/hub_registry_spec.md index bb0e4ec7e3..1a2cf9423d 100644 --- a/docs/sources/reference/api/hub_registry_spec.md +++ b/docs/sources/reference/api/hub_registry_spec.md @@ -77,11 +77,11 @@ grasp the context, here are some examples of registries: > - local mount point; > - remote docker addressed through SSH. -The latter would only require two new commands in docker, e.g. +The latter would only require two new commands in docker, e.g., `registryget` and `registryput`, wrapping access to the local filesystem (and optionally doing consistency checks). Authentication and authorization are then delegated -to SSH (e.g. with public keys). +to SSH (e.g., with public keys). ### Docker diff --git a/docs/sources/reference/api/registry_api.md b/docs/sources/reference/api/registry_api.md index f8bdd6657d..2840693fa8 100644 --- a/docs/sources/reference/api/registry_api.md +++ b/docs/sources/reference/api/registry_api.md @@ -62,10 +62,10 @@ grasp the context, here are some examples of registries: > - local mount point; > - remote docker addressed through SSH. -The latter would only require two new commands in docker, e.g. +The latter would only require two new commands in docker, e.g., `registryget` and `registryput`, wrapping access to the local filesystem (and optionally doing consistency checks). Authentication and authorization -are then delegated to SSH (e.g. with public keys). +are then delegated to SSH (e.g., with public keys). # Endpoints diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 15640cff17..56e4202041 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -335,7 +335,7 @@ schema. Create a new image from a container's changes - -a, --author="" Author (eg. "John Hannibal Smith ") + -a, --author="" Author (e.g., "John Hannibal Smith ") -m, --message="" Commit message It can be useful to commit a container's file changes or settings into a @@ -518,7 +518,7 @@ by default. ### Filtering The filtering flag (`-f` or `--filter`) format is of "key=value". If there are more -than one filter, then pass multiple flags (e.g. `--filter "foo=bar" --filter "bif=baz"`) +than one filter, then pass multiple flags (e.g., `--filter "foo=bar" --filter "bif=baz"`) Current filters: * dangling (boolean - true or false) @@ -929,7 +929,7 @@ removed before the image is removed. --sig-proxy=true Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied. -t, --tty=false Allocate a pseudo-tty -u, --user="" Username or UID - -v, --volume=[] Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container) + -v, --volume=[] Bind mount a volume (e.g., from the host: -v /host:/container, from docker: -v /container) --volumes-from=[] Mount volumes from the specified container(s) -w, --workdir="" Working directory inside the container diff --git a/docs/sources/terms/repository.md b/docs/sources/terms/repository.md index 52c83d45d8..c4d1d43539 100644 --- a/docs/sources/terms/repository.md +++ b/docs/sources/terms/repository.md @@ -13,10 +13,10 @@ server. Images can be associated with a repository (or multiple) by giving them an image name using one of three different commands: -1. At build time (e.g. `sudo docker build -t IMAGENAME`), -2. When committing a container (e.g. +1. At build time (e.g., `sudo docker build -t IMAGENAME`), +2. When committing a container (e.g., `sudo docker commit CONTAINERID IMAGENAME`) or -3. When tagging an image id with an image name (e.g. +3. When tagging an image id with an image name (e.g., `sudo docker tag IMAGEID IMAGENAME`). A Fully Qualified Image Name (FQIN) can be made up of 3 parts: -- cgit v1.2.1 From 17d870bed5ef997c30da1e8b9843f4e84202f8d4 Mon Sep 17 00:00:00 2001 From: Eric Windisch Date: Sat, 7 Jun 2014 23:37:31 -0700 Subject: Pause/freeze containers during commit Initiates a pause before committing a container, adds a pause option to the commit command, defaulting to 'true'. Fixes bug: #6267 Fixes bug: #3675 Docker-DCO-1.1-Signed-off-by: Eric Windisch (github: ewindisch) --- api/client/commands.go | 6 ++++++ api/common.go | 2 +- api/server/server.go | 6 ++++++ daemon/daemon.go | 8 ++++++-- docs/sources/reference/commandline/cli.md | 6 ++++++ integration-cli/docker_cli_commit_test.go | 27 +++++++++++++++++++++++++++ integration/container_test.go | 6 +++--- integration/runtime_test.go | 2 +- server/buildfile.go | 2 +- server/server.go | 2 +- 10 files changed, 58 insertions(+), 9 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 2bf40a666f..9580ddd91c 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1538,6 +1538,7 @@ func (cli *DockerCli) CmdPs(args ...string) error { func (cli *DockerCli) CmdCommit(args ...string) error { cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes") + flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit") flComment := cmd.String([]string{"m", "-message"}, "", "Commit message") flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith \")") // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. @@ -1569,6 +1570,11 @@ func (cli *DockerCli) CmdCommit(args ...string) error { v.Set("tag", tag) v.Set("comment", *flComment) v.Set("author", *flAuthor) + + if *flPause != true { + v.Set("pause", "0") + } + var ( config *runconfig.Config env engine.Env diff --git a/api/common.go b/api/common.go index a20c5d7d1c..e73705000c 100644 --- a/api/common.go +++ b/api/common.go @@ -11,7 +11,7 @@ import ( ) const ( - APIVERSION version.Version = "1.12" + APIVERSION version.Version = "1.13" DEFAULTHTTPHOST = "127.0.0.1" DEFAULTUNIXSOCKET = "/var/run/docker.sock" ) diff --git a/api/server/server.go b/api/server/server.go index 6cb9fc8723..0cb7134c68 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -439,6 +439,12 @@ func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWrit utils.Errorf("%s", err) } + if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") { + job.Setenv("pause", "1") + } else { + job.Setenv("pause", r.FormValue("pause")) + } + job.Setenv("repo", r.Form.Get("repo")) job.Setenv("tag", r.Form.Get("tag")) job.Setenv("author", r.Form.Get("author")) diff --git a/daemon/daemon.go b/daemon/daemon.go index aa8d2bad3f..9500526f9e 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -620,8 +620,12 @@ func (daemon *Daemon) createRootfs(container *Container, img *image.Image) error // Commit creates a new filesystem image from the current state of a container. // The image can optionally be tagged into a repository -func (daemon *Daemon) Commit(container *Container, repository, tag, comment, author string, config *runconfig.Config) (*image.Image, error) { - // FIXME: freeze the container before copying it to avoid data corruption? +func (daemon *Daemon) Commit(container *Container, repository, tag, comment, author string, pause bool, config *runconfig.Config) (*image.Image, error) { + if pause { + container.Pause() + defer container.Unpause() + } + if err := container.Mount(); err != nil { return nil, err } diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 56e4202041..ff41ec4324 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -337,6 +337,7 @@ schema. -a, --author="" Author (e.g., "John Hannibal Smith ") -m, --message="" Commit message + -p, --pause=true Pause container during commit It can be useful to commit a container's file changes or settings into a new image. This allows you debug a container by running an interactive @@ -344,6 +345,11 @@ shell, or to export a working dataset to another server. Generally, it is better to use Dockerfiles to manage your images in a documented and maintainable way. +By default, the container being committed and its processes will be paused +during the process of committing the image. This reduces the likelihood of +encountering data corruption during the process of creating the commit. +If this behavior is undesired, set the 'p' option to false. + ### Commit an existing container $ sudo docker ps diff --git a/integration-cli/docker_cli_commit_test.go b/integration-cli/docker_cli_commit_test.go index c02c89cd30..3a76a0f38a 100644 --- a/integration-cli/docker_cli_commit_test.go +++ b/integration-cli/docker_cli_commit_test.go @@ -34,6 +34,33 @@ func TestCommitAfterContainerIsDone(t *testing.T) { logDone("commit - echo foo and commit the image") } +func TestCommitWithoutPause(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo") + out, _, _, err := runCommandWithStdoutStderr(runCmd) + errorOut(err, t, fmt.Sprintf("failed to run container: %v %v", out, err)) + + cleanedContainerID := stripTrailingCharacters(out) + + waitCmd := exec.Command(dockerBinary, "wait", cleanedContainerID) + _, _, err = runCommandWithOutput(waitCmd) + errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out)) + + commitCmd := exec.Command(dockerBinary, "commit", "-p", "false", cleanedContainerID) + out, _, err = runCommandWithOutput(commitCmd) + errorOut(err, t, fmt.Sprintf("failed to commit container to image: %v %v", out, err)) + + cleanedImageID := stripTrailingCharacters(out) + + inspectCmd := exec.Command(dockerBinary, "inspect", cleanedImageID) + out, _, err = runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("failed to inspect image: %v %v", out, err)) + + deleteContainer(cleanedContainerID) + deleteImages(cleanedImageID) + + logDone("commit - echo foo and commit the image") +} + func TestCommitNewFile(t *testing.T) { cmd := exec.Command(dockerBinary, "run", "--name", "commiter", "busybox", "/bin/sh", "-c", "echo koye > /foo") if _, err := runCommand(cmd); err != nil { diff --git a/integration/container_test.go b/integration/container_test.go index 31a57df77b..48b3321a50 100644 --- a/integration/container_test.go +++ b/integration/container_test.go @@ -421,7 +421,7 @@ func TestCopyVolumeUidGid(t *testing.T) { t.Errorf("Container shouldn't be running") } - img, err := r.Commit(container1, "", "", "unit test commited image", "", nil) + img, err := r.Commit(container1, "", "", "unit test commited image", "", true, nil) if err != nil { t.Error(err) } @@ -447,7 +447,7 @@ func TestCopyVolumeUidGid(t *testing.T) { t.Errorf("Container shouldn't be running") } - img2, err := r.Commit(container2, "", "", "unit test commited image", "", nil) + img2, err := r.Commit(container2, "", "", "unit test commited image", "", true, nil) if err != nil { t.Error(err) } @@ -481,7 +481,7 @@ func TestCopyVolumeContent(t *testing.T) { t.Errorf("Container shouldn't be running") } - img, err := r.Commit(container1, "", "", "unit test commited image", "", nil) + img, err := r.Commit(container1, "", "", "unit test commited image", "", true, nil) if err != nil { t.Error(err) } diff --git a/integration/runtime_test.go b/integration/runtime_test.go index 754146c5f8..4c0f636d60 100644 --- a/integration/runtime_test.go +++ b/integration/runtime_test.go @@ -334,7 +334,7 @@ func TestDaemonCreate(t *testing.T) { } container, _, err = daemon.Create(config, "") - _, err = daemon.Commit(container, "testrepo", "testtag", "", "", config) + _, err = daemon.Commit(container, "testrepo", "testtag", "", "", true, config) if err != nil { t.Error(err) } diff --git a/server/buildfile.go b/server/buildfile.go index f5ef6e0d2a..71fed660b2 100644 --- a/server/buildfile.go +++ b/server/buildfile.go @@ -752,7 +752,7 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error { autoConfig := *b.config autoConfig.Cmd = autoCmd // Commit the container - image, err := b.daemon.Commit(container, "", "", "", b.maintainer, &autoConfig) + image, err := b.daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig) if err != nil { return err } diff --git a/server/server.go b/server/server.go index 0bbb9f31ca..a0ff5fe89d 100644 --- a/server/server.go +++ b/server/server.go @@ -1038,7 +1038,7 @@ func (srv *Server) ContainerCommit(job *engine.Job) engine.Status { return job.Error(err) } - img, err := srv.daemon.Commit(container, job.Getenv("repo"), job.Getenv("tag"), job.Getenv("comment"), job.Getenv("author"), &newConfig) + img, err := srv.daemon.Commit(container, job.Getenv("repo"), job.Getenv("tag"), job.Getenv("comment"), job.Getenv("author"), job.GetenvBool("pause"), &newConfig) if err != nil { return job.Error(err) } -- cgit v1.2.1 From ae1ff4dea311f8c6ff025b4835dc5d751f1b6261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Petazzoni?= Date: Tue, 1 Jul 2014 07:47:59 -0700 Subject: Add FAQ entry about bundled vs packaged libraries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docker-DCO-1.1-Signed-off-by: Jérôme Petazzoni (github: jpetazzo) --- docs/sources/faq.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/sources/faq.md b/docs/sources/faq.md index 2d38cf2ff8..635caac89f 100644 --- a/docs/sources/faq.md +++ b/docs/sources/faq.md @@ -187,6 +187,44 @@ Please read [our blog post]( http://blog.docker.io/2014/01/docker-code-contributions-require-developer-certificate-of-origin/) on the introduction of the DCO. +### When building an image, should I prefer system libraries or bundled ones? + +*This is a summary of a discussion on the [docker-dev mailing list]( +https://groups.google.com/forum/#!topic/docker-dev/L2RBSPDu1L0).* + +Virtually all programs depend on third-party libraries. Most frequently, +they will use dynamic linking and some kind of package dependency, so +that when multiple programs need the same library, it is installed only once. + +Some programs, however, will bundle their third-party libraries, because +they rely on very specific versions of those libraries. For instance, +Node.js bundles OpenSSL; MongoDB bundles V8 and Boost (among others). + +When creating a Docker image, is it better to use the bundled libraries, +or should you build those programs so that they use the default system +libraries instead? + +The key point about system libraries is not about saving disk or memory +space. It is about security. All major distributions handle security +seriously, by having dedicated security teams, following up closely +with published vulnerabilities, and disclosing advisories themselves. +(Look at the [Debian Security Information](https://www.debian.org/security/) +for an example of those procedures.) Upstream developers, however, +do not always implement similar practices. + +Before setting up a Docker image to compile a program from source, +if you want to use bundled libraries, you should check if the upstream +authors provide a convenient way to announce security vulnerabilities, +and if they update their bundled libraries in a timely manner. If they +don't, you are exposing yourself (and the users of your image) to +security vulnerabilities. + +Likewise, before using packages built by others, you should check if the +channels providing those packages implement similar security best practices. +Downloading and installing an "all-in-one" .deb or .rpm sounds great at first, +except if you have no way to figure out that it contains a copy of the +OpenSSL library vulnerable to the [Heartbleed](http://heartbleed.com/) bug. + ### Can I help by adding some questions and answers? Definitely! You can fork [the repo](https://github.com/dotcloud/docker) and -- cgit v1.2.1 From 957c510d729ac3dcbe892b145fb2d9ed766be2ca Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 1 Jul 2014 00:39:38 +0000 Subject: updated docs & tests Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- docs/man/docker-commit.1.md | 3 +++ docs/sources/reference/api/docker_remote_api.md | 5 +++++ docs/sources/reference/commandline/cli.md | 2 +- integration-cli/docker_cli_commit_test.go | 4 ++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/man/docker-commit.1.md b/docs/man/docker-commit.1.md index e9f3393381..c0f2c734c5 100644 --- a/docs/man/docker-commit.1.md +++ b/docs/man/docker-commit.1.md @@ -19,6 +19,9 @@ Using an existing container's name or ID you can create a new image. **-m, --message**="" Commit message +**-p, --pause**=true + Pause container during commit + # EXAMPLES ## Creating a new image from an existing container diff --git a/docs/sources/reference/api/docker_remote_api.md b/docs/sources/reference/api/docker_remote_api.md index c3cce3ea3e..36f35383e1 100644 --- a/docs/sources/reference/api/docker_remote_api.md +++ b/docs/sources/reference/api/docker_remote_api.md @@ -49,6 +49,11 @@ daemon is configured to listen on. **New!** `start` and `stop` will now return 304 if the container's status is not modified +`POST /commit` + +**New!** +Added a `pause` parameter (default `true`) to pause the container during commit + ## v1.12 ### Full Documentation diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index ff41ec4324..770ac1177d 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -346,7 +346,7 @@ is better to use Dockerfiles to manage your images in a documented and maintainable way. By default, the container being committed and its processes will be paused -during the process of committing the image. This reduces the likelihood of +while the image is committed. This reduces the likelihood of encountering data corruption during the process of creating the commit. If this behavior is undesired, set the 'p' option to false. diff --git a/integration-cli/docker_cli_commit_test.go b/integration-cli/docker_cli_commit_test.go index 3a76a0f38a..7caf3588ce 100644 --- a/integration-cli/docker_cli_commit_test.go +++ b/integration-cli/docker_cli_commit_test.go @@ -45,7 +45,7 @@ func TestCommitWithoutPause(t *testing.T) { _, _, err = runCommandWithOutput(waitCmd) errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out)) - commitCmd := exec.Command(dockerBinary, "commit", "-p", "false", cleanedContainerID) + commitCmd := exec.Command(dockerBinary, "commit", "-p=false", cleanedContainerID) out, _, err = runCommandWithOutput(commitCmd) errorOut(err, t, fmt.Sprintf("failed to commit container to image: %v %v", out, err)) @@ -58,7 +58,7 @@ func TestCommitWithoutPause(t *testing.T) { deleteContainer(cleanedContainerID) deleteImages(cleanedImageID) - logDone("commit - echo foo and commit the image") + logDone("commit - echo foo and commit the image with --pause=false") } func TestCommitNewFile(t *testing.T) { -- cgit v1.2.1 From c21c55e0b6d0f9582e4ee168fbd518b57dacc8fb Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 1 Jul 2014 15:03:07 -0400 Subject: more docs for dockerignore Docker-DCO-1.1-Signed-off-by: Tibor Vass (github: tiborvass) --- docs/sources/reference/builder.md | 32 +++++++++++++++++++++++++++++++ docs/sources/reference/commandline/cli.md | 6 +++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/docs/sources/reference/builder.md b/docs/sources/reference/builder.md index cf729664e2..91190933c9 100644 --- a/docs/sources/reference/builder.md +++ b/docs/sources/reference/builder.md @@ -83,6 +83,38 @@ be treated as an argument. This allows statements like: Here is the set of instructions you can use in a Dockerfile for building images. +## .dockerignore + +If a file named `.dockerignore` exists in the source repository, then it +is interpreted as a newline-separated list of exclusion patterns. +Exclusion patterns match files or directories relative to the source repository +that will be excluded from the context. Globbing is done using Go's +[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. + +The following example shows the use of the `.dockerignore` file to exclude the +`.git` directory from the context. Its effect can be seen in the changed size of +the uploaded context. + + $ docker build . + Uploading context 18.829 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello World + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + $ echo ".git" > .dockerignore + $ docker build . + Uploading context 6.76 MB + Uploading context + Step 0 : FROM busybox + ---> 769b9341d937 + Step 1 : CMD echo Hello World + ---> Using cache + ---> 99cc1ad10469 + Successfully built 99cc1ad10469 + ## FROM FROM diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 770ac1177d..93b97b02f9 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -223,7 +223,7 @@ will be excluded from the context. Globbing is done using Go's See also: -[*Dockerfile Reference*](/reference/builder/#dockerbuilder). +[*Dockerfile Reference*](/reference/builder). ### Examples: @@ -292,8 +292,8 @@ affect the build cache. ---> 99cc1ad10469 Successfully built 99cc1ad10469 -This example shows the use of the ``.dockerignore`` file to exclude the ``.git`` -directory the context. Its effect can be seen in the changed size of the +This example shows the use of the `.dockerignore` file to exclude the `.git` +directory from the context. Its effect can be seen in the changed size of the uploaded context. $ sudo docker build -t vieux/apache:2.0 . -- cgit v1.2.1 From 1dc0caf9c0170ab8e7f5a2f77f2dbdacff322eff Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Tue, 3 Jun 2014 15:09:33 +0400 Subject: Implement tail for docker logs Fixes #4330 Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- api/client/commands.go | 2 + api/server/server.go | 1 + .../reference/api/docker_remote_api_v1.13.md | 16 +-- docs/sources/reference/commandline/cli.md | 12 +- integration-cli/docker_cli_logs_test.go | 44 ++++++ pkg/tailfile/tailfile.go | 61 +++++++++ pkg/tailfile/tailfile_test.go | 148 +++++++++++++++++++++ server/server.go | 63 ++++++--- 8 files changed, 316 insertions(+), 31 deletions(-) create mode 100644 pkg/tailfile/tailfile.go create mode 100644 pkg/tailfile/tailfile_test.go diff --git a/api/client/commands.go b/api/client/commands.go index 9580ddd91c..7cdcd5ebe6 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1693,6 +1693,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error { cmd = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container") follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") + tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs(all logs by default)") ) if err := cmd.Parse(args); err != nil { @@ -1726,6 +1727,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error { if *follow { v.Set("follow", "1") } + v.Set("tail", *tail) return cli.streamHelper("GET", "/containers/"+name+"/logs?"+v.Encode(), env.GetSubEnv("Config").GetBool("Tty"), nil, cli.out, cli.err, nil) } diff --git a/api/server/server.go b/api/server/server.go index 0cb7134c68..b3a0590fda 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -378,6 +378,7 @@ func getContainersLogs(eng *engine.Engine, version version.Version, w http.Respo return err } logsJob.Setenv("follow", r.Form.Get("follow")) + logsJob.Setenv("tail", r.Form.Get("tail")) logsJob.Setenv("stdout", r.Form.Get("stdout")) logsJob.Setenv("stderr", r.Form.Get("stderr")) logsJob.Setenv("timestamps", r.Form.Get("timestamps")) diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md index 9eddb21051..e0ad957941 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.13.md +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -306,7 +306,7 @@ Get stdout and stderr logs from the container ``id`` **Example request**: - GET /containers/4fa6e0f0c678/logs?stderr=1&stdout=1×tamps=1&follow=1 HTTP/1.1 + GET /containers/4fa6e0f0c678/logs?stderr=1&stdout=1×tamps=1&follow=1&tail=10 HTTP/1.1 **Example response**: @@ -319,14 +319,12 @@ Get stdout and stderr logs from the container ``id``   - - **follow** – 1/True/true or 0/False/false, return stream. - Default false - - **stdout** – 1/True/true or 0/False/false, if logs=true, return - stdout log. Default false - - **stderr** – 1/True/true or 0/False/false, if logs=true, return - stderr log. Default false - - **timestamps** – 1/True/true or 0/False/false, if logs=true, print - timestamps for every log line. Default false + - **follow** – 1/True/true or 0/False/false, return stream. Default false + - **stdout** – 1/True/true or 0/False/false, show stdout log. Default false + - **stderr** – 1/True/true or 0/False/false, show stderr log. Default false + - **timestamps** – 1/True/true or 0/False/false, print timestamps for + every log line. Default false + - **tail** – Output specified number of lines at the end of logs: `all` or ``. Default all Status Codes: diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 770ac1177d..912feddfa9 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -738,13 +738,15 @@ specify this by adding the server name. -f, --follow=false Follow log output -t, --timestamps=false Show timestamps + --tail="all" Output the specified number of lines at the end of logs (all logs by default) -The `docker logs` command batch-retrieves all logs -present at the time of execution. +The `docker logs` command batch-retrieves logs present at the time of execution. -The ``docker logs --follow`` command will first return all logs from the -beginning and then continue streaming new output from the container's `STDOUT` -and `STDERR`. +The `docker logs --follow` command will continue streaming the new output from +the container's `STDOUT` and `STDERR`. + +Passing a negative number or a non-integer to --tail is invalid and the +value is set to all in that case. This behavior may change in the future. ## port diff --git a/integration-cli/docker_cli_logs_test.go b/integration-cli/docker_cli_logs_test.go index 75235b6bb8..8b1d006626 100644 --- a/integration-cli/docker_cli_logs_test.go +++ b/integration-cli/docker_cli_logs_test.go @@ -169,3 +169,47 @@ func TestLogsStderrInStdout(t *testing.T) { logDone("logs - stderr in stdout (with pseudo-tty)") } + +func TestLogsTail(t *testing.T) { + testLen := 100 + runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", fmt.Sprintf("for i in $(seq 1 %d); do echo =; done;", testLen)) + + out, _, _, err := runCommandWithStdoutStderr(runCmd) + errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err)) + + cleanedContainerID := stripTrailingCharacters(out) + exec.Command(dockerBinary, "wait", cleanedContainerID).Run() + + logsCmd := exec.Command(dockerBinary, "logs", "--tail", "5", cleanedContainerID) + out, _, _, err = runCommandWithStdoutStderr(logsCmd) + errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err)) + + lines := strings.Split(out, "\n") + + if len(lines) != 6 { + t.Fatalf("Expected log %d lines, received %d\n", 6, len(lines)) + } + + logsCmd = exec.Command(dockerBinary, "logs", "--tail", "all", cleanedContainerID) + out, _, _, err = runCommandWithStdoutStderr(logsCmd) + errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err)) + + lines = strings.Split(out, "\n") + + if len(lines) != testLen+1 { + t.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines)) + } + + logsCmd = exec.Command(dockerBinary, "logs", "--tail", "random", cleanedContainerID) + out, _, _, err = runCommandWithStdoutStderr(logsCmd) + errorOut(err, t, fmt.Sprintf("failed to log container: %v %v", out, err)) + + lines = strings.Split(out, "\n") + + if len(lines) != testLen+1 { + t.Fatalf("Expected log %d lines, received %d\n", testLen+1, len(lines)) + } + + deleteContainer(cleanedContainerID) + logDone("logs - logs tail") +} diff --git a/pkg/tailfile/tailfile.go b/pkg/tailfile/tailfile.go new file mode 100644 index 0000000000..2ffd36d258 --- /dev/null +++ b/pkg/tailfile/tailfile.go @@ -0,0 +1,61 @@ +package tailfile + +import ( + "bytes" + "errors" + "os" +) + +const blockSize = 1024 + +var eol = []byte("\n") +var ErrNonPositiveLinesNumber = errors.New("Lines number must be positive") + +//TailFile returns last n lines of file f +func TailFile(f *os.File, n int) ([][]byte, error) { + if n <= 0 { + return nil, ErrNonPositiveLinesNumber + } + size, err := f.Seek(0, os.SEEK_END) + if err != nil { + return nil, err + } + block := -1 + var data []byte + var cnt int + for { + var b []byte + step := int64(block * blockSize) + left := size + step // how many bytes to beginning + if left < 0 { + if _, err := f.Seek(0, os.SEEK_SET); err != nil { + return nil, err + } + b = make([]byte, blockSize+left) + if _, err := f.Read(b); err != nil { + return nil, err + } + data = append(b, data...) + break + } else { + b = make([]byte, blockSize) + if _, err := f.Seek(step, os.SEEK_END); err != nil { + return nil, err + } + if _, err := f.Read(b); err != nil { + return nil, err + } + data = append(b, data...) + } + cnt += bytes.Count(b, eol) + if cnt > n { + break + } + block-- + } + lines := bytes.Split(data, eol) + if n < len(lines) { + return lines[len(lines)-n-1 : len(lines)-1], nil + } + return lines[:len(lines)-1], nil +} diff --git a/pkg/tailfile/tailfile_test.go b/pkg/tailfile/tailfile_test.go new file mode 100644 index 0000000000..31217c036c --- /dev/null +++ b/pkg/tailfile/tailfile_test.go @@ -0,0 +1,148 @@ +package tailfile + +import ( + "io/ioutil" + "os" + "testing" +) + +func TestTailFile(t *testing.T) { + f, err := ioutil.TempFile("", "tail-test") + if err != nil { + t.Fatal(err) + } + defer f.Close() + defer os.RemoveAll(f.Name()) + testFile := []byte(`first line +second line +third line +fourth line +fifth line +next first line +next second line +next third line +next fourth line +next fifth line +last first line +next first line +next second line +next third line +next fourth line +next fifth line +next first line +next second line +next third line +next fourth line +next fifth line +last second line +last third line +last fourth line +last fifth line +truncated line`) + if _, err := f.Write(testFile); err != nil { + t.Fatal(err) + } + if _, err := f.Seek(0, os.SEEK_SET); err != nil { + t.Fatal(err) + } + expected := []string{"last fourth line", "last fifth line"} + res, err := TailFile(f, 2) + if err != nil { + t.Fatal(err) + } + for i, l := range res { + t.Logf("%s", l) + if expected[i] != string(l) { + t.Fatalf("Expected line %s, got %s", expected[i], l) + } + } +} + +func TestTailFileManyLines(t *testing.T) { + f, err := ioutil.TempFile("", "tail-test") + if err != nil { + t.Fatal(err) + } + defer f.Close() + defer os.RemoveAll(f.Name()) + testFile := []byte(`first line +second line +truncated line`) + if _, err := f.Write(testFile); err != nil { + t.Fatal(err) + } + if _, err := f.Seek(0, os.SEEK_SET); err != nil { + t.Fatal(err) + } + expected := []string{"first line", "second line"} + res, err := TailFile(f, 10000) + if err != nil { + t.Fatal(err) + } + for i, l := range res { + t.Logf("%s", l) + if expected[i] != string(l) { + t.Fatalf("Expected line %s, got %s", expected[i], l) + } + } +} + +func TestTailEmptyFile(t *testing.T) { + f, err := ioutil.TempFile("", "tail-test") + if err != nil { + t.Fatal(err) + } + defer f.Close() + defer os.RemoveAll(f.Name()) + res, err := TailFile(f, 10000) + if err != nil { + t.Fatal(err) + } + if len(res) != 0 { + t.Fatal("Must be empty slice from empty file") + } +} + +func TestTailNegativeN(t *testing.T) { + f, err := ioutil.TempFile("", "tail-test") + if err != nil { + t.Fatal(err) + } + defer f.Close() + defer os.RemoveAll(f.Name()) + testFile := []byte(`first line +second line +truncated line`) + if _, err := f.Write(testFile); err != nil { + t.Fatal(err) + } + if _, err := f.Seek(0, os.SEEK_SET); err != nil { + t.Fatal(err) + } + if _, err := TailFile(f, -1); err != ErrNonPositiveLinesNumber { + t.Fatalf("Expected ErrNonPositiveLinesNumber, got %s", err) + } + if _, err := TailFile(f, 0); err != ErrNonPositiveLinesNumber { + t.Fatalf("Expected ErrNonPositiveLinesNumber, got %s", err) + } +} + +func BenchmarkTail(b *testing.B) { + f, err := ioutil.TempFile("", "tail-test") + if err != nil { + b.Fatal(err) + } + defer f.Close() + defer os.RemoveAll(f.Name()) + for i := 0; i < 10000; i++ { + if _, err := f.Write([]byte("tailfile pretty interesting line\n")); err != nil { + b.Fatal(err) + } + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + if _, err := TailFile(f, 1000); err != nil { + b.Fatal(err) + } + } +} diff --git a/server/server.go b/server/server.go index a0ff5fe89d..3e6de00c1e 100644 --- a/server/server.go +++ b/server/server.go @@ -22,6 +22,7 @@ package server import ( + "bytes" "encoding/json" "fmt" "io" @@ -52,6 +53,7 @@ import ( "github.com/dotcloud/docker/image" "github.com/dotcloud/docker/pkg/graphdb" "github.com/dotcloud/docker/pkg/signal" + "github.com/dotcloud/docker/pkg/tailfile" "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/runconfig" "github.com/dotcloud/docker/utils" @@ -2153,8 +2155,10 @@ func (srv *Server) ContainerLogs(job *engine.Job) engine.Status { name = job.Args[0] stdout = job.GetenvBool("stdout") stderr = job.GetenvBool("stderr") + tail = job.Getenv("tail") follow = job.GetenvBool("follow") times = job.GetenvBool("timestamps") + lines = -1 format string ) if !(stdout || stderr) { @@ -2163,6 +2167,9 @@ func (srv *Server) ContainerLogs(job *engine.Job) engine.Status { if times { format = time.StampMilli } + if tail == "" { + tail = "all" + } container := srv.daemon.Get(name) if container == nil { return job.Errorf("No such container: %s", name) @@ -2190,25 +2197,47 @@ func (srv *Server) ContainerLogs(job *engine.Job) engine.Status { } else if err != nil { utils.Errorf("Error reading logs (json): %s", err) } else { - dec := json.NewDecoder(cLog) - for { - l := &utils.JSONLog{} - - if err := dec.Decode(l); err == io.EOF { - break - } else if err != nil { - utils.Errorf("Error streaming logs: %s", err) - break - } - logLine := l.Log - if times { - logLine = fmt.Sprintf("[%s] %s", l.Created.Format(format), logLine) + if tail != "all" { + var err error + lines, err = strconv.Atoi(tail) + if err != nil { + utils.Errorf("Failed to parse tail %s, error: %v, show all logs", err) + lines = -1 } - if l.Stream == "stdout" && stdout { - fmt.Fprintf(job.Stdout, "%s", logLine) + } + if lines != 0 { + if lines > 0 { + f := cLog.(*os.File) + ls, err := tailfile.TailFile(f, lines) + if err != nil { + return job.Error(err) + } + tmp := bytes.NewBuffer([]byte{}) + for _, l := range ls { + fmt.Fprintf(tmp, "%s\n", l) + } + cLog = tmp } - if l.Stream == "stderr" && stderr { - fmt.Fprintf(job.Stderr, "%s", logLine) + dec := json.NewDecoder(cLog) + for { + l := &utils.JSONLog{} + + if err := dec.Decode(l); err == io.EOF { + break + } else if err != nil { + utils.Errorf("Error streaming logs: %s", err) + break + } + logLine := l.Log + if times { + logLine = fmt.Sprintf("[%s] %s", l.Created.Format(format), logLine) + } + if l.Stream == "stdout" && stdout { + fmt.Fprintf(job.Stdout, "%s", logLine) + } + if l.Stream == "stderr" && stderr { + fmt.Fprintf(job.Stderr, "%s", logLine) + } } } } -- cgit v1.2.1 From 5c344dca4be275fc4e85c5e2dfd35133aff5cb23 Mon Sep 17 00:00:00 2001 From: Andrew Weiss Date: Mon, 30 Jun 2014 15:35:30 -0400 Subject: add DSC article Docker-DCO-1.1-Signed-off-by: Andrew Weiss (github: anweiss) --- docs/mkdocs.yml | 1 + docs/sources/articles/dsc.md | 117 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 docs/sources/articles/dsc.md diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 21b334197e..97dc8fc36b 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -87,6 +87,7 @@ pages: - ['articles/cfengine_process_management.md', 'Articles', 'Process management with CFEngine'] - ['articles/puppet.md', 'Articles', 'Using Puppet'] - ['articles/chef.md', 'Articles', 'Using Chef'] +- ['articles/dsc.md', 'Articles', 'Using PowerShell DSC'] - ['articles/ambassador_pattern_linking.md', 'Articles', 'Cross-Host linking using Ambassador Containers'] - ['articles/runmetrics.md', 'Articles', 'Runtime metrics'] - ['articles/baseimages.md', 'Articles', 'Creating a Base Image'] diff --git a/docs/sources/articles/dsc.md b/docs/sources/articles/dsc.md new file mode 100644 index 0000000000..94f5e9d4db --- /dev/null +++ b/docs/sources/articles/dsc.md @@ -0,0 +1,117 @@ +page_title: PowerShell DSC Usage +page_description: Using DSC to configure a new Docker host +page_keywords: powershell, dsc, installation, usage, docker, documentation + +# Using PowerShell DSC + +Windows PowerShell Desired State Configuration (DSC) is a configuration +management tool that extends the existing functionality of Windows PowerShell. +DSC uses a declarative syntax to define the state in which a target should be +configured. More information about PowerShell DSC can be found at +http://technet.microsoft.com/en-us/library/dn249912.aspx. + +## Requirements + +To use this guide you'll need a Windows host with PowerShell v4.0 or newer. + +The included DSC configuration script also uses the official PPA so +only an Ubuntu target is supported. The Ubuntu target must already have the +required OMI Server and PowerShell DSC for Linux providers installed. More +information can be found at https://github.com/MSFTOSSMgmt/WPSDSCLinux. The +source repository listed below also includes PowerShell DSC for Linux +installation and init scripts along with more detailed installation information. + +## Installation + +The DSC configuration example source is available in the following repository: +https://github.com/anweiss/DockerClientDSC. It can be cloned with: + + $ git clone https://github.com/anweiss/DockerClientDSC.git + +## Usage + +The DSC configuration utilizes a set of shell scripts to determine whether or +not the specified Docker components are configured on the target node(s). The +source repository also includes a script (`RunDockerClientConfig.ps1`) that can +be used to establish the required CIM session(s) and execute the +`Set-DscConfiguration` cmdlet. + +More detailed usage information can be found at +https://github.com/anweiss/DockerClientDSC. + +### Run Configuration +The Docker installation configuration is equivalent to running: + +``` +apt-get install docker.io +ln -sf /usr/bin/docker.io /usr/local/bin/docker +sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io +``` + +Ensure that your current working directory is set to the `DockerClientDSC` +source and load the DockerClient configuration into the current PowerShell +session + +```powershell +. .\DockerClient.ps1 +``` + +Generate the required DSC configuration .mof file for the targeted node + +```powershell +DockerClient -Hostname "myhost" +``` + +A sample DSC configuration data file has also been included and can be modified +and used in conjunction with or in place of the `Hostname` parameter: + +```powershell +DockerClient -ConfigurationData .\DockerConfigData.psd1 +``` + +Start the configuration application process on the targeted node + +```powershell +.\RunDockerClientConfig.ps1 -Hostname "myhost" +``` + +The `RunDockerClientConfig.ps1` script can also parse a DSC configuration data +file and execute configurations against multiple nodes as such: + +```powershell +.\RunDockerClientConfig.ps1 -ConfigurationData .\DockerConfigData.psd1 +``` + +### Images +Image configuration is equivalent to running: `docker pull [image]`. + +Using the same Run Configuration steps defined above, execute `DockerClient` +with the `Image` parameter: + +```powershell +DockerClient -Hostname "myhost" -Image node +``` + +The configuration process can be initiated as before: + +```powershell +.\RunDockerClientConfig.ps1 -Hostname "myhost" +``` + +### Containers +Container configuration is equivalent to running: +`docker run -d --name="[containername]" [image] '[command]'`. + +Using the same Run Configuration steps defined above, execute `DockerClient` +with the `Image`, `ContainerName`, and `Command` parameters: + +```powershell +DockerClient -Hostname "myhost" -Image node -ContainerName "helloworld" ` +-Command 'echo "Hello World!"' +``` + +The configuration process can be initiated as before: + +```powershell +.\RunDockerClientConfig.ps1 -Hostname "myhost" +``` -- cgit v1.2.1 From e06d533cc20c6aab10bf28a610445e7de6a8ef42 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 1 Jul 2014 21:33:33 +0000 Subject: update docs Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/client/commands.go | 2 +- docs/sources/reference/commandline/cli.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 7cdcd5ebe6..2d9c74f432 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1693,7 +1693,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error { cmd = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container") follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") - tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs(all logs by default)") + tail = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs (defaults to all logs)") ) if err := cmd.Parse(args); err != nil { diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 912feddfa9..b79f2ac7c2 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -738,15 +738,15 @@ specify this by adding the server name. -f, --follow=false Follow log output -t, --timestamps=false Show timestamps - --tail="all" Output the specified number of lines at the end of logs (all logs by default) + --tail="all" Output the specified number of lines at the end of logs (defaults to all logs) The `docker logs` command batch-retrieves logs present at the time of execution. The `docker logs --follow` command will continue streaming the new output from the container's `STDOUT` and `STDERR`. -Passing a negative number or a non-integer to --tail is invalid and the -value is set to all in that case. This behavior may change in the future. +Passing a negative number or a non-integer to `--tail` is invalid and the +value is set to `all` in that case. This behavior may change in the future. ## port -- cgit v1.2.1 From fc4c0d9de45da5ff5664fb9c914b68e176c626cd Mon Sep 17 00:00:00 2001 From: Tom Maaswinkel Date: Mon, 30 Jun 2014 10:16:49 +0200 Subject: Update usingdocker.md boot2docker on windows also uses an IP of its own. Docker-DCO-1.1-Signed-off-by: Tom Maaswinkel (github: SvenDowideit) --- docs/sources/userguide/usingdocker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/userguide/usingdocker.md b/docs/sources/userguide/usingdocker.md index c1f524f89a..f08b41d7d0 100644 --- a/docs/sources/userguide/usingdocker.md +++ b/docs/sources/userguide/usingdocker.md @@ -179,7 +179,7 @@ see the application. Our Python application is live! > **Note:** -> If you have used boot2docker on OSX you'll need to get the IP of the virtual +> If you have used boot2docker on OSX, or Windows, you'll need to get the IP of the virtual > host instead of using localhost. You can do this by running the following in > the boot2docker shell. > -- cgit v1.2.1 From 84990731f79e4e94229a7ff2039f812e8b036643 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Tue, 1 Jul 2014 12:02:39 +1000 Subject: expand to 'used b2d vm on any of the platforms' Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/sources/userguide/usingdocker.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/sources/userguide/usingdocker.md b/docs/sources/userguide/usingdocker.md index f08b41d7d0..16fdecc272 100644 --- a/docs/sources/userguide/usingdocker.md +++ b/docs/sources/userguide/usingdocker.md @@ -179,8 +179,9 @@ see the application. Our Python application is live! > **Note:** -> If you have used boot2docker on OSX, or Windows, you'll need to get the IP of the virtual -> host instead of using localhost. You can do this by running the following in +> If you have used the boot2docker virtual machine on OSX, Windows or Linux, +> you'll need to get the IP of the virtual host instead of using localhost. +> You can do this by running the following in > the boot2docker shell. > > $ boot2docker ip -- cgit v1.2.1 From 91c4fbb7bfe8851130f746911e34b9d190bb4572 Mon Sep 17 00:00:00 2001 From: Sven Dowideit Date: Tue, 1 Jul 2014 14:59:28 -0700 Subject: convert OSX into OS X Docker-DCO-1.1-Signed-off-by: Sven Dowideit (github: SvenDowideit) --- docs/sources/installation/binaries.md | 2 +- docs/sources/installation/mac.md | 4 ++-- docs/sources/userguide/usingdocker.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sources/installation/binaries.md b/docs/sources/installation/binaries.md index 97e2f93c4e..f6eb44fa64 100644 --- a/docs/sources/installation/binaries.md +++ b/docs/sources/installation/binaries.md @@ -36,7 +36,7 @@ In general, a 3.8 Linux kernel (or higher) is preferred, as some of the prior versions have known issues that are triggered by Docker. Note that Docker also has a client mode, which can run on virtually any -Linux kernel (it even builds on OSX!). +Linux kernel (it even builds on OS X!). ## Get the docker binary: diff --git a/docs/sources/installation/mac.md b/docs/sources/installation/mac.md index b6253de12d..2aff0e5b89 100644 --- a/docs/sources/installation/mac.md +++ b/docs/sources/installation/mac.md @@ -21,7 +21,7 @@ virtual machine and runs the Docker daemon. ## Installation -1. Download the latest release of the [Docker for OSX Installer]( +1. Download the latest release of the [Docker for OS X Installer]( https://github.com/boot2docker/osx-installer/releases) 2. Run the installer, which will install VirtualBox and the Boot2Docker management @@ -42,7 +42,7 @@ and `boot2docker start`. ## Upgrading -1. Download the latest release of the [Docker for OSX Installer]( +1. Download the latest release of the [Docker for OS X Installer]( https://github.com/boot2docker/osx-installer/releases) 2. Run the installer, which will update VirtualBox and the Boot2Docker management diff --git a/docs/sources/userguide/usingdocker.md b/docs/sources/userguide/usingdocker.md index 16fdecc272..7080e3ed43 100644 --- a/docs/sources/userguide/usingdocker.md +++ b/docs/sources/userguide/usingdocker.md @@ -179,7 +179,7 @@ see the application. Our Python application is live! > **Note:** -> If you have used the boot2docker virtual machine on OSX, Windows or Linux, +> If you have used the boot2docker virtual machine on OS X, Windows or Linux, > you'll need to get the IP of the virtual host instead of using localhost. > You can do this by running the following in > the boot2docker shell. -- cgit v1.2.1 From 3091d9a31e81be9b8a99aaae8f7d5c2e64043286 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Tue, 1 Jul 2014 11:56:35 +1000 Subject: removing the exclaimation mark from our hello-world examples, some users get trapped by the shell Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/sources/userguide/dockerhub.md | 2 +- docs/sources/userguide/dockerizing.md | 20 ++++++++++---------- docs/sources/userguide/index.md | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/sources/userguide/dockerhub.md b/docs/sources/userguide/dockerhub.md index 99e9a0a922..a461368436 100644 --- a/docs/sources/userguide/dockerhub.md +++ b/docs/sources/userguide/dockerhub.md @@ -65,7 +65,7 @@ Your Docker Hub account is now active and ready for you to use! ## Next steps -Next, let's start learning how to Dockerize applications with our "Hello World!" +Next, let's start learning how to Dockerize applications with our "Hello World" exercise. Go to [Dockerizing Applications](/userguide/dockerizing). diff --git a/docs/sources/userguide/dockerizing.md b/docs/sources/userguide/dockerizing.md index ed927df08a..f9de877a70 100644 --- a/docs/sources/userguide/dockerizing.md +++ b/docs/sources/userguide/dockerizing.md @@ -1,20 +1,20 @@ -page_title: Dockerizing Applications: A "Hello World!" -page_description: A simple "Hello World!" exercise that introduced you to Docker. +page_title: Dockerizing Applications: A "Hello World" +page_description: A simple "Hello World" exercise that introduced you to Docker. page_keywords: docker guide, docker, docker platform, virtualization framework, how to, dockerize, dockerizing apps, dockerizing applications, container, containers -# Dockerizing Applications: A "Hello World!" +# Dockerizing Applications: A "Hello World" *So what's this Docker thing all about?* Docker allows you to run applications inside containers. Running an application inside a container takes a single command: `docker run`. -## Hello World! +## Hello World Let's try it now. $ sudo docker run ubuntu:14.04 /bin/echo 'Hello World' - Hello World! + Hello World And you just launched your first container! @@ -34,17 +34,17 @@ image registry: [Docker Hub](https://hub.docker.com). Next we told Docker what command to run inside our new container: - /bin/echo 'Hello World!' + /bin/echo 'Hello World' When our container was launched Docker created a new Ubuntu 14.04 environment and then executed the `/bin/echo` command inside it. We saw the result on the command line: - Hello World! + Hello World So what happened to our container after that? Well Docker containers only run as long as the command you specify is active. Here, as soon as -`Hello World!` was echoed, the container stopped. +`Hello World` was echoed, the container stopped. ## An Interactive Container @@ -88,7 +88,7 @@ use the `exit` command to finish. As with our previous container, once the Bash shell process has finished, the container is stopped. -## A Daemonized Hello World! +## A Daemonized Hello World Now a container that runs a command and then exits has some uses but it's not overly helpful. Let's create a container that runs as a daemon, @@ -99,7 +99,7 @@ Again we can do this with the `docker run` command: $ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done" 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 -Wait what? Where's our "Hello World!" Let's look at what we've run here. +Wait what? Where's our "Hello World" Let's look at what we've run here. It should look pretty familiar. We ran `docker run` but this time we specified a flag: `-d`. The `-d` flag tells Docker to run the container and put it in the background, to daemonize it. diff --git a/docs/sources/userguide/index.md b/docs/sources/userguide/index.md index 87dab67cca..d8f8294c01 100644 --- a/docs/sources/userguide/index.md +++ b/docs/sources/userguide/index.md @@ -29,7 +29,7 @@ environment. To learn more; Go to [Using Docker Hub](/userguide/dockerhub). -## Dockerizing Applications: A "Hello World!" +## Dockerizing Applications: A "Hello World" *How do I run applications inside containers?* -- cgit v1.2.1 From a09f99b8b0e157e3bb72ad0c9dad8d83896c5182 Mon Sep 17 00:00:00 2001 From: Sven Dowideit Date: Tue, 1 Jul 2014 15:07:05 -0700 Subject: Lowercase world, because its not important. Docker-DCO-1.1-Signed-off-by: Sven Dowideit (github: SvenDowideit) --- docs/sources/examples/nodejs_web_app.md | 6 +++--- docs/sources/reference/commandline/cli.md | 6 +++--- docs/sources/userguide/dockerhub.md | 2 +- docs/sources/userguide/dockerizing.md | 22 +++++++++++----------- docs/sources/userguide/index.md | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/sources/examples/nodejs_web_app.md b/docs/sources/examples/nodejs_web_app.md index 5fb0300f56..a7b8eea7e3 100644 --- a/docs/sources/examples/nodejs_web_app.md +++ b/docs/sources/examples/nodejs_web_app.md @@ -24,7 +24,7 @@ describes your app and its dependencies: "name": "docker-centos-hello", "private": true, "version": "0.0.1", - "description": "Node.js Hello World app on CentOS using docker", + "description": "Node.js Hello world app on CentOS using docker", "author": "Daniel Gasienica ", "dependencies": { "express": "3.2.4" @@ -42,7 +42,7 @@ app using the [Express.js](http://expressjs.com/) framework: // App var app = express(); app.get('/', function (req, res) { - res.send('Hello World\n'); + res.send('Hello world\n'); }); app.listen(PORT); @@ -184,7 +184,7 @@ Now you can call your app using `curl` (install if needed via: Date: Sun, 02 Jun 2013 03:53:22 GMT Connection: keep-alive - Hello World + Hello world We hope this tutorial helped you get up and running with Node.js and CentOS on Docker. You can get the full source code at diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 93b97b02f9..bbcd00ed8f 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -246,7 +246,7 @@ See also: drwxr-xr-x 2 root root 4.0K Mar 12 2013 tmp drwxr-xr-x 2 root root 4.0K Nov 15 23:34 usr ---> b35f4035db3f - Step 3 : CMD echo Hello World + Step 3 : CMD echo Hello world ---> Running in 02071fceb21b ---> f52f38b7823e Successfully built f52f38b7823e @@ -277,7 +277,7 @@ affect the build cache. Uploading context Step 0 : FROM busybox ---> 769b9341d937 - Step 1 : CMD echo Hello World + Step 1 : CMD echo Hello world ---> Using cache ---> 99cc1ad10469 Successfully built 99cc1ad10469 @@ -287,7 +287,7 @@ affect the build cache. Uploading context Step 0 : FROM busybox ---> 769b9341d937 - Step 1 : CMD echo Hello World + Step 1 : CMD echo Hello world ---> Using cache ---> 99cc1ad10469 Successfully built 99cc1ad10469 diff --git a/docs/sources/userguide/dockerhub.md b/docs/sources/userguide/dockerhub.md index a461368436..5bb1edec8a 100644 --- a/docs/sources/userguide/dockerhub.md +++ b/docs/sources/userguide/dockerhub.md @@ -65,7 +65,7 @@ Your Docker Hub account is now active and ready for you to use! ## Next steps -Next, let's start learning how to Dockerize applications with our "Hello World" +Next, let's start learning how to Dockerize applications with our "Hello world" exercise. Go to [Dockerizing Applications](/userguide/dockerizing). diff --git a/docs/sources/userguide/dockerizing.md b/docs/sources/userguide/dockerizing.md index f9de877a70..02ac90306b 100644 --- a/docs/sources/userguide/dockerizing.md +++ b/docs/sources/userguide/dockerizing.md @@ -1,20 +1,20 @@ -page_title: Dockerizing Applications: A "Hello World" -page_description: A simple "Hello World" exercise that introduced you to Docker. +page_title: Dockerizing Applications: A "Hello world" +page_description: A simple "Hello world" exercise that introduced you to Docker. page_keywords: docker guide, docker, docker platform, virtualization framework, how to, dockerize, dockerizing apps, dockerizing applications, container, containers -# Dockerizing Applications: A "Hello World" +# Dockerizing Applications: A "Hello world" *So what's this Docker thing all about?* Docker allows you to run applications inside containers. Running an application inside a container takes a single command: `docker run`. -## Hello World +## Hello world Let's try it now. - $ sudo docker run ubuntu:14.04 /bin/echo 'Hello World' - Hello World + $ sudo docker run ubuntu:14.04 /bin/echo 'Hello world' + Hello world And you just launched your first container! @@ -34,17 +34,17 @@ image registry: [Docker Hub](https://hub.docker.com). Next we told Docker what command to run inside our new container: - /bin/echo 'Hello World' + /bin/echo 'Hello world' When our container was launched Docker created a new Ubuntu 14.04 environment and then executed the `/bin/echo` command inside it. We saw the result on the command line: - Hello World + Hello world So what happened to our container after that? Well Docker containers only run as long as the command you specify is active. Here, as soon as -`Hello World` was echoed, the container stopped. +`Hello world` was echoed, the container stopped. ## An Interactive Container @@ -88,7 +88,7 @@ use the `exit` command to finish. As with our previous container, once the Bash shell process has finished, the container is stopped. -## A Daemonized Hello World +## A Daemonized Hello world Now a container that runs a command and then exits has some uses but it's not overly helpful. Let's create a container that runs as a daemon, @@ -99,7 +99,7 @@ Again we can do this with the `docker run` command: $ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done" 1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147 -Wait what? Where's our "Hello World" Let's look at what we've run here. +Wait what? Where's our "Hello world" Let's look at what we've run here. It should look pretty familiar. We ran `docker run` but this time we specified a flag: `-d`. The `-d` flag tells Docker to run the container and put it in the background, to daemonize it. diff --git a/docs/sources/userguide/index.md b/docs/sources/userguide/index.md index d8f8294c01..e5c9ec272a 100644 --- a/docs/sources/userguide/index.md +++ b/docs/sources/userguide/index.md @@ -29,7 +29,7 @@ environment. To learn more; Go to [Using Docker Hub](/userguide/dockerhub). -## Dockerizing Applications: A "Hello World" +## Dockerizing Applications: A "Hello world" *How do I run applications inside containers?* -- cgit v1.2.1 From cccb64e8633eee309e6ce33c3bb41614edd70d81 Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 1 Jul 2014 19:14:22 -0400 Subject: Add backwards READ compatibility for the old libcontainer API Docker-DCO-1.1-Signed-off-by: Tibor Vass (github: tiborvass) --- daemon/execdriver/native/driver.go | 19 ++++++++++++++----- daemon/execdriver/native/info.go | 6 ++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index 1f27ef77b3..b789cc072d 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -173,12 +173,21 @@ func (d *driver) Terminate(p *execdriver.Command) error { // lets check the start time for the process state, err := libcontainer.GetState(filepath.Join(d.root, p.ID)) if err != nil { - // if we don't have the data on disk then we can assume the process is gone - // because this is only removed after we know the process has stopped - if os.IsNotExist(err) { - return nil + if !os.IsNotExist(err) { + return err } - return err + // TODO: Remove this part for version 1.2.0 + // This is added only to ensure smooth upgrades from pre 1.1.0 to 1.1.0 + data, err := ioutil.ReadAll(filepath.Join(d.root, p.ID, "start")) + if err != nil { + // if we don't have the data on disk then we can assume the process is gone + // because this is only removed after we know the process has stopped + if os.IsNotExist(err) { + return nil + } + return err + } + state.InitStartTime = string(data) } currentStartTime, err := system.GetProcessStartTime(p.Process.Pid) diff --git a/daemon/execdriver/native/info.go b/daemon/execdriver/native/info.go index 693a455a41..c34d0297b1 100644 --- a/daemon/execdriver/native/info.go +++ b/daemon/execdriver/native/info.go @@ -1,6 +1,7 @@ package native import ( + "os" "path/filepath" "github.com/docker/libcontainer" @@ -18,5 +19,10 @@ func (i *info) IsRunning() bool { if _, err := libcontainer.GetState(filepath.Join(i.driver.root, i.ID)); err == nil { return true } + // TODO: Remove this part for version 1.2.0 + // This is added only to ensure smooth upgrades from pre 1.1.0 to 1.1.0 + if _, err := os.Stat(filepath.Join(i.driver.root, i.ID, "pid")); err == nil { + return true + } return false } -- cgit v1.2.1 From d403936818b8785b65ff55ebab0d266b4a871ef6 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 2 Jul 2014 00:54:08 +0000 Subject: fix compilation and panic Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- daemon/execdriver/native/driver.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index b789cc072d..90333703c5 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -178,7 +178,7 @@ func (d *driver) Terminate(p *execdriver.Command) error { } // TODO: Remove this part for version 1.2.0 // This is added only to ensure smooth upgrades from pre 1.1.0 to 1.1.0 - data, err := ioutil.ReadAll(filepath.Join(d.root, p.ID, "start")) + data, err := ioutil.ReadFile(filepath.Join(d.root, p.ID, "start")) if err != nil { // if we don't have the data on disk then we can assume the process is gone // because this is only removed after we know the process has stopped @@ -187,7 +187,7 @@ func (d *driver) Terminate(p *execdriver.Command) error { } return err } - state.InitStartTime = string(data) + state = &libcontainer.State{InitStartTime: string(data)} } currentStartTime, err := system.GetProcessStartTime(p.Process.Pid) -- cgit v1.2.1 From 7abe70c0b1018729006fd5d614ada2dc67edb9b2 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Wed, 2 Jul 2014 09:36:57 -0600 Subject: Add NOFILE and NPROC ulimit settings to the OpenRC init script Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- contrib/init/openrc/docker.initd | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/init/openrc/docker.initd b/contrib/init/openrc/docker.initd index 2d79a73973..a9d21b1708 100755 --- a/contrib/init/openrc/docker.initd +++ b/contrib/init/openrc/docker.initd @@ -11,6 +11,9 @@ DOCKER_OPTS=${DOCKER_OPTS:-} start() { checkpath -f -m 0644 -o root:docker "$DOCKER_LOGFILE" + ulimit -n 1048576 + ulimit -u 1048576 + ebegin "Starting docker daemon" start-stop-daemon --start --background \ --exec "$DOCKER_BINARY" \ -- cgit v1.2.1 From bae79c3e7285c170f97a0f7f331a48fb47f0f40e Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Wed, 2 Jul 2014 09:38:19 -0600 Subject: Add NOFILE and NPROC ulimit settings to the SysV init script Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) --- contrib/init/sysvinit-debian/docker | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/init/sysvinit-debian/docker b/contrib/init/sysvinit-debian/docker index a3b9353754..6250cae053 100755 --- a/contrib/init/sysvinit-debian/docker +++ b/contrib/init/sysvinit-debian/docker @@ -88,6 +88,9 @@ case "$1" in touch "$DOCKER_LOGFILE" chgrp docker "$DOCKER_LOGFILE" + ulimit -n 1048576 + ulimit -u 1048576 + log_begin_msg "Starting $DOCKER_DESC: $BASE" start-stop-daemon --start --background \ --no-close \ -- cgit v1.2.1 From dad476803719ae2e86c703981caef0462e25260c Mon Sep 17 00:00:00 2001 From: unclejack Date: Mon, 30 Jun 2014 22:42:09 +0300 Subject: integcli: add & use pullImageIfNotExist for pulls This speeds up the tag cli integration tests by about 20 seconds. Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- integration-cli/docker_cli_tag_test.go | 22 +++++++--------------- integration-cli/docker_utils.go | 12 ++++++++++++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/integration-cli/docker_cli_tag_test.go b/integration-cli/docker_cli_tag_test.go index ef51f64644..032927e221 100644 --- a/integration-cli/docker_cli_tag_test.go +++ b/integration-cli/docker_cli_tag_test.go @@ -8,16 +8,12 @@ import ( // tagging a named image in a new unprefixed repo should work func TestTagUnprefixedRepoByName(t *testing.T) { - pullCmd := exec.Command(dockerBinary, "pull", "busybox") - out, exitCode, err := runCommandWithOutput(pullCmd) - errorOut(err, t, fmt.Sprintf("%s %s", out, err)) - - if err != nil || exitCode != 0 { - t.Fatal("pulling the busybox image from the registry has failed") + if err := pullImageIfNotExist("busybox:latest"); err != nil { + t.Fatal("couldn't find the busybox:latest image locally and failed to pull it") } - tagCmd := exec.Command(dockerBinary, "tag", "busybox", "testfoobarbaz") - out, _, err = runCommandWithOutput(tagCmd) + tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", "testfoobarbaz") + out, _, err := runCommandWithOutput(tagCmd) errorOut(err, t, fmt.Sprintf("%v %v", out, err)) deleteImages("testfoobarbaz") @@ -62,18 +58,14 @@ func TestTagInvalidUnprefixedRepo(t *testing.T) { // ensure we allow the use of valid tags func TestTagValidPrefixedRepo(t *testing.T) { - pullCmd := exec.Command(dockerBinary, "pull", "busybox") - out, exitCode, err := runCommandWithOutput(pullCmd) - errorOut(err, t, fmt.Sprintf("%s %s", out, err)) - - if err != nil || exitCode != 0 { - t.Fatal("pulling the busybox image from the registry has failed") + if err := pullImageIfNotExist("busybox:latest"); err != nil { + t.Fatal("couldn't find the busybox:latest image locally and failed to pull it") } validRepos := []string{"fooo/bar", "fooaa/test"} for _, repo := range validRepos { - tagCmd := exec.Command(dockerBinary, "tag", "busybox", repo) + tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", repo) _, _, err := runCommandWithOutput(tagCmd) if err != nil { t.Errorf("tag busybox %v should have worked: %s", repo, err) diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 22217e2f03..74576ba489 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -75,6 +75,18 @@ func imageExists(image string) error { return err } +func pullImageIfNotExist(image string) (err error) { + if err := imageExists(image); err != nil { + pullCmd := exec.Command(dockerBinary, "pull", image) + _, exitCode, err := runCommandWithOutput(pullCmd) + + if err != nil || exitCode != 0 { + err = fmt.Errorf("image '%s' wasn't found locally and it couldn't be pulled: %s", image, err) + } + } + return +} + func cmd(t *testing.T, args ...string) (string, int, error) { out, status, err := runCommandWithOutput(exec.Command(dockerBinary, args...)) errorOut(err, t, fmt.Sprintf("'%s' failed with errors: %v (%v)", strings.Join(args, " "), err, out)) -- cgit v1.2.1 From 170ba7f8feea9b284d20ed85e9ea9c947be2941c Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 2 Jul 2014 18:53:35 +0000 Subject: update release checklist and .gitignore Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- .gitignore | 1 + hack/RELEASE-CHECKLIST.md | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4f8f09c775..2a86e41caf 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ Vagrantfile docs/AWS_S3_BUCKET docs/GIT_BRANCH docs/VERSION +docs/GITCOMMIT diff --git a/hack/RELEASE-CHECKLIST.md b/hack/RELEASE-CHECKLIST.md index 6d7ed15297..2fe1a3ce96 100644 --- a/hack/RELEASE-CHECKLIST.md +++ b/hack/RELEASE-CHECKLIST.md @@ -138,11 +138,10 @@ make AWS_S3_BUCKET=beta-docs.docker.io docs-release ### 5. Commit and create a pull request to the "release" branch ```bash -export GITHUBUSER="YOUR_GITHUB_USER" git add VERSION CHANGELOG.md git commit -m "Bump version to $VERSION" git push $GITHUBUSER bump_$VERSION -echo "https://github.com/$GITHUBUSER/docker/compare/dotcloud:master...$GITHUBUSER:bump_$VERSION?expand=1" +echo "https://github.com/$GITHUBUSER/docker/compare/dotcloud:release...$GITHUBUSER:bump_$VERSION?expand=1" ``` That last command will give you the proper link to visit to ensure that you -- cgit v1.2.1 From d946cae36436a270b14d53585624e5567e590db2 Mon Sep 17 00:00:00 2001 From: Fred Lifton Date: Wed, 2 Jul 2014 16:33:13 -0700 Subject: Added Release Notes Release notes for v.1.1 have been added to the docs index.md page. Made some revisions to other content to make it shorter. Docker-DCO-1.1-Signed-off-by: Fred Lifton (github: fredlf) --- docs/sources/index.md | 90 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/docs/sources/index.md b/docs/sources/index.md index 57b9712238..3ff9c8dde7 100644 --- a/docs/sources/index.md +++ b/docs/sources/index.md @@ -22,8 +22,9 @@ Docker consists of: ## Why Docker? -- **Faster delivery of your applications** - * We want your environment to work better. Docker containers, +*Faster delivery of your applications* + +* We want your environment to work better. Docker containers, and the work flow that comes with them, help your developers, sysadmins, QA folks, and release engineers work together to get your code into production and make it useful. We've created a standard @@ -31,40 +32,42 @@ Docker consists of: inside containers while sysadmins and operators can work on running the container in your deployment. This separation of duties streamlines and simplifies the management and deployment of code. - * We make it easy to build new containers, enable rapid iteration of +* We make it easy to build new containers, enable rapid iteration of your applications, and increase the visibility of changes. This helps everyone in your organization understand how an application works and how it is built. - * Docker containers are lightweight and fast! Containers have +* Docker containers are lightweight and fast! Containers have sub-second launch times, reducing the cycle time of development, testing, and deployment. -- **Deploy and scale more easily** - * Docker containers run (almost) everywhere. You can deploy +*Deploy and scale more easily* + +* Docker containers run (almost) everywhere. You can deploy containers on desktops, physical servers, virtual machines, into data centers, and up to public and private clouds. - * Since Docker runs on so many platforms, it's easy to move your +* Since Docker runs on so many platforms, it's easy to move your applications around. You can easily move an application from a testing environment into the cloud and back whenever you need. - * Docker's lightweight containers also make scaling up and +* Docker's lightweight containers also make scaling up and down fast and easy. You can quickly launch more containers when needed and then shut them down easily when they're no longer needed. -- **Get higher density and run more workloads** - * Docker containers don't need a hypervisor, so you can pack more of +*Get higher density and run more workloads* + +* Docker containers don't need a hypervisor, so you can pack more of them onto your hosts. This means you get more value out of every server and can potentially reduce what you spend on equipment and licenses. -- **Faster deployment makes for easier management** - * As Docker speeds up your work flow, it gets easier to make lots +*Faster deployment makes for easier management* + +* As Docker speeds up your work flow, it gets easier to make lots of small changes instead of huge, big bang updates. Smaller changes mean reduced risk and more uptime. ## About this guide -First, the [Understanding Docker -section](introduction/understanding-docker.md) will help you: +The [Understanding Docker section](introduction/understanding-docker.md) will help you: - See how Docker works at a high level - Understand the architecture of Docker @@ -72,22 +75,59 @@ section](introduction/understanding-docker.md) will help you: - See how Docker compares to virtual machines - See some common use cases. -> [Click here to go to the Understanding -> Docker section](introduction/understanding-docker.md). - ### Installation Guides -Next, we'll show you how to install Docker on a variety of platforms in the -[installation](/installation/#installation) section. +The [installation section](/installation/#installation) will show you how to install +Docker on a variety of platforms. -> [Click here to go to the Installation -> section](/installation/#installation). ### Docker User Guide -Once you've gotten Docker installed we recommend you work through the -[Docker User Guide](/userguide/), to learn about Docker in more detail and -answer questions about usage and implementation. +To learn about Docker in more detail and to answer questions about usage and implementation, check out the [Docker User Guide](/userguide/). + +## Release Notes + +Version 1.1 + +### New Features + +*`.dockerignore` support* + +You can now add a `.dockerignore` file next to your `Dockerfile` and Docker will ignore files and directories specified in that file when sending the build context to the daemon. +Example: https://github.com/dotcloud/docker/blob/master/.dockerignore + +*Pause containers during commit* + +Doing a commit on a running container was not recommended because you could end up with files in an inconsistent state (for example, if they were being written during the commit). Containers are now paused when a commit is made to them. +You can disable this feature by doing a `docker commit --pause=false ` + +*Tailing logs* + +You can now tail the logs of a container. For example, you can get the last ten lines of a log by using `docker logs --tail 10 `. You can also follow the logs of a container without having to read the whole log file with `docker logs --tail 0 -f `. + +*Allow a tar file as context for docker build* + +You can now pass a tar archive to `docker build` as context. This can be used to automate docker builds, for example: `cat context.tar | docker build -` or `docker run builder_image | docker build -` + +*Bind mounting your whole filesystem in a container* + +`/` is now allowed as source of `--volumes`. This means you can bind-mount your whole system in a container if you need to. For example: `docker run -v /:/my_host ubuntu:ro ls /my_host`. However, it is now forbidden to mount to /. + + +### Other Improvements & Changes + +* Port allocation has been improved. In the previous release, Docker could prevent you from starting a container with previously allocated ports which seemed to be in use when in fact they were not. This has been fixed. + +* A bug in `docker save` was introduced in the last release. The `docker save` command could produce images with invalid metadata. The command now produces images with correct metadata. + +* Running `docker inspect` in a container now returns which containers it is linked to. + +* Parsing of the `docker commit` flag has improved validation, to better prevent you from committing an image with a name such as `-m`. Image names with dashes in them potentially conflict with command line flags. + +* The API now has Improved status codes for `start` and `stop`. Trying to start a running container will now return a 304 error. + +* Performance has been improved overall. Starting the daemon is faster than in previous releases. The daemon’s performance has also been improved when it is working with large numbers of images and containers. + +* Fixed an issue with white-spaces and multi-lines in Dockerfiles. -> [Click here to go to the Docker User Guide](/userguide/). -- cgit v1.2.1 From b59754bcb32fe5b8f416f407f71d2b50bb148c8a Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Sat, 28 Jun 2014 12:31:29 -0400 Subject: Fixed numerous inconsistencies in command help text * Replaced docker with Docker. * Consistently used STDIN, STDOUT, STDERR. * Consistently used TTY. * Fixed some grammar and spelling issues. * Fixed references to the index. Docker-DCO-1.1-Signed-off-by: James Turnbull (github: jamtur01) Docker-DCO-1.1-Signed-off-by: James Turnbull (github: SvenDowideit) --- api/client/commands.go | 58 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 2d9c74f432..6163f91c18 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -67,25 +67,25 @@ func (cli *DockerCli) CmdHelp(args ...string) error { {"inspect", "Return low-level information on a container"}, {"kill", "Kill a running container"}, {"load", "Load an image from a tar archive"}, - {"login", "Register or Login to the docker registry server"}, + {"login", "Register or log in to the Docker registry server"}, {"logs", "Fetch the logs of a container"}, - {"port", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT"}, + {"port", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT"}, {"pause", "Pause all processes within a container"}, {"ps", "List containers"}, - {"pull", "Pull an image or a repository from the docker registry server"}, - {"push", "Push an image or a repository to the docker registry server"}, + {"pull", "Pull an image or a repository from a Docker registry server"}, + {"push", "Push an image or a repository to a Docker registry server"}, {"restart", "Restart a running container"}, {"rm", "Remove one or more containers"}, {"rmi", "Remove one or more images"}, {"run", "Run a command in a new container"}, {"save", "Save an image to a tar archive"}, - {"search", "Search for an image in the docker index"}, + {"search", "Search for an image on the Docker Hub"}, {"start", "Start a stopped container"}, {"stop", "Stop a running container"}, {"tag", "Tag an image into a repository"}, {"top", "Lookup the running processes of a container"}, {"unpause", "Unpause a paused container"}, - {"version", "Show the docker version information"}, + {"version", "Show the Docker version information"}, {"wait", "Block until a container stops, then print its exit code"}, } { help += fmt.Sprintf(" %-10.10s%s\n", command[0], command[1]) @@ -123,12 +123,12 @@ func (cli *DockerCli) CmdBuild(args ...string) error { buf := bufio.NewReader(cli.in) magic, err := buf.Peek(tarHeaderSize) if err != nil && err != io.EOF { - return fmt.Errorf("failed to peek context header from stdin: %v", err) + return fmt.Errorf("failed to peek context header from STDIN: %v", err) } if !archive.IsArchive(magic) { dockerfile, err := ioutil.ReadAll(buf) if err != nil { - return fmt.Errorf("failed to read Dockerfile from stdin: %v", err) + return fmt.Errorf("failed to read Dockerfile from STDIN: %v", err) } context, err = archive.Generate("Dockerfile", string(dockerfile)) } else { @@ -248,7 +248,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error { // 'docker login': login / register a user to registry service. func (cli *DockerCli) CmdLogin(args ...string) error { - cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or Login to a docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.") + cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.") var username, password, email string @@ -374,7 +374,7 @@ func (cli *DockerCli) CmdWait(args ...string) error { // 'docker version': show version information func (cli *DockerCli) CmdVersion(args ...string) error { - cmd := cli.Subcmd("version", "", "Show the docker version information.") + cmd := cli.Subcmd("version", "", "Show the Docker version information.") if err := cmd.Parse(args); err != nil { return nil } @@ -497,8 +497,8 @@ func (cli *DockerCli) CmdInfo(args ...string) error { } func (cli *DockerCli) CmdStop(args ...string) error { - cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container (Send SIGTERM, and then SIGKILL after grace period)") - nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it.") + cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period") + nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.") if err := cmd.Parse(args); err != nil { return nil } @@ -525,7 +525,7 @@ func (cli *DockerCli) CmdStop(args ...string) error { func (cli *DockerCli) CmdRestart(args ...string) error { cmd := cli.Subcmd("restart", "[OPTIONS] CONTAINER [CONTAINER...]", "Restart a running container") - nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default=10") + nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.") if err := cmd.Parse(args); err != nil { return nil } @@ -582,8 +582,8 @@ func (cli *DockerCli) CmdStart(args ...string) error { tty bool cmd = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container") - attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's stdout/stderr and forward all signals to the process") - openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's stdin") + attach = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's STDOUT and STDERR and forward all signals to the process") + openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN") ) if err := cmd.Parse(args); err != nil { @@ -714,7 +714,7 @@ func (cli *DockerCli) CmdPause(args ...string) error { } func (cli *DockerCli) CmdInspect(args ...string) error { - cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container/image") + cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image") tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.") if err := cmd.Parse(args); err != nil { return nil @@ -794,7 +794,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error { } func (cli *DockerCli) CmdTop(args ...string) error { - cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Lookup the running processes of a container") + cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container") if err := cmd.Parse(args); err != nil { return nil } @@ -829,7 +829,7 @@ func (cli *DockerCli) CmdTop(args ...string) error { } func (cli *DockerCli) CmdPort(args ...string) error { - cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT") + cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT") if err := cmd.Parse(args); err != nil { return nil } @@ -877,7 +877,7 @@ func (cli *DockerCli) CmdPort(args ...string) error { func (cli *DockerCli) CmdRmi(args ...string) error { var ( cmd = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images") - force = cmd.Bool([]string{"f", "-force"}, false, "Force") + force = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image") noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") ) if err := cmd.Parse(args); err != nil { @@ -980,7 +980,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error { func (cli *DockerCli) CmdRm(args ...string) error { cmd := cli.Subcmd("rm", "[OPTIONS] CONTAINER [CONTAINER...]", "Remove one or more containers") - v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated to the container") + v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container") link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container") force := cmd.Bool([]string{"f", "-force"}, false, "Force removal of running container") @@ -1017,7 +1017,7 @@ func (cli *DockerCli) CmdRm(args ...string) error { // 'docker kill NAME' kills a running container func (cli *DockerCli) CmdKill(args ...string) error { - cmd := cli.Subcmd("kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container (send SIGKILL, or specified signal)") + cmd := cli.Subcmd("kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal") signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container") if err := cmd.Parse(args); err != nil { @@ -1149,7 +1149,7 @@ func (cli *DockerCli) CmdPush(args ...string) error { func (cli *DockerCli) CmdPull(args ...string) error { cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry") - tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in repository") + tag := cmd.String([]string{"#t", "#-tag"}, "", "Download tagged image in a repository") if err := cmd.Parse(args); err != nil { return nil } @@ -1542,7 +1542,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error { flComment := cmd.String([]string{"m", "-message"}, "", "Commit message") flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith \")") // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. - flConfig := cmd.String([]string{"#run", "#-run"}, "", "this option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") + flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") if err := cmd.Parse(args); err != nil { return nil } @@ -1735,8 +1735,8 @@ func (cli *DockerCli) CmdLogs(args ...string) error { func (cli *DockerCli) CmdAttach(args ...string) error { var ( cmd = cli.Subcmd("attach", "[OPTIONS] CONTAINER", "Attach to a running container") - noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach stdin") - proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied") + noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN") + proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied.") ) if err := cmd.Parse(args); err != nil { @@ -1807,11 +1807,11 @@ func (cli *DockerCli) CmdAttach(args ...string) error { } func (cli *DockerCli) CmdSearch(args ...string) error { - cmd := cli.Subcmd("search", "TERM", "Search the docker index for images") + cmd := cli.Subcmd("search", "TERM", "Search the Docker Hub for images") noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds") automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds") - stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least xxx stars") + stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars") if err := cmd.Parse(args); err != nil { return nil } @@ -1938,7 +1938,7 @@ func (cli *DockerCli) CmdRun(args ...string) error { } if cidFileInfo.Size() == 0 { if err := os.Remove(hostConfig.ContainerIDFile); err != nil { - fmt.Printf("failed to remove CID file '%s': %s \n", hostConfig.ContainerIDFile, err) + fmt.Printf("failed to remove Container ID file '%s': %s \n", hostConfig.ContainerIDFile, err) } } }() @@ -2188,7 +2188,7 @@ func (cli *DockerCli) CmdCp(args ...string) error { } func (cli *DockerCli) CmdSave(args ...string) error { - cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to stdout by default)") + cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to STDOUT by default)") outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT") if err := cmd.Parse(args); err != nil { -- cgit v1.2.1 From b07f193822d00e40580cd11320ed7e01b629f9d7 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Tue, 1 Jul 2014 12:58:04 +1000 Subject: Update cli.md and man pages to match current cli Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- api/client/commands.go | 2 +- contrib/completion/fish/docker.fish | 2 +- docs/docs-update.py | 214 ++++++++++++++++++++++++++++++ docs/man/docker-attach.1.md | 17 ++- docs/man/docker-build.1.md | 36 ++--- docs/man/docker-commit.1.md | 20 +-- docs/man/docker-cp.1.md | 14 +- docs/man/docker-diff.1.md | 15 ++- docs/man/docker-events.1.md | 17 ++- docs/man/docker-export.1.md | 16 ++- docs/man/docker-history.1.md | 18 +-- docs/man/docker-images.1.md | 39 +++--- docs/man/docker-import.1.md | 14 +- docs/man/docker-info.1.md | 8 +- docs/man/docker-inspect.1.md | 16 +-- docs/man/docker-kill.1.md | 13 +- docs/man/docker-load.1.md | 12 +- docs/man/docker-login.1.md | 19 +-- docs/man/docker-logs.1.md | 17 ++- docs/man/docker-pause.1.md | 15 +++ docs/man/docker-port.1.md | 14 +- docs/man/docker-ps.1.md | 42 +++--- docs/man/docker-pull.1.md | 12 +- docs/man/docker-push.1.md | 13 +- docs/man/docker-restart.1.md | 15 ++- docs/man/docker-rm.1.md | 29 ++-- docs/man/docker-rmi.1.md | 21 +-- docs/man/docker-run.1.md | 115 +++++++++------- docs/man/docker-save.1.md | 12 +- docs/man/docker-search.1.md | 29 ++-- docs/man/docker-start.1.md | 22 ++- docs/man/docker-stop.1.md | 17 +-- docs/man/docker-tag.1.md | 16 ++- docs/man/docker-top.1.md | 16 ++- docs/man/docker-unpause.1.md | 15 +++ docs/man/docker-version.1.md | 15 +++ docs/man/docker-wait.1.md | 15 ++- docs/man/docker.1.md | 8 +- docs/sources/reference/commandline/cli.md | 58 ++++---- runconfig/parse.go | 2 +- 40 files changed, 683 insertions(+), 327 deletions(-) create mode 100755 docs/docs-update.py create mode 100644 docs/man/docker-pause.1.md create mode 100644 docs/man/docker-unpause.1.md create mode 100644 docs/man/docker-version.1.md diff --git a/api/client/commands.go b/api/client/commands.go index 6163f91c18..df2125f5f3 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1540,7 +1540,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error { cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes") flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit") flComment := cmd.String([]string{"m", "-message"}, "", "Commit message") - flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith \")") + flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith \")") // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") if err := cmd.Parse(args); err != nil { diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index a1eac31df7..a4a9365f92 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -79,7 +79,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from build' -s t -l tag -d ' # commit complete -c docker -f -n '__fish_docker_no_subcommand' -a commit -d "Create a new image from a container's changes" -complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -s a -l author -d 'Author (eg. "John Hannibal Smith "' +complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -s a -l author -d 'Author (e.g., "John Hannibal Smith "' complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -s m -l message -d 'Commit message' complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -l run -d 'Config automatically applied when the image is run. (ex: -run=\'{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}\')' complete -c docker -A -f -n '__fish_seen_subcommand_from commit' -a '(__fish_print_docker_containers all)' -d "Container" diff --git a/docs/docs-update.py b/docs/docs-update.py new file mode 100755 index 0000000000..31bb47db3b --- /dev/null +++ b/docs/docs-update.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python + +# +# Sven's quick hack script to update the documentation +# +# call with: +# ./docs/update.py /usr/bin/docker +# + +import re +from sys import argv +import subprocess +import os +import os.path + +script, docker_cmd = argv + +def print_usage(outtext, docker_cmd, command): + help = "" + try: + #print "RUN ", "".join((docker_cmd, " ", command, " --help")) + help = subprocess.check_output("".join((docker_cmd, " ", command, " --help")), stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError, e: + help = e.output + for l in str(help).strip().split("\n"): + l = l.rstrip() + if l == '': + outtext.write("\n") + else: + # `docker --help` tells the user the path they called it with + l = re.sub(docker_cmd, "docker", l) + outtext.write(" "+l+"\n") + outtext.write("\n") + +# TODO: look for an complain about any missing commands +def update_cli_reference(): + originalFile = "docs/sources/reference/commandline/cli.md" + os.rename(originalFile, originalFile+".bak") + + intext = open(originalFile+".bak", "r") + outtext = open(originalFile, "w") + + mode = 'p' + space = " " + command = "" + # 2 mode line-by line parser + for line in intext: + if mode=='p': + # Prose + match = re.match("( \s*)Usage: docker ([a-z]+)", line) + if match: + # the begining of a Docker command usage block + space = match.group(1) + command = match.group(2) + mode = 'c' + else: + match = re.match("( \s*)Usage of .*docker.*:", line) + if match: + # the begining of the Docker --help usage block + space = match.group(1) + command = "" + mode = 'c' + else: + outtext.write(line) + else: + # command usage block + match = re.match("("+space+")(.*)|^$", line) + #print "CMD ", command + if not match: + # The end of the current usage block - Shell out to run docker to see the new output + print_usage(outtext, docker_cmd, command) + outtext.write(line) + mode = 'p' + if mode == 'c': + print_usage(outtext, docker_cmd, command) + +def update_man_pages(): + cmds = [] + try: + help = subprocess.check_output("".join((docker_cmd)), stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError, e: + help = e.output + for l in str(help).strip().split("\n"): + l = l.rstrip() + if l != "": + match = re.match(" (.*?) .*", l) + if match: + cmds.append(match.group(1)) + + desc_re = re.compile(r".*# DESCRIPTION(.*?)# (OPTIONS|EXAMPLES?).*", re.MULTILINE|re.DOTALL) + example_re = re.compile(r".*# EXAMPLES?(.*)# HISTORY.*", re.MULTILINE|re.DOTALL) + history_re = re.compile(r".*# HISTORY(.*)", re.MULTILINE|re.DOTALL) + + for command in cmds: + print "COMMAND: "+command + history = "" + description = "" + examples = "" + if os.path.isfile("docs/man/docker-"+command+".1.md"): + intext = open("docs/man/docker-"+command+".1.md", "r") + txt = intext.read() + intext.close() + match = desc_re.match(txt) + if match: + description = match.group(1) + match = example_re.match(txt) + if match: + examples = match.group(1) + match = history_re.match(txt) + if match: + history = match.group(1).strip() + + usage = "" + usage_description = "" + params = {} + key_params = {} + + help = "" + try: + help = subprocess.check_output("".join((docker_cmd, " ", command, " --help")), stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError, e: + help = e.output + last_key = "" + for l in str(help).split("\n"): + l = l.rstrip() + if l != "": + match = re.match("Usage: docker "+command+"(.*)", l) + if match: + usage = match.group(1).strip() + else: + #print ">>>>"+l + match = re.match(" (-+)(.*) \s+(.*)", l) + if match: + last_key = match.group(2).rstrip() + #print " found "+match.group(1) + key_params[last_key] = match.group(1)+last_key + params[last_key] = match.group(3) + else: + if last_key != "": + params[last_key] = params[last_key] + "\n" + l + else: + if usage_description != "": + usage_description = usage_description + "\n" + usage_description = usage_description + l + + # replace [OPTIONS] with the list of params + options = "" + match = re.match("\[OPTIONS\](.*)", usage) + if match: + usage = match.group(1) + + new_usage = "" + # TODO: sort without the `-`'s + for key in sorted(params.keys(), key=lambda s: s.lower()): + # split on commas, remove --?.*=.*, put in *'s mumble + ps = [] + opts = [] + for k in key_params[key].split(","): + #print "......"+k + match = re.match("(-+)([A-Za-z-0-9]*)(?:=(.*))?", k.lstrip()) + if match: + p = "**"+match.group(1)+match.group(2)+"**" + o = "**"+match.group(1)+match.group(2)+"**" + if match.group(3): + # if ="" then use UPPERCASE(group(2))" + val = match.group(3) + if val == "\"\"": + val = match.group(2).upper() + p = p+"[=*"+val+"*]" + val = match.group(3) + if val in ("true", "false"): + params[key] = params[key].rstrip() + if not params[key].endswith('.'): + params[key] = params[key]+ "." + params[key] = params[key] + " The default is *"+val+"*." + val = "*true*|*false*" + o = o+"="+val + ps.append(p) + opts.append(o) + else: + print "nomatch:"+k + new_usage = new_usage+ "\n["+"|".join(ps)+"]" + options = options + ", ".join(opts) + "\n "+ params[key]+"\n\n" + if new_usage != "": + new_usage = new_usage.strip() + "\n" + usage = new_usage + usage + + + outtext = open("docs/man/docker-"+command+".1.md", "w") + outtext.write("""% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +""") + outtext.write("docker-"+command+" - "+usage_description+"\n\n") + outtext.write("# SYNOPSIS\n**docker "+command+"**\n"+usage+"\n\n") + if description != "": + outtext.write("# DESCRIPTION"+description) + if options == "": + options = "There are no available options.\n\n" + outtext.write("# OPTIONS\n"+options) + if examples != "": + outtext.write("# EXAMPLES"+examples) + outtext.write("# HISTORY\n") + if history != "": + outtext.write(history+"\n") + recent_history_re = re.compile(".*June 2014.*", re.MULTILINE|re.DOTALL) + if not recent_history_re.match(history): + outtext.write("June 2014, updated by Sven Dowideit \n") + outtext.close() + +# main +update_cli_reference() +update_man_pages() diff --git a/docs/man/docker-attach.1.md b/docs/man/docker-attach.1.md index 91188aaaef..0ca9797018 100644 --- a/docs/man/docker-attach.1.md +++ b/docs/man/docker-attach.1.md @@ -1,11 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-attach - Attach to a running container # SYNOPSIS -**docker attach** **--no-stdin**[=*false*] **--sig-proxy**[=*true*] CONTAINER +**docker attach** +[**--no-stdin**[=*false*]] +[**--sig-proxy**[=*true*]] + CONTAINER # DESCRIPTION If you **docker run** a container in detached mode (**-d**), you can reattach to @@ -19,11 +22,10 @@ the client. # OPTIONS **--no-stdin**=*true*|*false* -When set to true, do not attach to stdin. The default is *false*. + Do not attach STDIN. The default is *false*. -**--sig-proxy**=*true*|*false*: -When set to true, proxify received signals to the process (even in non-tty -mode). SIGCHLD is not proxied. The default is *true*. +**--sig-proxy**=*true*|*false* + Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied. The default is *true*. # EXAMPLES @@ -56,3 +58,4 @@ attach** command: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-build.1.md b/docs/man/docker-build.1.md index 3c031445aa..2b426f1cef 100644 --- a/docs/man/docker-build.1.md +++ b/docs/man/docker-build.1.md @@ -1,12 +1,17 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-build - Build an image from a Dockerfile source at PATH +docker-build - Build a new image from the source code at PATH # SYNOPSIS -**docker build** [**--no-cache**[=*false*]] [**-q**|**--quiet**[=*false*]] - [**--rm**] [**-t**|**--tag**=TAG] PATH | URL | - +**docker build** +[**--force-rm**[=*false*]] +[**--no-cache**[=*false*]] +[**-q**|**--quiet**[=*false*]] +[**--rm**[=*true*]] +[**-t**|**--tag**[=*TAG*]] + PATH | URL | - # DESCRIPTION This will read the Dockerfile from the directory specified in **PATH**. @@ -25,22 +30,20 @@ When a Git repository is set as the **URL**, the repository is used as context. # OPTIONS +**--force-rm**=*true*|*false* + Always remove intermediate containers, even after unsuccessful builds. The default is *false*. + +**--no-cache**=*true*|*false* + Do not use cache when building the image. The default is *false*. **-q**, **--quiet**=*true*|*false* - When set to true, suppress verbose build output. Default is *false*. + Suppress the verbose output generated by the containers. The default is *false*. **--rm**=*true*|*false* - When true, remove intermediate containers that are created during the -build process. The default is true. + Remove intermediate containers after a successful build. The default is *true*. -**-t**, **--tag**=*tag* - The name to be applied to the resulting image on successful completion of -the build. `tag` in this context means the entire image name including the -optional TAG after the ':'. - -**--no-cache**=*true*|*false* - When set to true, do not use a cache when building the image. The -default is *false*. +**-t**, **--tag**="" + Repository name (and optionally a tag) to be applied to the resulting image in case of success # EXAMPLES @@ -115,3 +118,4 @@ Note: You can set an arbitrary Git repository via the `git://` schema. # HISTORY March 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-commit.1.md b/docs/man/docker-commit.1.md index c0f2c734c5..5ec3808dfb 100644 --- a/docs/man/docker-commit.1.md +++ b/docs/man/docker-commit.1.md @@ -1,22 +1,23 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-commit - Create a new image from the changes to an existing -container +docker-commit - Create a new image from a container's changes # SYNOPSIS -**docker commit** **-a**|**--author**[=""] **-m**|**--message**[=""] -CONTAINER [REPOSITORY[:TAG]] +**docker commit** +[**-a**|**--author**[=*AUTHOR*]] +[**-m**|**--message**[=*MESSAGE*]] + CONTAINER [REPOSITORY[:TAG]] # DESCRIPTION Using an existing container's name or ID you can create a new image. # OPTIONS -**-a, --author**="" - Author name. (e.g., "John Hannibal Smith " +**-a**, **--author**="" + Author (e.g., "John Hannibal Smith ") -**-m, --message**="" +**-m**, **--message**="" Commit message **-p, --pause**=true @@ -35,3 +36,4 @@ create a new image run docker ps to find the container's ID and then run: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and in +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-cp.1.md b/docs/man/docker-cp.1.md index 1801e7318d..750a6d1d53 100644 --- a/docs/man/docker-cp.1.md +++ b/docs/man/docker-cp.1.md @@ -1,18 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-cp - Copy files/folders from the PATH to the HOSTPATH # SYNOPSIS -**docker cp** CONTAINER:PATH HOSTPATH +**docker cp** +CONTAINER:PATH HOSTPATH # DESCRIPTION Copy files/folders from a container's filesystem to the host path. Paths are relative to the root of the filesystem. Files can be copied from a running or stopped container. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES An important shell script file, created in a bash shell, is copied from the exited container to the current dir on the host: @@ -21,4 +25,4 @@ the exited container to the current dir on the host: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-diff.1.md b/docs/man/docker-diff.1.md index 2053f2c3d2..d7aae25f85 100644 --- a/docs/man/docker-diff.1.md +++ b/docs/man/docker-diff.1.md @@ -1,18 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-diff - Inspect changes on a container's filesystem # SYNOPSIS -**docker diff** CONTAINER +**docker diff** +CONTAINER # DESCRIPTION Inspect changes on a container's filesystem. You can use the full or shortened container ID or the container name set using **docker run --name** option. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES Inspect the changes to on a nginx container: # docker diff 1fdfd1f54c1b @@ -40,5 +44,4 @@ Inspect the changes to on a nginx container: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-events.1.md b/docs/man/docker-events.1.md index 2ebe9247d4..ca8f63db53 100644 --- a/docs/man/docker-events.1.md +++ b/docs/man/docker-events.1.md @@ -1,10 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-events - Get real time events from the server -**docker events** **--since**=""|*epoch-time* +# SYNOPSIS +**docker events** +[**--since**[=*SINCE*]] +[**--until**[=*UNTIL*]] + # DESCRIPTION Get event information from the Docker daemon. Information can include historical @@ -12,8 +16,10 @@ information and real-time information. # OPTIONS **--since**="" -Show previously created events and then stream. This can be in either -seconds since epoch, or date string. + Show all events created since timestamp + +**--until**="" + Stream events until this timestamp # EXAMPLES @@ -44,3 +50,4 @@ Again the output container IDs have been shortened for the purposes of this docu # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-export.1.md b/docs/man/docker-export.1.md index ab11aa1266..efd884a79d 100644 --- a/docs/man/docker-export.1.md +++ b/docs/man/docker-export.1.md @@ -1,19 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-export - Export the contents of a filesystem as a tar archive to -STDOUT. +docker-export - Export the contents of a filesystem as a tar archive to STDOUT # SYNOPSIS -**docker export** CONTAINER +**docker export** +CONTAINER # DESCRIPTION Export the contents of a container's filesystem using the full or shortened container ID or container name. The output is exported to STDOUT and can be redirected to a tar file. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES Export the contents of the container called angry_bell to a tar file called test.tar: @@ -24,3 +27,4 @@ called test.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-history.1.md b/docs/man/docker-history.1.md index 1b3a9858b5..ee58e03fca 100644 --- a/docs/man/docker-history.1.md +++ b/docs/man/docker-history.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-history - Show the history of an image # SYNOPSIS -**docker history** **--no-trunc**[=*false*] [**-q**|**--quiet**[=*false*]] +**docker history** +[**--no-trunc**[=*false*]] +[**-q**|**--quiet**[=*false*]] IMAGE # DESCRIPTION @@ -13,14 +15,13 @@ docker-history - Show the history of an image Show the history of when and how an image was created. # OPTIONS - **--no-trunc**=*true*|*false* - When true don't truncate output. Default is false + Don't truncate output. The default is *false*. -**-q**, **--quiet=*true*|*false* - When true only show numeric IDs. Default is false. +**-q**, **--quiet**=*true*|*false* + Only show numeric IDs. The default is *false*. -# EXAMPLE +# EXAMPLES $ sudo docker history fedora IMAGE CREATED CREATED BY SIZE 105182bb5e8b 5 days ago /bin/sh -c #(nop) ADD file:71356d2ad59aa3119d 372.7 MB @@ -30,3 +31,4 @@ Show the history of when and how an image was created. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-images.1.md b/docs/man/docker-images.1.md index 602ccf7c90..a940192e9a 100644 --- a/docs/man/docker-images.1.md +++ b/docs/man/docker-images.1.md @@ -1,17 +1,16 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-images - List the images in the local repository +docker-images - List images # SYNOPSIS **docker images** -[**-a**|**--all**=*false*] -[**--no-trunc**[=*false*] -[**-q**|**--quiet**[=*false*] -[**-t**|**--tree**=*false*] -[**-v**|**--viz**=*false*] -[NAME] +[**-a**|**--all**[=*false*]] +[**-f**|**--filter**[=*[]*]] +[**--no-trunc**[=*false*]] +[**-q**|**--quiet**[=*false*]] + [NAME] # DESCRIPTION This command lists the images stored in the local Docker repository. @@ -30,26 +29,17 @@ called fedora. It may be tagged with 18, 19, or 20, etc. to manage different versions. # OPTIONS - **-a**, **--all**=*true*|*false* - When set to true, also include all intermediate images in the list. The -default is false. + Show all images (by default filter out the intermediate image layers). The default is *false*. + +**-f**, **--filter**=[] + Provide filter values (i.e. 'dangling=true') **--no-trunc**=*true*|*false* - When set to true, list the full image ID and not the truncated ID. The -default is false. + Don't truncate output. The default is *false*. **-q**, **--quiet**=*true*|*false* - When set to true, list the complete image ID as part of the output. The -default is false. - -**-t**, **--tree**=*true*|*false* - When set to true, list the images in a tree dependency tree (hierarchy) -format. The default is false. - -**-v**, **--viz**=*true*|*false* - When set to true, list the graph in graphviz format. The default is -*false*. + Only show numeric IDs. The default is *false*. # EXAMPLES @@ -97,3 +87,4 @@ tools. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-import.1.md b/docs/man/docker-import.1.md index 6b76d191fa..f320eafa26 100644 --- a/docs/man/docker-import.1.md +++ b/docs/man/docker-import.1.md @@ -1,17 +1,20 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-import - Create an empty filesystem image and import the contents -of the tarball into it. +docker-import - Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it. # SYNOPSIS -**docker import** URL|- [REPOSITORY[:TAG]] +**docker import** +URL|- [REPOSITORY[:TAG]] # DESCRIPTION Create a new filesystem image from the contents of a tarball (`.tar`, `.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it. +# OPTIONS +There are no available options. + # EXAMPLES ## Import from a remote location @@ -37,3 +40,4 @@ Import to docker via pipe and stdin: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-info.1.md b/docs/man/docker-info.1.md index 8c03945dbe..cae9a32909 100644 --- a/docs/man/docker-info.1.md +++ b/docs/man/docker-info.1.md @@ -1,12 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-info - Display system wide information +docker-info - Display system-wide information # SYNOPSIS **docker info** + # DESCRIPTION This command displays system wide information regarding the Docker installation. Information displayed includes the number of containers and images, pool name, @@ -44,3 +45,4 @@ Here is a sample output: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-inspect.1.md b/docs/man/docker-inspect.1.md index a82c76a625..29511fbe66 100644 --- a/docs/man/docker-inspect.1.md +++ b/docs/man/docker-inspect.1.md @@ -1,12 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-inspect - Return low-level information on a container/image +docker-inspect - Return low-level information on a container or image # SYNOPSIS -**docker inspect** [**-f**|**--format**="" CONTAINER|IMAGE -[CONTAINER|IMAGE...] +**docker inspect** +[**-f**|**--format**[=*FORMAT*]] +CONTAINER|IMAGE [CONTAINER|IMAGE...] # DESCRIPTION @@ -17,8 +18,7 @@ each result. # OPTIONS **-f**, **--format**="" - The text/template package of Go describes all the details of the -format. See examples section + Format the output using the given go template. # EXAMPLES @@ -224,6 +224,6 @@ Use an image's ID or name (e.g., repository/name[:tag]) to get information }] # HISTORY - April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-kill.1.md b/docs/man/docker-kill.1.md index 8175002d33..a454c432f6 100644 --- a/docs/man/docker-kill.1.md +++ b/docs/man/docker-kill.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-kill - Kill a running container (send SIGKILL, or specified signal) +docker-kill - Kill a running container using SIGKILL or a specified signal # SYNOPSIS -**docker kill** **--signal**[=*"KILL"*] CONTAINER [CONTAINER...] +**docker kill** +[**-s**|**--signal**[=*"KILL"*]] + CONTAINER [CONTAINER...] # DESCRIPTION @@ -13,9 +15,10 @@ The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal. # OPTIONS -**-s**, **--signal**=*"KILL"* +**-s**, **--signal**="KILL" Signal to send to the container # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-load.1.md b/docs/man/docker-load.1.md index 535b701cca..41ab5f64c8 100644 --- a/docs/man/docker-load.1.md +++ b/docs/man/docker-load.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-load - Load an image from a tar archive on STDIN # SYNOPSIS -**docker load** **--input**="" +**docker load** +[**-i**|**--input**[=*INPUT*]] + # DESCRIPTION @@ -13,11 +15,10 @@ Loads a tarred repository from a file or the standard input stream. Restores both images and tags. # OPTIONS - **-i**, **--input**="" Read from a tar archive file, instead of STDIN -# EXAMPLE +# EXAMPLES $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE @@ -34,3 +35,4 @@ Restores both images and tags. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-login.1.md b/docs/man/docker-login.1.md index 0a9cb283dd..6583342656 100644 --- a/docs/man/docker-login.1.md +++ b/docs/man/docker-login.1.md @@ -1,12 +1,15 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-login - Register or Login to a docker registry server. +docker-login - Register or log in to a Docker registry server, if no server is specified "https://index.docker.io/v1/" is the default. # SYNOPSIS -**docker login** [**-e**|**-email**=""] [**-p**|**--password**=""] - [**-u**|**--username**=""] [SERVER] +**docker login** +[**-e**|**--email**[=*EMAIL*]] +[**-p**|**--password**[=*PASSWORD*]] +[**-u**|**--username**[=*USERNAME*]] + [SERVER] # DESCRIPTION Register or Login to a docker registry server, if no server is @@ -15,7 +18,7 @@ login to a private registry you can specify this by adding the server name. # OPTIONS **-e**, **--email**="" - Email address + Email **-p**, **--password**="" Password @@ -23,7 +26,7 @@ login to a private registry you can specify this by adding the server name. **-u**, **--username**="" Username -# EXAMPLE +# EXAMPLES ## Login to a local registry @@ -32,4 +35,4 @@ login to a private registry you can specify this by adding the server name. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-logs.1.md b/docs/man/docker-logs.1.md index 0b9ce867e9..5881b0512f 100644 --- a/docs/man/docker-logs.1.md +++ b/docs/man/docker-logs.1.md @@ -1,11 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-logs - Fetch the logs of a container # SYNOPSIS -**docker logs** **--follow**[=*false*] CONTAINER +**docker logs** +[**-f**|**--follow**[=*false*]] +[**-t**|**--timestamps**[=*false*]] +CONTAINER # DESCRIPTION The **docker logs** command batch-retrieves whatever logs are present for @@ -18,9 +21,13 @@ The **docker logs --follow** command combines commands **docker logs** and then continue streaming new output from the container’s stdout and stderr. # OPTIONS -**-f, --follow**=*true*|*false* - When *true*, follow log output. The default is false. +**-f**, **--follow**=*true*|*false* + Follow log output. The default is *false*. + +**-t**, **--timestamps**=*true*|*false* + Show timestamps. The default is *false*. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-pause.1.md b/docs/man/docker-pause.1.md new file mode 100644 index 0000000000..e6c0c2455d --- /dev/null +++ b/docs/man/docker-pause.1.md @@ -0,0 +1,15 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-pause - Pause all processes within a container + +# SYNOPSIS +**docker pause** +CONTAINER + +# OPTIONS +There are no available options. + +# HISTORY +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-port.1.md b/docs/man/docker-port.1.md index 9773e4d80c..a92f75cd57 100644 --- a/docs/man/docker-port.1.md +++ b/docs/man/docker-port.1.md @@ -1,15 +1,17 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-port - Lookup the public-facing port which is NAT-ed to PRIVATE_PORT +docker-port - Lookup the public-facing port that is NAT-ed to PRIVATE_PORT # SYNOPSIS -**docker port** CONTAINER PRIVATE_PORT +**docker port** +CONTAINER PRIVATE_PORT -# DESCRIPTION -Lookup the public-facing port which is NAT-ed to PRIVATE_PORT +# OPTIONS +There are no available options. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-ps.1.md b/docs/man/docker-ps.1.md index 60fce0213a..454be74ad1 100644 --- a/docs/man/docker-ps.1.md +++ b/docs/man/docker-ps.1.md @@ -1,14 +1,20 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-ps - List containers # SYNOPSIS -**docker ps** [**-a**|**--all**=*false*] [**--before**=""] -[**-l**|**--latest**=*false*] [**-n**=*-1*] [**--no-trunc**=*false*] -[**-q**|**--quiet**=*false*] [**-s**|**--size**=*false*] -[**--since**=""] +**docker ps** +[**-a**|**--all**[=*false*]] +[**--before**[=*BEFORE*]] +[**-l**|**--latest**[=*false*]] +[**-n**[=*-1*]] +[**--no-trunc**[=*false*]] +[**-q**|**--quiet**[=*false*]] +[**-s**|**--size**[=*false*]] +[**--since**[=*SINCE*]] + # DESCRIPTION @@ -16,36 +22,31 @@ List the containers in the local repository. By default this show only the running containers. # OPTIONS - **-a**, **--all**=*true*|*false* - When true show all containers. Only running containers are shown by -default. Default is false. + Show all containers. Only running containers are shown by default. The default is *false*. **--before**="" - Show only container created before Id or Name, include non-running -ones. + Show only container created before Id or Name, include non-running ones. **-l**, **--latest**=*true*|*false* - When true show only the latest created container, include non-running -ones. The default is false. + Show only the latest created container, include non-running ones. The default is *false*. -**-n**=NUM - Show NUM (integer) last created containers, include non-running ones. -The default is -1 (none) +**-n**=-1 + Show n last created containers, include non-running ones. **--no-trunc**=*true*|*false* - When true truncate output. Default is false. + Don't truncate output. The default is *false*. **-q**, **--quiet**=*true*|*false* - When false only display numeric IDs. Default is false. + Only display numeric IDs. The default is *false*. **-s**, **--size**=*true*|*false* - When true display container sizes. Default is false. + Display sizes. The default is *false*. **--since**="" Show only containers created since Id or Name, include non-running ones. -# EXAMPLE +# EXAMPLES # Display all containers, including non-running # docker ps -a @@ -66,3 +67,4 @@ The default is -1 (none) # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-pull.1.md b/docs/man/docker-pull.1.md index d8e177b2b2..c397b42ea9 100644 --- a/docs/man/docker-pull.1.md +++ b/docs/man/docker-pull.1.md @@ -1,11 +1,12 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-pull - Pull an image or a repository from the registry # SYNOPSIS -**docker pull** [REGISTRY_PATH/]NAME[:TAG] +**docker pull** +NAME[:TAG] # DESCRIPTION @@ -14,6 +15,9 @@ there is more than one image for a repository (e.g., fedora) then all images for that repository name are pulled down including any tags. It is also possible to specify a non-default registry to pull from. +# OPTIONS +There are no available options. + # EXAMPLES # Pull a repository with multiple images @@ -48,4 +52,4 @@ It is also possible to specify a non-default registry to pull from. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-push.1.md b/docs/man/docker-push.1.md index dbb6e7d1b1..4b05b62a7f 100644 --- a/docs/man/docker-push.1.md +++ b/docs/man/docker-push.1.md @@ -1,11 +1,12 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-push - Push an image or a repository to the registry # SYNOPSIS -**docker push** NAME[:TAG] +**docker push** +NAME[:TAG] # DESCRIPTION Push an image or a repository to a registry. The default registry is the Docker @@ -13,7 +14,10 @@ Index located at [index.docker.io](https://index.docker.io/v1/). However the image can be pushed to another, perhaps private, registry as demonstrated in the example below. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES # Pushing a new image to a registry @@ -42,3 +46,4 @@ listed. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-restart.1.md b/docs/man/docker-restart.1.md index 44634f6613..6374273cfc 100644 --- a/docs/man/docker-restart.1.md +++ b/docs/man/docker-restart.1.md @@ -1,21 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-restart - Restart a running container # SYNOPSIS -**docker restart** [**-t**|**--time**[=*10*]] CONTAINER [CONTAINER...] +**docker restart** +[**-t**|**--time**[=*10*]] + CONTAINER [CONTAINER...] # DESCRIPTION Restart each container listed. # OPTIONS -**-t**, **--time**=NUM - Number of seconds to try to stop for before killing the container. Once -killed it will then be restarted. Default=10 +**-t**, **--time**=10 + Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-rm.1.md b/docs/man/docker-rm.1.md index ae85af5277..f41a6edb17 100644 --- a/docs/man/docker-rm.1.md +++ b/docs/man/docker-rm.1.md @@ -1,16 +1,15 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 - +% Docker Community +% JUNE 2014 # NAME - -docker-rm - Remove one or more containers. +docker-rm - Remove one or more containers # SYNOPSIS - -**docker rm** [**-f**|**--force**[=*false*] [**-l**|**--link**[=*false*] [**-v**| -**--volumes**[=*false*] -CONTAINER [CONTAINER...] +**docker rm** +[**-f**|**--force**[=*false*]] +[**-l**|**--link**[=*false*]] +[**-v**|**--volumes**[=*false*]] + CONTAINER [CONTAINER...] # DESCRIPTION @@ -20,18 +19,14 @@ remove a running container unless you use the \fB-f\fR option. To see all containers on a host use the **docker ps -a** command. # OPTIONS - **-f**, **--force**=*true*|*false* - When set to true, force the removal of the container. The default is -*false*. + Force removal of running container. The default is *false*. **-l**, **--link**=*true*|*false* - When set to true, remove the specified link and not the underlying -container. The default is *false*. + Remove the specified link and not the underlying container. The default is *false*. **-v**, **--volumes**=*true*|*false* - When set to true, remove the volumes associated to the container. The -default is *false*. + Remove the volumes associated with the container. The default is *false*. # EXAMPLES @@ -51,6 +46,6 @@ command. The use that name as follows: docker rm hopeful_morse # HISTORY - April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-rmi.1.md b/docs/man/docker-rmi.1.md index b728dc16a9..e03ecc4bca 100644 --- a/docs/man/docker-rmi.1.md +++ b/docs/man/docker-rmi.1.md @@ -1,12 +1,14 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-rmi \- Remove one or more images. +docker-rmi - Remove one or more images # SYNOPSIS - -**docker rmi** [**-f**|**--force**[=*false*] IMAGE [IMAGE...] +**docker rmi** +[**-f**|**--force**[=*false*]] +[**--no-prune**[=*false*]] +IMAGE [IMAGE...] # DESCRIPTION @@ -16,10 +18,11 @@ container unless you use the **-f** option. To see all images on a host use the **docker images** command. # OPTIONS - **-f**, **--force**=*true*|*false* - When set to true, force the removal of the image. The default is -*false*. + Force removal of the image. The default is *false*. + +**--no-prune**=*true*|*false* + Do not delete untagged parents. The default is *false*. # EXAMPLES @@ -30,6 +33,6 @@ Here is an example of removing and image: docker rmi fedora/httpd # HISTORY - April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-run.1.md b/docs/man/docker-run.1.md index ec9db8fd08..1e1adbe55d 100644 --- a/docs/man/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -1,26 +1,40 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-run - Run a process in an isolated container +docker-run - Run a command in a new container # SYNOPSIS **docker run** -[**-a**|**--attach**[=]] [**-c**|**--cpu-shares**[=0] -[**-m**|**--memory**=*memory-limit*] -[**--cidfile**=*file*] [**-d**|**--detach**[=*false*]] [**--dns**=*IP-address*] -[**--name**=*name*] [**-u**|**--user**=*username*|*uid*] -[**--link**=*name*:*alias*] -[**-e**|**--env**=*environment*] [**--entrypoint**=*command*] -[**--expose**=*port*] [**-P**|**--publish-all**[=*false*]] -[**-p**|**--publish**=*port-mapping*] [**-h**|**--hostname**=*hostname*] -[**--rm**[=*false*]] [**--privileged**[=*false*]] +[**-a**|**--attach**[=*[]*]] +[**-c**|**--cpu-shares**[=*0*]] +[**--cidfile**[=*CIDFILE*]] +[**--cpuset**[=*CPUSET*]] +[**-d**|**--detach**[=*false*]] +[**--dns-search**[=*[]*]] +[**--dns**[=*[]*]] +[**-e**|**--env**[=*[]*]] +[**--entrypoint**[=*ENTRYPOINT*]] +[**--env-file**[=*[]*]] +[**--expose**[=*[]*]] +[**-h**|**--hostname**[=*HOSTNAME*]] [**-i**|**--interactive**[=*false*]] -[**-t**|**--tty**[=*false*]] [**--lxc-conf**=*options*] -[**-n**|**--networking**[=*true*]] -[**-v**|**--volume**=*volume*] [**--volumes-from**=*container-id*] -[**-w**|**--workdir**=*directory*] [**--sig-proxy**[=*true*]] -IMAGE [COMMAND] [ARG...] +[**--link**[=*[]*]] +[**--lxc-conf**[=*[]*]] +[**-m**|**--memory**[=*MEMORY*]] +[**--name**[=*NAME*]] +[**--net**[=*"bridge"*]] +[**-P**|**--publish-all**[=*false*]] +[**-p**|**--publish**[=*[]*]] +[**--privileged**[=*false*]] +[**--rm**[=*false*]] +[**--sig-proxy**[=*true*]] +[**-t**|**--tty**[=*false*]] +[**-u**|**--user**[=*USER*]] +[**-v**|**--volume**[=*[]*]] +[**--volumes-from**[=*[]*]] +[**-w**|**--workdir**[=*WORKDIR*]] + IMAGE [COMMAND] [ARG...] # DESCRIPTION @@ -56,6 +70,8 @@ run**. **--cidfile**=*file* Write the container ID to the file specified. +**--cpuset**="" + CPUs in which to allow execution (0-3, 0,1) **-d**, **-detach**=*true*|*false* Detached mode. This runs the container in the background. It outputs the new @@ -67,6 +83,8 @@ the detached mode, then you cannot use the **-rm** option. When attached in the tty mode, you can detach from a running container without stopping the process by pressing the keys CTRL-P CTRL-Q. +**--dns-search**=[] + Set custom dns search domains **--dns**=*IP-address* Set custom DNS servers. This option can be used to override the DNS @@ -92,6 +110,8 @@ pass in more options via the COMMAND. But, sometimes an operator may want to run something else inside the container, so you can override the default ENTRYPOINT at runtime by using a **--entrypoint** and a string to specify the new ENTRYPOINT. +**--env-file**=[] + Read in a line delimited file of ENV variables **--expose**=*port* Expose a port from the container without publishing it to your host. A @@ -100,36 +120,12 @@ developer can expose the port using the EXPOSE parameter of the Dockerfile, 2) the operator can use the **--expose** option with **docker run**, or 3) the container can be started with the **--link**. -**-m**, **-memory**=*memory-limit* - Allows you to constrain the memory available to a container. If the host -supports swap memory, then the -m memory setting can be larger than physical -RAM. If a limit of 0 is specified, the container's memory is not limited. The -actual limit may be rounded up to a multiple of the operating system's page -size, if it is not already. The memory limit should be formatted as follows: -``, where unit = b, k, m or g. - -**-P**, **-publish-all**=*true*|*false* - When set to true publish all exposed ports to the host interfaces. The -default is false. If the operator uses -P (or -p) then Docker will make the -exposed port accessible on the host and the ports will be available to any -client that can reach the host. To find the map between the host ports and the -exposed ports, use **docker port**. - - -**-p**, **-publish**=[] - Publish a container's port to the host (format: ip:hostPort:containerPort | -ip::containerPort | hostPort:containerPort) (use **docker port** to see the -actual mapping) - - **-h**, **-hostname**=*hostname* Sets the container host name that is available inside the container. - **-i**, **-interactive**=*true*|*false* When set to true, keep stdin open even if not attached. The default is false. - **--link**=*name*:*alias* Add link to another container. The format is name:alias. If the operator uses **--link** when starting the new client container, then the client @@ -137,16 +133,16 @@ container can access the exposed port via a private networking interface. Docker will set some environment variables in the client container to help indicate which interface and port to use. +**--lxc-conf**=[] + (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1" -**-n**, **-networking**=*true*|*false* - By default, all containers have networking enabled (true) and can make -outgoing connections. The operator can disable networking with **--networking** -to false. This disables all incoming and outgoing networking. In cases like this -, I/O can only be performed through files or by using STDIN/STDOUT. - -Also by default, the container will use the same DNS servers as the host. The -operator may override this with **-dns**. - +**-m**, **-memory**=*memory-limit* + Allows you to constrain the memory available to a container. If the host +supports swap memory, then the -m memory setting can be larger than physical +RAM. If a limit of 0 is specified, the container's memory is not limited. The +actual limit may be rounded up to a multiple of the operating system's page +size, if it is not already. The memory limit should be formatted as follows: +``, where unit = b, k, m or g. **--name**=*name* Assign a name to the container. The operator can identify a container in @@ -162,6 +158,24 @@ string name. The name is useful when defining links (see **--link**) (or any other place you need to identify a container). This works for both background and foreground Docker containers. +**--net**="bridge" + Set the Network mode for the container + 'bridge': creates a new network stack for the container on the docker bridge + 'none': no networking for this container + 'container:': reuses another container network stack + 'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. + +**-P**, **-publish-all**=*true*|*false* + When set to true publish all exposed ports to the host interfaces. The +default is false. If the operator uses -P (or -p) then Docker will make the +exposed port accessible on the host and the ports will be available to any +client that can reach the host. To find the map between the host ports and the +exposed ports, use **docker port**. + +**-p**, **-publish**=[] + Publish a container's port to the host (format: ip:hostPort:containerPort | +ip::containerPort | hostPort:containerPort) (use **docker port** to see the +actual mapping) **--privileged**=*true*|*false* Give extended privileges to this container. By default, Docker containers are @@ -356,3 +370,4 @@ changes will also be reflected on the host in /var/db. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-save.1.md b/docs/man/docker-save.1.md index 126af6b154..a6546a0441 100644 --- a/docs/man/docker-save.1.md +++ b/docs/man/docker-save.1.md @@ -1,11 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-save - Save an image to a tar archive (streamed to STDOUT by default) # SYNOPSIS -**docker save** [**-o**|**--output**=""] IMAGE +**docker save** +[**-o**|**--output**[=*OUTPUT*]] +IMAGE # DESCRIPTION Produces a tarred repository to the standard output stream. Contains all @@ -17,7 +19,7 @@ Stream to a file instead of STDOUT by using **-o**. **-o**, **--output**="" Write to an file, instead of STDOUT -# EXAMPLE +# EXAMPLES Save all fedora repository images to a fedora-all.tar and save the latest fedora image to a fedora-latest.tar: @@ -32,4 +34,4 @@ fedora image to a fedora-latest.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-search.1.md b/docs/man/docker-search.1.md index 945dd34e59..e3103c65a2 100644 --- a/docs/man/docker-search.1.md +++ b/docs/man/docker-search.1.md @@ -1,12 +1,15 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-search - Search the docker index for images +docker-search - Search the Docker Hub for images # SYNOPSIS -**docker search** **--no-trunc**[=*false*] **--automated**[=*false*] - **-s**|**--stars**[=*0*] TERM +**docker search** +[**--automated**[=*false*]] +[**--no-trunc**[=*false*]] +[**-s**|**--stars**[=*0*]] +TERM # DESCRIPTION @@ -16,17 +19,16 @@ number of stars awarded, whether the image is official, and whether it is automated. # OPTIONS -**--no-trunc**=*true*|*false* - When true display the complete description. The default is false. +**--automated**=*true*|*false* + Only show automated builds. The default is *false*. -**-s**, **--stars**=NUM - Only displays with at least NUM (integer) stars. I.e. only those images -ranked >=NUM. +**--no-trunc**=*true*|*false* + Don't truncate output. The default is *false*. -**--automated**=*true*|*false* - When true only show automated builds. The default is false. +**-s**, **--stars**=0 + Only displays with at least x stars -# EXAMPLE +# EXAMPLES ## Search the registry for ranked images @@ -53,3 +55,4 @@ ranked 1 or higher: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-start.1.md b/docs/man/docker-start.1.md index 2815f1b07f..a01e190b61 100644 --- a/docs/man/docker-start.1.md +++ b/docs/man/docker-start.1.md @@ -1,29 +1,27 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-start - Restart a stopped container # SYNOPSIS -**docker start** [**a**|**--attach**[=*false*]] [**-i**|**--interactive** -[=*true*] CONTAINER [CONTAINER...] +**docker start** +[**-a**|**--attach**[=*false*]] +[**-i**|**--interactive**[=*false*]] +CONTAINER [CONTAINER...] # DESCRIPTION Start a stopped container. -# OPTION +# OPTIONS **-a**, **--attach**=*true*|*false* - When true attach to container's stdout/stderr and forward all signals to -the process + Attach container's STDOUT and STDERR and forward all signals to the process. The default is *false*. **-i**, **--interactive**=*true*|*false* - When true attach to container's stdin - -# NOTES -If run on a started container, start takes no action and succeeds -unconditionally. + Attach container's STDIN. The default is *false*. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-stop.1.md b/docs/man/docker-stop.1.md index 6ec81cd472..224a2a5115 100644 --- a/docs/man/docker-stop.1.md +++ b/docs/man/docker-stop.1.md @@ -1,22 +1,23 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-stop - Stop a running container - grace period) +docker-stop - Stop a running container by sending SIGTERM and then SIGKILL after a grace period # SYNOPSIS -**docker stop** [**-t**|**--time**[=*10*]] CONTAINER [CONTAINER...] +**docker stop** +[**-t**|**--time**[=*10*]] + CONTAINER [CONTAINER...] # DESCRIPTION Stop a running container (Send SIGTERM, and then SIGKILL after grace period) # OPTIONS -**-t**, **--time**=NUM - Wait NUM number of seconds for the container to stop before killing it. -The default is 10 seconds. +**-t**, **--time**=10 + Number of seconds to wait for the container to stop before killing it. Default is 10 seconds. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-tag.1.md b/docs/man/docker-tag.1.md index 01b5b9137c..fda6eb6738 100644 --- a/docs/man/docker-tag.1.md +++ b/docs/man/docker-tag.1.md @@ -1,12 +1,13 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-tag - Tag an image in the repository +docker-tag - Tag an image into a repository # SYNOPSIS -**docker tag** [**-f**|**--force**[=*false*] -IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG] +**docker tag** +[**-f**|**--force**[=*false*]] + IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG] # DESCRIPTION This will give a new alias to an image in the repository. This refers to the @@ -31,6 +32,10 @@ separated by a ':' recommended to be used for a version to disinguish images with the same name. Note that here TAG is a part of the overall name or "tag". +# OPTIONS +**-f**, **--force**=*true*|*false* + Force. The default is *false*. + # EXAMPLES ## Giving an image a new alias @@ -50,3 +55,4 @@ registry you must tag it with the registry hostname and port (if needed). # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-top.1.md b/docs/man/docker-top.1.md index 2c00c527a5..0d55d77d54 100644 --- a/docs/man/docker-top.1.md +++ b/docs/man/docker-top.1.md @@ -1,18 +1,22 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME -docker-top - Lookup the running processes of a container +docker-top - Display the running processes of a container # SYNOPSIS -**docker top** CONTAINER [ps-OPTION] +**docker top** +CONTAINER [ps OPTIONS] # DESCRIPTION Look up the running process of the container. ps-OPTION can be any of the options you would pass to a Linux ps command. -# EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES Run **docker top** with the ps option of -x: @@ -24,4 +28,4 @@ Run **docker top** with the ps option of -x: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-unpause.1.md b/docs/man/docker-unpause.1.md new file mode 100644 index 0000000000..8949548b67 --- /dev/null +++ b/docs/man/docker-unpause.1.md @@ -0,0 +1,15 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-unpause - Unpause all processes within a container + +# SYNOPSIS +**docker unpause** +CONTAINER + +# OPTIONS +There are no available options. + +# HISTORY +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-version.1.md b/docs/man/docker-version.1.md new file mode 100644 index 0000000000..9c029b239d --- /dev/null +++ b/docs/man/docker-version.1.md @@ -0,0 +1,15 @@ +% DOCKER(1) Docker User Manuals +% Docker Community +% JUNE 2014 +# NAME +docker-version - Show the Docker version information. + +# SYNOPSIS +**docker version** + + +# OPTIONS +There are no available options. + +# HISTORY +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-wait.1.md b/docs/man/docker-wait.1.md index 6754151f09..286bea0426 100644 --- a/docs/man/docker-wait.1.md +++ b/docs/man/docker-wait.1.md @@ -1,16 +1,21 @@ % DOCKER(1) Docker User Manuals -% William Henry -% APRIL 2014 +% Docker Community +% JUNE 2014 # NAME docker-wait - Block until a container stops, then print its exit code. # SYNOPSIS -**docker wait** CONTAINER [CONTAINER...] +**docker wait** +CONTAINER [CONTAINER...] # DESCRIPTION + Block until a container stops, then print its exit code. -#EXAMPLE +# OPTIONS +There are no available options. + +# EXAMPLES $ sudo docker run -d fedora sleep 99 079b83f558a2bc52ecad6b2a5de13622d584e6bb1aea058c11b36511e85e7622 @@ -20,4 +25,4 @@ Block until a container stops, then print its exit code. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based on docker.io source material and internal work. - +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index ae5efff87e..fe3929dcad 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -127,6 +127,9 @@ inside it) **docker-logs(1)** Fetch the logs of a container +**docker-pause(1)** + Pause all processes within a container + **docker-port(1)** Lookup the public-facing port which is NAT-ed to PRIVATE_PORT @@ -169,7 +172,10 @@ inside it) **docker-top(1)** Lookup the running processes of a container -**version** +**docker-unpause(1)** + Unpause all processes within a container + +**docker-version(1)** Show the Docker version information **docker-wait(1)** diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index d7f9724231..301593f2f1 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -54,9 +54,9 @@ expect an integer, and they can only be specified once. -b, --bridge="" Attach containers to a pre-existing network bridge use 'none' to disable container networking --bip="" Use this CIDR notation address for the network bridge's IP, not compatible with -b - -d, --daemon=false Enable daemon mode -D, --debug=false Enable debug mode - --dns=[] Force docker to use specific DNS servers + -d, --daemon=false Enable daemon mode + --dns=[] Force Docker to use specific DNS servers --dns-search=[] Force Docker to use specific DNS search domains -e, --exec-driver="native" Force the Docker runtime to use a specific exec driver -G, --group="docker" Group to assign the unix socket specified by -H when running in daemon mode @@ -73,8 +73,8 @@ expect an integer, and they can only be specified once. -p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file -r, --restart=true Restart previously running containers -s, --storage-driver="" Force the Docker runtime to use a specific storage driver - --storage-opt=[] Set storage driver options --selinux-enabled=false Enable selinux support + --storage-opt=[] Set storage driver options --tls=false Use TLS; implied by tls-verify flags --tlscacert="/home/sven/.docker/ca.pem" Trust only remotes providing a certificate signed by the CA given here --tlscert="/home/sven/.docker/cert.pem" Path to TLS certificate file @@ -134,8 +134,8 @@ like this: Attach to a running container - --no-stdin=false Do not attach stdin - --sig-proxy=true Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied. + --no-stdin=false Do not attach STDIN + --sig-proxy=true Proxify all received signals to the process (even in non-TTY mode). SIGCHLD is not proxied. The `attach` command will allow you to view or interact with any running container, detached (`-d`) @@ -481,7 +481,7 @@ To see how the `docker:latest` image was built: List images -a, --all=false Show all images (by default filter out the intermediate image layers) - -f, --filter=[]: Provide filter values (i.e. 'dangling=true') + -f, --filter=[] Provide filter values (i.e. 'dangling=true') --no-trunc=false Don't truncate output -q, --quiet=false Only show numeric IDs @@ -600,6 +600,8 @@ tar, then the ownerships might not get preserved. Usage: docker info + Display system-wide information + For example: $ sudo docker -D info @@ -627,7 +629,7 @@ ensure we know how your setup is configured. Usage: docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...] - Return low-level information on a container/image + Return low-level information on a container or image -f, --format="" Format the output using the given go template. @@ -681,7 +683,7 @@ contains complex json object, so to grab it as JSON, you use Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...] - Kill a running container (send SIGKILL, or specified signal) + Kill a running container using SIGKILL or a specified signal -s, --signal="KILL" Signal to send to the container @@ -718,7 +720,7 @@ Restores both images and tags. Usage: docker login [OPTIONS] [SERVER] - Register or Login to a docker registry server, if no server is specified "https://index.docker.io/v1/" is the default. + Register or log in to a Docker registry server, if no server is specified "https://index.docker.io/v1/" is the default. -e, --email="" Email -p, --password="" Password @@ -752,7 +754,7 @@ value is set to `all` in that case. This behavior may change in the future. Usage: docker port CONTAINER PRIVATE_PORT - Lookup the public-facing port which is NAT-ed to PRIVATE_PORT + Lookup the public-facing port that is NAT-ed to PRIVATE_PORT ## ps @@ -781,7 +783,7 @@ Running `docker ps` showing 2 linked containers. ## pull - Usage: docker pull [REGISTRY_PATH/]NAME[:TAG] + Usage: docker pull NAME[:TAG] Pull an image or a repository from the registry @@ -824,7 +826,7 @@ registry or to a self-hosted one. Restart a running container - -t, --time=10 Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default=10 + -t, --time=10 Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds. ## rm @@ -834,7 +836,7 @@ registry or to a self-hosted one. -f, --force=false Force removal of running container -l, --link=false Remove the specified link and not the underlying container - -v, --volumes=false Remove the volumes associated to the container + -v, --volumes=false Remove the volumes associated with the container ### Known Issues (rm) @@ -870,7 +872,7 @@ delete them. Any running containers will not be deleted. Remove one or more images - -f, --force=false Force + -f, --force=false Force removal of the image --no-prune=false Do not delete untagged parents ### Removing tagged images @@ -910,6 +912,7 @@ removed before the image is removed. -a, --attach=[] Attach to stdin, stdout or stderr. -c, --cpu-shares=0 CPU shares (relative weight) --cidfile="" Write the container ID to the file + --cpuset="" CPUs in which to allow execution (0-3, 0,1) -d, --detach=false Detached mode: Run container in the background, print new container id --dns=[] Set custom dns servers --dns-search=[] Set custom dns search domains @@ -927,11 +930,11 @@ removed before the image is removed. 'bridge': creates a new network stack for the container on the docker bridge 'none': no networking for this container 'container:': reuses another container network stack - 'host': use the host network stack inside the container + 'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. + -P, --publish-all=false Publish all exposed ports to the host interfaces -p, --publish=[] Publish a container's port to the host format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort (use 'docker port' to see the actual mapping) - -P, --publish-all=false Publish all exposed ports to the host interfaces --privileged=false Give extended privileges to this container --rm=false Automatically remove the container when it exits (incompatible with -d) --sig-proxy=true Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied. @@ -1150,7 +1153,7 @@ application change: Usage: docker save IMAGE - Save an image to a tar archive (streamed to stdout by default) + Save an image to a tar archive (streamed to STDOUT by default) -o, --output="" Write to an file, instead of STDOUT @@ -1175,11 +1178,11 @@ Search [Docker Hub](https://hub.docker.com) for images Usage: docker search TERM - Search the docker index for images + Search the Docker Hub for images - --no-trunc=false Don't truncate output - -s, --stars=0 Only displays with at least xxx stars - --automated=false Only show automated builds + --automated=false Only show automated builds + --no-trunc=false Don't truncate output + -s, --stars=0 Only displays with at least x stars See [*Find Public Images on Docker Hub*]( /userguide/dockerrepos/#find-public-images-on-docker-hub) for @@ -1191,8 +1194,8 @@ more details on finding shared images from the command line. Restart a stopped container - -a, --attach=false Attach container's stdout/stderr and forward all signals to the process - -i, --interactive=false Attach container's stdin + -a, --attach=false Attach container's STDOUT and STDERR and forward all signals to the process + -i, --interactive=false Attach container's STDIN When run on a container that has already been started, takes no action and succeeds unconditionally. @@ -1201,9 +1204,9 @@ takes no action and succeeds unconditionally. Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...] - Stop a running container (Send SIGTERM, and then SIGKILL after grace period) + Stop a running container by sending SIGTERM and then SIGKILL after a grace period - -t, --time=10 Number of seconds to wait for the container to stop before killing it. + -t, --time=10 Number of seconds to wait for the container to stop before killing it. Default is 10 seconds. The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL @@ -1224,13 +1227,13 @@ them to [*Share Images via Repositories*]( Usage: docker top CONTAINER [ps OPTIONS] - Lookup the running processes of a container + Display the running processes of a container ## version Usage: docker version - Show the docker version information. + Show the Docker version information. Show the Docker version, API version, Git commit, and Go version of both Docker client and daemon. @@ -1240,3 +1243,4 @@ both Docker client and daemon. Usage: docker wait CONTAINER [CONTAINER...] Block until a container stops, then print its exit code. + diff --git a/runconfig/parse.go b/runconfig/parse.go index 2f2ca9b163..dfd9f4ddd3 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -72,7 +72,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf ) cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to stdin, stdout or stderr.") - cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)") + cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume (e.g., from the host: -v /host:/container, from docker: -v /container)") cmd.Var(&flLinks, []string{"#link", "-link"}, "Add link to another container (name:alias)") cmd.Var(&flEnv, []string{"e", "-env"}, "Set environment variables") cmd.Var(&flEnvFile, []string{"-env-file"}, "Read in a line delimited file of ENV variables") -- cgit v1.2.1 From fa29b1f062d25c1a8ca62f02b9cc7533df4c7449 Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Wed, 2 Jul 2014 10:30:25 +1000 Subject: I'm going to wish I didn't do this Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- CONTRIBUTING.md | 4 ++-- README.md | 2 +- contrib/completion/zsh/_docker | 2 +- contrib/init/systemd/docker.service | 2 +- contrib/init/systemd/socket-activation/docker.service | 2 +- contrib/init/sysvinit-redhat/docker | 6 +++--- daemon/daemon.go | 2 +- docs/README.md | 8 ++++---- docs/man/Dockerfile.5.md | 2 +- docs/man/README.md | 2 +- docs/man/docker-attach.1.md | 2 +- docs/man/docker-build.1.md | 2 +- docs/man/docker-commit.1.md | 2 +- docs/man/docker-cp.1.md | 2 +- docs/man/docker-diff.1.md | 2 +- docs/man/docker-events.1.md | 2 +- docs/man/docker-export.1.md | 2 +- docs/man/docker-history.1.md | 2 +- docs/man/docker-images.1.md | 2 +- docs/man/docker-import.1.md | 2 +- docs/man/docker-info.1.md | 2 +- docs/man/docker-inspect.1.md | 2 +- docs/man/docker-kill.1.md | 2 +- docs/man/docker-load.1.md | 2 +- docs/man/docker-login.1.md | 2 +- docs/man/docker-logs.1.md | 2 +- docs/man/docker-port.1.md | 1 - docs/man/docker-ps.1.md | 2 +- docs/man/docker-pull.1.md | 5 +++++ docs/man/docker-push.1.md | 8 ++++++-- docs/man/docker-restart.1.md | 5 +++++ docs/man/docker-rm.1.md | 4 ++++ docs/man/docker-rmi.1.md | 4 ++++ docs/man/docker-run.1.md | 4 ++++ docs/man/docker-save.1.md | 5 +++++ docs/man/docker-search.1.md | 4 ++++ docs/man/docker-start.1.md | 4 ++++ docs/man/docker-stop.1.md | 4 ++++ docs/man/docker-tag.1.md | 4 ++++ docs/man/docker-top.1.md | 5 +++++ docs/man/docker-wait.1.md | 5 +++++ docs/man/docker.1.md | 2 +- docs/mkdocs.yml | 2 +- docs/release.sh | 2 +- docs/sources/articles/security.md | 4 ++-- docs/sources/articles/using_supervisord.md | 2 +- docs/sources/contributing/devenvironment.md | 2 +- docs/sources/examples/postgresql_service.Dockerfile | 2 +- docs/sources/examples/postgresql_service.md | 2 +- docs/sources/faq.md | 4 ++-- docs/sources/introduction/understanding-docker.md | 12 ++++++------ docs/sources/reference/run.md | 2 +- docs/sources/userguide/index.md | 8 ++++---- docs/sources/userguide/usingdocker.md | 2 +- docs/theme/mkdocs/css/main.css | 4 ++-- hack/dind | 2 +- hack/infrastructure/README.md | 13 ++++++------- hack/make/ubuntu | 4 ++-- 58 files changed, 126 insertions(+), 71 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3df8619f7..d07b972eb7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ This information will help us review and fix your issue faster. For instructions on setting up your development environment, please see our dedicated [dev environment setup -docs](http://docs.docker.io/en/latest/contributing/devenvironment/). +docs](http://docs.docker.com/contributing/devenvironment/). ## Contribution guidelines @@ -190,7 +190,7 @@ There are several exceptions to the signing requirement. Currently these are: * 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](http://docs.docker.io) +If you have any questions, please refer to the FAQ in the [docs](http://docs.docker.com) ### How can I become a maintainer? diff --git a/README.md b/README.md index 608e638eab..3c378de6f4 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ Docker can be used to run short-lived commands, long-running daemons (app servers, databases etc.), interactive shell sessions, etc. You can find a [list of real-world -examples](http://docs.docker.io/en/latest/examples/) in the +examples](http://docs.docker.com/examples/) in the documentation. Under the hood diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 4578d1eda7..3f96f00ef7 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -1,6 +1,6 @@ #compdef docker # -# zsh completion for docker (http://docker.io) +# zsh completion for docker (http://docker.com) # # version: 0.2.2 # author: Felix Riedel diff --git a/contrib/init/systemd/docker.service b/contrib/init/systemd/docker.service index 1bc4d1f569..6f3cc33c36 100644 --- a/contrib/init/systemd/docker.service +++ b/contrib/init/systemd/docker.service @@ -1,6 +1,6 @@ [Unit] Description=Docker Application Container Engine -Documentation=http://docs.docker.io +Documentation=http://docs.docker.com After=network.target [Service] diff --git a/contrib/init/systemd/socket-activation/docker.service b/contrib/init/systemd/socket-activation/docker.service index a3382ab414..4af71378c8 100644 --- a/contrib/init/systemd/socket-activation/docker.service +++ b/contrib/init/systemd/socket-activation/docker.service @@ -1,6 +1,6 @@ [Unit] Description=Docker Application Container Engine -Documentation=http://docs.docker.io +Documentation=http://docs.docker.com After=network.target [Service] diff --git a/contrib/init/sysvinit-redhat/docker b/contrib/init/sysvinit-redhat/docker index 06699f6ab1..aa94c04811 100755 --- a/contrib/init/sysvinit-redhat/docker +++ b/contrib/init/sysvinit-redhat/docker @@ -2,10 +2,10 @@ # # /etc/rc.d/init.d/docker # -# Daemon for docker.io +# Daemon for docker.com # # chkconfig: 2345 95 95 -# description: Daemon for docker.io +# description: Daemon for docker.com ### BEGIN INIT INFO # Provides: docker @@ -16,7 +16,7 @@ # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: start and stop docker -# Description: Daemon for docker.io +# Description: Daemon for docker.com ### END INIT INFO # Source function library. diff --git a/daemon/daemon.go b/daemon/daemon.go index 9500526f9e..23402d9518 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -836,7 +836,7 @@ func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*D localCopy := path.Join(config.Root, "init", fmt.Sprintf("dockerinit-%s", dockerversion.VERSION)) sysInitPath := utils.DockerInitPath(localCopy) if sysInitPath == "" { - return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.io/en/latest/contributing/devenvironment for official build instructions.") + return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.com/contributing/devenvironment for official build instructions.") } if sysInitPath != localCopy { diff --git a/docs/README.md b/docs/README.md index 99dc8712c9..17299401e7 100755 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@ The source for Docker documentation is here under `sources/` and uses extended Markdown, as implemented by [MkDocs](http://mkdocs.org). -The HTML files are built and hosted on `https://docs.docker.io`, and update +The HTML files are built and hosted on `https://docs.docker.com`, and update automatically after each change to the master or release branch of [Docker on GitHub](https://github.com/dotcloud/docker) thanks to post-commit hooks. The `docs` branch maps to the "latest" documentation and the `master` (unreleased @@ -21,14 +21,14 @@ In the rare case where your change is not forward-compatible, you may need to base your changes on the `docs` branch. Also, now that we have a `docs` branch, we can keep the -[http://docs.docker.io](http://docs.docker.io) docs up to date with any bugs +[http://docs.docker.com](http://docs.docker.com) docs up to date with any bugs found between Docker code releases. **Warning**: When *reading* the docs, the -[http://beta-docs.docker.io](http://beta-docs.docker.io) documentation may +[http://docs-stage.docker.com](http://docs-stage.docker.com) documentation may include features not yet part of any official Docker release. The `beta-docs` site should be used only for understanding bleeding-edge development and -`docs.docker.io` (which points to the `docs` branch`) should be used for the +`docs.docker.com` (which points to the `docs` branch`) should be used for the latest official release. ## Contributing diff --git a/docs/man/Dockerfile.5.md b/docs/man/Dockerfile.5.md index 73c1312b87..b0a863f657 100644 --- a/docs/man/Dockerfile.5.md +++ b/docs/man/Dockerfile.5.md @@ -203,4 +203,4 @@ or run later, during the next build stage. # HISTORY -*May 2014, Compiled by Zac Dover (zdover at redhat dot com) based on docker.io Dockerfile documentation. +*May 2014, Compiled by Zac Dover (zdover at redhat dot com) based on docker.com Dockerfile documentation. diff --git a/docs/man/README.md b/docs/man/README.md index d04d82454f..45f1a91c00 100644 --- a/docs/man/README.md +++ b/docs/man/README.md @@ -68,4 +68,4 @@ The Pandoc Docker container will process the Markdown files and generate the man pages inside the `docker/docs/man/man1` directory using Docker volumes. For more information on Docker volumes see the man page for `docker run` and also look at the article [Sharing Directories via Volumes] -(http://docs.docker.io/use/working_with_volumes/). +(http://docs.docker.com/use/working_with_volumes/). diff --git a/docs/man/docker-attach.1.md b/docs/man/docker-attach.1.md index 0ca9797018..1b4e68b65f 100644 --- a/docs/man/docker-attach.1.md +++ b/docs/man/docker-attach.1.md @@ -57,5 +57,5 @@ attach** command: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-build.1.md b/docs/man/docker-build.1.md index 2b426f1cef..c562660b6f 100644 --- a/docs/man/docker-build.1.md +++ b/docs/man/docker-build.1.md @@ -117,5 +117,5 @@ Note: You can set an arbitrary Git repository via the `git://` schema. # HISTORY March 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-commit.1.md b/docs/man/docker-commit.1.md index 5ec3808dfb..bbd1db21b0 100644 --- a/docs/man/docker-commit.1.md +++ b/docs/man/docker-commit.1.md @@ -35,5 +35,5 @@ create a new image run docker ps to find the container's ID and then run: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and in +based on docker.com source material and in June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-cp.1.md b/docs/man/docker-cp.1.md index 750a6d1d53..dc8f295bbe 100644 --- a/docs/man/docker-cp.1.md +++ b/docs/man/docker-cp.1.md @@ -24,5 +24,5 @@ the exited container to the current dir on the host: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-diff.1.md b/docs/man/docker-diff.1.md index d7aae25f85..acf0911b04 100644 --- a/docs/man/docker-diff.1.md +++ b/docs/man/docker-diff.1.md @@ -43,5 +43,5 @@ Inspect the changes to on a nginx container: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-events.1.md b/docs/man/docker-events.1.md index ca8f63db53..8fa85871a8 100644 --- a/docs/man/docker-events.1.md +++ b/docs/man/docker-events.1.md @@ -49,5 +49,5 @@ Again the output container IDs have been shortened for the purposes of this docu # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-export.1.md b/docs/man/docker-export.1.md index efd884a79d..8fd7834a15 100644 --- a/docs/man/docker-export.1.md +++ b/docs/man/docker-export.1.md @@ -26,5 +26,5 @@ called test.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-history.1.md b/docs/man/docker-history.1.md index ee58e03fca..ddb164e50b 100644 --- a/docs/man/docker-history.1.md +++ b/docs/man/docker-history.1.md @@ -30,5 +30,5 @@ Show the history of when and how an image was created. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-images.1.md b/docs/man/docker-images.1.md index a940192e9a..c572ee674b 100644 --- a/docs/man/docker-images.1.md +++ b/docs/man/docker-images.1.md @@ -86,5 +86,5 @@ tools. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-import.1.md b/docs/man/docker-import.1.md index f320eafa26..2d67b8bc78 100644 --- a/docs/man/docker-import.1.md +++ b/docs/man/docker-import.1.md @@ -39,5 +39,5 @@ Import to docker via pipe and stdin: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-info.1.md b/docs/man/docker-info.1.md index cae9a32909..2945d61dfe 100644 --- a/docs/man/docker-info.1.md +++ b/docs/man/docker-info.1.md @@ -44,5 +44,5 @@ Here is a sample output: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-inspect.1.md b/docs/man/docker-inspect.1.md index 29511fbe66..a52d57c974 100644 --- a/docs/man/docker-inspect.1.md +++ b/docs/man/docker-inspect.1.md @@ -225,5 +225,5 @@ Use an image's ID or name (e.g., repository/name[:tag]) to get information # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-kill.1.md b/docs/man/docker-kill.1.md index a454c432f6..3c8d59e6d5 100644 --- a/docs/man/docker-kill.1.md +++ b/docs/man/docker-kill.1.md @@ -20,5 +20,5 @@ The main process inside each container specified will be sent SIGKILL, # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) - based on docker.io source material and internal work. + based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-load.1.md b/docs/man/docker-load.1.md index 41ab5f64c8..07dac46138 100644 --- a/docs/man/docker-load.1.md +++ b/docs/man/docker-load.1.md @@ -34,5 +34,5 @@ Restores both images and tags. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-login.1.md b/docs/man/docker-login.1.md index 6583342656..c269353079 100644 --- a/docs/man/docker-login.1.md +++ b/docs/man/docker-login.1.md @@ -34,5 +34,5 @@ login to a private registry you can specify this by adding the server name. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-logs.1.md b/docs/man/docker-logs.1.md index 5881b0512f..5c3df75b9e 100644 --- a/docs/man/docker-logs.1.md +++ b/docs/man/docker-logs.1.md @@ -29,5 +29,5 @@ then continue streaming new output from the container’s stdout and stderr. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-port.1.md b/docs/man/docker-port.1.md index a92f75cd57..07b84b12d9 100644 --- a/docs/man/docker-port.1.md +++ b/docs/man/docker-port.1.md @@ -13,5 +13,4 @@ There are no available options. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-ps.1.md b/docs/man/docker-ps.1.md index 454be74ad1..9264d53a66 100644 --- a/docs/man/docker-ps.1.md +++ b/docs/man/docker-ps.1.md @@ -66,5 +66,5 @@ the running containers. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -based on docker.io source material and internal work. +based on docker.com source material and internal work. June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-pull.1.md b/docs/man/docker-pull.1.md index c397b42ea9..6fb0dc1000 100644 --- a/docs/man/docker-pull.1.md +++ b/docs/man/docker-pull.1.md @@ -51,5 +51,10 @@ There are no available options. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. + +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-push.1.md b/docs/man/docker-push.1.md index 4b05b62a7f..56d814181d 100644 --- a/docs/man/docker-push.1.md +++ b/docs/man/docker-push.1.md @@ -10,7 +10,7 @@ NAME[:TAG] # DESCRIPTION Push an image or a repository to a registry. The default registry is the Docker -Index located at [index.docker.io](https://index.docker.io/v1/). However the +Hub located at [hub.docker.com](https://hub.docker.com/). However the image can be pushed to another, perhaps private, registry as demonstrated in the example below. @@ -28,7 +28,7 @@ and then committing it to a new image name: Now push the image to the registry using the image ID. In this example the registry is on host named registry-host and listening on port 5000. -Default Docker commands will push to the default `index.docker.io` +Default Docker commands will push to the default `hub.docker.com` registry. Instead, push to the local registry, which is on a host called registry-host*. To do this, tag the image with the host name or IP address, and the port of the registry: @@ -45,5 +45,9 @@ listed. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-restart.1.md b/docs/man/docker-restart.1.md index 6374273cfc..6f93858ba1 100644 --- a/docs/man/docker-restart.1.md +++ b/docs/man/docker-restart.1.md @@ -18,5 +18,10 @@ Restart each container listed. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. + +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-rm.1.md b/docs/man/docker-rm.1.md index f41a6edb17..9195137ec1 100644 --- a/docs/man/docker-rm.1.md +++ b/docs/man/docker-rm.1.md @@ -47,5 +47,9 @@ command. The use that name as follows: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-rmi.1.md b/docs/man/docker-rmi.1.md index e03ecc4bca..7a2973f873 100644 --- a/docs/man/docker-rmi.1.md +++ b/docs/man/docker-rmi.1.md @@ -34,5 +34,9 @@ Here is an example of removing and image: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-run.1.md b/docs/man/docker-run.1.md index 1e1adbe55d..fa73d8eee4 100644 --- a/docs/man/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -369,5 +369,9 @@ changes will also be reflected on the host in /var/db. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-save.1.md b/docs/man/docker-save.1.md index a6546a0441..403c3fb614 100644 --- a/docs/man/docker-save.1.md +++ b/docs/man/docker-save.1.md @@ -33,5 +33,10 @@ fedora image to a fedora-latest.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. + +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-search.1.md b/docs/man/docker-search.1.md index e3103c65a2..061042c7ac 100644 --- a/docs/man/docker-search.1.md +++ b/docs/man/docker-search.1.md @@ -54,5 +54,9 @@ ranked 1 or higher: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-start.1.md b/docs/man/docker-start.1.md index a01e190b61..ed9f77b43e 100644 --- a/docs/man/docker-start.1.md +++ b/docs/man/docker-start.1.md @@ -23,5 +23,9 @@ Start a stopped container. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-stop.1.md b/docs/man/docker-stop.1.md index 224a2a5115..14bd7b30e6 100644 --- a/docs/man/docker-stop.1.md +++ b/docs/man/docker-stop.1.md @@ -19,5 +19,9 @@ Stop a running container (Send SIGTERM, and then SIGKILL after # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-tag.1.md b/docs/man/docker-tag.1.md index fda6eb6738..aae222085f 100644 --- a/docs/man/docker-tag.1.md +++ b/docs/man/docker-tag.1.md @@ -54,5 +54,9 @@ registry you must tag it with the registry hostname and port (if needed). # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-top.1.md b/docs/man/docker-top.1.md index 0d55d77d54..5ba44d697d 100644 --- a/docs/man/docker-top.1.md +++ b/docs/man/docker-top.1.md @@ -27,5 +27,10 @@ Run **docker top** with the ps option of -x: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. + +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker-wait.1.md b/docs/man/docker-wait.1.md index 286bea0426..cfa19ef861 100644 --- a/docs/man/docker-wait.1.md +++ b/docs/man/docker-wait.1.md @@ -24,5 +24,10 @@ There are no available options. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) +<<<<<<< HEAD based on docker.io source material and internal work. June 2014, updated by Sven Dowideit +======= +based on docker.com source material and internal work. + +>>>>>>> 834ef8a... I'm going to wish I didn't do this diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index fe3929dcad..a7a826ed9f 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -190,4 +190,4 @@ For example: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) based - on docker.io source material and internal work. + on docker.com source material and internal work. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 97dc8fc36b..f4ebcb68fe 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -1,5 +1,5 @@ site_name: Docker Documentation -#site_url: http://docs.docker.io/ +#site_url: http://docs.docker.com/ site_url: / site_description: Documentation for fast and lightweight Docker container based virtualization framework. site_favicon: img/favicon.png diff --git a/docs/release.sh b/docs/release.sh index d579a307ba..f6dc2ec59f 100755 --- a/docs/release.sh +++ b/docs/release.sh @@ -9,7 +9,7 @@ To publish the Docker documentation you need to set your access_key and secret_k (with the keys in a [profile $AWS_S3_BUCKET] section - so you can have more than one set of keys in your file) and set the AWS_S3_BUCKET env var to the name of your bucket. -make AWS_S3_BUCKET=beta-docs.docker.io docs-release +make AWS_S3_BUCKET=docs-stage.docker.com docs-release will then push the documentation site to your s3 bucket. EOF diff --git a/docs/sources/articles/security.md b/docs/sources/articles/security.md index 4c39c18a69..dcc61f386c 100644 --- a/docs/sources/articles/security.md +++ b/docs/sources/articles/security.md @@ -5,7 +5,7 @@ page_keywords: Docker, Docker documentation, security # Docker Security > *Adapted from* [Containers & Docker: How Secure are -> They?](http://blog.docker.io/2013/08/containers-docker-how-secure-are-they/) +> They?](http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/) There are three major areas to consider when reviewing Docker security: @@ -251,4 +251,4 @@ with Docker, since everything is provided by the kernel anyway. For more context and especially for comparisons with VMs and other container systems, please also see the [original blog post]( -http://blog.docker.io/2013/08/containers-docker-how-secure-are-they/). +http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/). diff --git a/docs/sources/articles/using_supervisord.md b/docs/sources/articles/using_supervisord.md index fd7c07cabf..91b8976d78 100644 --- a/docs/sources/articles/using_supervisord.md +++ b/docs/sources/articles/using_supervisord.md @@ -27,7 +27,7 @@ Let's start by creating a basic `Dockerfile` for our new image. FROM ubuntu:13.04 - MAINTAINER examples@docker.io + MAINTAINER examples@docker.com RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update RUN apt-get upgrade -y diff --git a/docs/sources/contributing/devenvironment.md b/docs/sources/contributing/devenvironment.md index 9188031e3f..606f9302fc 100644 --- a/docs/sources/contributing/devenvironment.md +++ b/docs/sources/contributing/devenvironment.md @@ -16,7 +16,7 @@ Docker's build environment itself is a Docker container, so the first step is to install Docker on your system. You can follow the [install instructions most relevant to your -system](https://docs.docker.io/installation/). Make sure you +system](https://docs.docker.com/installation/). Make sure you have a working, up-to-date docker installation, then continue to the next step. diff --git a/docs/sources/examples/postgresql_service.Dockerfile b/docs/sources/examples/postgresql_service.Dockerfile index 219a537882..364a18a81d 100644 --- a/docs/sources/examples/postgresql_service.Dockerfile +++ b/docs/sources/examples/postgresql_service.Dockerfile @@ -1,5 +1,5 @@ # -# example Dockerfile for http://docs.docker.io/en/latest/examples/postgresql_service/ +# example Dockerfile for http://docs.docker.com/examples/postgresql_service/ # FROM ubuntu diff --git a/docs/sources/examples/postgresql_service.md b/docs/sources/examples/postgresql_service.md index b9fae49d99..5265935e3d 100644 --- a/docs/sources/examples/postgresql_service.md +++ b/docs/sources/examples/postgresql_service.md @@ -21,7 +21,7 @@ Start by creating a new `Dockerfile`: > suitably secure. # - # example Dockerfile for http://docs.docker.io/examples/postgresql_service/ + # example Dockerfile for http://docs.docker.com/examples/postgresql_service/ # FROM ubuntu diff --git a/docs/sources/faq.md b/docs/sources/faq.md index 635caac89f..667058c86f 100644 --- a/docs/sources/faq.md +++ b/docs/sources/faq.md @@ -178,13 +178,13 @@ Cloud: ### How do I report a security issue with Docker? You can learn about the project's security policy -[here](https://www.docker.io/security/) and report security issues to +[here](https://www.docker.com/security/) and report security issues to this [mailbox](mailto:security@docker.com). ### Why do I need to sign my commits to Docker with the DCO? Please read [our blog post]( -http://blog.docker.io/2014/01/docker-code-contributions-require-developer-certificate-of-origin/) +http://blog.docker.com/2014/01/docker-code-contributions-require-developer-certificate-of-origin/) on the introduction of the DCO. ### When building an image, should I prefer system libraries or bundled ones? diff --git a/docs/sources/introduction/understanding-docker.md b/docs/sources/introduction/understanding-docker.md index 3a7615ebc8..c79573a635 100644 --- a/docs/sources/introduction/understanding-docker.md +++ b/docs/sources/introduction/understanding-docker.md @@ -112,7 +112,7 @@ Docker images are the **build** component of Docker. #### Docker Registries Docker registries hold images. These are public or private stores from which you upload or download images. The public Docker registry is called -[Docker Hub](http://index.docker.io). It provides a huge collection of existing +[Docker Hub](http://hub.docker.com). It provides a huge collection of existing images for your use. These can be images you create yourself or you can use images that others have previously created. Docker registries are the **distribution** component of Docker. @@ -156,7 +156,7 @@ basis for a new image, for example if you have a base Apache image you could use this as the base of all your web application images. > **Note:** Docker usually gets these base images from -> [Docker Hub](https://index.docker.io). +> [Docker Hub](https://hub.docker.com). > Docker images are then built from these base images using a simple, descriptive set of steps we call *instructions*. Each instruction creates a new layer in our @@ -173,17 +173,17 @@ returns a final image. ### How does a Docker registry work? The Docker registry is the store for your Docker images. Once you build a Docker -image you can *push* it to a public registry [Docker Hub](https://index.docker.io) or to +image you can *push* it to a public registry [Docker Hub](https://hub.docker.com) or to your own registry running behind your firewall. Using the Docker client, you can search for already published images and then pull them down to your Docker host to build containers from them. -[Docker Hub](https://index.docker.io) provides both public and private storage +[Docker Hub](https://hub.docker.com) provides both public and private storage for images. Public storage is searchable and can be downloaded by anyone. Private storage is excluded from search results and only you and your users can pull images down and use them to build containers. You can [sign up for a storage plan -here](https://index.docker.io/plans). +here](https://hub.docker.com/plans). ### How does a container work? A container consists of an operating system, user-added files, and meta-data. As @@ -216,7 +216,7 @@ In order, Docker does the following: - **Pulls the `ubuntu` image:** Docker checks for the presence of the `ubuntu` image and, if it doesn't exist locally on the host, then Docker downloads it from -[Docker Hub](https://index.docker.io). If the image already exists, then Docker +[Docker Hub](https://hub.docker.com). If the image already exists, then Docker uses it for the new container. - **Creates a new container:** Once Docker has the image, it uses it to create a container. diff --git a/docs/sources/reference/run.md b/docs/sources/reference/run.md index 37dba587b6..a539ab0d18 100644 --- a/docs/sources/reference/run.md +++ b/docs/sources/reference/run.md @@ -240,7 +240,7 @@ to access to all devices on the host as well as set some configuration in AppArmor to allow the container nearly all the same access to the host as processes running outside containers on the host. Additional information about running with `--privileged` is available on the -[Docker Blog](http://blog.docker.io/2013/09/docker-can-now-run-within-docker/). +[Docker Blog](http://blog.docker.com/2013/09/docker-can-now-run-within-docker/). If the Docker daemon was started using the `lxc` exec-driver (`docker -d --exec-driver=lxc`) then the operator can also specify LXC options diff --git a/docs/sources/userguide/index.md b/docs/sources/userguide/index.md index e5c9ec272a..eef59c000b 100644 --- a/docs/sources/userguide/index.md +++ b/docs/sources/userguide/index.md @@ -82,11 +82,11 @@ Go to [Working with Docker Hub](/userguide/dockerrepos). ## Getting help -* [Docker homepage](http://www.docker.io/) +* [Docker homepage](http://www.docker.com/) * [Docker Hub](https://hub.docker.com) -* [Docker blog](http://blog.docker.io/) -* [Docker documentation](http://docs.docker.io/) -* [Docker Getting Started Guide](http://www.docker.io/gettingstarted/) +* [Docker blog](http://blog.docker.com/) +* [Docker documentation](http://docs.docker.com/) +* [Docker Getting Started Guide](http://www.docker.com/gettingstarted/) * [Docker code on GitHub](https://github.com/dotcloud/docker) * [Docker mailing list](https://groups.google.com/forum/#!forum/docker-user) diff --git a/docs/sources/userguide/usingdocker.md b/docs/sources/userguide/usingdocker.md index 7080e3ed43..857eac5e56 100644 --- a/docs/sources/userguide/usingdocker.md +++ b/docs/sources/userguide/usingdocker.md @@ -19,7 +19,7 @@ In the process we learned about several Docker commands: > **Tip:** > Another way to learn about `docker` commands is our -> [interactive tutorial](https://www.docker.io/gettingstarted). +> [interactive tutorial](https://www.docker.com/tryit/). The `docker` client is pretty simple. Each action you can take with Docker is a command and each command can take a series of diff --git a/docs/theme/mkdocs/css/main.css b/docs/theme/mkdocs/css/main.css index 42a7a18a56..18e65ebd3f 100644 --- a/docs/theme/mkdocs/css/main.css +++ b/docs/theme/mkdocs/css/main.css @@ -4,7 +4,7 @@ Core Docker style file used on - www.docker.io + www.docker.com docker-index ****************************** */ /* this is about 10% darker, but slightly different */ @@ -2146,4 +2146,4 @@ a:hover { background: url("../img/homepage/docker-whale-home-logo+@2x.png"); background-size: 459px 261px; } -} \ No newline at end of file +} diff --git a/hack/dind b/hack/dind index a9de03e4ff..77629ad0a5 100755 --- a/hack/dind +++ b/hack/dind @@ -3,7 +3,7 @@ set -e # DinD: a wrapper script which allows docker to be run inside a docker container. # Original version by Jerome Petazzoni -# See the blog post: http://blog.docker.io/2013/09/docker-can-now-run-within-docker/ +# See the blog post: http://blog.docker.com/2013/09/docker-can-now-run-within-docker/ # # This script should be executed inside a docker container in privilieged mode # ('docker run --privileged', introduced in docker 0.6). diff --git a/hack/infrastructure/README.md b/hack/infrastructure/README.md index 9b2ffda956..d12fc4c63e 100644 --- a/hack/infrastructure/README.md +++ b/hack/infrastructure/README.md @@ -20,7 +20,7 @@ AWS | packages (S3 bucket), dotCloud PAAS, dev-env, ci CloudFlare | cdn Digital Ocean | ci dotCloud PAAS | website, index, registry, ssl, blog -DynECT | dns (docker.io) +DynECT | dns (docker.com) GitHub | repository Linode | stackbrew Mailgun | outgoing e-mail @@ -36,20 +36,19 @@ and which service is handling them. URL | Service ---------------------------------------------|--------------------------------- - http://blog.docker.io/ | blog + http://blog.docker.com/ | blog *http://cdn-registry-1.docker.io/ | registry (pull) http://debug.docker.io/ | debug tool - http://docs.docker.io/ | docsproxy (proxy to readthedocs) + http://docs.docker.com/ | documentation served from an S3 bucket http://docker-ci.dotcloud.com/ | ci - http://docker.io/ | redirect to www.docker.io (dynect) - http://docker.readthedocs.org/ | docs + http://docker.com/ | redirect to www.docker.com (dynect) *http://get.docker.io/ | packages https://github.com/dotcloud/docker | repository -*https://index.docker.io/ | index +*https://hub.docker.com/ | Docker Hub http://registry-1.docker.io/ | registry (push) http://staging-docker-ci.dotcloud.com/ | ci *http://test.docker.io/ | packages -*http://www.docker.io/ | website +*http://www.docker.com/ | website http://? (internal URL, not for public use) | stackbrew *Ordered-by: lexicographic* diff --git a/hack/make/ubuntu b/hack/make/ubuntu index c55123fb7a..0d19d7528b 100644 --- a/hack/make/ubuntu +++ b/hack/make/ubuntu @@ -8,8 +8,8 @@ if [ -n "$(git status --porcelain)" ]; then fi PACKAGE_ARCHITECTURE="$(dpkg-architecture -qDEB_HOST_ARCH)" -PACKAGE_URL="http://www.docker.io/" -PACKAGE_MAINTAINER="docker@dotcloud.com" +PACKAGE_URL="http://www.docker.com/" +PACKAGE_MAINTAINER="support@docker.com" PACKAGE_DESCRIPTION="Linux container runtime Docker complements LXC with a high-level API which operates at the process level. It runs unix processes with strong guarantees of isolation and -- cgit v1.2.1 From c3f4972f6d036520df589676c7ebeef397d327c2 Mon Sep 17 00:00:00 2001 From: Fred Lifton Date: Wed, 2 Jul 2014 17:41:52 -0700 Subject: Corrected version number to 3 digits. Docker-DCO-1.1-Signed-off-by: Fred Lifton (github: fredlf) --- docs/sources/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/index.md b/docs/sources/index.md index 3ff9c8dde7..75414b4364 100644 --- a/docs/sources/index.md +++ b/docs/sources/index.md @@ -87,7 +87,7 @@ To learn about Docker in more detail and to answer questions about usage and imp ## Release Notes -Version 1.1 +Version 1.1.0 ### New Features -- cgit v1.2.1 From f8d9ecfb2ceda0cc2aed3d8fd3fbcbf625a8fcdd Mon Sep 17 00:00:00 2001 From: SvenDowideit Date: Thu, 3 Jul 2014 11:07:42 +1000 Subject: missed these merge conflicts when manually rebasing too many files Docker-DCO-1.1-Signed-off-by: SvenDowideit (github: SvenDowideit) --- docs/man/docker-pull.1.md | 7 +------ docs/man/docker-push.1.md | 6 +----- docs/man/docker-restart.1.md | 7 +------ docs/man/docker-rm.1.md | 6 +----- docs/man/docker-rmi.1.md | 6 +----- docs/man/docker-run.1.md | 6 +----- docs/man/docker-save.1.md | 7 +------ docs/man/docker-search.1.md | 6 +----- docs/man/docker-start.1.md | 6 +----- docs/man/docker-stop.1.md | 6 +----- docs/man/docker-tag.1.md | 6 +----- docs/man/docker-top.1.md | 7 +------ docs/man/docker-wait.1.md | 7 +------ 13 files changed, 13 insertions(+), 70 deletions(-) diff --git a/docs/man/docker-pull.1.md b/docs/man/docker-pull.1.md index 6fb0dc1000..465c97aadd 100644 --- a/docs/man/docker-pull.1.md +++ b/docs/man/docker-pull.1.md @@ -51,10 +51,5 @@ There are no available options. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. - ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-push.1.md b/docs/man/docker-push.1.md index 56d814181d..8523cb539e 100644 --- a/docs/man/docker-push.1.md +++ b/docs/man/docker-push.1.md @@ -45,9 +45,5 @@ listed. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-restart.1.md b/docs/man/docker-restart.1.md index 6f93858ba1..2a08caa5e8 100644 --- a/docs/man/docker-restart.1.md +++ b/docs/man/docker-restart.1.md @@ -18,10 +18,5 @@ Restart each container listed. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. - ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-rm.1.md b/docs/man/docker-rm.1.md index 9195137ec1..1b45376976 100644 --- a/docs/man/docker-rm.1.md +++ b/docs/man/docker-rm.1.md @@ -47,9 +47,5 @@ command. The use that name as follows: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-rmi.1.md b/docs/man/docker-rmi.1.md index 7a2973f873..08d740a3be 100644 --- a/docs/man/docker-rmi.1.md +++ b/docs/man/docker-rmi.1.md @@ -34,9 +34,5 @@ Here is an example of removing and image: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-run.1.md b/docs/man/docker-run.1.md index fa73d8eee4..e7571ac21a 100644 --- a/docs/man/docker-run.1.md +++ b/docs/man/docker-run.1.md @@ -369,9 +369,5 @@ changes will also be reflected on the host in /var/db. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-save.1.md b/docs/man/docker-save.1.md index 403c3fb614..533b4c8435 100644 --- a/docs/man/docker-save.1.md +++ b/docs/man/docker-save.1.md @@ -33,10 +33,5 @@ fedora image to a fedora-latest.tar: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. - ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-search.1.md b/docs/man/docker-search.1.md index 061042c7ac..3937b870a3 100644 --- a/docs/man/docker-search.1.md +++ b/docs/man/docker-search.1.md @@ -54,9 +54,5 @@ ranked 1 or higher: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-start.1.md b/docs/man/docker-start.1.md index ed9f77b43e..e23fd70ab4 100644 --- a/docs/man/docker-start.1.md +++ b/docs/man/docker-start.1.md @@ -23,9 +23,5 @@ Start a stopped container. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-stop.1.md b/docs/man/docker-stop.1.md index 14bd7b30e6..0cc19918c3 100644 --- a/docs/man/docker-stop.1.md +++ b/docs/man/docker-stop.1.md @@ -19,9 +19,5 @@ Stop a running container (Send SIGTERM, and then SIGKILL after # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-tag.1.md b/docs/man/docker-tag.1.md index aae222085f..041c9e1cb5 100644 --- a/docs/man/docker-tag.1.md +++ b/docs/man/docker-tag.1.md @@ -54,9 +54,5 @@ registry you must tag it with the registry hostname and port (if needed). # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-top.1.md b/docs/man/docker-top.1.md index 5ba44d697d..9781739cde 100644 --- a/docs/man/docker-top.1.md +++ b/docs/man/docker-top.1.md @@ -27,10 +27,5 @@ Run **docker top** with the ps option of -x: # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. - ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit diff --git a/docs/man/docker-wait.1.md b/docs/man/docker-wait.1.md index cfa19ef861..798f6d652c 100644 --- a/docs/man/docker-wait.1.md +++ b/docs/man/docker-wait.1.md @@ -24,10 +24,5 @@ There are no available options. # HISTORY April 2014, Originally compiled by William Henry (whenry at redhat dot com) -<<<<<<< HEAD -based on docker.io source material and internal work. -June 2014, updated by Sven Dowideit -======= based on docker.com source material and internal work. - ->>>>>>> 834ef8a... I'm going to wish I didn't do this +June 2014, updated by Sven Dowideit -- cgit v1.2.1 From 79812e36468c6e9be19b7c028e37787d5ae6288b Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 3 Jul 2014 01:15:11 +0000 Subject: Bump version to v1.1.0 Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- CHANGELOG.md | 24 ++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a7d3c2e19..e55cb0c759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## 1.1.0 (2014-07-03) + +#### Notable features since 1.0.1 ++ Add `.dockerignore` support ++ Pause containers during `docker commit` ++ Add `--tail` to `docker logs` + +#### Builder ++ Allow a tar file as context for `docker build` +* Fix issue with white-spaces and multi-lines in `Dockerfiles` + +#### Runtime +* Overall performance improvements +* Allow `/` as source of `docker run -v` +* Fix port allocation +* Fix bug in `docker save` +* Add links information to `docker inspect` + +#### Client +* Improve command line parsing for `docker commit` + +#### Remote API +* Improve status code for the `start` and `stop` endpoints + ## 1.0.1 (2014-06-19) #### Notable features since 1.0.0 diff --git a/VERSION b/VERSION index 3f60217db9..9084fa2f71 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1-dev +1.1.0 -- cgit v1.2.1 From 44456ba065118231d02334f6b1faee7971a41d3a Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 8 Jul 2014 12:23:08 -0700 Subject: Revert "allow overwrite in untar" This reverts commit 5a3d774e5651da772a065282a1fb1a31e19e911c. Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: vieux) --- archive/archive.go | 15 ++++++--------- archive/archive_test.go | 3 --- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/archive/archive.go b/archive/archive.go index 8d8b7412cc..b9701b58af 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -383,8 +383,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) // identity (uncompressed), gzip, bzip2, xz. // If `dest` does not exist, it is created unless there are multiple entries in `archive`. // In the latter case, an error is returned. -// If `dest` is an existing file, it gets overwritten. -// If `dest` is an existing directory, its files get merged (with overwrite for conflicting files). +// An other error is returned if `dest` exists but is not a directory, to prevent overwriting. func Untar(archive io.Reader, dest string, options *TarOptions) error { if archive == nil { return fmt.Errorf("Empty archive") @@ -400,7 +399,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { var ( dirs []*tar.Header - create bool + destNotExist bool multipleEntries bool ) @@ -409,10 +408,9 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { return err } // destination does not exist, so it is assumed it has to be created. - create = true + destNotExist = true } else if !fi.IsDir() { - // destination exists and is not a directory, so it will be overwritten. - create = true + return fmt.Errorf("Trying to untar to `%s`: exists but not a directory", dest) } // Iterate through the files in the archive. @@ -427,7 +425,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } // Return an error if destination needs to be created and there is more than 1 entry in the tar stream. - if create && multipleEntries { + if destNotExist && multipleEntries { return fmt.Errorf("Trying to untar an archive with multiple entries to an inexistant target `%s`: did you mean `%s` instead?", dest, filepath.Dir(dest)) } @@ -447,7 +445,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } var path string - if create { + if destNotExist { path = dest // we are renaming hdr.Name to dest } else { path = filepath.Join(dest, hdr.Name) @@ -467,7 +465,6 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } } } - if err := createTarFile(path, dest, hdr, tr, options == nil || !options.NoLchown); err != nil { return err } diff --git a/archive/archive_test.go b/archive/archive_test.go index 1b5e146965..e05cd72e49 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -176,9 +176,6 @@ func TestTarUntarFile(t *testing.T) { if err := ioutil.WriteFile(path.Join(origin, "before", "file"), []byte("hello world"), 0700); err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(path.Join(origin, "after", "file2"), []byte("please overwrite me"), 0700); err != nil { - t.Fatal(err) - } tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) if err != nil { -- cgit v1.2.1 From 94c27842d8d129bdacde98d81e2013ff13143ee8 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 8 Jul 2014 12:26:59 -0700 Subject: Revert "improve untar when using files instead of directories. Specifies behavior on non-existant targets." This reverts commit 1c8d3106df0bd2aba304c7b3863949ca11c2b133. Conflicts: archive/archive_test.go Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: vieux) --- archive/archive.go | 37 ++++--------------------------------- archive/archive_test.go | 38 -------------------------------------- 2 files changed, 4 insertions(+), 71 deletions(-) diff --git a/archive/archive.go b/archive/archive.go index b9701b58af..2ba62f5363 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -378,12 +378,10 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) } // Untar reads a stream of bytes from `archive`, parses it as a tar archive, -// and unpacks it into the directory at `dest`. +// and unpacks it into the directory at `path`. // The archive may be compressed with one of the following algorithms: // identity (uncompressed), gzip, bzip2, xz. -// If `dest` does not exist, it is created unless there are multiple entries in `archive`. -// In the latter case, an error is returned. -// An other error is returned if `dest` exists but is not a directory, to prevent overwriting. +// FIXME: specify behavior when target path exists vs. doesn't exist. func Untar(archive io.Reader, dest string, options *TarOptions) error { if archive == nil { return fmt.Errorf("Empty archive") @@ -397,21 +395,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { tr := tar.NewReader(decompressedArchive) - var ( - dirs []*tar.Header - destNotExist bool - multipleEntries bool - ) - - if fi, err := os.Lstat(dest); err != nil { - if !os.IsNotExist(err) { - return err - } - // destination does not exist, so it is assumed it has to be created. - destNotExist = true - } else if !fi.IsDir() { - return fmt.Errorf("Trying to untar to `%s`: exists but not a directory", dest) - } + var dirs []*tar.Header // Iterate through the files in the archive. for { @@ -424,11 +408,6 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { return err } - // Return an error if destination needs to be created and there is more than 1 entry in the tar stream. - if destNotExist && multipleEntries { - return fmt.Errorf("Trying to untar an archive with multiple entries to an inexistant target `%s`: did you mean `%s` instead?", dest, filepath.Dir(dest)) - } - // Normalize name, for safety and for a simple is-root check hdr.Name = filepath.Clean(hdr.Name) @@ -444,12 +423,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { } } - var path string - if destNotExist { - path = dest // we are renaming hdr.Name to dest - } else { - path = filepath.Join(dest, hdr.Name) - } + path := filepath.Join(dest, hdr.Name) // If path exits we almost always just want to remove and replace it // The only exception is when it is a directory *and* the file from @@ -469,9 +443,6 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { return err } - // Successfully added an entry. Predicting multiple entries for next iteration (not current one). - multipleEntries = true - // Directory mtimes must be handled at the end to avoid further // file creation in them to modify the directory mtime if hdr.Typeflag == tar.TypeDir { diff --git a/archive/archive_test.go b/archive/archive_test.go index e05cd72e49..61ee0af8e7 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -160,44 +160,6 @@ func TestTarWithOptions(t *testing.T) { } } -func TestTarUntarFile(t *testing.T) { - origin, err := ioutil.TempDir("", "docker-test-untar-origin-file") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(origin) - - if err := os.MkdirAll(path.Join(origin, "before"), 0700); err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(path.Join(origin, "after"), 0700); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(path.Join(origin, "before", "file"), []byte("hello world"), 0700); err != nil { - t.Fatal(err) - } - - tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) - if err != nil { - t.Fatal(err) - } - - if err := Untar(tar, path.Join(origin, "after", "file2"), nil); err != nil { - t.Fatal(err) - } - - catCmd := exec.Command("cat", path.Join(origin, "after", "file2")) - out, err := CmdStream(catCmd, nil) - if err != nil { - t.Fatalf("Failed to start command: %s", err) - } - if output, err := ioutil.ReadAll(out); err != nil { - t.Error(err) - } else if string(output) != "hello world" { - t.Fatalf("Expected 'hello world', got '%s'", output) - } -} - // Some tar archives such as http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev21.tar.gz // use PAX Global Extended Headers. // Failing prevents the archives from being uncompressed during ADD -- cgit v1.2.1 From 699556e6619ce6806030e87ee1f3ea57bcdefd81 Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 8 Jul 2014 15:34:04 -0400 Subject: Tests for ADD tar Docker-DCO-1.1-Signed-off-by: Tibor Vass (github: tiborvass) Conflicts: integration-cli/docker_cli_build_test.go Docker-DCO-1.1-Signed-off-by: Tibor Vass (github: vieux) --- .../build_tests/TestBuildAddTar/1/Dockerfile | 3 + .../build_tests/TestBuildAddTar/1/test.tar | Bin 0 -> 2560 bytes .../build_tests/TestBuildAddTar/2/Dockerfile | 3 + .../build_tests/TestBuildAddTar/2/test.tar | Bin 0 -> 2560 bytes integration-cli/docker_cli_build_test.go | 199 +++++++++++++++++++++ 5 files changed, 205 insertions(+) create mode 100644 integration-cli/build_tests/TestBuildAddTar/1/Dockerfile create mode 100644 integration-cli/build_tests/TestBuildAddTar/1/test.tar create mode 100644 integration-cli/build_tests/TestBuildAddTar/2/Dockerfile create mode 100644 integration-cli/build_tests/TestBuildAddTar/2/test.tar diff --git a/integration-cli/build_tests/TestBuildAddTar/1/Dockerfile b/integration-cli/build_tests/TestBuildAddTar/1/Dockerfile new file mode 100644 index 0000000000..2091b0e4d9 --- /dev/null +++ b/integration-cli/build_tests/TestBuildAddTar/1/Dockerfile @@ -0,0 +1,3 @@ +FROM busybox +ADD test.tar /test.tar +RUN cat /test.tar/test/foo diff --git a/integration-cli/build_tests/TestBuildAddTar/1/test.tar b/integration-cli/build_tests/TestBuildAddTar/1/test.tar new file mode 100644 index 0000000000..33639c6476 Binary files /dev/null and b/integration-cli/build_tests/TestBuildAddTar/1/test.tar differ diff --git a/integration-cli/build_tests/TestBuildAddTar/2/Dockerfile b/integration-cli/build_tests/TestBuildAddTar/2/Dockerfile new file mode 100644 index 0000000000..830e9ddbee --- /dev/null +++ b/integration-cli/build_tests/TestBuildAddTar/2/Dockerfile @@ -0,0 +1,3 @@ +FROM busybox +ADD test.tar / +RUN cat /test/foo diff --git a/integration-cli/build_tests/TestBuildAddTar/2/test.tar b/integration-cli/build_tests/TestBuildAddTar/2/test.tar new file mode 100644 index 0000000000..33639c6476 Binary files /dev/null and b/integration-cli/build_tests/TestBuildAddTar/2/test.tar differ diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 2f2f2b6e0c..039423e06c 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -1564,3 +1564,202 @@ func TestDockerignoringDockerfile(t *testing.T) { } logDone("build - test .dockerignore of Dockerfile") } + +func TestBuildLineBreak(t *testing.T) { + name := "testbuildlinebreak" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox +RUN sh -c 'echo root:testpass \ + > /tmp/passwd' +RUN mkdir -p /var/run/sshd +RUN [ "$(cat /tmp/passwd)" = "root:testpass" ] +RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`, + true) + if err != nil { + t.Fatal(err) + } + logDone("build - line break with \\") +} + +func TestBuildEOLInLine(t *testing.T) { + name := "testbuildeolinline" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox +RUN sh -c 'echo root:testpass > /tmp/passwd' +RUN echo "foo \n bar"; echo "baz" +RUN mkdir -p /var/run/sshd +RUN [ "$(cat /tmp/passwd)" = "root:testpass" ] +RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`, + true) + if err != nil { + t.Fatal(err) + } + logDone("build - end of line in dockerfile instruction") +} + +func TestBuildCommentsShebangs(t *testing.T) { + name := "testbuildcomments" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox +# This is an ordinary comment. +RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh +RUN [ ! -x /hello.sh ] +# comment with line break \ +RUN chmod +x /hello.sh +RUN [ -x /hello.sh ] +RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ] +RUN [ "$(/hello.sh)" = "hello world" ]`, + true) + if err != nil { + t.Fatal(err) + } + logDone("build - comments and shebangs") +} + +func TestBuildUsersAndGroups(t *testing.T) { + name := "testbuildusers" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox + +# Make sure our defaults work +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ] + +# TODO decide if "args.user = strconv.Itoa(syscall.Getuid())" is acceptable behavior for changeUser in sysvinit instead of "return nil" when "USER" isn't specified (so that we get the proper group list even if that is the empty list, even in the default case of not supplying an explicit USER to run as, which implies USER 0) +USER root +RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ] + +# Setup dockerio user and group +RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd +RUN echo 'dockerio:x:1001:' >> /etc/group + +# Make sure we can switch to our user and all the information is exactly as we expect it to be +USER dockerio +RUN id -G +RUN id -Gn +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ] + +# Switch back to root and double check that worked exactly as we might expect it to +USER root +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ] + +# Add a "supplementary" group for our dockerio user +RUN echo 'supplementary:x:1002:dockerio' >> /etc/group + +# ... and then go verify that we get it like we expect +USER dockerio +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ] +USER 1001 +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ] + +# super test the new "user:group" syntax +USER dockerio:dockerio +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ] +USER 1001:dockerio +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ] +USER dockerio:1001 +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ] +USER 1001:1001 +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ] +USER dockerio:supplementary +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ] +USER dockerio:1002 +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ] +USER 1001:supplementary +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ] +USER 1001:1002 +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ] + +# make sure unknown uid/gid still works properly +USER 1042:1043 +RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`, + true) + if err != nil { + t.Fatal(err) + } + logDone("build - users and groups") +} + +func TestBuildEnvUsage(t *testing.T) { + name := "testbuildenvusage" + defer deleteImages(name) + dockerfile := `FROM busybox +ENV FOO /foo/baz +ENV BAR /bar +ENV BAZ $BAR +ENV FOOPATH $PATH:$FOO +RUN [ "$BAR" = "$BAZ" ] +RUN [ "$FOOPATH" = "$PATH:/foo/baz" ] +ENV FROM hello/docker/world +ENV TO /docker/world/hello +ADD $FROM $TO +RUN [ "$(cat $TO)" = "hello" ]` + ctx, err := fakeContext(dockerfile, map[string]string{ + "hello/docker/world": "hello", + }) + if err != nil { + t.Fatal(err) + } + _, err = buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + logDone("build - environment variables usage") +} + +func TestBuildAddScript(t *testing.T) { + name := "testbuildaddscript" + defer deleteImages(name) + dockerfile := ` +FROM busybox +ADD test /test +RUN ["chmod","+x","/test"] +RUN ["/test"] +RUN [ "$(cat /testfile)" = 'test!' ]` + ctx, err := fakeContext(dockerfile, map[string]string{ + "test": "#!/bin/sh\necho 'test!' > /testfile", + }) + if err != nil { + t.Fatal(err) + } + _, err = buildImageFromContext(name, ctx, true) + if err != nil { + t.Fatal(err) + } + logDone("build - add and run script") +} + +func TestBuildAddTar(t *testing.T) { + + checkOutput := func(out string) { + n := -1 + x := "" + for i, line := range strings.Split(out, "\n") { + if strings.HasPrefix(line, "Step 2") { + n = i + 2 + x = line[strings.Index(line, "cat ")+4:] + } + if i == n { + if line != "Hi" { + t.Fatalf("Could not find contents of %s (expected 'Hi' got '%s'", x, line) + } + n = -2 + } + } + if n > -2 { + t.Fatalf("Could not find contents of %s in build output", x) + } + } + + for _, n := range []string{"1", "2"} { + buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildAddTar", n) + buildCmd := exec.Command(dockerBinary, "build", "-t", "testbuildaddtar", ".") + buildCmd.Dir = buildDirectory + out, _, err := runCommandWithOutput(buildCmd) + errorOut(err, t, fmt.Sprintf("build failed to complete for TestBuildAddTar/%s: %v", n, err)) + checkOutput(out) + } +} -- cgit v1.2.1 From dc62f3cdccfd744c7e1d345da7f167df98cf9686 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 8 Jul 2014 21:35:22 +0000 Subject: Bump version to v1.1.1 Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- CHANGELOG.md | 5 +++++ VERSION | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e55cb0c759..327a8a7e69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.1.1 (2014-07-09) + +#### Builder +* Fix issue with ADD + ## 1.1.0 (2014-07-03) #### Notable features since 1.0.1 diff --git a/VERSION b/VERSION index 9084fa2f71..524cb55242 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.0 +1.1.1 -- cgit v1.2.1 From 699bc47137ab78b7d88ec7623ad10e04f7b67f33 Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Thu, 10 Jul 2014 13:19:18 +0400 Subject: Set state running before dumping to disk Fixes #4766 Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) Conflicts: daemon/container.go Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: vieux) --- daemon/container.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/container.go b/daemon/container.go index 5b41438680..41a2d390e0 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -1080,10 +1080,10 @@ func (container *Container) waitForStart() error { c.Close() } } + container.State.SetRunning(command.Pid()) if err := container.ToDisk(); err != nil { utils.Debugf("%s", err) } - container.State.SetRunning(command.Pid()) } // We use a callback here instead of a goroutine and an chan for -- cgit v1.2.1 From 21341e9e134399feef88872f11fb4339401cf6f5 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Mon, 14 Jul 2014 12:34:04 -0600 Subject: Add a conditional to contrib/init/sysvinit-debian/docker for Dash vs Bash support Docker-DCO-1.1-Signed-off-by: Andrew Page (github: tianon) Docker-DCO-1.1-Signed-off-by: Tianon Gravi (github: vieux) --- contrib/init/sysvinit-debian/docker | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/init/sysvinit-debian/docker b/contrib/init/sysvinit-debian/docker index 6250cae053..d79d9c6c07 100755 --- a/contrib/init/sysvinit-debian/docker +++ b/contrib/init/sysvinit-debian/docker @@ -89,7 +89,11 @@ case "$1" in chgrp docker "$DOCKER_LOGFILE" ulimit -n 1048576 - ulimit -u 1048576 + if [ "$BASH" ]; then + ulimit -u 1048576 + else + ulimit -p 1048576 + fi log_begin_msg "Starting $DOCKER_DESC: $BASE" start-stop-daemon --start --background \ -- cgit v1.2.1 From 2c185e25c22b82614210908c445a32fa3dbe5ed1 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 21 Jul 2014 19:59:44 -0700 Subject: Always mark as stopped for non running containers Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: vieux) --- daemon/daemon.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index 23402d9518..a94a4458ad 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -209,6 +209,7 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool, con } daemon.execDriver.Terminate(cmd) } + if err := container.Unmount(); err != nil { utils.Debugf("unmount error %s", err) } @@ -219,21 +220,20 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool, con info := daemon.execDriver.Info(container.ID) if !info.IsRunning() { utils.Debugf("Container %s was supposed to be running but is not.", container.ID) + + utils.Debugf("Marking as stopped") + + container.State.SetStopped(-127) + if err := container.ToDisk(); err != nil { + return err + } + if daemon.config.AutoRestart { utils.Debugf("Marking as restarting") - if err := container.Unmount(); err != nil { - utils.Debugf("restart unmount error %s", err) - } if containersToStart != nil { *containersToStart = append(*containersToStart, container) } - } else { - utils.Debugf("Marking as stopped") - container.State.SetStopped(-127) - if err := container.ToDisk(); err != nil { - return err - } } } } -- cgit v1.2.1 From 4e12484ea12d23fd70fd3bf636e786f4f741ab64 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 22 Jul 2014 00:16:26 -0700 Subject: Copy values out of hostConfig Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: vieux) --- daemon/container.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/daemon/container.go b/daemon/container.go index 41a2d390e0..30337de6b5 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -422,8 +422,17 @@ func (container *Container) allocateNetwork() error { if container.Config.ExposedPorts != nil { portSpecs = container.Config.ExposedPorts } + if container.hostConfig.PortBindings != nil { - bindings = container.hostConfig.PortBindings + for p, b := range container.hostConfig.PortBindings { + bindings[p] = []nat.PortBinding{} + for _, bb := range b { + bindings[p] = append(bindings[p], nat.PortBinding{ + HostIp: bb.HostIp, + HostPort: bb.HostPort, + }) + } + } } container.NetworkSettings.PortMapping = nil -- cgit v1.2.1 From d84a070e476ce923dd03e28232564a87704613ab Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 23 Jul 2014 00:29:56 +0000 Subject: Bump version to v1.1.2 Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- CHANGELOG.md | 9 +++++++++ VERSION | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 327a8a7e69..8ec9ce3df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.1.2 (2014-07-23) + +#### Runtime ++ Fix port allocation for existing containers ++ Fix containers restart on daemon restart + +#### Packaging ++ Fix /etc/init.d/docker issue on Debian + ## 1.1.1 (2014-07-09) #### Builder diff --git a/VERSION b/VERSION index 524cb55242..45a1b3f445 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.1 +1.1.2 -- cgit v1.2.1