Merge pull request #3439 from dotcloud/bump_v0.7.3

Bump v0.7.3
This commit is contained in:
Tianon Gravi 2014-01-03 16:01:56 -08:00
commit 76910d16cc
132 changed files with 2961 additions and 816 deletions

View file

@ -20,6 +20,7 @@ Antony Messerli <amesserl@rackspace.com>
Asbjørn Enge <asbjorn@hanafjedle.net>
Barry Allard <barry.allard@gmail.com>
Ben Toews <mastahyeti@gmail.com>
Ben Wiklund <ben@daisyowl.com>
Benoit Chesneau <bchesneau@gmail.com>
Bhiraj Butala <abhiraj.butala@gmail.com>
Bouke Haarsma <bouke@webatoom.nl>
@ -47,6 +48,7 @@ Daniel YC Lin <dlin.tw@gmail.com>
Darren Coxall <darren@darrencoxall.com>
David Calavera <david.calavera@gmail.com>
David Sissitka <me@dsissitka.com>
Dinesh Subhraveti <dineshs@altiscale.com>
Deni Bertovic <deni@kset.org>
Dominik Honnef <dominik@honnef.co>
Don Spaulding <donspauldingii@gmail.com>
@ -68,6 +70,7 @@ Francisco Souza <f@souza.cc>
Frederick F. Kautz IV <fkautz@alumni.cmu.edu>
Gabriel Monroy <gabriel@opdemand.com>
Gareth Rushgrove <gareth@morethanseven.net>
Graydon Hoare <graydon@pobox.com>
Greg Thornton <xdissent@me.com>
Guillaume J. Charmes <guillaume.charmes@dotcloud.com>
Gurjeet Singh <gurjeet@singh.im>
@ -113,6 +116,7 @@ Kyle Conroy <kyle.j.conroy@gmail.com>
Laurie Voss <github@seldo.com>
Louis Opter <kalessin@kalessin.fr>
Manuel Meurer <manuel@krautcomputing.com>
Manuel Woelker <docker@manuel.woelker.org>
Marco Hennings <marco.hennings@freiheit.com>
Marcus Farkas <toothlessgear@finitebox.com>
Marcus Ramberg <marcus@nordaaker.com>

View file

@ -1,5 +1,66 @@
# Changelog
## 0.7.3 (2013-01-02)
#### Builder
+ Update ADD to use the image cache, based on a hash of the added content
* Add error message for empty Dockerfile
#### Documentation
- Fix outdated link to the "Introduction" on www.docker.io
+ Update the docs to get wider when the screen does
- Add information about needing to install LXC when using raw binaries
* Update Fedora documentation to disentangle the docker and docker.io conflict
* Add a note about using the new `-mtu` flag in several GCE zones
+ Add FrugalWare installation instructions
+ Add a more complete example of `docker run`
- Fix API documentation for creating and starting Privileged containers
- Add missing "name" parameter documentation on "/containers/create"
* Add a mention of `lxc-checkconfig` as a way to check for some of the necessary kernel configuration
- Update the 1.8 API documentation with some additions that were added to the docs for 1.7
#### Hack
- Add missing libdevmapper dependency to the packagers documentation
* Update minimum Go requirement to a hard line at Go 1.2+
* Many minor improvements to the Vagrantfile
+ Add ability to customize dockerinit search locations when compiling (to be used very sparingly only by packagers of platforms who require a nonstandard location)
+ Add coverprofile generation reporting
- Add `-a` to our Go build flags, removing the need for recompiling the stdlib manually
* Update Dockerfile to be more canonical and have less spurious warnings during build
- Fix some miscellaneous `docker pull` progress bar display issues
* Migrate more miscellaneous packages under the "pkg" folder
* Update TextMate highlighting to automatically be enabled for files named "Dockerfile"
* Reorganize syntax highlighting files under a common "contrib/syntax" directory
* Update install.sh script (https://get.docker.io/) to not fail if busybox fails to download or run at the end of the Ubuntu/Debian installation
* Add support for container names in bash completion
#### Packaging
+ Add an official Docker client binary for Darwin (Mac OS X)
* Remove empty "Vendor" string and added "License" on deb package
+ Add a stubbed version of "/etc/default/docker" in the deb package
#### Runtime
* Update layer application to extract tars in place, avoiding file churn while handling whiteouts
- Fix permissiveness of mtime comparisons in tar handling (since GNU tar and Go tar do not yet support sub-second mtime precision)
* Reimplement `docker top` in pure Go to work more consistently, and even inside Docker-in-Docker (thus removing the shell injection vulnerability present in some versions of `lxc-ps`)
+ Update `-H unix://` to work similarly to `-H tcp://` by inserting the default values for missing portions
- Fix more edge cases regarding dockerinit and deleted or replaced docker or dockerinit files
* Update container name validation to include '.'
- Fix use of a symlink or non-absolute path as the argument to `-g` to work as expected
* Update to handle external mounts outside of LXC, fixing many small mounting quirks and making future execution backends and other features simpler
* Update to use proper box-drawing characters everywhere in `docker images -tree`
* Move MTU setting from LXC configuration to directly use netlink
* Add `-S` option to external tar invocation for more efficient spare file handling
+ Add arch/os info to User-Agent string, especially for registry requests
+ Add `-mtu` option to Docker daemon for configuring MTU
- Fix `docker build` to exit with a non-zero exit code on error
+ Add `DOCKER_HOST` environment variable to configure the client `-H` flag without specifying it manually for every invocation
## 0.7.2 (2013-12-16)
#### Runtime
@ -15,7 +76,7 @@
- Prevent deletion of image if ANY container is depending on it even if the container is not running
* Update docker push to use new progress display
* Use os.Lstat to allow mounting unix sockets when inspecting volumes
- Adjusted handling of inactive user login
- Adjust handling of inactive user login
- Add missing defines in devicemapper for older kernels
- Allow untag operations with no container validation
- Add auth config to docker build
@ -110,7 +171,7 @@
#### Runtime
* Improved stability, fixes some race conditons
* Improve stability, fixes some race conditons
* Skip the volumes mounted when deleting the volumes of container.
* Fix layer size computation: handle hard links correctly
* Use the work Path for docker cp CONTAINER:PATH
@ -153,7 +214,7 @@
+ Add lock around write operations in graph
* Check if port is valid
* Fix restart runtime error with ghost container networking
+ Added some more colors and animals to increase the pool of generated names
+ Add some more colors and animals to increase the pool of generated names
* Fix issues in docker inspect
+ Escape apparmor confinement
+ Set environment variables using a file.
@ -307,7 +368,7 @@
* Improve network performance for VirtualBox
* Revamp install.sh to be usable by more people, and to use official install methods whenever possible (apt repo, portage tree, etc.)
- Fix contrib/mkimage-debian.sh apt caching prevention
+ Added Dockerfile.tmLanguage to contrib
+ Add Dockerfile.tmLanguage to contrib
* Configured FPM to make /etc/init/docker.conf a config file
* Enable SSH Agent forwarding in Vagrant VM
* Several small tweaks/fixes for contrib/mkimage-debian.sh
@ -421,7 +482,7 @@
* Mount /dev/shm as a tmpfs
- Switch from http to https for get.docker.io
* Let userland proxy handle container-bound traffic
* Updated the Docker CLI to specify a value for the "Host" header.
* Update the Docker CLI to specify a value for the "Host" header.
- Change network range to avoid conflict with EC2 DNS
- Reduce connect and read timeout when pinging the registry
* Parallel pull
@ -617,7 +678,7 @@
+ Builder: 'docker build git://URL' fetches and builds a remote git repository
* Runtime: 'docker ps -s' optionally prints container size
* Tests: Improved and simplified
* Tests: improved and simplified
- Runtime: fix a regression introduced in 0.4.3 which caused the logs command to fail.
- Builder: fix a regression when using ADD with single regular file.
@ -632,7 +693,7 @@
+ ADD of a local file will detect tar archives and unpack them
* ADD improvements: use tar for copy + automatically unpack local archives
* ADD uses tar/untar for copies instead of calling 'cp -ar'
* Fixed the behavior of ADD to be (mostly) reverse-compatible, predictable and well-documented.
* Fix the behavior of ADD to be (mostly) reverse-compatible, predictable and well-documented.
- Fix a bug which caused builds to fail if ADD was the first command
* Nicer output for 'docker build'
@ -677,7 +738,7 @@
+ Detect faulty DNS configuration and replace it with a public default
+ Allow docker run <name>:<id>
+ You can now specify public port (ex: -p 80:4500)
* Improved image removal to garbage-collect unreferenced parents
* Improve image removal to garbage-collect unreferenced parents
#### Client
@ -731,7 +792,7 @@
#### Documentation
* Improved install instructions.
* Improve install instructions.
## 0.3.3 (2013-05-23)
@ -816,7 +877,7 @@
+ Support for data volumes ('docker run -v=PATH')
+ Share data volumes between containers ('docker run -volumes-from')
+ Improved documentation
+ Improve documentation
* Upgrade to Go 1.0.3
* Various upgrades to the dev environment for contributors
@ -872,7 +933,7 @@
- Add debian packaging
- Documentation: installing on Arch Linux
- Documentation: running Redis on docker
- Fixed lxc 0.9 compatibility
- Fix lxc 0.9 compatibility
- Automatically load aufs module
- Various bugfixes and stability improvements
@ -907,7 +968,7 @@
- Stabilize process management
- Layers can include a commit message
- Simplified 'docker attach'
- Fixed support for re-attaching
- Fix support for re-attaching
- Various bugfixes and stability improvements
- Auto-download at run
- Auto-login on push

View file

@ -24,40 +24,32 @@
#
docker-version 0.6.1
FROM ubuntu:12.04
MAINTAINER Solomon Hykes <solomon@dotcloud.com>
FROM stackbrew/ubuntu:12.04
MAINTAINER Tianon Gravi <admwiggin@gmail.com> (@tianon)
# Build dependencies
RUN echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y -q curl
RUN apt-get install -y -q git
RUN apt-get install -y -q mercurial
RUN apt-get install -y -q build-essential libsqlite3-dev
# Add precise-backports to get s3cmd >= 1.1.0 (so we get ENV variable support in our .s3cfg)
RUN echo 'deb http://archive.ubuntu.com/ubuntu precise-backports main universe' > /etc/apt/sources.list.d/backports.list
# Install Go
RUN curl -s https://go.googlecode.com/files/go1.2.src.tar.gz | tar -v -C /usr/local -xz
ENV PATH /usr/local/go/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
ENV GOPATH /go:/go/src/github.com/dotcloud/docker/vendor
RUN cd /usr/local/go/src && ./make.bash && go install -ldflags '-w -linkmode external -extldflags "-static -Wl,--unresolved-symbols=ignore-in-shared-libs"' -tags netgo -a std
# Ubuntu stuff
RUN apt-get install -y -q ruby1.9.3 rubygems libffi-dev
RUN gem install --no-rdoc --no-ri fpm
RUN apt-get install -y -q reprepro dpkg-sig
RUN apt-get install -y -q python-pip
RUN pip install s3cmd==1.1.0-beta3
RUN pip install python-magic==0.4.6
RUN /bin/echo -e '[default]\naccess_key=$AWS_ACCESS_KEY\nsecret_key=$AWS_SECRET_KEY\n' > /.s3cfg
# Runtime dependencies
RUN apt-get install -y -q iptables
RUN apt-get install -y -q lxc
RUN apt-get install -y -q aufs-tools
# Packaged dependencies
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq \
apt-utils \
aufs-tools \
build-essential \
curl \
dpkg-sig \
git \
iptables \
libsqlite3-dev \
lxc \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.0* \
--no-install-recommends
# Get lvm2 source for compiling statically
RUN git clone https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout v2_02_103
RUN git clone https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103
# see https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# note: we can't use "git clone -b" above because it requires at least git 1.7.10 to be able to use that on a tag instead of a branch and we only have 1.7.9.5
@ -65,9 +57,26 @@ RUN git clone https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /u
RUN cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper
# see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
# Install Go
RUN curl -s https://go.googlecode.com/files/go1.2.src.tar.gz | tar -v -C /usr/local -xz
ENV PATH /usr/local/go/bin:$PATH
ENV GOPATH /go:/go/src/github.com/dotcloud/docker/vendor
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
# Compile Go for cross compilation
ENV DOCKER_CROSSPLATFORMS darwin/amd64 darwin/386
# TODO add linux/386 and linux/arm
RUN cd /usr/local/go/src && bash -xc 'for platform in $DOCKER_CROSSPLATFORMS; do GOOS=${platform%/*} GOARCH=${platform##*/} ./make.bash --no-clean 2>&1; done'
# Grab Go's cover tool for dead-simple code coverage testing
RUN go get code.google.com/p/go.tools/cmd/cover
# TODO replace FPM with some very minimal debhelper stuff
RUN gem install --no-rdoc --no-ri fpm --version 1.0.1
# Setup s3cmd config
RUN /bin/echo -e '[default]\naccess_key=$AWS_ACCESS_KEY\nsecret_key=$AWS_SECRET_KEY' > /.s3cfg
VOLUME /var/lib/docker
WORKDIR /go/src/github.com/dotcloud/docker

View file

@ -3,4 +3,6 @@ Guillaume Charmes <guillaume@dotcloud.com> (@creack)
Victor Vieux <victor@dotcloud.com> (@vieux)
Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
api.go: Victor Vieux <victor@dotcloud.com> (@vieux)
Dockerfile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
Makefile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
Vagrantfile: Daniel Mizyrycki <daniel@dotcloud.com> (@mzdaniel)

View file

@ -1,4 +1,4 @@
.PHONY: all binary build default docs shell test
.PHONY: all binary build cross default docs shell test
DOCKER_RUN_DOCKER := docker run -rm -i -t -privileged -e TESTFLAGS -v $(CURDIR)/bundles:/go/src/github.com/dotcloud/docker/bundles docker
@ -10,6 +10,9 @@ all: build
binary: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary
cross: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross
docs:
docker build -t docker-docs docs && docker run -p 8000:8000 docker-docs

View file

@ -1 +1 @@
0.7.2
0.7.3

4
Vagrantfile vendored
View file

@ -26,7 +26,7 @@ fi
# Adding an apt gpg key is idempotent.
wget -q -O - https://get.docker.io/gpg | apt-key add -
# Creating the docker.list file is idempotent, but it may overrite desired
# Creating the docker.list file is idempotent, but it may overwrite desired
# settings if it already exists. This could be solved with md5sum but it
# doesn't seem worth it.
echo 'deb http://get.docker.io/ubuntu docker main' > \
@ -41,7 +41,7 @@ apt-get install -q -y lxc-docker
usermod -a -G docker "$user"
tmp=`mktemp -q` && {
# Only install the backport kernel, don't bother upgrade if the backport is
# Only install the backport kernel, don't bother upgrading if the backport is
# already installed. We want parse the output of apt so we need to save it
# with 'tee'. NOTE: The installation of the kernel will trigger dkms to
# install vboxguest if needed.

2
api.go
View file

@ -10,7 +10,7 @@ import (
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/systemd"
"github.com/dotcloud/docker/pkg/systemd"
"github.com/dotcloud/docker/utils"
"github.com/gorilla/mux"
"io"

View file

@ -3,6 +3,8 @@ package archive
import (
"archive/tar"
"bytes"
"compress/gzip"
"compress/bzip2"
"fmt"
"github.com/dotcloud/docker/utils"
"io"
@ -59,6 +61,43 @@ func DetectCompression(source []byte) Compression {
return Uncompressed
}
func xzDecompress(archive io.Reader) (io.Reader, error) {
args := []string{"xz", "-d", "-c", "-q"}
return CmdStream(exec.Command(args[0], args[1:]...), archive, nil)
}
func DecompressStream(archive io.Reader) (io.Reader, error) {
buf := make([]byte, 10)
totalN := 0
for totalN < 10 {
n, err := archive.Read(buf[totalN:])
if err != nil {
if err == io.EOF {
return nil, fmt.Errorf("Tarball too short")
}
return nil, err
}
totalN += n
utils.Debugf("[tar autodetect] n: %d", n)
}
compression := DetectCompression(buf)
wrap := io.MultiReader(bytes.NewReader(buf), archive)
switch compression {
case Uncompressed:
return wrap, nil
case Gzip:
return gzip.NewReader(wrap)
case Bzip2:
return bzip2.NewReader(wrap), nil
case Xz:
return xzDecompress(wrap)
default:
return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension())
}
}
func (compression *Compression) Flag() string {
switch *compression {
case Bzip2:
@ -110,7 +149,7 @@ func escapeName(name string) string {
// Tar creates an archive from the directory at `path`, only including files whose relative
// paths are included in `filter`. If `filter` is nil, then all files are included.
func TarFilter(path string, options *TarOptions) (io.Reader, error) {
args := []string{"tar", "--numeric-owner", "-f", "-", "-C", path, "-T", "-"}
args := []string{"tar", "-S", "--numeric-owner", "-f", "-", "-C", path, "-T", "-"}
if options.Includes == nil {
options.Includes = []string{"."}
}
@ -155,7 +194,7 @@ func TarFilter(path string, options *TarOptions) (io.Reader, error) {
}
}
return CmdStream(exec.Command(args[0], args[1:]...), &files, func() {
return CmdStream(exec.Command(args[0], args[1:]...), bytes.NewBufferString(files), func() {
if tmpDir != "" {
_ = os.RemoveAll(tmpDir)
}
@ -189,7 +228,7 @@ func Untar(archive io.Reader, path string, options *TarOptions) error {
compression := DetectCompression(buf)
utils.Debugf("Archive compression detected: %s", compression.Extension())
args := []string{"--numeric-owner", "-f", "-", "-C", path, "-x" + compression.Flag()}
args := []string{"-S", "--numeric-owner", "-f", "-", "-C", path, "-x" + compression.Flag()}
if options != nil {
for _, exclude := range options.Excludes {
@ -301,7 +340,7 @@ func CopyFileWithTar(src, dst string) error {
// CmdStream executes a command, and returns its stdout as a stream.
// If the command fails to run or doesn't complete successfully, an error
// will be returned, including anything written on stderr.
func CmdStream(cmd *exec.Cmd, input *string, atEnd func()) (io.Reader, error) {
func CmdStream(cmd *exec.Cmd, input io.Reader, atEnd func()) (io.Reader, error) {
if input != nil {
stdin, err := cmd.StdinPipe()
if err != nil {
@ -312,7 +351,7 @@ func CmdStream(cmd *exec.Cmd, input *string, atEnd func()) (io.Reader, error) {
}
// Write stdin if any
go func() {
_, _ = stdin.Write([]byte(*input))
io.Copy(stdin, input)
stdin.Close()
}()
}

View file

@ -6,6 +6,7 @@ import (
"path/filepath"
"strings"
"syscall"
"time"
)
type ChangeType int
@ -34,6 +35,21 @@ func (change *Change) String() string {
return fmt.Sprintf("%s %s", kind, change.Path)
}
// Gnu tar and the go tar writer don't have sub-second mtime
// precision, which is problematic when we apply changes via tar
// files, we handle this by comparing for exact times, *or* same
// second count and either a or b having exactly 0 nanoseconds
func sameFsTime(a, b time.Time) bool {
return a == b ||
(a.Unix() == b.Unix() &&
(a.Nanosecond() == 0 || b.Nanosecond() == 0))
}
func sameFsTimeSpec(a, b syscall.Timespec) bool {
return a.Sec == b.Sec &&
(a.Nsec == b.Nsec || a.Nsec == 0 || b.Nsec == 0)
}
func Changes(layers []string, rw string) ([]Change, error) {
var changes []Change
err := filepath.Walk(rw, func(path string, f os.FileInfo, err error) error {
@ -85,7 +101,7 @@ func Changes(layers []string, rw string) ([]Change, error) {
// However, if it's a directory, maybe it wasn't actually modified.
// If you modify /foo/bar/baz, then /foo will be part of the changed files only because it's the parent of bar
if stat.IsDir() && f.IsDir() {
if f.Size() == stat.Size() && f.Mode() == stat.Mode() && f.ModTime() == stat.ModTime() {
if f.Size() == stat.Size() && f.Mode() == stat.Mode() && sameFsTime(f.ModTime(), stat.ModTime()) {
// Both directories are the same, don't record the change
return nil
}
@ -181,7 +197,7 @@ func (info *FileInfo) addChanges(oldInfo *FileInfo, changes *[]Change) {
oldStat.Rdev != newStat.Rdev ||
// Don't look at size for dirs, its not a good measure of change
(oldStat.Size != newStat.Size && oldStat.Mode&syscall.S_IFDIR != syscall.S_IFDIR) ||
getLastModification(oldStat) != getLastModification(newStat) {
!sameFsTimeSpec(getLastModification(oldStat), getLastModification(newStat)) {
change := Change{
Path: newChild.path(),
Kind: ChangeModify,

View file

@ -258,48 +258,44 @@ func TestChangesDirsMutated(t *testing.T) {
}
func TestApplyLayer(t *testing.T) {
t.Skip("Skipping TestApplyLayer due to known failures") // Disable this for now as it is broken
return
src, err := ioutil.TempDir("", "docker-changes-test")
if err != nil {
t.Fatal(err)
}
createSampleDir(t, src)
defer os.RemoveAll(src)
dst := src + "-copy"
if err := copyDir(src, dst); err != nil {
t.Fatal(err)
}
mutateSampleDir(t, dst)
defer os.RemoveAll(dst)
// src, err := ioutil.TempDir("", "docker-changes-test")
// if err != nil {
// t.Fatal(err)
// }
// createSampleDir(t, src)
// dst := src + "-copy"
// if err := copyDir(src, dst); err != nil {
// t.Fatal(err)
// }
// mutateSampleDir(t, dst)
changes, err := ChangesDirs(dst, src)
if err != nil {
t.Fatal(err)
}
// changes, err := ChangesDirs(dst, src)
// if err != nil {
// t.Fatal(err)
// }
layer, err := ExportChanges(dst, changes)
if err != nil {
t.Fatal(err)
}
// layer, err := ExportChanges(dst, changes)
// if err != nil {
// t.Fatal(err)
// }
layerCopy, err := NewTempArchive(layer, "")
if err != nil {
t.Fatal(err)
}
// layerCopy, err := NewTempArchive(layer, "")
// if err != nil {
// t.Fatal(err)
// }
if err := ApplyLayer(src, layerCopy); err != nil {
t.Fatal(err)
}
// if err := ApplyLayer(src, layerCopy); err != nil {
// t.Fatal(err)
// }
changes2, err := ChangesDirs(src, dst)
if err != nil {
t.Fatal(err)
}
// changes2, err := ChangesDirs(src, dst)
// if err != nil {
// t.Fatal(err)
// }
// if len(changes2) != 0 {
// t.Fatalf("Unexpected differences after re applying mutation: %v", changes)
// }
// os.RemoveAll(src)
// os.RemoveAll(dst)
if len(changes2) != 0 {
t.Fatalf("Unexpected differences after reapplying mutation: %v", changes2)
}
}

View file

@ -1,6 +1,9 @@
package archive
import (
"archive/tar"
"github.com/dotcloud/docker/utils"
"io"
"os"
"path/filepath"
"strings"
@ -8,87 +11,181 @@ import (
"time"
)
// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.
// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major,
// then the top 12 bits of the minor
func mkdev(major int64, minor int64) uint32 {
return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
}
func timeToTimespec(time time.Time) (ts syscall.Timespec) {
if time.IsZero() {
// Return UTIME_OMIT special value
ts.Sec = 0
ts.Nsec = ((1 << 30) - 2)
return
}
return syscall.NsecToTimespec(time.UnixNano())
}
// ApplyLayer parses a diff in the standard layer format from `layer`, and
// applies it to the directory `dest`.
func ApplyLayer(dest string, layer Archive) error {
// Poor man's diff applyer in 2 steps:
// We need to be able to set any perms
oldmask := syscall.Umask(0)
defer syscall.Umask(oldmask)
// Step 1: untar everything in place
if err := Untar(layer, dest, nil); err != nil {
layer, err := DecompressStream(layer)
if err != nil {
return err
}
modifiedDirs := make(map[string]*syscall.Stat_t)
addDir := func(file string) {
d := filepath.Dir(file)
if _, exists := modifiedDirs[d]; !exists {
if s, err := os.Lstat(d); err == nil {
if sys := s.Sys(); sys != nil {
if stat, ok := sys.(*syscall.Stat_t); ok {
modifiedDirs[d] = stat
tr := tar.NewReader(layer)
var dirs []*tar.Header
// Iterate through the files in the archive.
for {
hdr, err := tr.Next()
if err == io.EOF {
// end of tar archive
break
}
if err != nil {
return err
}
// Normalize name, for safety and for a simple is-root check
hdr.Name = filepath.Clean(hdr.Name)
if !strings.HasSuffix(hdr.Name, "/") {
// Not the root directory, ensure that the parent directory exists.
// This happened in some tests where an image had a tarfile without any
// parent directories.
parent := filepath.Dir(hdr.Name)
parentPath := filepath.Join(dest, parent)
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
err = os.MkdirAll(parentPath, 600)
if err != nil {
return err
}
}
}
// Skip AUFS metadata dirs
if strings.HasPrefix(hdr.Name, ".wh..wh.") {
continue
}
path := filepath.Join(dest, hdr.Name)
base := filepath.Base(path)
if strings.HasPrefix(base, ".wh.") {
originalBase := base[len(".wh."):]
originalPath := filepath.Join(filepath.Dir(path), originalBase)
if err := os.RemoveAll(originalPath); err != nil {
return err
}
} else {
// 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
// the layer is also a directory. Then we want to merge them (i.e.
// just apply the metadata from the layer).
hasDir := false
if fi, err := os.Lstat(path); err == nil {
if fi.IsDir() && hdr.Typeflag == tar.TypeDir {
hasDir = true
} else {
if err := os.RemoveAll(path); err != nil {
return err
}
}
}
switch hdr.Typeflag {
case tar.TypeDir:
if !hasDir {
err = os.Mkdir(path, os.FileMode(hdr.Mode))
if err != nil {
return err
}
}
dirs = append(dirs, hdr)
case tar.TypeReg, tar.TypeRegA:
// Source is regular file
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, os.FileMode(hdr.Mode))
if err != nil {
return err
}
if _, err := io.Copy(file, tr); err != nil {
file.Close()
return err
}
file.Close()
case tar.TypeBlock, tar.TypeChar, tar.TypeFifo:
mode := uint32(hdr.Mode & 07777)
switch hdr.Typeflag {
case tar.TypeBlock:
mode |= syscall.S_IFBLK
case tar.TypeChar:
mode |= syscall.S_IFCHR
case tar.TypeFifo:
mode |= syscall.S_IFIFO
}
if err := syscall.Mknod(path, mode, int(mkdev(hdr.Devmajor, hdr.Devminor))); err != nil {
return err
}
case tar.TypeLink:
if err := os.Link(filepath.Join(dest, hdr.Linkname), path); err != nil {
return err
}
case tar.TypeSymlink:
if err := os.Symlink(hdr.Linkname, path); err != nil {
return err
}
default:
utils.Debugf("unhandled type %d\n", hdr.Typeflag)
}
if err = syscall.Lchown(path, hdr.Uid, hdr.Gid); err != nil {
return err
}
// There is no LChmod, so ignore mode for symlink. Also, this
// must happen after chown, as that can modify the file mode
if hdr.Typeflag != tar.TypeSymlink {
err = syscall.Chmod(path, uint32(hdr.Mode&07777))
if err != nil {
return err
}
}
// Directories must be handled at the end to avoid further
// file creation in them to modify the mtime
if hdr.Typeflag != tar.TypeDir {
ts := []syscall.Timespec{timeToTimespec(hdr.AccessTime), timeToTimespec(hdr.ModTime)}
// syscall.UtimesNano doesn't support a NOFOLLOW flag atm, and
if hdr.Typeflag != tar.TypeSymlink {
if err := syscall.UtimesNano(path, ts); err != nil {
return err
}
} else {
if err := LUtimesNano(path, ts); err != nil {
return err
}
}
}
}
}
// Step 2: walk for whiteouts and apply them, removing them in the process
err := filepath.Walk(dest, func(fullPath string, f os.FileInfo, err error) error {
if err != nil {
if os.IsNotExist(err) {
// This happens in the case of whiteouts in parent dir removing a directory
// We just ignore it
return filepath.SkipDir
}
return err
}
// Rebase path
path, err := filepath.Rel(dest, fullPath)
if err != nil {
return err
}
path = filepath.Join("/", path)
// Skip AUFS metadata
if matched, err := filepath.Match("/.wh..wh.*", path); err != nil {
return err
} else if matched {
addDir(fullPath)
if err := os.RemoveAll(fullPath); err != nil {
return err
}
}
filename := filepath.Base(path)
if strings.HasPrefix(filename, ".wh.") {
rmTargetName := filename[len(".wh."):]
rmTargetPath := filepath.Join(filepath.Dir(fullPath), rmTargetName)
// Remove the file targeted by the whiteout
addDir(rmTargetPath)
if err := os.RemoveAll(rmTargetPath); err != nil {
return err
}
// Remove the whiteout itself
addDir(fullPath)
if err := os.RemoveAll(fullPath); err != nil {
return err
}
}
return nil
})
if err != nil {
return err
}
for k, v := range modifiedDirs {
lastAccess := getLastAccess(v)
lastModification := getLastModification(v)
aTime := time.Unix(lastAccess.Unix())
mTime := time.Unix(lastModification.Unix())
if err := os.Chtimes(k, aTime, mTime); err != nil {
for _, hdr := range dirs {
path := filepath.Join(dest, hdr.Name)
ts := []syscall.Timespec{timeToTimespec(hdr.AccessTime), timeToTimespec(hdr.ModTime)}
if err := syscall.UtimesNano(path, ts); err != nil {
return err
}
}

View file

@ -9,3 +9,7 @@ func getLastAccess(stat *syscall.Stat_t) syscall.Timespec {
func getLastModification(stat *syscall.Stat_t) syscall.Timespec {
return stat.Mtimespec
}
func LUtimesNano(path string, ts []syscall.Timespec) error {
return nil
}

View file

@ -1,6 +1,9 @@
package archive
import "syscall"
import (
"syscall"
"unsafe"
)
func getLastAccess(stat *syscall.Stat_t) syscall.Timespec {
return stat.Atim
@ -9,3 +12,21 @@ func getLastAccess(stat *syscall.Stat_t) syscall.Timespec {
func getLastModification(stat *syscall.Stat_t) syscall.Timespec {
return stat.Mtim
}
func LUtimesNano(path string, ts []syscall.Timespec) error {
// These are not currently available in syscall
AT_FDCWD := -100
AT_SYMLINK_NOFOLLOW := 0x100
var _path *byte
_path, err := syscall.BytePtrFromString(path)
if err != nil {
return err
}
if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(AT_FDCWD), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(AT_SYMLINK_NOFOLLOW), 0, 0); err != 0 && err != syscall.ENOSYS {
return err
}
return nil
}

View file

@ -163,7 +163,7 @@ func Login(authConfig *AuthConfig, factory *utils.HTTPRequestFactory) (string, e
loginAgainstOfficialIndex := serverAddress == IndexServerAddress()
// to avoid sending the server address to the server it should be removed before marshalled
// to avoid sending the server address to the server it should be removed before being marshalled
authCopy := *authConfig
authCopy.ServerAddress = ""
@ -254,11 +254,11 @@ func (config *ConfigFile) ResolveAuthConfig(registry string) AuthConfig {
// default to the index server
return config.Configs[IndexServerAddress()]
}
// if its not the index server there are three cases:
// if it's not the index server there are three cases:
//
// 1. this is a full config url -> it should be used as is
// 2. it could be a full url, but with the wrong protocol
// 3. it can be the hostname optionally with a port
// 1. a full config url -> it should be used as is
// 2. a full url, but with the wrong protocol
// 3. a hostname, with an optional port
//
// as there is only one auth entry which is fully qualified we need to start
// parsing and matching

View file

@ -1,7 +1,10 @@
package docker
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/auth"
@ -11,11 +14,17 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"reflect"
"regexp"
"sort"
"strings"
)
var (
ErrDockerfileEmpty = errors.New("Dockerfile cannot be empty")
)
type BuildFile interface {
Build(io.Reader) (string, error)
CmdFrom(string) error
@ -26,10 +35,13 @@ type buildFile struct {
runtime *Runtime
srv *Server
image string
maintainer string
config *Config
context string
image string
maintainer string
config *Config
contextPath string
context *utils.TarSum
verbose bool
utilizeCache bool
rm bool
@ -87,6 +99,27 @@ func (b *buildFile) CmdMaintainer(name string) error {
return b.commit("", b.config.Cmd, fmt.Sprintf("MAINTAINER %s", name))
}
// probeCache checks to see if image-caching is enabled (`b.utilizeCache`)
// and if so attempts to look up the current `b.image` and `b.config` pair
// in the current server `b.srv`. If an image is found, probeCache returns
// `(true, nil)`. If no image is found, it returns `(false, nil)`. If there
// is any error, it returns `(false, err)`.
func (b *buildFile) probeCache() (bool, error) {
if b.utilizeCache {
if cache, err := b.srv.ImageGetCached(b.image, b.config); err != nil {
return false, err
} else if cache != nil {
fmt.Fprintf(b.outStream, " ---> Using cache\n")
utils.Debugf("[BUILDER] Use cached version")
b.image = cache.ID
return true, nil
} else {
utils.Debugf("[BUILDER] Cache miss")
}
}
return false, nil
}
func (b *buildFile) CmdRun(args string) error {
if b.image == "" {
return fmt.Errorf("Please provide a source image with `from` prior to run")
@ -104,17 +137,12 @@ func (b *buildFile) CmdRun(args string) error {
utils.Debugf("Command to be executed: %v", b.config.Cmd)
if b.utilizeCache {
if cache, err := b.srv.ImageGetCached(b.image, b.config); err != nil {
return err
} else if cache != nil {
fmt.Fprintf(b.outStream, " ---> Using cache\n")
utils.Debugf("[BUILDER] Use cached version")
b.image = cache.ID
return nil
} else {
utils.Debugf("[BUILDER] Cache miss")
}
hit, err := b.probeCache()
if err != nil {
return err
}
if hit {
return nil
}
cid, err := b.run()
@ -260,44 +288,27 @@ func (b *buildFile) CmdVolume(args string) error {
return nil
}
func (b *buildFile) addRemote(container *Container, orig, dest string) error {
file, err := utils.Download(orig)
func (b *buildFile) checkPathForAddition(orig string) error {
origPath := path.Join(b.contextPath, orig)
if !strings.HasPrefix(origPath, b.contextPath) {
return fmt.Errorf("Forbidden path outside the build context: %s (%s)", orig, origPath)
}
_, err := os.Stat(origPath)
if err != nil {
return err
return fmt.Errorf("%s: no such file or directory", orig)
}
defer file.Body.Close()
// If the destination is a directory, figure out the filename.
if strings.HasSuffix(dest, "/") {
u, err := url.Parse(orig)
if err != nil {
return err
}
path := u.Path
if strings.HasSuffix(path, "/") {
path = path[:len(path)-1]
}
parts := strings.Split(path, "/")
filename := parts[len(parts)-1]
if filename == "" {
return fmt.Errorf("cannot determine filename from url: %s", u)
}
dest = dest + filename
}
return container.Inject(file.Body, dest)
return nil
}
func (b *buildFile) addContext(container *Container, orig, dest string) error {
origPath := path.Join(b.context, orig)
destPath := path.Join(container.RootfsPath(), dest)
var (
origPath = path.Join(b.contextPath, orig)
destPath = path.Join(container.RootfsPath(), dest)
)
// Preserve the trailing '/'
if strings.HasSuffix(dest, "/") {
destPath = destPath + "/"
}
if !strings.HasPrefix(origPath, b.context) {
return fmt.Errorf("Forbidden path outside the build context: %s (%s)", orig, origPath)
}
fi, err := os.Stat(origPath)
if err != nil {
return fmt.Errorf("%s: no such file or directory", orig)
@ -321,7 +332,7 @@ func (b *buildFile) addContext(container *Container, orig, dest string) error {
}
func (b *buildFile) CmdAdd(args string) error {
if b.context == "" {
if b.context == nil {
return fmt.Errorf("No context given. Impossible to use ADD")
}
tmp := strings.SplitN(args, " ", 2)
@ -341,8 +352,90 @@ func (b *buildFile) CmdAdd(args string) error {
cmd := b.config.Cmd
b.config.Cmd = []string{"/bin/sh", "-c", fmt.Sprintf("#(nop) ADD %s in %s", orig, dest)}
b.config.Image = b.image
// FIXME: do we really need this?
var (
origPath = orig
destPath = dest
)
if utils.IsURL(orig) {
resp, err := utils.Download(orig)
if err != nil {
return err
}
tmpDirName, err := ioutil.TempDir(b.contextPath, "docker-remote")
if err != nil {
return err
}
tmpFileName := path.Join(tmpDirName, "tmp")
tmpFile, err := os.OpenFile(tmpFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if err != nil {
return err
}
defer os.RemoveAll(tmpDirName)
if _, err = io.Copy(tmpFile, resp.Body); err != nil {
return err
}
origPath = path.Join(filepath.Base(tmpDirName), filepath.Base(tmpFileName))
tmpFile.Close()
// If the destination is a directory, figure out the filename.
if strings.HasSuffix(dest, "/") {
u, err := url.Parse(orig)
if err != nil {
return err
}
path := u.Path
if strings.HasSuffix(path, "/") {
path = path[:len(path)-1]
}
parts := strings.Split(path, "/")
filename := parts[len(parts)-1]
if filename == "" {
return fmt.Errorf("cannot determine filename from url: %s", u)
}
destPath = dest + filename
}
}
if err := b.checkPathForAddition(origPath); err != nil {
return err
}
// Hash path and check the cache
if b.utilizeCache {
var (
hash string
sums = b.context.GetSums()
)
if fi, err := os.Stat(path.Join(b.contextPath, origPath)); err != nil {
return err
} else if fi.IsDir() {
var subfiles []string
for file, sum := range sums {
if strings.HasPrefix(file, origPath) {
subfiles = append(subfiles, sum)
}
}
sort.Strings(subfiles)
hasher := sha256.New()
hasher.Write([]byte(strings.Join(subfiles, ",")))
hash = "dir:" + hex.EncodeToString(hasher.Sum(nil))
} else {
hash = "file:" + sums[origPath]
}
b.config.Cmd = []string{"/bin/sh", "-c", fmt.Sprintf("#(nop) ADD %s in %s", hash, dest)}
hit, err := b.probeCache()
if err != nil {
return err
}
if hit {
return nil
}
}
// Create the container and start it
container, _, err := b.runtime.Create(b.config, "")
if err != nil {
@ -355,14 +448,8 @@ func (b *buildFile) CmdAdd(args string) error {
}
defer container.Unmount()
if utils.IsURL(orig) {
if err := b.addRemote(container, orig, dest); err != nil {
return err
}
} else {
if err := b.addContext(container, orig, dest); err != nil {
return err
}
if err := b.addContext(container, origPath, destPath); err != nil {
return err
}
if err := b.commit(container.ID, cmd, fmt.Sprintf("ADD %s in %s", orig, dest)); err != nil {
@ -460,17 +547,12 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
b.config.Cmd = []string{"/bin/sh", "-c", "#(nop) " + comment}
defer func(cmd []string) { b.config.Cmd = cmd }(cmd)
if b.utilizeCache {
if cache, err := b.srv.ImageGetCached(b.image, b.config); err != nil {
return err
} else if cache != nil {
fmt.Fprintf(b.outStream, " ---> Using cache\n")
utils.Debugf("[BUILDER] Use cached version")
b.image = cache.ID
return nil
} else {
utils.Debugf("[BUILDER] Cache miss")
}
hit, err := b.probeCache()
if err != nil {
return err
}
if hit {
return nil
}
container, warnings, err := b.runtime.Create(b.config, "")
@ -511,17 +593,17 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
var lineContinuation = regexp.MustCompile(`\s*\\\s*\n`)
func (b *buildFile) Build(context io.Reader) (string, error) {
// FIXME: @creack "name" is a terrible variable name
name, err := ioutil.TempDir("", "docker-build")
tmpdirPath, err := ioutil.TempDir("", "docker-build")
if err != nil {
return "", err
}
if err := archive.Untar(context, name, nil); err != nil {
b.context = &utils.TarSum{Reader: context}
if err := archive.Untar(b.context, tmpdirPath, nil); err != nil {
return "", err
}
defer os.RemoveAll(name)
b.context = name
filename := path.Join(name, "Dockerfile")
defer os.RemoveAll(tmpdirPath)
b.contextPath = tmpdirPath
filename := path.Join(tmpdirPath, "Dockerfile")
if _, err := os.Stat(filename); os.IsNotExist(err) {
return "", fmt.Errorf("Can't build a directory with no Dockerfile")
}
@ -529,6 +611,9 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
if err != nil {
return "", err
}
if len(fileBytes) == 0 {
return "", ErrDockerfileEmpty
}
dockerfile := string(fileBytes)
dockerfile = lineContinuation.ReplaceAllString(dockerfile, "")
stepN := 0

View file

@ -12,8 +12,8 @@ import (
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker/pkg/term"
"github.com/dotcloud/docker/registry"
"github.com/dotcloud/docker/term"
"github.com/dotcloud/docker/utils"
"io"
"io/ioutil"
@ -238,6 +238,10 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
}
err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), body, cli.out, headers)
if jerr, ok := err.(*utils.JSONError); ok {
// If no error code is set, default to 1
if jerr.Code == 0 {
jerr.Code = 1
}
return &utils.StatusError{Status: jerr.Message, StatusCode: jerr.Code}
}
return err
@ -469,6 +473,13 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
fmt.Fprintf(cli.out, "LXC Version: %s\n", remoteInfo.Get("LXCVersion"))
fmt.Fprintf(cli.out, "EventsListeners: %d\n", remoteInfo.GetInt("NEventsListener"))
fmt.Fprintf(cli.out, "Kernel Version: %s\n", remoteInfo.Get("KernelVersion"))
if initSha1 := remoteInfo.Get("InitSha1"); initSha1 != "" {
fmt.Fprintf(cli.out, "Init SHA1: %s\n", initSha1)
}
if initPath := remoteInfo.Get("InitPath"); initPath != "" {
fmt.Fprintf(cli.out, "Init Path: %s\n", initPath)
}
}
if len(remoteInfo.GetList("IndexServerAddress")) != 0 {
@ -1237,9 +1248,9 @@ func (cli *DockerCli) WalkTree(noTrunc bool, images *[]APIImages, byParent map[s
cli.WalkTree(noTrunc, &subimages, byParent, prefix+" ", printNode)
}
} else {
printNode(cli, noTrunc, image, prefix+"|─")
printNode(cli, noTrunc, image, prefix+"─")
if subimages, exists := byParent[image.ID]; exists {
cli.WalkTree(noTrunc, &subimages, byParent, prefix+"| ", printNode)
cli.WalkTree(noTrunc, &subimages, byParent, prefix+" ", printNode)
}
}
}
@ -1814,6 +1825,8 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co
flVolumes.Set(dstDir)
binds = append(binds, bind)
flVolumes.Delete(bind)
} else if bind == "/" {
return nil, nil, cmd, fmt.Errorf("Invalid volume: path can't be '/'")
}
}

View file

@ -128,7 +128,9 @@ func TestParseRunVolumes(t *testing.T) {
t.Fatalf("Error parsing volume flags, without volume, no volume should be present. Received %v", config.Volumes)
}
mustParse(t, "-v /")
if _, _, err := parse(t, "-v /"); err == nil {
t.Fatalf("Expected error, but got none")
}
if _, _, err := parse(t, "-v /:/"); err == nil {
t.Fatalf("Error parsing volume flags, `-v /:/` should fail but didn't")

View file

@ -18,6 +18,7 @@ type DaemonConfig struct {
DefaultIp net.IP
InterContainerCommunication bool
GraphDriver string
Mtu int
}
// ConfigFromJob creates and returns a new DaemonConfig object
@ -41,5 +42,10 @@ func ConfigFromJob(job *engine.Job) *DaemonConfig {
config.DefaultIp = net.ParseIP(job.Getenv("DefaultIp"))
config.InterContainerCommunication = job.GetenvBool("InterContainerCommunication")
config.GraphDriver = job.Getenv("GraphDriver")
if mtu := job.GetenvInt("Mtu"); mtu != -1 {
config.Mtu = mtu
} else {
config.Mtu = DefaultNetworkMtu
}
return &config
}

View file

@ -7,7 +7,8 @@ import (
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/graphdriver"
"github.com/dotcloud/docker/term"
"github.com/dotcloud/docker/mount"
"github.com/dotcloud/docker/pkg/term"
"github.com/dotcloud/docker/utils"
"github.com/kr/pty"
"io"
@ -48,7 +49,6 @@ type Container struct {
network *NetworkInterface
NetworkSettings *NetworkSettings
SysInitPath string
ResolvConfPath string
HostnamePath string
HostsPath string
@ -297,7 +297,11 @@ func (container *Container) generateEnvConfig(env []string) error {
if err != nil {
return err
}
ioutil.WriteFile(container.EnvConfigPath(), data, 0600)
p, err := container.EnvConfigPath()
if err != nil {
return err
}
ioutil.WriteFile(p, data, 0600)
return nil
}
@ -578,6 +582,7 @@ func (container *Container) Start() (err error) {
params = append(params,
"-g", network.Gateway,
"-i", fmt.Sprintf("%s/%d", network.IPAddress, network.IPPrefixLen),
"-mtu", strconv.Itoa(container.runtime.config.Mtu),
)
}
@ -681,6 +686,45 @@ func (container *Container) Start() (err error) {
}
}
root := container.RootfsPath()
envPath, err := container.EnvConfigPath()
if err != nil {
return err
}
// Mount docker specific files into the containers root fs
if err := mount.Mount(runtime.sysInitPath, path.Join(root, "/.dockerinit"), "none", "bind,ro"); err != nil {
return err
}
if err := mount.Mount(envPath, path.Join(root, "/.dockerenv"), "none", "bind,ro"); err != nil {
return err
}
if err := mount.Mount(container.ResolvConfPath, path.Join(root, "/etc/resolv.conf"), "none", "bind,ro"); err != nil {
return err
}
if container.HostnamePath != "" && container.HostsPath != "" {
if err := mount.Mount(container.HostnamePath, path.Join(root, "/etc/hostname"), "none", "bind,ro"); err != nil {
return err
}
if err := mount.Mount(container.HostsPath, path.Join(root, "/etc/hosts"), "none", "bind,ro"); err != nil {
return err
}
}
// Mount user specified volumes
for r, v := range container.Volumes {
mountAs := "ro"
if container.VolumesRW[v] {
mountAs = "rw"
}
if err := mount.Mount(v, path.Join(root, r), "none", fmt.Sprintf("bind,%s", mountAs)); err != nil {
return err
}
}
container.cmd = exec.Command(params[0], params[1:]...)
// Setup logging of stdout and stderr to disk
@ -836,7 +880,7 @@ func (container *Container) createVolumes() error {
volPath = path.Join(container.RootfsPath(), volPath)
rootVolPath, err := utils.FollowSymlinkInScope(volPath, container.RootfsPath())
if err != nil {
panic(err)
return err
}
if _, err := os.Stat(rootVolPath); err != nil {
@ -1358,6 +1402,32 @@ func (container *Container) GetImage() (*Image, error) {
}
func (container *Container) Unmount() error {
var (
err error
root = container.RootfsPath()
mounts = []string{
path.Join(root, "/.dockerinit"),
path.Join(root, "/.dockerenv"),
path.Join(root, "/etc/resolv.conf"),
}
)
if container.HostnamePath != "" && container.HostsPath != "" {
mounts = append(mounts, path.Join(root, "/etc/hostname"), path.Join(root, "/etc/hosts"))
}
for r := range container.Volumes {
mounts = append(mounts, path.Join(root, r))
}
for _, m := range mounts {
if lastError := mount.Unmount(m); lastError != nil {
err = lastError
}
}
if err != nil {
return err
}
return container.runtime.Unmount(container)
}
@ -1377,8 +1447,20 @@ func (container *Container) jsonPath() string {
return path.Join(container.root, "config.json")
}
func (container *Container) EnvConfigPath() string {
return path.Join(container.root, "config.env")
func (container *Container) EnvConfigPath() (string, error) {
p := path.Join(container.root, "config.env")
if _, err := os.Stat(p); err != nil {
if os.IsNotExist(err) {
f, err := os.Create(p)
if err != nil {
return "", err
}
f.Close()
} else {
return "", err
}
}
return p, nil
}
func (container *Container) lxcConfigPath() string {

View file

@ -4,7 +4,7 @@
#
# This script provides supports completion of:
# - commands and their options
# - container ids
# - container ids and names
# - image repos and tags
# - filepaths
#
@ -25,21 +25,24 @@ __docker_containers_all()
{
local containers
containers="$( docker ps -a -q )"
COMPREPLY=( $( compgen -W "$containers" -- "$cur" ) )
names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) )
}
__docker_containers_running()
{
local containers
containers="$( docker ps -q )"
COMPREPLY=( $( compgen -W "$containers" -- "$cur" ) )
names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) )
}
__docker_containers_stopped()
{
local containers
containers="$( comm -13 <(docker ps -q | sort -u) <(docker ps -a -q | sort -u) )"
COMPREPLY=( $( compgen -W "$containers" -- "$cur" ) )
names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) )
}
__docker_image_repos()
@ -70,8 +73,9 @@ __docker_containers_and_images()
{
local containers images
containers="$( docker ps -a -q )"
names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
images="$( docker images | awk 'NR>1{print $1":"$2}' )"
COMPREPLY=( $( compgen -W "$images $containers" -- "$cur" ) )
COMPREPLY=( $( compgen -W "$images $names $containers" -- "$cur" ) )
__ltrim_colon_completions "$cur"
}

View file

@ -144,9 +144,9 @@ if [ -z "$strictDebootstrap" ]; then
echo 'force-unsafe-io' | sudo tee etc/dpkg/dpkg.cfg.d/02apt-speedup > /dev/null
# we want to effectively run "apt-get clean" after every install to keep images small (see output of "apt-get clean -s" for context)
{
aptGetClean='rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true'
echo 'DPkg::Post-Invoke { "'$aptGetClean'"; };'
echo 'APT::Update::Post-Invoke { "'$aptGetClean'"; };'
aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";'
echo "DPkg::Post-Invoke { ${aptGetClean} };"
echo "APT::Update::Post-Invoke { ${aptGetClean} };"
echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";'
} | sudo tee etc/apt/apt.conf.d/no-cache > /dev/null
# and remove the translations, too

View file

@ -4,6 +4,10 @@
<dict>
<key>name</key>
<string>Dockerfile</string>
<key>fileTypes</key>
<array>
<string>Dockerfile</string>
</array>
<key>patterns</key>
<array>
<dict>

View file

@ -40,6 +40,7 @@ func main() {
flInterContainerComm = flag.Bool("icc", true, "Enable inter-container communication")
flGraphDriver = flag.String("s", "", "Force the docker runtime to use a specific storage driver")
flHosts = docker.NewListOpts(docker.ValidateHost)
flMtu = flag.Int("mtu", docker.DefaultNetworkMtu, "Set the containers network mtu")
)
flag.Var(&flDns, "dns", "Force docker to use specific DNS servers")
flag.Var(&flHosts, "H", "Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise")
@ -51,8 +52,13 @@ func main() {
return
}
if flHosts.Len() == 0 {
// If we do not have a host, default to unix socket
flHosts.Set(fmt.Sprintf("unix://%s", docker.DEFAULTUNIXSOCKET))
defaultHost := os.Getenv("DOCKER_HOST")
if defaultHost == "" || *flDaemon {
// If we do not have a host, default to unix socket
defaultHost = fmt.Sprintf("unix://%s", docker.DEFAULTUNIXSOCKET)
}
flHosts.Set(defaultHost)
}
if *bridgeName != "" && *bridgeIp != "" {
@ -69,6 +75,7 @@ func main() {
flag.Usage()
return
}
eng, err := engine.New(*flRoot)
if err != nil {
log.Fatal(err)
@ -86,6 +93,7 @@ func main() {
job.Setenv("DefaultIp", *flDefaultIp)
job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
job.Setenv("GraphDriver", *flGraphDriver)
job.SetenvInt("Mtu", *flMtu)
if err := job.Run(); err != nil {
log.Fatal(err)
}

View file

@ -46,7 +46,7 @@ directory:
* Linux: `pip install -r docs/requirements.txt`
* Mac OS X: `[sudo] pip-2.7 -r docs/requirements.txt`
* Mac OS X: `[sudo] pip-2.7 install -r docs/requirements.txt`
###Alternative Installation: Docker Container

View file

@ -26,10 +26,10 @@ Docker Remote API
2. Versions
===========
The current version of the API is 1.7
The current version of the API is 1.8
Calling /images/<name>/insert is the same as calling
/v1.7/images/<name>/insert
/v1.8/images/<name>/insert
You can still call an old version of the api using
/v1.0/images/<name>/insert

View file

@ -1078,7 +1078,7 @@ Monitor Docker's events
.. sourcecode:: http
POST /events?since=1374067924
GET /events?since=1374067924
**Example response**:

View file

@ -1122,7 +1122,7 @@ Monitor Docker's events
.. sourcecode:: http
POST /events?since=1374067924
GET /events?since=1374067924
**Example response**:

View file

@ -1093,7 +1093,7 @@ Monitor Docker's events
.. sourcecode:: http
POST /events?since=1374067924
GET /events?since=1374067924
**Example response**:

View file

@ -1228,7 +1228,7 @@ Monitor Docker's events
.. sourcecode:: http
POST /events?since=1374067924
GET /events?since=1374067924
**Example response**:

View file

@ -122,7 +122,6 @@ Create a container
"AttachStdout":true,
"AttachStderr":true,
"PortSpecs":null,
"Privileged": false,
"Tty":false,
"OpenStdin":false,
"StdinOnce":false,
@ -136,10 +135,12 @@ Create a container
"/tmp": {}
},
"VolumesFrom":"",
"WorkingDir":""
"WorkingDir":"",
"ExposedPorts":{
"22/tcp": {}
}
}
**Example response**:
.. sourcecode:: http
@ -364,10 +365,11 @@ Start a container
{
"Binds":["/tmp:/tmp"],
"LxcConf":{"lxc.utsname":"docker"},
"PortBindings":null
"PortBindings":{ "22/tcp": [{ "HostPort": "11022" }] },
"Privileged":false,
"PublishAllPorts":false
}
Binds need to reference Volumes that were defined during container creation.
**Example response**:
@ -1159,7 +1161,7 @@ Monitor Docker's events
.. sourcecode:: http
POST /events?since=1374067924
GET /events?since=1374067924
**Example response**:

View file

@ -122,7 +122,6 @@ Create a container
"AttachStdout":true,
"AttachStderr":true,
"PortSpecs":null,
"Privileged": false,
"Tty":false,
"OpenStdin":false,
"StdinOnce":false,
@ -132,12 +131,16 @@ Create a container
],
"Dns":null,
"Image":"base",
"Volumes":{},
"Volumes":{
"/tmp": {}
},
"VolumesFrom":"",
"WorkingDir":""
"WorkingDir":"",
"ExposedPorts":{
"22/tcp": {}
}
}
**Example response**:
.. sourcecode:: http
@ -151,6 +154,7 @@ Create a container
}
:jsonparam config: the container's configuration
:query name: Assign the specified name to the container. Must match ``/?[a-zA-Z0-9_-]+``.
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 406: impossible to attach (container not running)
@ -377,7 +381,10 @@ Start a container
{
"Binds":["/tmp:/tmp"],
"LxcConf":{"lxc.utsname":"docker"}
"LxcConf":{"lxc.utsname":"docker"},
"PortBindings":{ "22/tcp": [{ "HostPort": "11022" }] },
"PublishAllPorts":false,
"Privileged":false
}
**Example response**:
@ -1173,7 +1180,7 @@ Monitor Docker's events
.. sourcecode:: http
POST /events?since=1374067924
GET /events?since=1374067924
**Example response**:

View file

@ -19,7 +19,8 @@ Docker Registry API
- It doesnt have a local database
- It will be open-sourced at some point
We expect that there will be multiple registries out there. To help to grasp the context, here are some examples of registries:
We expect that there will be multiple registries out there. To help to grasp
the context, here are some examples of registries:
- **sponsor registry**: such a registry is provided by a third-party hosting infrastructure as a convenience for their customers and the docker community as a whole. Its costs are supported by the third party, but the management and operation of the registry are supported by dotCloud. It features read/write access, and delegates authentication and authorization to the Index.
- **mirror registry**: such a registry is provided by a third-party hosting infrastructure but is targeted at their customers only. Some mechanism (unspecified to date) ensures that public images are pulled from a sponsor registry to the mirror registry, to make sure that the customers of the third-party provider can “docker pull” those images locally.
@ -37,7 +38,10 @@ We expect that there will be multiple registries out there. To help to grasp the
- local mount point;
- remote docker addressed through SSH.
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).
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).
2. Endpoints
============

View file

@ -15,11 +15,13 @@ Registry & Index Spec
---------
The Index is responsible for centralizing information about:
- User accounts
- Checksums of the images
- Public namespaces
The Index has different components:
- Web UI
- Meta-data store (comments, stars, list public repositories)
- Authentication service
@ -27,7 +29,7 @@ The Index has different components:
The index is authoritative for those information.
We expect that there will be only one instance of the index, run and managed by dotCloud.
We expect that there will be only one instance of the index, run and managed by Docker Inc.
1.2 Registry
------------
@ -53,12 +55,16 @@ We expect that there will be multiple registries out there. To help to grasp the
- local mount point;
- remote docker addressed through SSH.
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).
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).
1.3 Docker
----------
On top of being a runtime for LXC, Docker is the Registry client. It supports:
- Push / Pull on the registry
- Client authentication on the Index
@ -72,21 +78,33 @@ On top of being a runtime for LXC, Docker is the Registry client. It supports:
1. Contact the Index to know where I should download “samalba/busybox”
2. Index replies:
a. “samalba/busybox” is on Registry A
b. here are the checksums for “samalba/busybox” (for all layers)
a. ``samalba/busybox`` is on Registry A
b. here are the checksums for ``samalba/busybox`` (for all layers)
c. token
3. Contact Registry A to receive the layers for “samalba/busybox” (all of them to the base image). Registry A is authoritative for “samalba/busybox” but keeps a copy of all inherited layers and serve them all from the same location.
3. Contact Registry A to receive the layers for ``samalba/busybox`` (all of them to the base image). Registry A is authoritative for “samalba/busybox” but keeps a copy of all inherited layers and serve them all from the same location.
4. registry contacts index to verify if token/user is allowed to download images
5. Index returns true/false lettings registry know if it should proceed or error out
6. Get the payload for all layers
Its possible to run docker pull \https://<registry>/repositories/samalba/busybox. In this case, docker bypasses the Index. However the security is not guaranteed (in case Registry A is corrupted) because there wont be any checksum checks.
It's possible to run:
Currently registry redirects to s3 urls for downloads, going forward all downloads need to be streamed through the registry. The Registry will then abstract the calls to S3 by a top-level class which implements sub-classes for S3 and local storage.
.. code-block:: bash
Token is only returned when the 'X-Docker-Token' header is sent with request.
docker pull https://<registry>/repositories/samalba/busybox
Basic Auth is required to pull private repos. Basic auth isn't required for pulling public repos, but if one is provided, it needs to be valid and for an active account.
In this case, Docker bypasses the Index. However the security is not guaranteed
(in case Registry A is corrupted) because there wont be any checksum checks.
Currently registry redirects to s3 urls for downloads, going forward all
downloads need to be streamed through the registry. The Registry will then
abstract the calls to S3 by a top-level class which implements sub-classes for
S3 and local storage.
Token is only returned when the ``X-Docker-Token`` header is sent with request.
Basic Auth is required to pull private repos. Basic auth isn't required for
pulling public repos, but if one is provided, it needs to be valid and for an
active account.
API (pulling repository foo/bar):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -155,7 +173,9 @@ API (pulling repository foo/bar):
**Index can be replaced!** For a private Registry deployed, a custom Index can be used to serve and validate token according to different policies.
Docker computes the checksums and submit them to the Index at the end of the push. When a repository name does not have checksums on the Index, it means that the push is in progress (since checksums are submitted at the end).
Docker computes the checksums and submit them to the Index at the end of the
push. When a repository name does not have checksums on the Index, it means
that the push is in progress (since checksums are submitted at the end).
API (pushing repos foo/bar):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -237,10 +257,11 @@ API (pushing repos foo/bar):
2.3 Delete
----------
If you need to delete something from the index or registry, we need a nice clean way to do that. Here is the workflow.
If you need to delete something from the index or registry, we need a nice
clean way to do that. Here is the workflow.
1. Docker contacts the index to request a delete of a repository “samalba/busybox” (authentication required with user credentials)
2. If authentication works and repository is valid, “samalba/busybox” is marked as deleted and a temporary token is returned
1. Docker contacts the index to request a delete of a repository ``samalba/busybox`` (authentication required with user credentials)
2. If authentication works and repository is valid, ``samalba/busybox`` is marked as deleted and a temporary token is returned
3. Send a delete request to the registry for the repository (along with the token)
4. Registry A contacts the Index to verify the token (token must corresponds to the repository name)
5. Index validates the token. Registry A deletes the repository and everything associated to it.
@ -312,24 +333,40 @@ The Index has two main purposes (along with its fancy social features):
3.1 Without an Index
--------------------
Using the Registry without the Index can be useful to store the images on a private network without having to rely on an external entity controlled by dotCloud.
In this case, the registry will be launched in a special mode (--standalone? --no-index?). In this mode, the only thing which changes is that Registry will never contact the Index to verify a token. It will be the Registry owner responsibility to authenticate the user who pushes (or even pulls) an image using any mechanism (HTTP auth, IP based, etc...).
Using the Registry without the Index can be useful to store the images on a
private network without having to rely on an external entity controlled by
Docker Inc.
In this scenario, the Registry is responsible for the security in case of data corruption since the checksums are not delivered by a trusted entity.
In this case, the registry will be launched in a special mode (--standalone?
--no-index?). In this mode, the only thing which changes is that Registry will
never contact the Index to verify a token. It will be the Registry owner
responsibility to authenticate the user who pushes (or even pulls) an image
using any mechanism (HTTP auth, IP based, etc...).
As hinted previously, a standalone registry can also be implemented by any HTTP server handling GET/PUT requests (or even only GET requests if no write access is necessary).
In this scenario, the Registry is responsible for the security in case of data
corruption since the checksums are not delivered by a trusted entity.
As hinted previously, a standalone registry can also be implemented by any HTTP
server handling GET/PUT requests (or even only GET requests if no write access
is necessary).
3.2 With an Index
-----------------
The Index data needed by the Registry are simple:
- Serve the checksums
- Provide and authorize a Token
In the scenario of a Registry running on a private network with the need of centralizing and authorizing, its easy to use a custom Index.
In the scenario of a Registry running on a private network with the need of
centralizing and authorizing, its easy to use a custom Index.
The only challenge will be to tell Docker to contact (and trust) this custom Index. Docker will be configurable at some point to use a specific Index, itll be the private entity responsibility (basically the organization who uses Docker in a private environment) to maintain the Index and the Dockers configuration among its consumers.
The only challenge will be to tell Docker to contact (and trust) this custom
Index. Docker will be configurable at some point to use a specific Index, itll
be the private entity responsibility (basically the organization who uses
Docker in a private environment) to maintain the Index and the Dockers
configuration among its consumers.
4. The API
==========
@ -339,16 +376,22 @@ The first version of the api is available here: https://github.com/jpetazzo/dock
4.1 Images
----------
The format returned in the images is not defined here (for layer and json), basically because Registry stores exactly the same kind of information as Docker uses to manage them.
The format returned in the images is not defined here (for layer and JSON),
basically because Registry stores exactly the same kind of information as
Docker uses to manage them.
The format of ancestry is a line-separated list of image ids, in age order. I.e. the images parent is on the last line, the parent of the parent on the next-to-last line, etc.; if the image has no parent, the file is empty.
The format of ancestry is a line-separated list of image ids, in age order,
i.e. the images parent is on the last line, the parent of the parent on the
next-to-last line, etc.; if the image has no parent, the file is empty.
GET /v1/images/<image_id>/layer
PUT /v1/images/<image_id>/layer
GET /v1/images/<image_id>/json
PUT /v1/images/<image_id>/json
GET /v1/images/<image_id>/ancestry
PUT /v1/images/<image_id>/ancestry
.. code-block:: bash
GET /v1/images/<image_id>/layer
PUT /v1/images/<image_id>/layer
GET /v1/images/<image_id>/json
PUT /v1/images/<image_id>/json
GET /v1/images/<image_id>/ancestry
PUT /v1/images/<image_id>/ancestry
4.2 Users
---------
@ -393,7 +436,9 @@ PUT /v1/users/<username>
4.2.3 Login (Index)
^^^^^^^^^^^^^^^^^^^
Does nothing else but asking for a user authentication. Can be used to validate credentials. HTTP Basic Auth for now, maybe change in future.
Does nothing else but asking for a user authentication. Can be used to validate
credentials. HTTP Basic Auth for now, maybe change in future.
GET /v1/users
@ -405,7 +450,10 @@ GET /v1/users
4.3 Tags (Registry)
-------------------
The Registry does not know anything about users. Even though repositories are under usernames, its just a namespace for the registry. Allowing us to implement organizations or different namespaces per user later, without modifying the Registrys API.
The Registry does not know anything about users. Even though repositories are
under usernames, its just a namespace for the registry. Allowing us to
implement organizations or different namespaces per user later, without
modifying the Registrys API.
The following naming restrictions apply:
@ -439,7 +487,10 @@ DELETE /v1/repositories/<namespace>/<repo_name>/tags/<tag>
4.4 Images (Index)
------------------
For the Index to “resolve” the repository name to a Registry location, it uses the X-Docker-Endpoints header. In other terms, this requests always add a “X-Docker-Endpoints” to indicate the location of the registry which hosts this repository.
For the Index to “resolve” the repository name to a Registry location, it uses
the X-Docker-Endpoints header. In other terms, this requests always add a
``X-Docker-Endpoints`` to indicate the location of the registry which hosts this
repository.
4.4.1 Get the images
^^^^^^^^^^^^^^^^^^^^^
@ -484,17 +535,20 @@ Return 202 OK
======================
Its possible to chain Registries server for several reasons:
- Load balancing
- Delegate the next request to another server
When a Registry is a reference for a repository, it should host the entire images chain in order to avoid breaking the chain during the download.
When a Registry is a reference for a repository, it should host the entire
images chain in order to avoid breaking the chain during the download.
The Index and Registry use this mechanism to redirect on one or the other.
Example with an image download:
On every request, a special header can be returned:
X-Docker-Endpoints: server1,server2
On every request, a special header can be returned::
X-Docker-Endpoints: server1,server2
On the next request, the client will always pick a server from this list.
@ -504,7 +558,8 @@ On the next request, the client will always pick a server from this list.
6.1 On the Index
-----------------
The Index supports both “Basic” and “Token” challenges. Usually when there is a “401 Unauthorized”, the Index replies this::
The Index supports both “Basic” and “Token” challenges. Usually when there is a
``401 Unauthorized``, the Index replies this::
401 Unauthorized
WWW-Authenticate: Basic realm="auth required",Token
@ -543,11 +598,13 @@ The Registry only supports the Token challenge::
401 Unauthorized
WWW-Authenticate: Token
The only way is to provide a token on “401 Unauthorized” responses::
The only way is to provide a token on ``401 Unauthorized`` responses::
Authorization: Token signature=123abc,repository=”foo/bar”,access=read
Authorization: Token signature=123abc,repository="foo/bar",access=read
Usually, the Registry provides a Cookie when a Token verification succeeded. Every time the Registry passes a Cookie, you have to pass it back the same cookie.::
Usually, the Registry provides a Cookie when a Token verification succeeded.
Every time the Registry passes a Cookie, you have to pass it back the same
cookie.::
200 OK
Set-Cookie: session="wD/J7LqL5ctqw8haL10vgfhrb2Q=?foo=UydiYXInCnAxCi4=&timestamp=RjEzNjYzMTQ5NDcuNDc0NjQzCi4="; Path=/; HttpOnly

View file

@ -12,7 +12,7 @@ To list available commands, either run ``docker`` with no parameters or execute
$ sudo docker
Usage: docker [OPTIONS] COMMAND [arg...]
-H=[unix:///var/run/docker.sock]: tcp://host:port to bind/connect to or unix://path/to/socket to use
-H=[unix:///var/run/docker.sock]: tcp://[host[:port]] to bind/connect to or unix://[/path/to/socket] to use. When host=[0.0.0.0], port=[4243] or path=[/var/run/docker.sock] is omitted, default values are used.
A self-sufficient runtime for linux containers.
@ -27,7 +27,7 @@ To list available commands, either run ``docker`` with no parameters or execute
Usage of docker:
-D=false: Enable debug mode
-H=[unix:///var/run/docker.sock]: Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise
-H=[unix:///var/run/docker.sock]: tcp://[host[:port]] to bind or unix://[/path/to/socket] to use. When host=[0.0.0.0], port=[4243] or path=[/var/run/docker.sock] is omitted, default values are used.
-api-enable-cors=false: Enable CORS headers in the remote API
-b="": Attach containers to a pre-existing network bridge; use 'none' to disable container networking
-bip="": Use the provided CIDR notation address for the dynamically created bridge (docker0); Mutually exclusive of -b
@ -37,19 +37,32 @@ To list available commands, either run ``docker`` with no parameters or execute
-icc=true: Enable inter-container communication
-ip="0.0.0.0": Default IP address to use when binding container ports
-iptables=true: Disable docker's addition of iptables rules
-mtu=1500: Set the containers network mtu
-p="/var/run/docker.pid": Path to use for daemon PID file
-r=true: Restart previously running containers
-s="": Force the docker runtime to use a specific storage driver
-v=false: Print version information and quit
The docker daemon is the persistent process that manages containers. Docker uses the same binary for both the
The Docker daemon is the persistent process that manages containers. Docker uses the same binary for both the
daemon and client. To run the daemon you provide the ``-d`` flag.
To force docker to use devicemapper as the storage driver, use ``docker -d -s devicemapper``
To force Docker to use devicemapper as the storage driver, use ``docker -d -s devicemapper``.
To set the dns server for all docker containers, use ``docker -d -dns 8.8.8.8``
To set the DNS server for all Docker containers, use ``docker -d -dns 8.8.8.8``.
To run the daemon with debug output, use ``docker -d -D``.
The docker client will also honor the ``DOCKER_HOST`` environment variable to set
the ``-H`` flag for the client.
::
docker -H tcp://0.0.0.0:4243 ps
# or
export DOCKER_HOST="tcp://0.0.0.0:4243"
docker ps
# both are equal
To run the daemon with debug output, use ``docker -d -D``
.. _cli_attach:
@ -68,11 +81,11 @@ To run the daemon with debug output, use ``docker -d -D``
You can detach from the container again (and leave it running) with
``CTRL-c`` (for a quiet exit) or ``CTRL-\`` to get a stacktrace of
the Docker client when it quits. When you detach from the container's
process the exit code will be retuned to the client.
process the exit code will be returned to the client.
To stop a container, use ``docker stop``
To stop a container, use ``docker stop``.
To kill the container, use ``docker kill``
To kill the container, use ``docker kill``.
.. _cli_attach_examples:
@ -128,12 +141,11 @@ Examples:
-no-cache: Do not use the cache when building the image.
-rm: Remove intermediate containers after a successful build
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 :ref:`ADD <dockerfile_add>` instruction. When a
single ``Dockerfile`` is given as URL, then no context is set. When a
git repository is set as URL, then the repository is used as the
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 :ref:`ADD <dockerfile_add>` instruction. When a single ``Dockerfile``
is given as ``URL``, then no context is set. When a Git repository is set as
``URL``, then the repository is used as the context
.. _cli_build_examples:
@ -168,13 +180,13 @@ Examples:
---> f52f38b7823e
Successfully built f52f38b7823e
This example specifies that the PATH is ``.``, and so all the files in
the local directory get tar'd and sent to the Docker daemon. The PATH
This example specifies that the ``PATH`` is ``.``, and so all the files in
the local directory get tar'd and sent to the Docker daemon. The ``PATH``
specifies where to find the files for the "context" of the build on
the Docker daemon. Remember that the daemon could be running on a
remote machine and that no parsing of the Dockerfile happens at the
remote machine and that no parsing of the ``Dockerfile`` happens at the
client side (where you're running ``docker build``). That means that
*all* the files at PATH get sent, not just the ones listed to
*all* the files at ``PATH`` get sent, not just the ones listed to
:ref:`ADD <dockerfile_add>` in the ``Dockerfile``.
The transfer of context from the local machine to the Docker daemon is
@ -197,16 +209,16 @@ tag will be ``2.0``
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
to the ``docker`` daemon. Since there is no context, a ``Dockerfile``
``ADD`` only works if it refers to a remote URL.
.. code-block:: bash
$ sudo docker build github.com/creack/docker-firefox
This will clone the Github repository and use the cloned repository as
This will clone the GitHub repository and use the cloned repository as
context. The ``Dockerfile`` at the root of the repository is used as
``Dockerfile``. Note that you can specify an arbitrary git repository
``Dockerfile``. Note that you can specify an arbitrary Git repository
by using the ``git://`` schema.
@ -247,7 +259,7 @@ Change the command that a container runs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sometimes you have an application container running just a service and you need
to make a quick change (run bash?) and then change it back.
to make a quick change and then change it back.
In this example, we run a container with ``ls`` and then change the image to
run ``ls /etc``.
@ -270,9 +282,9 @@ Full -run example
The ``-run`` JSON hash changes the ``Config`` section when running ``docker inspect CONTAINERID``
or ``config`` when running ``docker inspect IMAGEID``.
(multiline is ok within a single quote ``'``)
(Multiline is okay within a single quote ``'``)
::
.. code-block:: bash
$ sudo docker commit -run='
{
@ -315,7 +327,7 @@ or ``config`` when running ``docker inspect IMAGEID``.
Copy files/folders from the containers filesystem to the host
path. Paths are relative to the root of the filesystem.
.. code-block:: bash
$ sudo docker cp 7bb0e258aefe:/etc/debian_version .
@ -329,7 +341,7 @@ or ``config`` when running ``docker inspect IMAGEID``.
::
Usage: docker diff CONTAINER
List the changed files and directories in a container's filesystem
There are 3 events that are listed in the 'diff':
@ -338,7 +350,7 @@ There are 3 events that are listed in the 'diff':
2. ```D``` - Delete
3. ```C``` - Change
for example:
For example:
.. code-block:: bash
@ -366,7 +378,7 @@ for example:
Usage: docker events
Get real time events from the server
-since="": Show previously created events and then stream.
(either seconds since epoch, or date string as below)
@ -429,8 +441,8 @@ Show events in the past from a specified time
Usage: docker export CONTAINER
Export the contents of a filesystem as a tar archive to STDOUT
for example:
For example:
.. code-block:: bash
@ -450,7 +462,7 @@ for example:
-notrunc=false: Don't truncate output
-q=false: only show numeric IDs
To see how the docker:latest image was built:
To see how the ``docker:latest`` image was built:
.. code-block:: bash
@ -482,7 +494,7 @@ To see how the docker:latest image was built:
d5e85dc5b1d8 2 weeks ago /bin/sh -c apt-get update
13e642467c11 2 weeks ago /bin/sh -c echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt/sources.list
ae6dde92a94e 2 weeks ago /bin/sh -c #(nop) MAINTAINER Solomon Hykes <solomon@dotcloud.com>
ubuntu:12.04 6 months ago
ubuntu:12.04 6 months ago
.. _cli_images:
@ -500,7 +512,7 @@ To see how the docker:latest image was built:
-q=false: only show numeric IDs
-tree=false: output graph in tree format
-viz=false: output graph in graphviz format
Listing the most recently created images
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -553,15 +565,15 @@ Displaying image hierarchy
$ sudo docker images -tree
|─8dbd9e392a96 Size: 131.5 MB (virtual 131.5 MB) Tags: ubuntu:12.04,ubuntu:latest,ubuntu:precise
─8dbd9e392a96 Size: 131.5 MB (virtual 131.5 MB) Tags: ubuntu:12.04,ubuntu:latest,ubuntu:precise
└─27cf78414709 Size: 180.1 MB (virtual 180.1 MB)
└─b750fe79269d Size: 24.65 kB (virtual 180.1 MB) Tags: ubuntu:12.10,ubuntu:quantal
|─f98de3b610d5 Size: 12.29 kB (virtual 180.1 MB)
| └─7da80deb7dbf Size: 16.38 kB (virtual 180.1 MB)
| └─65ed2fee0a34 Size: 20.66 kB (virtual 180.2 MB)
| └─a2b9ea53dddc Size: 819.7 MB (virtual 999.8 MB)
| └─a29b932eaba8 Size: 28.67 kB (virtual 999.9 MB)
| └─e270a44f124d Size: 12.29 kB (virtual 999.9 MB) Tags: progrium/buildstep:latest
─f98de3b610d5 Size: 12.29 kB (virtual 180.1 MB)
└─7da80deb7dbf Size: 16.38 kB (virtual 180.1 MB)
└─65ed2fee0a34 Size: 20.66 kB (virtual 180.2 MB)
└─a2b9ea53dddc Size: 819.7 MB (virtual 999.8 MB)
└─a29b932eaba8 Size: 28.67 kB (virtual 999.9 MB)
└─e270a44f124d Size: 12.29 kB (virtual 999.9 MB) Tags: progrium/buildstep:latest
└─17e74ac162d8 Size: 53.93 kB (virtual 180.2 MB)
└─339a3f56b760 Size: 24.65 kB (virtual 180.2 MB)
└─904fcc40e34d Size: 96.7 MB (virtual 276.9 MB)
@ -588,10 +600,9 @@ Displaying image hierarchy
(.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it.
At this time, the URL must start with ``http`` and point to a single
file archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) containing a
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
standard in.
archive, you can use the ``-`` parameter to take the data from *stdin*.
Examples
~~~~~~~~
@ -601,24 +612,30 @@ Import from a remote location
This will create a new untagged image.
``$ sudo docker import http://example.com/exampleimage.tgz``
.. code-block:: bash
$ sudo docker import http://example.com/exampleimage.tgz
Import from a local file
........................
Import to docker via pipe and standard in
Import to docker via pipe and *stdin*.
``$ cat exampleimage.tgz | sudo docker import - exampleimagelocal:new``
.. code-block:: bash
$ cat exampleimage.tgz | sudo docker import - exampleimagelocal:new
Import from a local directory
.............................
``$ sudo tar -c . | docker import - exampleimagedir``
.. code-block:: bash
Note the ``sudo`` in this example -- you must preserve the ownership
of the files (especially root ownership) during the archiving with
tar. If you are not root (or sudo) when you tar, then the ownerships
might not get preserved.
$ sudo tar -c . | docker import - exampleimagedir
Note the ``sudo`` in this example -- you must preserve the ownership of the
files (especially root ownership) during the archiving with tar. If you are not
root (or the sudo command) when you tar, then the ownerships might not get
preserved.
.. _cli_info:
@ -657,16 +674,16 @@ might not get preserved.
Insert a file from URL in the IMAGE at PATH
Use the specified IMAGE as the parent for a new image which adds a
:ref:`layer <layer_def>` containing the new file. ``insert`` does not modify
the original image, and the new image has the contents of the parent image,
plus the new file.
Use the specified ``IMAGE`` as the parent for a new image which adds a
:ref:`layer <layer_def>` containing the new file. The ``insert`` command does
not modify the original image, and the new image has the contents of the parent
image, plus the new file.
Examples
~~~~~~~~
Insert file from github
Insert file from GitHub
.......................
.. code-block:: bash
@ -681,16 +698,16 @@ Insert file from github
::
Usage: docker inspect [OPTIONS] CONTAINER
Usage: docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]
Return low-level information on a container
Return low-level information on a container/image
-format="": template to output results
-format="": Format the output using the given go template.
By default, this will render all results in a JSON array. If a format
is specified, the given template will be executed for each result.
Go's `text/template <http://golang.org/pkg/text/template/>` package
Go's `text/template <http://golang.org/pkg/text/template/>`_ package
describes all the details of the format.
Examples
@ -795,14 +812,14 @@ Known Issues (kill)
Fetch the logs of a container
``docker logs`` is a convenience which batch-retrieves whatever logs
are present at the time of execution. This does not guarantee
execution order when combined with a ``docker run`` (i.e. your run may
not have generated any logs at the time you execute ``docker logs``).
The ``docker logs`` command is a convenience which batch-retrieves whatever
logs are present at the time of execution. This does not guarantee execution
order when combined with a ``docker run`` (i.e. your run may not have generated
any logs at the time you execute ``docker logs``).
``docker logs -f`` combines ``docker logs`` and ``docker attach``: it
will first return all logs from the beginning and then continue
streaming new output from the container's stdout and stderr.
The ``docker logs -f`` command combines ``docker logs`` and ``docker attach``:
it will first return all logs from the beginning and then continue streaming
new output from the container's stdout and stderr.
.. _cli_port:
@ -940,7 +957,7 @@ Removing tagged images
~~~~~~~~~~~~~~~~~~~~~~
Images can be removed either by their short or long ID's, or their image names.
If an image has more than one name, each of them needs to be removed before the
If an image has more than one name, each of them needs to be removed before the
image is removed.
.. code-block:: bash
@ -952,7 +969,7 @@ image is removed.
test2 latest fd484f19954f 23 seconds ago 7 B (virtual 4.964 MB)
$ sudo docker rmi fd484f19954f
Error: Conflict, fd484f19954f wasn't deleted
Error: Conflict, cannot delete image fd484f19954f because it is tagged in multiple repositories
2013/12/11 05:47:16 Error: failed to remove one or more images
$ sudo docker rmi test1
@ -1004,13 +1021,14 @@ image is removed.
-link="": Add link to another container (name:alias)
-name="": Assign the specified name to the container. If no name is specific docker will generate a random name
-P=false: Publish all exposed ports to the host interfaces
``'docker run'`` first ``'creates'`` a writeable container layer over
the specified image, and then ``'starts'`` it using the specified
command. That is, ``'docker run'`` is equivalent to the API
``/containers/create`` then ``/containers/(id)/start``.
``docker run`` can be used in combination with ``docker commit`` to :ref:`change the command that a container runs <cli_commit_examples>`.
The ``docker run`` command first ``creates`` a writeable container layer over
the specified image, and then ``starts`` it using the specified command. That
is, ``docker run`` is equivalent to the API ``/containers/create`` then
``/containers/(id)/start``.
The ``docker run`` command can be used in combination with ``docker commit`` to
:ref:`change the command that a container runs <cli_commit_examples>`.
Known Issues (run -volumes-from)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1026,10 +1044,10 @@ Examples:
$ sudo docker run -cidfile /tmp/docker_test.cid ubuntu echo "test"
This will create a container and print "test" to the console. The
``cidfile`` flag makes docker attempt to create a new file and write the
container ID to it. If the file exists already, docker will return an
error. Docker will close this file when docker run exits.
This will create a container and print ``test`` to the console. The
``cidfile`` flag makes Docker attempt to create a new file and write the
container ID to it. If the file exists already, Docker will return an
error. Docker will close this file when ``docker run`` exits.
.. code-block:: bash
@ -1063,7 +1081,7 @@ use-cases, like running Docker within Docker.
$ sudo docker run -w /path/to/dir/ -i -t ubuntu pwd
The ``-w`` lets the command being executed inside directory given,
here /path/to/dir/. If the path does not exists it is created inside the
here ``/path/to/dir/``. If the path does not exists it is created inside the
container.
.. code-block:: bash
@ -1080,7 +1098,7 @@ using the container, but inside the current working directory.
$ sudo docker run -p 127.0.0.1:80:8080 ubuntu bash
This binds port ``8080`` of the container to port ``80`` on 127.0.0.1 of the
This binds port ``8080`` of the container to port ``80`` on ``127.0.0.1`` of the
host machine. :ref:`port_redirection` explains in detail how to manipulate ports
in Docker.
@ -1114,11 +1132,31 @@ to the newly created container.
$ sudo docker run -volumes-from 777f7dc92da7,ba8c0c54f0f2:ro -i -t ubuntu pwd
The ``-volumes-from`` flag mounts all the defined volumes from the
refrence containers. Containers can be specified by a comma seperated
referenced containers. Containers can be specified by a comma seperated
list or by repetitions of the ``-volumes-from`` argument. The container
id may be optionally suffixed with ``:ro`` or ``:rw`` to mount the volumes in
ID may be 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 (rw or ro) as the reference container.
in the same mode (read write or read only) as the reference container.
A complete example
..................
.. code-block:: bash
$ sudo docker run -d -name static static-web-files sh
$ sudo docker run -d -expose=8098 -name riak riakserver
$ sudo docker run -d -m 100m -e DEVELOPMENT=1 -e BRANCH=example-code -v $(pwd):/app/bin:ro -name app appserver
$ sudo docker run -d -p 1443:443 -dns=dns.dev.org -v /var/log/httpd -volumes-from static -link riak -link app -h www.sven.dev.org -name web webserver
$ sudo docker run -t -i -rm -volumes-from web -w /var/log/httpd busybox tail -f access.log
This example shows 5 containers that might be set up to test a web application change:
1. Start a pre-prepared volume image ``static-web-files`` (in the background) that has CSS, image and static HTML in it, (with a ``VOLUME`` instruction in the ``Dockerfile`` to allow the web server to use those files);
2. Start a pre-prepared ``riakserver`` image, give the container name ``riak`` and expose port ``8098`` to any containers that link to it;
3. Start the ``appserver`` image, restricting its memory usage to 100MB, setting two environment variables ``DEVELOPMENT`` and ``BRANCH`` and bind-mounting the current directory (``$(pwd)``) in the container in read-only mode as ``/app/bin``;
4. Start the ``webserver``, mapping port ``443`` in the container to port ``1443`` on the Docker server, setting the DNS server to ``dns.dev.org``, creating a volume to put the log files into (so we can access it from another container), then importing the files from the volume exposed by the ``static`` container, and linking to all exposed ports from ``riak`` and ``app``. Lastly, we set the hostname to ``web.sven.dev.org`` so its consistent with the pre-generated SSL certificate;
5. Finally, we create a container that runs ``tail -f access.log`` using the logs volume from the ``web`` container, setting the workdir to ``/var/log/httpd``. The ``-rm`` option means that when the container exits, the container's layer is removed.
.. _cli_save:
@ -1205,7 +1243,7 @@ The main process inside the container will receive SIGTERM, and after a grace pe
``version``
-----------
Show the version of the docker client, daemon, and latest released version.
Show the version of the Docker client, daemon, and latest released version.
.. _cli_wait:

View file

@ -136,7 +136,7 @@ You can run an interactive session in the newly built container:
Extra Step: Build and view the Documentation
-------------------------------------------
--------------------------------------------
If you want to read the documentation from a local website, or are making changes
to it, you can build the documentation and then serve it by:

View file

@ -94,5 +94,13 @@ The password is ``screencast``.
$ ifconfig
$ ssh root@192.168.33.10 -p 49154
# Thanks for watching, Thatcher thatcher@dotcloud.com
Update:
-------
For Ubuntu 13.10 using stackbrew/ubuntu, you may need do these additional steps:
1. change /etc/pam.d/sshd, pam_loginuid line 'required' to 'optional'
2. echo LANG=\"en_US.UTF-8\" > /etc/default/locale

View file

@ -111,7 +111,7 @@ What does Docker add to just plain LXC?
registry to store and transfer private containers, for internal
server deployments for example.
* *Tool ecosystem.*
* *Tool ecosystem.*
Docker defines an API for automating and customizing the
creation and deployment of containers. There are a huge number
of tools integrating with Docker to extend its
@ -122,6 +122,11 @@ What does Docker add to just plain LXC?
(Jenkins, Strider, Travis), etc. Docker is rapidly establishing
itself as the standard for container-based tooling.
What is different between a Docker container and a VM?
......................................................
There's a great StackOverflow answer `showing the differences <http://stackoverflow.com/questions/16047306/how-is-docker-io-different-from-a-normal-virtual-machine>`_.
Do I lose my data when the container exits?
...........................................
@ -129,6 +134,53 @@ Not at all! Any data that your application writes to disk gets preserved
in its container until you explicitly delete the container. The file
system for the container persists even after the container halts.
How far do Docker containers scale?
...................................
Some of the largest server farms in the world today are based on containers.
Large web deployments like Google and Twitter, and platform providers such as
Heroku and dotCloud all run on container technology, at a scale of hundreds of
thousands or even millions of containers running in parallel.
How do I connect Docker containers?
...................................
Currently the recommended way to link containers is via the `link` primitive.
You can see details of how to `work with links here
<http://docs.docker.io/en/latest/use/working_with_links_names/>`_.
Also of useful when enabling more flexible service portability is the
`Ambassador linking pattern
<http://docs.docker.io/en/latest/use/ambassador_pattern_linking/>`_.
How do I run more than one process in a Docker container?
.........................................................
Any capable process supervisor such as http://supervisord.org/, runit, s6, or
daemontools can do the trick. Docker will start up the process management
daemon which will then fork to run additional processes. As long as the
processor manager daemon continues to run, the container will continue to as
well. You can see a more substantial example `that uses supervisord here
<http://docs.docker.io/en/latest/examples/using_supervisord/>`_.
What platforms does Docker run on?
..................................
Linux:
- Ubuntu 12.04, 13.04 et al
- Fedora 19/20+
- RHEL 6.5+
- Centos 6+
- Gento
- ArchLinux
Cloud:
- Amazon EC2
- Google Compute Engine
- Rackspace
Can I help by adding some questions and answers?
................................................

View file

@ -25,7 +25,7 @@ currently in active development, so this documentation will change
frequently.
For an overview of Docker, please see the `Introduction
<http://www.docker.io>`_. When you're ready to start working with
<http://www.docker.io/learn_more/>`_. When you're ready to start working with
Docker, we have a `quick start <http://www.docker.io/gettingstarted>`_
and a more in-depth guide to :ref:`ubuntu_linux` and other
:ref:`installation_list` paths including prebuilt binaries,

View file

@ -21,6 +21,11 @@ Check Your Kernel
Your host's Linux kernel must meet the Docker :ref:`kernel`
Check for User Space Tools
--------------------------
You must have a working installation of the `lxc <http://linuxcontainers.org>`_ utilities and library.
Get the docker binary:
----------------------

View file

@ -1,6 +1,6 @@
:title: Requirements and Installation on Fedora
:description: Please note this project is currently under heavy development. It should not be used in production.
:keywords: Docker, Docker documentation, fedora, requirements, virtualbox, vagrant, git, ssh, putty, cygwin, linux
:keywords: Docker, Docker documentation, Fedora, requirements, virtualbox, vagrant, git, ssh, putty, cygwin, linux
.. _fedora:
@ -18,13 +18,34 @@ architecture.
Installation
------------
The ``docker-io`` package provides Docker on Fedora.
If you have the (unrelated) ``docker`` package installed already, it will
conflict with ``docker-io``. There's a `bug report`_ filed for it.
To proceed with ``docker-io`` installation on Fedora 19, please remove
``docker`` first.
.. code-block:: bash
sudo yum -y remove docker
For Fedora 20 and later, the ``wmdocker`` package will provide the same
functionality as ``docker`` and will also not conflict with ``docker-io``.
.. code-block:: bash
sudo yum -y install wmdocker
sudo yum -y remove docker
Install the ``docker-io`` package which will install Docker on our host.
.. code-block:: bash
sudo yum -y install docker-io
To update the ``docker-io`` package
To update the ``docker-io`` package:
.. code-block:: bash
@ -50,3 +71,5 @@ Now let's verify that Docker is working.
**Done!**, now continue with the :ref:`hello_world` example.
.. _bug report: https://bugzilla.redhat.com/show_bug.cgi?id=1043676

View file

@ -0,0 +1,80 @@
:title: Installation on FrugalWare
:description: Docker installation on FrugalWare.
:keywords: frugalware linux, virtualization, docker, documentation, installation
.. _frugalware:
FrugalWare
==========
.. include:: install_header.inc
.. include:: install_unofficial.inc
Installing on FrugalWare is handled via the official packages:
* `lxc-docker i686 <http://www.frugalware.org/packages/200141>`_
* `lxc-docker x86_64 <http://www.frugalware.org/packages/200130>`_
The `lxc-docker` package will install the latest tagged version of Docker.
Dependencies
------------
Docker depends on several packages which are specified as dependencies in
the packages. The core dependencies are:
* systemd
* lvm2
* sqlite3
* libguestfs
* lxc
* iproute2
* bridge-utils
Installation
------------
A simple
::
pacman -S lxc-docker
is all that is needed.
Starting Docker
---------------
There is a systemd service unit created for Docker. To start Docker as service:
::
sudo systemctl start lxc-docker
To start on system boot:
::
sudo systemctl enable lxc-docker
Network Configuration
---------------------
IPv4 packet forwarding is disabled by default on FrugalWare, so Internet access from inside
the container may not work.
To enable packet forwarding, run the following command as the ``root`` user on the host system:
::
sysctl net.ipv4.ip_forward=1
And, to make it persistent across reboots, add the following to a file named **/etc/sysctl.d/docker.conf**:
::
net.ipv4.ip_forward=1

View file

@ -57,9 +57,17 @@
docker-playground:~$ curl get.docker.io | bash
docker-playground:~$ sudo update-rc.d docker defaults
7. Start a new container:
7. If running in zones: us-central1-a, europe-west1-1, and europe-west1-b, the docker daemon must be started with the `-mtu` flag. Without the flag, you may experience intermittent network pauses.
`See this issue <https://code.google.com/p/google-compute-engine/issues/detail?id=57>`_ for more details.
.. code-block:: bash
docker -d -mtu 1460
8. Start a new container:
.. code-block:: bash
docker-playground:~$ sudo docker run busybox echo 'docker on GCE \o/'
docker on GCE \o/

View file

@ -22,6 +22,7 @@ Contents:
fedora
archlinux
gentoolinux
frugalware
vagrant
windows
amazon

View file

@ -115,6 +115,8 @@ Then run ``update-grub``, and reboot.
Details
-------
To automatically check some of the requirements below, you can run `lxc-checkconfig`.
Networking:
- CONFIG_BRIDGE

View file

@ -28,6 +28,15 @@ Installation
Firstly, you need to install the EPEL repository. Please follow the `EPEL installation instructions`_.
The ``docker-io`` package provides Docker on EPEL.
If you already have the (unrelated) ``docker`` package installed, it will
conflict with ``docker-io``. There's a `bug report`_ filed for it.
To proceed with ``docker-io`` installation, please remove
``docker`` first.
Next, let's install the ``docker-io`` package which will install Docker on our host.
.. code-block:: bash
@ -68,4 +77,5 @@ If you have any issues - please report them directly in the `Red Hat Bugzilla fo
.. _Extra Packages for Enterprise Linux (EPEL): https://fedoraproject.org/wiki/EPEL
.. _EPEL installation instructions: https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F
.. _Red Hat Bugzilla for docker-io component : https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=docker-io
.. _bug report: https://bugzilla.redhat.com/show_bug.cgi?id=1043676

View file

@ -9,7 +9,7 @@ Learn Basic Commands
Starting Docker
---------------
If you have used one of the quick install paths', Docker may have been
If you have used one of the quick install paths, Docker may have been
installed with upstart, Ubuntu's system for starting processes at boot
time. You should be able to run ``sudo docker help`` and get output.
@ -30,8 +30,8 @@ Download a pre-built image
# Download an ubuntu image
sudo docker pull ubuntu
This will find the ``ubuntu`` image by name in the :ref:`Central Index
<searching_central_index>` and download it from the top-level Central
This will find the ``ubuntu`` image by name in the :ref:`Central Index
<searching_central_index>` and download it from the top-level Central
Repository to a local image cache.
.. NOTE:: When the image has successfully downloaded, you will see a
@ -53,21 +53,23 @@ Running an interactive shell
.. _dockergroup:
sudo and the docker Group
-------------------------
The sudo command and the docker Group
-------------------------------------
The ``docker`` daemon always runs as root, and since ``docker``
version 0.5.2, ``docker`` binds to a Unix socket instead of a TCP
port. By default that Unix socket is owned by the user *root*, and so,
by default, you can access it with ``sudo``.
The ``docker`` daemon always runs as the root user, and since Docker version
0.5.2, the ``docker`` daemon binds to a Unix socket instead of a TCP port. By
default that Unix socket is owned by the user *root*, and so, by default, you
can access it with ``sudo``.
Starting in version 0.5.3, if you (or your Docker installer) create a
Unix group called *docker* and add users to it, then the ``docker``
daemon will make the ownership of the Unix socket read/writable by the
*docker* group when the daemon starts. The ``docker`` daemon must
always run as root, but if you run the ``docker`` client as a user in
always run as the root user, but if you run the ``docker`` client as a user in
the *docker* group then you don't need to add ``sudo`` to all the
client commands. Warning: the *docker* group is root-equivalent.
client commands.
.. warning:: The *docker* group is root-equivalent.
**Example:**
@ -97,10 +99,10 @@ Bind Docker to another host/port or a Unix socket
<https://github.com/dotcloud/docker/issues/1369>`_). Make sure you
control access to ``docker``.
With -H it is possible to make the Docker daemon to listen on a
specific ip and port. By default, it will listen on
With ``-H`` it is possible to make the Docker daemon to listen on a
specific IP and port. By default, it will listen on
``unix:///var/run/docker.sock`` to allow only local connections by the
*root* user. You *could* set it to 0.0.0.0:4243 or a specific host ip to
*root* user. You *could* set it to ``0.0.0.0:4243`` or a specific host IP to
give access to everybody, but that is **not recommended** because then
it is trivial for someone to gain root access to the host where the
daemon is running.
@ -179,10 +181,10 @@ Committing (saving) a container state
Save your containers state to a container image, so the state can be re-used.
When you commit your container only the differences between the image
the container was created from and the current state of the container
will be stored (as a diff). See which images you already have using
``sudo docker images``
When you commit your container only the differences between the image the
container was created from and the current state of the container will be
stored (as a diff). See which images you already have using the ``docker
images`` command.
.. code-block:: bash
@ -194,7 +196,5 @@ will be stored (as a diff). See which images you already have using
You now have a image state from which you can create new instances.
Read more about :ref:`working_with_the_repository` or continue to the
complete :ref:`cli`

View file

@ -251,6 +251,11 @@ All new files and directories are created with mode 0755, uid and gid
if you build using STDIN (``docker build - < somefile``), there is no build
context, so the Dockerfile can only contain an 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 authentication.
The copy obeys the following rules:
* The ``<src>`` path must be inside the *context* of the build; you cannot

View file

@ -31,7 +31,7 @@ container, Docker provide ways to bind the container port to an
interface of the host system. To simplify communication between
containers, Docker provides the linking mechanism.
Binding a port to an host interface
Binding a port to a host interface
-----------------------------------
To bind a port of the container to a specific interface of the host

View file

@ -13,7 +13,7 @@ Share Directories via Volumes
A *data volume* is a specially-designated directory within one or more
containers that bypasses the :ref:`ufs_def` to provide several useful
features for persistant or shared data:
features for persistent or shared data:
* **Data volumes can be shared and reused between containers.** This
is the feature that makes data volumes so powerful. You can use it
@ -30,35 +30,58 @@ Each container can have zero or more data volumes.
Getting Started
...............
Using data volumes is as simple as adding a new flag: ``-v``. The
parameter ``-v`` can be used more than once in order to create more
volumes within the new container. The example below shows the
instruction to create a container with two new volumes::
Using data volumes is as simple as adding a ``-v`` parameter to the ``docker run``
command. The ``-v`` parameter can be used more than once in order to
create more volumes within the new container. To create a new container with
two new volumes::
docker run -v /var/volume1 -v /var/volume2 shykes/couchdb
$ docker run -v /var/volume1 -v /var/volume2 busybox true
For a Dockerfile, the VOLUME instruction will add one or more new
volumes to any container created from the image::
This command will create the new container with two new volumes that
exits instantly (``true`` is pretty much the smallest, simplest program
that you can run). Once created you can mount its volumes in any other
container using the ``-volumes-from`` option; irrespecive of whether the
container is running or not.
VOLUME ["/var/volume1", "/var/volume2"]
Or, you can use the VOLUME instruction in a Dockerfile to add one or more new
volumes to any container created from that image::
# BUILD-USING: docker build -t data .
# RUN-USING: docker run -name DATA data
FROM busybox
VOLUME ["/var/volume1", "/var/volume2"]
CMD ["/usr/bin/true"]
Mount Volumes from an Existing Container:
-----------------------------------------
Creating and mounting a Data Volume Container
---------------------------------------------
The command below creates a new container which is running as daemon
``-d`` and with one volume ``/var/lib/couchdb``::
If you have some persistent data that you want to share between containers,
or want to use from non-persistent containers, its best to create a named
Data Volume Container, and then to mount the data from it.
COUCH1=$(sudo docker run -d -v /var/lib/couchdb shykes/couchdb:2013-05-03)
Create a named container with volumes to share (``/var/volume1`` and ``/var/volume2``)::
From the container id of that previous container ``$COUCH1`` it's
possible to create new container sharing the same volume using the
parameter ``-volumes-from container_id``::
$ docker run -v /var/volume1 -v /var/volume2 -name DATA busybox true
COUCH2=$(sudo docker run -d -volumes-from $COUCH1 shykes/couchdb:2013-05-03)
Then mount those data volumes into your application containers::
Now, the second container has the all the information from the first volume.
$ docker run -t -i -rm -volumes-from DATA -name client1 ubuntu bash
You can use multiple ``-volumes-from`` parameters to bring together multiple
data volumes from multiple containers.
Interestingly, you can mount the volumes that came from the ``DATA`` container in
yet another container via the ``client1`` middleman container::
$ docker run -t -i -rm -volumes-from client1 ubuntu -name client2 bash
This allows you to abstract the actual data source from users of that data,
similar to :ref:`ambassador_pattern_linking <ambassador_pattern_linking>`.
If you remove containers that mount volumes, including the initial DATA container,
or the middleman, the volumes will not be deleted until there are no containers still
referencing those volumes. This allows you to upgrade, or effectivly migrate data volumes
between containers.
Mount a Host Directory as a Container Volume:
---------------------------------------------
@ -68,13 +91,13 @@ Mount a Host Directory as a Container Volume:
-v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro].
If "host-dir" is missing, then docker creates a new volume.
This is not available for a Dockerfile due the portability and sharing
purpose of it. The [host-dir] volumes is something 100% host dependent
and will break on any other machine.
This is not available from a Dockerfile as it makes the built image less portable
or shareable. [host-dir] volumes are 100% host dependent and will break on any
other machine.
For example::
sudo docker run -v /var/logs:/var/host_logs:ro shykes/couchdb:2013-05-03
sudo docker run -v /var/logs:/var/host_logs:ro ubuntu bash
The command above mounts the host directory ``/var/logs`` into the
container with read only permissions as ``/var/host_logs``.
@ -87,3 +110,6 @@ Known Issues
* :issue:`2702`: "lxc-start: Permission denied - failed to mount"
could indicate a permissions problem with AppArmor. Please see the
issue for a workaround.
* :issue:`2528`: the busybox container is used to make the resulting container as small and
simple as possible - whenever you need to interact with the data in the volume
you mount it into another container.

View file

@ -86,26 +86,26 @@
</div>
</div>
<div class="container">
<div class="container-fluid">
<!-- Docs nav
================================================== -->
<div class="row main-row">
<div class="row-fluid main-row">
<div class="span3 sidebar bs-docs-sidebar">
<div class="sidebar bs-docs-sidebar">
<div class="page-title" >
<h4>DOCUMENTATION</h4>
</div>
{{ toctree(collapse=False, maxdepth=3) }}
<form>
<input type="text" id="st-search-input" class="st-search-input span3" style="width:160px;" />
<input type="text" id="st-search-input" class="st-search-input span3" placeholder="search in documentation" style="width:210px;" />
<div id="st-results-container"></div>
</form>
</div>
<!-- body block -->
<div class="span9 main-content">
<div class="main-content">
<!-- Main section
================================================== -->
@ -134,13 +134,22 @@
</div>
<div class="social links">
<a class="twitter" href="http://twitter.com/docker">Twitter</a>
<a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
<a title="Docker on Twitter" class="twitter" href="http://twitter.com/docker">Twitter</a>
<a title="Docker on GitHub" class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
<a title="Docker on Reddit" class="reddit" href="http://www.reddit.com/r/Docker/">Reddit</a>
<a title="Docker on Google+" class="googleplus" href="https://plus.google.com/u/0/b/100381662757235514581/communities/108146856671494713993">Google+</a>
<a title="Docker on Facebook" class="facebook" href="https://www.facebook.com/docker.run">Facebook</a>
<a title="Docker on SlideShare" class="slideshare" href="http://www.slideshare.net/dotCloud">Slideshare</a>
<a title="Docker on Youtube" class="youtube" href="http://www.youtube.com/user/dockerrun/">Youtube</a>
<a title="Docker on Flickr" class="flickr" href="http://www.flickr.com/photos/99741659@N08/">Flickr</a>
<a title="Docker on LinkedIn" class="linkedin" href="http://www.linkedin.com/company/dotcloud">LinkedIn</a>
</div>
<div class="tbox version-flyer ">
<div class="content">
<small>Current version:</small>
<p class="version-note">Note: You are currently browsing the development documentation. The current release may work differently.</p>
<small>Available versions:</small>
<ul class="inline">
{% for slug, url in versions %}
<li class="alternative"><a href="{{ url }}{%- for word in pagename.split('/') -%}
@ -163,6 +172,7 @@
</div>
<!-- end of footer -->
</div>
</div>

View file

@ -62,9 +62,12 @@ p a.btn {
-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
}
.brand.logo a {
.brand-logo a {
color: white;
}
.brand-logo a img {
width: auto;
}
.inline-icon {
margin-bottom: 6px;
}
@ -186,8 +189,15 @@ body {
.main-row {
margin-top: 40px;
}
.sidebar {
width: 215px;
float: left;
}
.main-content {
padding: 16px 18px inherit;
margin-left: 230px;
/* space for sidebar */
}
/* =======================
Social footer
@ -198,20 +208,54 @@ body {
}
.social .twitter,
.social .github,
.social .googleplus {
background: url("https://www.docker.io/static/img/footer-links.png") no-repeat transparent;
.social .googleplus,
.social .facebook,
.social .slideshare,
.social .linkedin,
.social .flickr,
.social .youtube,
.social .reddit {
background: url("../img/social/docker_social_logos.png") no-repeat transparent;
display: inline-block;
height: 35px;
height: 32px;
overflow: hidden;
text-indent: 9999px;
width: 35px;
margin-right: 10px;
width: 32px;
margin-right: 5px;
}
.social :hover {
-webkit-transform: rotate(-10deg);
-moz-transform: rotate(-10deg);
-o-transform: rotate(-10deg);
-ms-transform: rotate(-10deg);
transform: rotate(-10deg);
}
.social .twitter {
background-position: 0px 2px;
background-position: -160px 0px;
}
.social .reddit {
background-position: -256px 0px;
}
.social .github {
background-position: -59px 2px;
background-position: -64px 0px;
}
.social .googleplus {
background-position: -96px 0px;
}
.social .facebook {
background-position: 0px 0px;
}
.social .slideshare {
background-position: -128px 0px;
}
.social .youtube {
background-position: -192px 0px;
}
.social .flickr {
background-position: -32px 0px;
}
.social .linkedin {
background-position: -224px 0px;
}
form table th {
vertical-align: top;
@ -342,6 +386,7 @@ div.alert.alert-block {
border: 1px solid #88BABC;
padding: 5px;
font-size: larger;
max-width: 300px;
}
.version-flyer .content {
padding-right: 45px;
@ -351,18 +396,18 @@ div.alert.alert-block {
background-position: right center;
background-repeat: no-repeat;
}
.version-flyer .alternative {
visibility: hidden;
display: none;
}
.version-flyer .active-slug {
visibility: visible;
display: inline-block;
font-weight: bolder;
}
.version-flyer:hover .alternative {
animation-duration: 1s;
display: inline-block;
visibility: visible;
}
.version-flyer .version-note {
font-size: 16px;
color: black;
}
/* =====================================
Styles for
@ -410,7 +455,7 @@ dt:hover > a.headerlink {
.admonition.seealso {
border-color: #23cb1f;
}
/* Add styles for other types of comments */
.versionchanged,
.versionadded,
.versionmodified,
@ -418,15 +463,12 @@ dt:hover > a.headerlink {
font-size: larger;
font-weight: bold;
}
.versionchanged {
color: lightseagreen;
}
.versionadded {
color: mediumblue;
}
.deprecated {
color: orangered;
}

View file

@ -98,7 +98,6 @@ p a {
}
.navbar .brand {
margin-left: 0px;
float: left;
@ -126,9 +125,11 @@ p a {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
}
.brand.logo a {
.brand-logo a {
color: white;
img {
width: auto;
}
}
.logo {
@ -317,10 +318,18 @@ body {
margin-top: 40px;
}
.sidebar {
width: 215px;
float: left;
}
.main-content {
padding: 16px 18px inherit;
margin-left: 230px; /* space for sidebar */
}
/* =======================
Social footer
======================= */
@ -330,24 +339,64 @@ body {
margin-top: 15px;
}
.social .twitter, .social .github, .social .googleplus {
background: url("https://www.docker.io/static/img/footer-links.png") no-repeat transparent;
display: inline-block;
height: 35px;
overflow: hidden;
text-indent: 9999px;
width: 35px;
margin-right: 10px;
.social {
.twitter, .github, .googleplus, .facebook, .slideshare, .linkedin, .flickr, .youtube, .reddit {
background: url("../img/social/docker_social_logos.png") no-repeat transparent;
display: inline-block;
height: 32px;
overflow: hidden;
text-indent: 9999px;
width: 32px;
margin-right: 5px;
}
}
.social :hover {
-webkit-transform: rotate(-10deg);
-moz-transform: rotate(-10deg);
-o-transform: rotate(-10deg);
-ms-transform: rotate(-10deg);
transform: rotate(-10deg);
}
.social .twitter {
background-position: 0px 2px;
background-position: -160px 0px;
}
.social .reddit {
background-position: -256px 0px;
}
.social .github {
background-position: -59px 2px;
background-position: -64px 0px;
}
.social .googleplus {
background-position: -96px 0px;
}
.social .facebook {
background-position: -0px 0px;
}
.social .slideshare {
background-position: -128px 0px;
}
.social .youtube {
background-position: -192px 0px;
}
.social .flickr {
background-position: -32px 0px;
}
.social .linkedin {
background-position: -224px 0px;
}
// Styles on the forms
// ----------------------------------
@ -528,31 +577,34 @@ div.alert.alert-block {
border: 1px solid #88BABC;
padding: 5px;
font-size: larger;
max-width: 300px;
.content {
padding-right: 45px;
margin-top: 7px;
margin-left: 7px;
// display: inline-block;
background-image: url('../img/container3.png');
background-position: right center;
background-repeat: no-repeat;
}
.alternative {
visibility: hidden;
display: none;
}
.active-slug {
visibility: visible;
display: inline-block;
font-weight: bolder;
}
&:hover .alternative {
animation-duration: 1s;
display: inline-block;
visibility: visible;
}
.version-note {
font-size: 16px;
color: black;
}
}
@ -612,3 +664,24 @@ dt:hover > a.headerlink {
}
/* Add styles for other types of comments */
.versionchanged,
.versionadded,
.versionmodified,
.deprecated {
font-size: larger;
font-weight: bold;
}
.versionchanged {
color: lightseagreen;
}
.versionadded {
color: mediumblue;
}
.deprecated {
color: orangered;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -53,14 +53,6 @@ $(function(){
}
}
if (doc_version == "") {
$('.version-flyer ul').html('<li class="alternative active-slug"><a href="" title="Switch to local">Local</a></li>');
}
// mark the active documentation in the version widget
$(".version-flyer a:contains('" + doc_version + "')").parent().addClass('active-slug');
// attached handler on click
// Do not attach to first element or last (intro, faq) so that
// first and last link directly instead of accordian
@ -95,4 +87,18 @@ $(function(){
// add class to all those which have children
$('.sidebar > ul > li').not(':last').not(':first').addClass('has-children');
if (doc_version == "") {
$('.version-flyer ul').html('<li class="alternative active-slug"><a href="" title="Switch to local">Local</a></li>');
}
if (doc_version == "master") {
$('.version-flyer .version-note').hide();
}
// mark the active documentation in the version widget
$(".version-flyer a:contains('" + doc_version + "')").parent().addClass('active-slug').setAttribute("title", "Current version");
});

View file

@ -6,6 +6,7 @@ import (
"io"
"log"
"os"
"path/filepath"
"runtime"
"strings"
)
@ -79,9 +80,24 @@ func New(root string) (*Engine, error) {
}
}
}
if err := os.MkdirAll(root, 0700); err != nil && !os.IsExist(err) {
return nil, err
}
// Docker makes some assumptions about the "absoluteness" of root
// ... so let's make sure it has no symlinks
if p, err := filepath.Abs(root); err != nil {
log.Fatalf("Unable to get absolute root (%s): %s", root, err)
} else {
root = p
}
if p, err := filepath.EvalSymlinks(root); err != nil {
log.Fatalf("Unable to canonicalize root (%s): %s", root, err)
} else {
root = p
}
eng := &Engine{
root: root,
handlers: make(map[string]Handler),

View file

@ -18,7 +18,7 @@ func TestRegister(t *testing.T) {
eng := newTestEngine(t)
//Should fail because globan handlers are copied
//Should fail because global handlers are copied
//at the engine creation
if err := eng.Register("dummy1", nil); err == nil {
t.Fatalf("Expecting error, got none")

View file

@ -10,6 +10,7 @@ import (
"os"
"path"
"path/filepath"
"runtime"
"strings"
"syscall"
"time"
@ -56,6 +57,7 @@ func (graph *Graph) restore() error {
graph.idIndex.Add(id)
}
}
utils.Debugf("Restored %d elements", len(dir))
return nil
}
@ -130,7 +132,8 @@ func (graph *Graph) Create(layerData archive.Archive, container *Container, comm
DockerVersion: VERSION,
Author: author,
Config: config,
Architecture: "x86_64",
Architecture: runtime.GOARCH,
OS: runtime.GOOS,
}
if container != nil {
img.Parent = container.Image

View file

@ -25,12 +25,12 @@ import (
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/graphdriver"
mountpk "github.com/dotcloud/docker/mount"
"github.com/dotcloud/docker/utils"
"os"
"os/exec"
"path"
"strings"
"syscall"
)
func init() {
@ -296,7 +296,7 @@ func (a *Driver) unmount(id string) error {
func (a *Driver) mounted(id string) (bool, error) {
target := path.Join(a.rootPath(), "mnt", id)
return Mounted(target)
return mountpk.Mounted(target)
}
// During cleanup aufs needs to unmount all mountpoints
@ -327,7 +327,7 @@ func (a *Driver) aufsMount(ro []string, rw, target string) (err error) {
for _, layer := range ro {
branch := fmt.Sprintf("append:%s=ro+wh", layer)
if err = mount("none", target, "aufs", syscall.MS_REMOUNT, branch); err != nil {
if err = mount("none", target, "aufs", MsRemount, branch); err != nil {
return
}
}

View file

@ -2,9 +2,7 @@ package aufs
import (
"github.com/dotcloud/docker/utils"
"os"
"os/exec"
"path/filepath"
"syscall"
)
@ -17,21 +15,3 @@ func Unmount(target string) error {
}
return nil
}
func Mounted(mountpoint string) (bool, error) {
mntpoint, err := os.Stat(mountpoint)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
parent, err := os.Stat(filepath.Join(mountpoint, ".."))
if err != nil {
return false, err
}
mntpointSt := mntpoint.Sys().(*syscall.Stat_t)
parentSt := parent.Sys().(*syscall.Stat_t)
return mntpointSt.Dev != parentSt.Dev, nil
}

View file

@ -2,6 +2,8 @@ package aufs
import "errors"
const MsRemount = 0
func mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
return errors.New("mount is not implemented on darwin")
}

View file

@ -2,6 +2,8 @@ package aufs
import "syscall"
const MsRemount = syscall.MS_REMOUNT
func mount(source string, target string, fstype string, flags uintptr, data string) error {
return syscall.Mount(source, target, fstype, flags, data)
}

View file

@ -154,7 +154,7 @@ func (devices *DeviceSet) allocateTransactionId() uint64 {
func (devices *DeviceSet) saveMetadata() error {
jsonData, err := json.Marshal(devices.MetaData)
if err != nil {
return fmt.Errorf("Error encoding metaadata to json: %s", err)
return fmt.Errorf("Error encoding metadata to json: %s", err)
}
tmpFile, err := ioutil.TempFile(filepath.Dir(devices.jsonFile()), ".json")
if err != nil {

View file

@ -36,8 +36,9 @@ To build docker, you will need the following system dependencies
* An amd64 machine
* A recent version of git and mercurial
* Go version 1.2 or later (see notes below regarding using Go 1.1.2 and dynbinary)
* Go version 1.2 or later
* SQLite version 3.7.9 or later
* libdevmapper from lvm2 version 1.02.77 or later (http://www.sourceware.org/lvm2/)
* A clean checkout of the source must be added to a valid Go [workspace](http://golang.org/doc/code.html#Workspaces)
under the path *src/github.com/dotcloud/docker*.
@ -91,8 +92,7 @@ You would do the users of your distro a disservice and "void the docker warranty
A good comparison is Busybox: all distros package it as a statically linked binary, because it just
makes sense. Docker is the same way.
If you *must* have a non-static Docker binary, or require Go 1.1.2 (since Go 1.2 is still freshly released
at the time of this writing), please use:
If you *must* have a non-static Docker binary, please use:
```bash
./hack/make.sh dynbinary

View file

@ -136,7 +136,7 @@ sudo('echo -e "deb http://archive.ubuntu.com/ubuntu raring main universe\n'
sudo('DEBIAN_FRONTEND=noninteractive apt-get install -q -y wget python-dev'
' python-pip supervisor git mercurial linux-image-extra-$(uname -r)'
' aufs-tools make libfontconfig libevent-dev libsqlite3-dev libssl-dev')
sudo('wget -O - https://go.googlecode.com/files/go1.1.2.linux-amd64.tar.gz | '
sudo('wget -O - https://go.googlecode.com/files/go1.2.linux-amd64.tar.gz | '
'tar -v -C /usr/local -xz; ln -s /usr/local/go/bin/go /usr/bin/go')
sudo('GOPATH=/go go get -d github.com/dotcloud/docker')
sudo('pip install -r {}/requirements.txt'.format(CFG_PATH))

View file

@ -116,7 +116,7 @@ case "$lsb_dist" in
(
set -x
$sh_c 'docker run busybox echo "Docker has been successfully installed!"'
)
) || true
fi
exit 0
;;

View file

@ -15,8 +15,9 @@ set -e
# - The script is intented to be run inside the docker container specified
# in the Dockerfile at the root of the source. In other words:
# DO NOT CALL THIS SCRIPT DIRECTLY.
# - The right way to call this script is to invoke "docker build ." from
# your checkout of the Docker repository, and then
# - The right way to call this script is to invoke "make" from
# your checkout of the Docker repository.
# the Makefile will so a "docker build -t docker ." and then
# "docker run hack/make.sh" in the resulting container image.
#
@ -28,7 +29,7 @@ RESOLVCONF=$(readlink --canonicalize /etc/resolv.conf)
grep -q "$RESOLVCONF" /proc/mounts || {
echo >&2 "# WARNING! I don't seem to be running in a docker container."
echo >&2 "# The result of this command might be an incorrect build, and will not be officially supported."
echo >&2 "# Try this: 'docker build -t docker . && docker run docker ./hack/make.sh'"
echo >&2 "# Try this: 'make all'"
}
# List of bundles to create when no argument is passed
@ -40,6 +41,7 @@ DEFAULT_BUNDLES=(
dyntest
dyntest-integration
cover
cross
tgz
ubuntu
)
@ -63,10 +65,13 @@ fi
# Use these flags when compiling the tests and final binary
LDFLAGS='-X main.GITCOMMIT "'$GITCOMMIT'" -X main.VERSION "'$VERSION'" -w'
LDFLAGS_STATIC='-X github.com/dotcloud/docker/utils.IAMSTATIC true -linkmode external -extldflags "-lpthread -static -Wl,--unresolved-symbols=ignore-in-object-files"'
BUILDFLAGS='-tags netgo'
BUILDFLAGS='-tags netgo -a'
HAVE_GO_TEST_COVER=
if go help testflag | grep -q -- -cover; then
if \
go help testflag | grep -- -cover > /dev/null \
&& go tool -n cover > /dev/null 2>&1 \
; then
HAVE_GO_TEST_COVER=1
fi
@ -85,10 +90,6 @@ go_test_dir() {
coverprofile="$DEST/coverprofiles/${coverprofile//\//-}"
testcover=( -cover -coverprofile "$coverprofile" )
fi
( # we run "go test -i" ouside the "set -x" to provde cleaner output
cd "$dir"
go test -i -ldflags "$LDFLAGS" $BUILDFLAGS
)
(
set -x
cd "$dir"

23
hack/make/cross Normal file
View file

@ -0,0 +1,23 @@
#!/bin/bash
DEST=$1
# if we have our linux/amd64 version compiled, let's symlink it in
if [ -x "$DEST/../binary/docker-$VERSION" ]; then
mkdir -p "$DEST/linux/amd64"
(
cd "$DEST/linux/amd64"
ln -s ../../../binary/* ./
)
echo "Created symlinks:" "$DEST/linux/amd64/"*
fi
for platform in $DOCKER_CROSSPLATFORMS; do
(
mkdir -p "$DEST/$platform" # bundles/VERSION/cross/GOOS/GOARCH/docker-VERSION
export GOOS=${platform%/*}
export GOARCH=${platform##*/}
export LDFLAGS_STATIC="" # we just need a simple client for these platforms (TODO this might change someday)
source "$(dirname "$BASH_SOURCE")/binary" "$DEST/$platform"
)
done

View file

@ -3,7 +3,7 @@
DEST=$1
# dockerinit still needs to be a static binary, even if docker is dynamic
CGO_ENABLED=0 go build -a -o $DEST/dockerinit-$VERSION -ldflags "$LDFLAGS -d" $BUILDFLAGS ./dockerinit
CGO_ENABLED=0 go build -o $DEST/dockerinit-$VERSION -ldflags "$LDFLAGS -d" $BUILDFLAGS ./dockerinit
echo "Created binary: $DEST/dockerinit-$VERSION"
ln -sf dockerinit-$VERSION $DEST/dockerinit
@ -12,6 +12,6 @@ export DOCKER_INITSHA1="$(sha1sum $DEST/dockerinit-$VERSION | cut -d' ' -f1)"
# exported so that "dyntest" can easily access it later without recalculating it
(
export LDFLAGS_STATIC="-X github.com/dotcloud/docker/utils.INITSHA1 \"$DOCKER_INITSHA1\""
export LDFLAGS_STATIC="-X github.com/dotcloud/docker/utils.INITSHA1 \"$DOCKER_INITSHA1\" -X github.com/dotcloud/docker/utils.INITPATH \"$DOCKER_INITPATH\""
source "$(dirname "$BASH_SOURCE")/binary"
)

View file

@ -1,23 +1,29 @@
#!/bin/bash
DEST="$1"
BINARY="$DEST/../binary/docker-$VERSION"
TGZ="$DEST/docker-$VERSION.tgz"
CROSS="$DEST/../cross"
set -e
if [ ! -x "$BINARY" ]; then
echo >&2 'error: binary must be run before tgz'
if [ ! -d "$CROSS/linux/amd64" ]; then
echo >&2 'error: binary and cross must be run before tgz'
false
fi
mkdir -p "$DEST/build"
mkdir -p "$DEST/build/usr/local/bin"
cp -L "$BINARY" "$DEST/build/usr/local/bin/docker"
tar --numeric-owner --owner 0 -C "$DEST/build" -czf "$TGZ" usr
rm -rf "$DEST/build"
echo "Created tgz: $TGZ"
for d in "$CROSS/"*/*; do
GOARCH="$(basename "$d")"
GOOS="$(basename "$(dirname "$d")")"
mkdir -p "$DEST/$GOOS/$GOARCH"
TGZ="$DEST/$GOOS/$GOARCH/docker-$VERSION.tgz"
mkdir -p "$DEST/build"
mkdir -p "$DEST/build/usr/local/bin"
cp -L "$d/docker-$VERSION" "$DEST/build/usr/local/bin/docker"
tar --numeric-owner --owner 0 -C "$DEST/build" -czf "$TGZ" usr
rm -rf "$DEST/build"
echo "Created tgz: $TGZ"
done

View file

@ -17,6 +17,7 @@ repeatability across servers.
Docker is a great building block for automating distributed systems:
large-scale web deployments, database clusters, continuous deployment systems,
private PaaS, service-oriented architectures, etc."
PACKAGE_LICENSE="Apache-2.0"
# Build docker as an ubuntu package using FPM and REPREPRO (sue me).
# bundle_binary must be called first.
@ -30,6 +31,20 @@ bundle_ubuntu() {
mkdir -p $DIR/lib/systemd
cp -R contrib/init/systemd $DIR/lib/systemd/system
mkdir -p $DIR/etc/default
cat > $DIR/etc/default/docker <<'EOF'
# Docker Upstart and SysVinit configuration file
# Customize location of Docker binary (especially for development testing).
#DOCKER="/usr/local/bin/docker"
# Use DOCKER_OPTS to modify the daemon startup options.
#DOCKER_OPTS="-dns 8.8.8.8"
# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy=http://127.0.0.1:3128/
EOF
# Copy the binary
# This will fail if the binary bundle hasn't been built
mkdir -p $DIR/usr/bin
@ -104,7 +119,7 @@ EOF
--replaces lxc-docker \
--replaces lxc-docker-virtual-package \
--url "$PACKAGE_URL" \
--vendor "$PACKAGE_VENDOR" \
--license "$PACKAGE_LICENSE" \
--config-files /etc/init/docker.conf \
--config-files /etc/init.d/docker \
--config-files /etc/default/docker \
@ -118,13 +133,9 @@ EOF
--description "$PACKAGE_DESCRIPTION" \
--maintainer "$PACKAGE_MAINTAINER" \
--url "$PACKAGE_URL" \
--vendor "$PACKAGE_VENDOR" \
--config-files /etc/init/docker.conf \
--config-files /etc/init.d/docker \
--config-files /etc/default/docker \
--license "$PACKAGE_LICENSE" \
--deb-compression xz \
-t deb .
# note: the --config-files lines have to be duplicated to stop overwrite on package upgrade (since we have to use this funky virtual package)
)
}

View file

@ -47,6 +47,7 @@ cd /go/src/github.com/dotcloud/docker
RELEASE_BUNDLES=(
binary
cross
tgz
ubuntu
)
@ -113,6 +114,77 @@ s3_url() {
esac
}
release_build() {
GOOS=$1
GOARCH=$2
BINARY=bundles/$VERSION/cross/$GOOS/$GOARCH/docker-$VERSION
TGZ=bundles/$VERSION/tgz/$GOOS/$GOARCH/docker-$VERSION.tgz
# we need to map our GOOS and GOARCH to uname values
# see https://en.wikipedia.org/wiki/Uname
# ie, GOOS=linux -> "uname -s"=Linux
S3OS=$GOOS
case "$S3OS" in
darwin)
S3OS=Darwin
;;
freebsd)
S3OS=FreeBSD
;;
linux)
S3OS=Linux
;;
*)
echo >&2 "error: can't convert $S3OS to an appropriate value for 'uname -s'"
exit 1
;;
esac
S3ARCH=$GOARCH
case "$S3ARCH" in
amd64)
S3ARCH=x86_64
;;
386)
S3ARCH=i386
;;
arm)
# GOARCH is fine
;;
*)
echo >&2 "error: can't convert $S3ARCH to an appropriate value for 'uname -m'"
exit 1
;;
esac
S3DIR=s3://$BUCKET/builds/$S3OS/$S3ARCH
if [ ! -x "$BINARY" ]; then
echo >&2 "error: can't find $BINARY - was it compiled properly?"
exit 1
fi
if [ ! -f "$TGZ" ]; then
echo >&2 "error: can't find $TGZ - was it packaged properly?"
exit 1
fi
echo "Uploading $BINARY to $S3OS/$S3ARCH/docker-$VERSION"
s3cmd --follow-symlinks --preserve --acl-public put $BINARY $S3DIR/docker-$VERSION
echo "Uploading $TGZ to $S3OS/$S3ARCH/docker-$VERSION.tgz"
s3cmd --follow-symlinks --preserve --acl-public put $TGZ $S3DIR/docker-$VERSION.tgz
if [ -z "$NOLATEST" ]; then
echo "Copying $S3OS/$S3ARCH/docker-$VERSION to $S3OS/$S3ARCH/docker-latest"
s3cmd --acl-public cp $S3DIR/docker-$VERSION $S3DIR/docker-latest
echo "Copying $S3OS/$S3ARCH/docker-$VERSION.tgz to $S3OS/$S3ARCH/docker-latest.tgz"
s3cmd --acl-public cp $S3DIR/docker-$VERSION.tgz $S3DIR/docker-latest.tgz
fi
}
# Upload the 'ubuntu' bundle to S3:
# 1. A full APT repository is published at $BUCKET/ubuntu/
# 2. Instructions for using the APT repository are uploaded at $BUCKET/ubuntu/index
@ -189,31 +261,21 @@ EOF
echo "APT repository uploaded. Instructions available at $(s3_url)/ubuntu"
}
# Upload a tgz to S3
release_tgz() {
[ -e bundles/$VERSION/tgz/docker-$VERSION.tgz ] || {
echo >&2 './hack/make.sh must be run before release_binary'
# Upload binaries and tgz files to S3
release_binaries() {
[ -e bundles/$VERSION/cross/linux/amd64/docker-$VERSION ] || {
echo >&2 './hack/make.sh must be run before release_binaries'
exit 1
}
S3DIR=s3://$BUCKET/builds/Linux/x86_64
s3cmd --acl-public put bundles/$VERSION/tgz/docker-$VERSION.tgz $S3DIR/docker-$VERSION.tgz
for d in bundles/$VERSION/cross/*/*; do
GOARCH="$(basename "$d")"
GOOS="$(basename "$(dirname "$d")")"
release_build "$GOOS" "$GOARCH"
done
if [ -z "$NOLATEST" ]; then
echo "Copying docker-$VERSION.tgz to docker-latest.tgz"
s3cmd --acl-public cp $S3DIR/docker-$VERSION.tgz $S3DIR/docker-latest.tgz
fi
}
# TODO create redirect from builds/*/i686 to builds/*/i386
# Upload a static binary to S3
release_binary() {
[ -e bundles/$VERSION/binary/docker-$VERSION ] || {
echo >&2 './hack/make.sh must be run before release_binary'
exit 1
}
S3DIR=s3://$BUCKET/builds/Linux/x86_64
s3cmd --acl-public put bundles/$VERSION/binary/docker-$VERSION $S3DIR/docker-$VERSION
cat <<EOF | write_to_s3 s3://$BUCKET/builds/index
# To install, run the following command as root:
curl -O $(s3_url)/builds/Linux/x86_64/docker-$VERSION && chmod +x docker-$VERSION && sudo mv docker-$VERSION /usr/local/bin/docker
@ -226,8 +288,6 @@ EOF
s3cmd --acl-public --add-header='x-amz-website-redirect-location:/builds/' --mime-type='text/plain' put /tmp/emptyfile s3://$BUCKET/builds/info
if [ -z "$NOLATEST" ]; then
echo "Copying docker-$VERSION to docker-latest"
s3cmd --acl-public cp $S3DIR/docker-$VERSION $S3DIR/docker-latest
echo "Advertising $VERSION on $BUCKET as most recent version"
echo $VERSION | write_to_s3 s3://$BUCKET/latest
fi
@ -246,11 +306,15 @@ release_test() {
main() {
setup_s3
release_binary
release_tgz
release_binaries
release_ubuntu
release_index
release_test
}
main
echo
echo
echo "Release complete; see $(s3_url)"
echo

View file

@ -6,7 +6,7 @@ if [[ ! -d vendor ]]; then
fi
vendor_dir=${PWD}/vendor
git_clone () {
rm_pkg_dir () {
PKG=$1
REV=$2
(
@ -16,11 +16,31 @@ git_clone () {
echo "src/$PKG already exists. Removing."
rm -fr src/$PKG
fi
)
}
git_clone () {
PKG=$1
REV=$2
(
set -e
rm_pkg_dir $PKG $REV
cd $vendor_dir && git clone http://$PKG src/$PKG
cd src/$PKG && git checkout -f $REV && rm -fr .git
)
}
hg_clone () {
PKG=$1
REV=$2
(
set -e
rm_pkg_dir $PKG $REV
cd $vendor_dir && hg clone http://$PKG src/$PKG
cd src/$PKG && hg checkout -r $REV && rm -fr .hg
)
}
git_clone github.com/kr/pty 3b1f6487b
git_clone github.com/gorilla/context/ 708054d61e5
@ -29,13 +49,6 @@ git_clone github.com/gorilla/mux/ 9b36453141c
git_clone github.com/syndtr/gocapability 3454319be2
# Docker requires code.google.com/p/go.net/websocket
PKG=code.google.com/p/go.net REV=84a4013f96e0
(
set -e
cd $vendor_dir
if [[ ! -d src/$PKG ]]; then
hg clone https://$PKG src/$PKG
fi
cd src/$PKG && hg checkout -r $REV
)
hg_clone code.google.com/p/go.net 84a4013f96e0
hg_clone code.google.com/p/gosqlite 74691fb6f837

View file

@ -28,6 +28,7 @@ type Image struct {
Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"`
Architecture string `json:"architecture,omitempty"`
OS string `json:"os,omitempty"`
graph *Graph
Size int64
}

View file

@ -432,7 +432,6 @@ func TestGetContainersChanges(t *testing.T) {
}
func TestGetContainersTop(t *testing.T) {
t.Skip("Fixme. Skipping test for now. Reported error when testing using dind: 'api_test.go:527: Expected 2 processes, found 0.'")
eng := NewTestEngine(t)
defer mkRuntimeFromEngine(eng, t).Nuke()
srv := mkServerFromEngine(eng, t)
@ -475,7 +474,7 @@ func TestGetContainersTop(t *testing.T) {
})
r := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/"+containerID+"/top?ps_args=u", bytes.NewReader([]byte{}))
req, err := http.NewRequest("GET", "/containers/"+containerID+"/top?ps_args=aux", nil)
if err != nil {
t.Fatal(err)
}
@ -498,11 +497,11 @@ func TestGetContainersTop(t *testing.T) {
if len(procs.Processes) != 2 {
t.Fatalf("Expected 2 processes, found %d.", len(procs.Processes))
}
if procs.Processes[0][10] != "/bin/sh" && procs.Processes[0][10] != "cat" {
t.Fatalf("Expected `cat` or `/bin/sh`, found %s.", procs.Processes[0][10])
if procs.Processes[0][10] != "/bin/sh -c cat" {
t.Fatalf("Expected `/bin/sh -c cat`, found %s.", procs.Processes[0][10])
}
if procs.Processes[1][10] != "/bin/sh" && procs.Processes[1][10] != "cat" {
t.Fatalf("Expected `cat` or `/bin/sh`, found %s.", procs.Processes[1][10])
if procs.Processes[1][10] != "/bin/sh -c cat" {
t.Fatalf("Expected `/bin/sh -c cat`, found %s.", procs.Processes[1][10])
}
}

View file

@ -425,16 +425,10 @@ func TestBuildEntrypointRunCleanup(t *testing.T) {
}
}
func TestBuildImageWithCache(t *testing.T) {
func checkCacheBehavior(t *testing.T, template testContextTemplate, expectHit bool) {
eng := NewTestEngine(t)
defer nuke(mkRuntimeFromEngine(eng, t))
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
`,
nil, nil}
img, err := buildImage(template, t, eng, true)
if err != nil {
t.Fatal(err)
@ -443,43 +437,115 @@ func TestBuildImageWithCache(t *testing.T) {
imageId := img.ID
img = nil
img, err = buildImage(template, t, eng, true)
img, err = buildImage(template, t, eng, expectHit)
if err != nil {
t.Fatal(err)
}
if imageId != img.ID {
t.Logf("Image ids should match: %s != %s", imageId, img.ID)
hit := imageId == img.ID
if hit != expectHit {
t.Logf("Cache misbehavior, got hit=%t, expected hit=%t: (first: %s, second %s)",
hit, expectHit, imageId, img.ID)
t.Fail()
}
}
func TestBuildImageWithoutCache(t *testing.T) {
eng := NewTestEngine(t)
defer nuke(mkRuntimeFromEngine(eng, t))
func TestBuildImageWithCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
`,
nil, nil}
checkCacheBehavior(t, template, true)
}
img, err := buildImage(template, t, eng, true)
if err != nil {
t.Fatal(err)
}
imageId := img.ID
func TestBuildImageWithoutCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
`,
nil, nil}
checkCacheBehavior(t, template, false)
}
img = nil
img, err = buildImage(template, t, eng, false)
if err != nil {
t.Fatal(err)
}
func TestBuildADDLocalFileWithCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
run echo "first"
add foo /usr/lib/bla/bar
run echo "second"
`,
[][2]string{{"foo", "hello"}},
nil}
checkCacheBehavior(t, template, true)
}
if imageId == img.ID {
t.Logf("Image ids should not match: %s == %s", imageId, img.ID)
t.Fail()
}
func TestBuildADDLocalFileWithoutCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
run echo "first"
add foo /usr/lib/bla/bar
run echo "second"
`,
[][2]string{{"foo", "hello"}},
nil}
checkCacheBehavior(t, template, false)
}
func TestBuildADDRemoteFileWithCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
run echo "first"
add http://{SERVERADDR}/baz /usr/lib/baz/quux
run echo "second"
`,
nil,
[][2]string{{"/baz", "world!"}}}
checkCacheBehavior(t, template, true)
}
func TestBuildADDRemoteFileWithoutCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
run echo "first"
add http://{SERVERADDR}/baz /usr/lib/baz/quux
run echo "second"
`,
nil,
[][2]string{{"/baz", "world!"}}}
checkCacheBehavior(t, template, false)
}
func TestBuildADDLocalAndRemoteFilesWithCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
run echo "first"
add foo /usr/lib/bla/bar
add http://{SERVERADDR}/baz /usr/lib/baz/quux
run echo "second"
`,
[][2]string{{"foo", "hello"}},
[][2]string{{"/baz", "world!"}}}
checkCacheBehavior(t, template, true)
}
func TestBuildADDLocalAndRemoteFilesWithoutCache(t *testing.T) {
template := testContextTemplate{`
from {IMAGE}
maintainer dockerio
run echo "first"
add foo /usr/lib/bla/bar
add http://{SERVERADDR}/baz /usr/lib/baz/quux
run echo "second"
`,
[][2]string{{"foo", "hello"}},
[][2]string{{"/baz", "world!"}}}
checkCacheBehavior(t, template, false)
}
func TestForbiddenContextPath(t *testing.T) {
@ -630,3 +696,11 @@ func TestBuildFails(t *testing.T) {
t.Fatalf("StatusCode %d unexpected, should be 23", sterr.Code)
}
}
func TestBuildFailsDockerfileEmpty(t *testing.T) {
_, err := buildImage(testContextTemplate{``, nil, nil}, t, nil, true)
if err != docker.ErrDockerfileEmpty {
t.Fatal("Expected: %v, got: %v", docker.ErrDockerfileEmpty, err)
}
}

View file

@ -5,7 +5,7 @@ import (
"fmt"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker/term"
"github.com/dotcloud/docker/pkg/term"
"github.com/dotcloud/docker/utils"
"io"
"io/ioutil"
@ -968,3 +968,66 @@ func TestRunCidFile(t *testing.T) {
})
}
func TestContainerOrphaning(t *testing.T) {
// setup a temporary directory
tmpDir, err := ioutil.TempDir("", "project")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
// setup a CLI and server
cli := docker.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr)
defer cleanup(globalEngine, t)
srv := mkServerFromEngine(globalEngine, t)
// closure to build something
buildSomething := func(template string, image string) string {
dockerfile := path.Join(tmpDir, "Dockerfile")
replacer := strings.NewReplacer("{IMAGE}", unitTestImageID)
contents := replacer.Replace(template)
ioutil.WriteFile(dockerfile, []byte(contents), 0x777)
if err := cli.CmdBuild("-t", image, tmpDir); err != nil {
t.Fatal(err)
}
img, err := srv.ImageInspect(image)
if err != nil {
t.Fatal(err)
}
return img.ID
}
// build an image
imageName := "orphan-test"
template1 := `
from {IMAGE}
cmd ["/bin/echo", "holla"]
`
img1 := buildSomething(template1, imageName)
// create a container using the fist image
if err := cli.CmdRun(imageName); err != nil {
t.Fatal(err)
}
// build a new image that splits lineage
template2 := `
from {IMAGE}
cmd ["/bin/echo", "holla"]
expose 22
`
buildSomething(template2, imageName)
// remove the second image by name
resp, err := srv.ImageDelete(imageName, true)
// see if we deleted the first image (and orphaned the container)
for _, i := range resp {
if img1 == i.Deleted {
t.Fatal("Orphaned image with container")
}
}
}

View file

@ -748,6 +748,54 @@ func TestRandomContainerName(t *testing.T) {
}
}
func TestContainerNameValidation(t *testing.T) {
eng := NewTestEngine(t)
runtime := mkRuntimeFromEngine(eng, t)
defer nuke(runtime)
for _, test := range []struct {
Name string
Valid bool
}{
{"abc-123_AAA.1", true},
{"\000asdf", false},
} {
config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
if err != nil {
if !test.Valid {
continue
}
t.Fatal(err)
}
var shortID string
job := eng.Job("create", test.Name)
if err := job.ImportEnv(config); err != nil {
t.Fatal(err)
}
job.Stdout.AddString(&shortID)
if err := job.Run(); err != nil {
if !test.Valid {
continue
}
t.Fatal(err)
}
container := runtime.Get(shortID)
if container.Name != "/"+test.Name {
t.Fatalf("Expect /%s got %s", test.Name, container.Name)
}
if c := runtime.Get("/" + test.Name); c == nil {
t.Fatalf("Couldn't retrieve test container as /%s", test.Name)
} else if c.ID != container.ID {
t.Fatalf("Container /%s has ID %s instead of %s", test.Name, c.ID, container.ID)
}
}
}
func TestLinkChildContainer(t *testing.T) {
eng := NewTestEngine(t)
runtime := mkRuntimeFromEngine(eng, t)

View file

@ -32,6 +32,7 @@ func mkRuntime(f utils.Fataler) *docker.Runtime {
config := &docker.DaemonConfig{
Root: root,
AutoRestart: false,
Mtu: docker.DefaultNetworkMtu,
}
r, err := docker.NewRuntimeFromDirectory(config)
if err != nil {

View file

@ -14,19 +14,12 @@ lxc.network.type = empty
lxc.network.type = veth
lxc.network.link = {{.NetworkSettings.Bridge}}
lxc.network.name = eth0
lxc.network.mtu = 1500
{{end}}
# root filesystem
{{$ROOTFS := .RootfsPath}}
lxc.rootfs = {{$ROOTFS}}
{{if and .HostnamePath .HostsPath}}
# enable domain name support
lxc.mount.entry = {{escapeFstabSpaces .HostnamePath}} {{escapeFstabSpaces $ROOTFS}}/etc/hostname none bind,ro 0 0
lxc.mount.entry = {{escapeFstabSpaces .HostsPath}} {{escapeFstabSpaces $ROOTFS}}/etc/hosts none bind,ro 0 0
{{end}}
# use a dedicated pts for the container (and limit the number of pseudo terminal
# available)
lxc.pts = 1024
@ -74,32 +67,20 @@ lxc.cgroup.devices.allow = c 10:200 rwm
# standard mount point
# Use mnt.putold as per https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/986385
lxc.pivotdir = lxc_putold
# NOTICE: These mounts must be applied within the namespace
# WARNING: procfs is a known attack vector and should probably be disabled
# if your userspace allows it. eg. see http://blog.zx2c4.com/749
lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
# WARNING: sysfs is a known attack vector and should probably be disabled
# if your userspace allows it. eg. see http://bit.ly/T9CkqJ
# WARNING: sysfs is a known attack vector and should probably be disabled
# if your userspace allows it. eg. see http://bit.ly/T9CkqJ
lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,nosuid,noexec 0 0
#lxc.mount.entry = varrun {{escapeFstabSpaces $ROOTFS}}/var/run tmpfs mode=755,size=4096k,nosuid,nodev,noexec 0 0
#lxc.mount.entry = varlock {{escapeFstabSpaces $ROOTFS}}/var/lock tmpfs size=1024k,nosuid,nodev,noexec 0 0
lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
# Inject dockerinit
lxc.mount.entry = {{escapeFstabSpaces .SysInitPath}} {{escapeFstabSpaces $ROOTFS}}/.dockerinit none bind,ro 0 0
# Inject env
lxc.mount.entry = {{escapeFstabSpaces .EnvConfigPath}} {{escapeFstabSpaces $ROOTFS}}/.dockerenv none bind,ro 0 0
# In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
lxc.mount.entry = {{escapeFstabSpaces .ResolvConfPath}} {{escapeFstabSpaces $ROOTFS}}/etc/resolv.conf none bind,ro 0 0
{{if .Volumes}}
{{ $rw := .VolumesRW }}
{{range $virtualPath, $realPath := .Volumes}}
lxc.mount.entry = {{escapeFstabSpaces $realPath}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $virtualPath}} none bind,{{ if index $rw $virtualPath }}rw{{else}}ro{{end}} 0 0
{{end}}
{{end}}
{{if (getHostConfig .).Privileged}}
{{if (getCapabilities .).AppArmor}}
lxc.aa_profile = unconfined

5
mount/flags_darwin.go Normal file
View file

@ -0,0 +1,5 @@
package mount
func parseOptions(options string) (int, string) {
panic("Not implemented")
}

61
mount/flags_linux.go Normal file
View file

@ -0,0 +1,61 @@
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},
"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, ",")
}

53
mount/mount.go Normal file
View file

@ -0,0 +1,53 @@
package mount
import (
"time"
)
// Looks at /proc/self/mountinfo to determine of the specified
// mountpoint has been mounted
func Mounted(mountpoint string) (bool, error) {
entries, err := parseMountTable()
if err != nil {
return false, err
}
// Search the table for the mountpoint
for _, e := range entries {
if e.mountpoint == mountpoint {
return true, nil
}
}
return false, nil
}
// Mount the specified options at the target path
// Options must be specified as fstab style
func Mount(device, target, mType, options string) error {
if mounted, err := Mounted(target); err != nil || mounted {
return err
}
flag, data := parseOptions(options)
if err := mount(device, target, mType, uintptr(flag), data); err != nil {
return err
}
return nil
}
// Unmount the target only if it is mounted
func Unmount(target string) (err error) {
if mounted, err := Mounted(target); err != nil || !mounted {
return err
}
// Simple retry logic for unmount
for i := 0; i < 10; i++ {
if err = unmount(target, 0); err == nil {
return nil
}
time.Sleep(100 * time.Millisecond)
}
return
}

67
mount/mount_test.go Normal file
View file

@ -0,0 +1,67 @@
package mount
import (
"os"
"path"
"syscall"
"testing"
)
func TestMountOptionsParsing(t *testing.T) {
options := "bind,ro,size=10k"
flag, data := parseOptions(options)
if data != "size=10k" {
t.Fatalf("Expected size=10 got %s", data)
}
expectedFlag := syscall.MS_BIND | syscall.MS_RDONLY
if flag != expectedFlag {
t.Fatalf("Expected %d got %d", expectedFlag, flag)
}
}
func TestMounted(t *testing.T) {
tmp := path.Join(os.TempDir(), "mount-tests")
if err := os.MkdirAll(tmp, 0777); err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
var (
sourcePath = path.Join(tmp, "sourcefile.txt")
targetPath = path.Join(tmp, "targetfile.txt")
)
f, err := os.Create(sourcePath)
if err != nil {
t.Fatal(err)
}
f.WriteString("hello")
f.Close()
f, err = os.Create(targetPath)
if err != nil {
t.Fatal(err)
}
f.Close()
if err := Mount(sourcePath, targetPath, "none", "bind,ro"); err != nil {
t.Fatal(err)
}
defer func() {
if err := Unmount(targetPath); err != nil {
t.Fatal(err)
}
}()
mounted, err := Mounted(targetPath)
if err != nil {
t.Fatal(err)
}
if !mounted {
t.Fatalf("Expected %s to be mounted", targetPath)
}
}

9
mount/mounter_darwin.go Normal file
View file

@ -0,0 +1,9 @@
package mount
func mount(device, target, mType string, flag uintptr, data string) error {
panic("Not implemented")
}
func unmount(target string, flag int) error {
panic("Not implemented")
}

13
mount/mounter_linux.go Normal file
View file

@ -0,0 +1,13 @@
package mount
import (
"syscall"
)
func mount(device, target, mType string, flag uintptr, data string) error {
return syscall.Mount(device, target, mType, flag, data)
}
func unmount(target string, flag int) error {
return syscall.Unmount(target, flag)
}

56
mount/mountinfo.go Normal file
View file

@ -0,0 +1,56 @@
package mount
import (
"bufio"
"fmt"
"io"
"os"
)
const (
// We only parse upto the mountinfo because that is all we
// care about right now
mountinfoFormat = "%d %d %d:%d %s %s %s"
)
// Represents one line from /proc/self/mountinfo
type procEntry struct {
id, parent, major, minor int
source, mountpoint, opts string
}
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from bind mounts
func parseMountTable() ([]*procEntry, 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) ([]*procEntry, error) {
var (
s = bufio.NewScanner(r)
out = []*procEntry{}
)
for s.Scan() {
if err := s.Err(); err != nil {
return nil, err
}
var (
p = &procEntry{}
text = s.Text()
)
if _, err := fmt.Sscanf(text, mountinfoFormat,
&p.id, &p.parent, &p.major, &p.minor,
&p.source, &p.mountpoint, &p.opts); err != nil {
return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err)
}
out = append(out, p)
}
return out, nil
}

445
mount/mountinfo_test.go Normal file
View file

@ -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)
}
}

View file

@ -5,7 +5,7 @@ import (
"errors"
"fmt"
"github.com/dotcloud/docker/iptables"
"github.com/dotcloud/docker/netlink"
"github.com/dotcloud/docker/pkg/netlink"
"github.com/dotcloud/docker/proxy"
"github.com/dotcloud/docker/utils"
"log"
@ -19,6 +19,7 @@ import (
const (
DefaultNetworkBridge = "docker0"
DisableNetworkBridge = "none"
DefaultNetworkMtu = 1500
portRangeStart = 49153
portRangeEnd = 65535
siocBRADDBR = 0x89a0
@ -118,7 +119,6 @@ func CreateBridgeIface(config *DaemonConfig) error {
"192.168.44.1/24",
}
nameservers := []string{}
resolvConf, _ := utils.GetResolvConf()
// we don't check for an error here, because we don't really care
@ -628,7 +628,7 @@ func (iface *NetworkInterface) Release() {
log.Printf("Unable to release port %s", nat)
}
} else if nat.Port.Proto() == "udp" {
if err := iface.manager.tcpPortAllocator.Release(ip, hostPort); err != nil {
if err := iface.manager.udpPortAllocator.Release(ip, hostPort); err != nil {
log.Printf("Unable to release port %s: %s", nat, err)
}
}

View file

@ -129,7 +129,7 @@ func ValidateEnv(val string) (string, error) {
}
func ValidateHost(val string) (string, error) {
host, err := utils.ParseHost(DEFAULTHTTPHOST, DEFAULTHTTPPORT, val)
host, err := utils.ParseHost(DEFAULTHTTPHOST, DEFAULTHTTPPORT, DEFAULTUNIXSOCKET, val)
if err != nil {
return val, err
}

Some files were not shown because too many files have changed in this diff Show more