├── .dockerignore ├── .drone.yml ├── .gitignore ├── .wrap-docker-args ├── Dockerfile ├── Dockerfile.dapper ├── LICENSE ├── README.md ├── base-image ├── .dockerignore ├── .no-chown ├── Dockerfile.dapper ├── build.sh ├── config │ ├── amd64 │ │ └── buildroot-config-static │ ├── arm │ │ └── buildroot-config-static │ ├── arm64 │ │ └── buildroot-config-static │ └── busybox-ps-modprobe-only.config └── scripts │ ├── build │ ├── build-busybox-static │ ├── clean │ ├── download │ └── package ├── build.sh ├── main └── main.go ├── one.go ├── scratch.go ├── scripts ├── build ├── ci ├── common ├── crosstools.list ├── install-libs.sh ├── package └── test ├── selinux └── selinux_linux.go ├── trash.yml ├── util ├── util.go ├── util_linux.go └── util_test.go └── vendor └── github.com ├── Sirupsen └── logrus │ ├── .gitignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── entry.go │ ├── entry_test.go │ ├── exported.go │ ├── formatter.go │ ├── formatter_bench_test.go │ ├── hook_test.go │ ├── hooks.go │ ├── json_formatter.go │ ├── json_formatter_test.go │ ├── logger.go │ ├── logrus.go │ ├── logrus_test.go │ ├── terminal_bsd.go │ ├── terminal_linux.go │ ├── terminal_notwindows.go │ ├── terminal_windows.go │ ├── text_formatter.go │ ├── text_formatter_test.go │ └── writer.go ├── docker ├── docker │ ├── .dockerignore │ ├── .gitignore │ ├── .mailmap │ ├── AUTHORS │ ├── CHANGELOG.md │ ├── CONTRIBUTING.md │ ├── Dockerfile │ ├── Dockerfile.gccgo │ ├── Dockerfile.simple │ ├── LICENSE │ ├── MAINTAINERS │ ├── Makefile │ ├── NOTICE │ ├── README.md │ ├── ROADMAP.md │ ├── VERSION │ └── pkg │ │ ├── README.md │ │ ├── ioutils │ │ ├── bytespipe.go │ │ ├── bytespipe_test.go │ │ ├── fmt.go │ │ ├── fmt_test.go │ │ ├── multireader.go │ │ ├── multireader_test.go │ │ ├── readers.go │ │ ├── readers_test.go │ │ ├── scheduler.go │ │ ├── scheduler_gccgo.go │ │ ├── temp_unix.go │ │ ├── temp_windows.go │ │ ├── writeflusher.go │ │ ├── writers.go │ │ └── writers_test.go │ │ ├── longpath │ │ ├── longpath.go │ │ └── longpath_test.go │ │ └── mount │ │ ├── flags.go │ │ ├── flags_freebsd.go │ │ ├── flags_linux.go │ │ ├── flags_unsupported.go │ │ ├── mount.go │ │ ├── mount_test.go │ │ ├── mounter_freebsd.go │ │ ├── mounter_linux.go │ │ ├── mounter_unsupported.go │ │ ├── mountinfo.go │ │ ├── mountinfo_freebsd.go │ │ ├── mountinfo_linux.go │ │ ├── mountinfo_linux_test.go │ │ ├── mountinfo_unsupported.go │ │ ├── sharedsubtree_linux.go │ │ └── sharedsubtree_linux_test.go └── libnetwork │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile.build │ ├── LICENSE │ ├── MAINTAINERS │ ├── Makefile │ ├── README.md │ ├── ROADMAP.md │ ├── Vagrantfile │ ├── circle.yml │ ├── controller.go │ ├── default_gateway.go │ ├── default_gateway_freebsd.go │ ├── default_gateway_linux.go │ ├── default_gateway_windows.go │ ├── drivers.go │ ├── drivers_freebsd.go │ ├── drivers_linux.go │ ├── drivers_windows.go │ ├── endpoint.go │ ├── endpoint_cnt.go │ ├── endpoint_info.go │ ├── error.go │ ├── errors_test.go │ ├── libnetwork_internal_test.go │ ├── libnetwork_test.go │ ├── machines │ ├── network.go │ ├── resolvconf │ ├── README.md │ ├── dns │ │ └── resolvconf.go │ ├── resolvconf.go │ └── resolvconf_test.go │ ├── sandbox.go │ ├── sandbox_externalkey.go │ ├── sandbox_externalkey_unix.go │ ├── sandbox_externalkey_windows.go │ ├── sandbox_store.go │ ├── sandbox_test.go │ ├── store.go │ ├── store_test.go │ └── wrapmake.sh ├── flynn └── go-shlex │ ├── COPYING │ ├── Makefile │ ├── README.md │ ├── shlex.go │ └── shlex_test.go ├── j-keck └── arping │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── arp_datagram.go │ ├── arping.go │ ├── arping_bsd.go │ ├── arping_linux.go │ ├── arping_windows.go │ └── netutils.go ├── rancher └── netconf │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── bonding.go │ ├── bridge.go │ ├── ipv4ll_linux.go │ ├── netconf_linux.go │ ├── types.go │ └── vlan.go ├── ryanuber └── go-glob │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── glob.go │ └── glob_test.go ├── stretchr └── testify │ ├── .gitignore │ ├── .travis.yml │ ├── LICENCE.txt │ ├── README.md │ ├── assert │ ├── assertions.go │ ├── assertions_test.go │ ├── doc.go │ ├── errors.go │ ├── forward_assertions.go │ ├── forward_assertions_test.go │ ├── http_assertions.go │ └── http_assertions_test.go │ ├── doc.go │ ├── package_test.go │ └── require │ ├── doc.go │ ├── forward_requirements.go │ ├── forward_requirements_test.go │ ├── requirements.go │ └── requirements_test.go └── vishvananda └── netlink ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── addr.go ├── addr_linux.go ├── addr_test.go ├── class.go ├── class_linux.go ├── class_test.go ├── filter.go ├── filter_linux.go ├── filter_test.go ├── link.go ├── link_linux.go ├── link_test.go ├── link_tuntap_linux.go ├── neigh.go ├── neigh_linux.go ├── neigh_test.go ├── netlink.go ├── netlink_test.go ├── netlink_unspecified.go ├── nl ├── addr_linux.go ├── addr_linux_test.go ├── link_linux.go ├── nl_linux.go ├── nl_linux_test.go ├── route_linux.go ├── route_linux_test.go ├── tc_linux.go ├── tc_linux_test.go ├── xfrm_linux.go ├── xfrm_linux_test.go ├── xfrm_policy_linux.go ├── xfrm_policy_linux_test.go ├── xfrm_state_linux.go └── xfrm_state_linux_test.go ├── protinfo.go ├── protinfo_linux.go ├── protinfo_test.go ├── qdisc.go ├── qdisc_linux.go ├── qdisc_test.go ├── route.go ├── route_linux.go ├── route_test.go ├── xfrm.go ├── xfrm_policy.go ├── xfrm_policy_linux.go ├── xfrm_policy_test.go ├── xfrm_state.go ├── xfrm_state_linux.go └── xfrm_state_test.go /.dockerignore: -------------------------------------------------------------------------------- 1 | base-image 2 | assets 3 | .vendor 4 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: rancher/dapper:1.10.3 3 | volumes: 4 | - /var/run/docker.sock:/var/run/docker.sock 5 | commands: 6 | - dapper ./scripts/ci 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /build 3 | /assets 4 | /base-image/assets/ 5 | /base-image/build/ 6 | /base-image/cache/ 7 | /base-image/dist/ 8 | /.vendor 9 | -------------------------------------------------------------------------------- /.wrap-docker-args: -------------------------------------------------------------------------------- 1 | --privileged 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD build/base-files.tar.gz / 3 | COPY build/ca-certificates.crt /usr/etc/ssl/certs/ 4 | COPY build/dockerlaunch /usr/bin/ 5 | COPY build/docker* /usr/bin/ 6 | VOLUME /var/lib/docker 7 | ENTRYPOINT ["/usr/bin/dockerlaunch", "/usr/bin/docker"] 8 | CMD ["daemon", "-s", "overlay"] 9 | -------------------------------------------------------------------------------- /Dockerfile.dapper: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | RUN apt-get update && \ 4 | apt-get -y install locales sudo vim less curl wget git rsync build-essential isolinux xorriso gccgo \ 5 | libblkid-dev libmount-dev libselinux1-dev cpio genisoimage qemu-kvm python-pip ca-certificates pkg-config tox 6 | 7 | COPY ./scripts/install-libs.sh /tmp/ 8 | RUN /tmp/install-libs.sh 9 | 10 | RUN wget -O - https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz | tar -xz -C /usr/local 11 | RUN wget -O /usr/local/bin/docker -L https://get.docker.com/builds/Linux/x86_64/docker-1.10.3 && \ 12 | chmod +x /usr/local/bin/docker 13 | 14 | ENV PATH /usr/local/go/bin:$PATH 15 | RUN mkdir -p /go/src /go/bin && chmod -R 777 /go 16 | ENV GOPATH /go 17 | ENV PATH /go/bin:$PATH 18 | 19 | ENV DAPPER_SOURCE /go/src/github.com/rancher/docker-from-scratch 20 | ENV DAPPER_OUTPUT "" 21 | ENV DAPPER_DOCKER_SOCKET true 22 | ENV DAPPER_ENV NO_TEST ARCH 23 | 24 | RUN mkdir -p ${DAPPER_SOURCE}/assets && ln -s ${DAPPER_SOURCE} /source 25 | 26 | WORKDIR ${DAPPER_SOURCE}/assets 27 | 28 | RUN wget https://github.com/rancher/docker-from-scratch/releases/download/bin-v0.4.0/base-files_amd64.tar.gz && \ 29 | wget https://github.com/rancher/docker-from-scratch/releases/download/bin-v0.4.0/base-files_arm.tar.gz && \ 30 | wget https://github.com/rancher/docker-from-scratch/releases/download/bin-v0.4.0/base-files_arm64.tar.gz 31 | 32 | ENV DOCKER_VERSION=1.11.2 DOCKER_PATCH_VERSION=v1.11.2-ros1 33 | ENV VERSION=v${DOCKER_VERSION}-2 34 | 35 | RUN wget -O docker-${DOCKER_VERSION}_amd64.tgz -L https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz && \ 36 | wget -L https://github.com/rancher/docker/releases/download/${DOCKER_PATCH_VERSION}/docker-${DOCKER_VERSION}_arm.tgz && \ 37 | wget -L https://github.com/rancher/docker/releases/download/${DOCKER_PATCH_VERSION}/docker-${DOCKER_VERSION}_arm64.tgz 38 | 39 | WORKDIR ${DAPPER_SOURCE} 40 | 41 | CMD ./scripts/ci 42 | -------------------------------------------------------------------------------- /base-image/.dockerignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | .buildroot-ccache 4 | .kernel-ccache 5 | .dl 6 | -------------------------------------------------------------------------------- /base-image/.no-chown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/docker-from-scratch/084910d99b12408467a559f338e5a27bf4a1aed3/base-image/.no-chown -------------------------------------------------------------------------------- /base-image/Dockerfile.dapper: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04.3 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y build-essential wget libncurses5-dev unzip bc curl python rsync ccache 5 | 6 | RUN locale-gen en_US.UTF-8 7 | ENV LANG en_US.UTF-8 8 | 9 | ENV DAPPER_SOURCE /source 10 | ENV DAPPER_OUTPUT ./dist 11 | ENV SHELL /bin/bash 12 | WORKDIR ${DAPPER_SOURCE} 13 | -------------------------------------------------------------------------------- /base-image/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0) 5 | 6 | dapper ./scripts/build 7 | 8 | echo Done 9 | -------------------------------------------------------------------------------- /base-image/scripts/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0)/.. 5 | 6 | : ${CONFIG:=$(pwd)/config} 7 | : ${ARCH:='amd64 arm arm64'} 8 | 9 | ./scripts/download 10 | 11 | for arch in $ARCH; do 12 | ./scripts/build-busybox-static ${CONFIG}/${arch}/buildroot-config-static ${CONFIG}/busybox-ps-modprobe-only.config 13 | ./scripts/package ${arch} 14 | done 15 | -------------------------------------------------------------------------------- /base-image/scripts/build-busybox-static: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0)/.. 5 | 6 | : ${ARTIFACTS:=$(pwd)/assets} 7 | : ${BUILD:=$(pwd)/build} 8 | 9 | busybox_install() 10 | { 11 | local conf=$1 12 | local bbconf=$2 13 | 14 | mkdir -p ${BUILD} 15 | cd ${BUILD} 16 | 17 | local buildroot=$(ls -1 ${ARTIFACTS}/buildroot-*.tar.bz2) 18 | 19 | if [ ! -e "${buildroot}" ]; then 20 | echo "Failed to find busybox archive, found : ${buildroot}" 1>&2 21 | return 1 22 | else 23 | buildroot=$(basename $buildroot) 24 | fi 25 | 26 | rm -rf ${buildroot/.tar.bz2//} 27 | tar xvjf ${ARTIFACTS}/${buildroot} 28 | cd ${buildroot/.tar.bz2//} 29 | 30 | cp $conf .config 31 | if [ -n "$bbconf" ]; then 32 | cp $bbconf package/busybox/ 33 | fi 34 | make oldconfig 35 | make 36 | } 37 | 38 | busybox_install "$1" "$2" 39 | -------------------------------------------------------------------------------- /base-image/scripts/clean: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0)/.. 4 | 5 | rm -rf build dist 6 | -------------------------------------------------------------------------------- /base-image/scripts/download: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | cd $(dirname $0)/.. 6 | 7 | : ${ARTIFACTS:=$(pwd)/assets} 8 | 9 | check() 10 | { 11 | local hash=$1 12 | local file=$2 13 | 14 | if [ ! -e "$file" ]; then 15 | return 1 16 | fi 17 | 18 | CURRENT=$(sha1sum $file | awk '{print $1}') 19 | 20 | [ "$hash" = "$CURRENT" ] 21 | } 22 | 23 | download() 24 | { 25 | mkdir -p ${ARTIFACTS} 26 | 27 | local url=$2 28 | local file=${ARTIFACTS}/$(basename $2) 29 | local hash=$1 30 | 31 | if ! check $hash $file; then 32 | curl -sL $url > $file 33 | fi 34 | 35 | if ! check $hash $file; then 36 | echo "ERROR: $file does not match checksum $hash, got $CURRENT" 1>&2 37 | return 1 38 | fi 39 | } 40 | 41 | download 8f53493301804c0fabe444666edc344842b06e1a https://buildroot.org/downloads/buildroot-2016.02.tar.bz2 42 | -------------------------------------------------------------------------------- /base-image/scripts/package: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0)/.. 5 | 6 | rm -rf build/stage 7 | mkdir -p build/stage 8 | mkdir -p dist 9 | pushd build/stage 10 | 11 | BASE=$(echo ../buildroot-*/output/target/) 12 | 13 | mkdir -p usr/bin usr/share usr/libexec/git-core 14 | 15 | cp $BASE/bin/busybox usr/bin 16 | cp $BASE/usr/bin/xz usr/bin 17 | cp $BASE/usr/bin/git usr/bin 18 | cp $BASE/usr/bin/ssh usr/bin 19 | cp $BASE/usr/sbin/xtables-multi usr/bin/iptables 20 | cp -rf $BASE/usr/share/git-core usr/share 21 | 22 | ln -s ../../bin/git usr/libexec/git-core/git-clone 23 | ln -s ../../bin/git usr/libexec/git-core/git-checkout 24 | ln -s bin usr/sbin 25 | 26 | # Okay, this is a hack. I won't tell anyone if you don't. 27 | # Honestly, who uses git submodules anyways... 28 | echo '#!/usr/bin/busybox echo' > usr/libexec/git-core/git-submodule 29 | chmod +x usr/libexec/git-core/git-submodule 30 | 31 | ln -s busybox usr/bin/ps 32 | ln -s busybox usr/bin/modprobe 33 | 34 | tar cvzf ../../dist/base-files_${1}.tar.gz . 35 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | rm -rf ./build 5 | 6 | export NO_TEST=true 7 | dapper ./scripts/ci 8 | -------------------------------------------------------------------------------- /main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/rancher/docker-from-scratch" 5 | ) 6 | 7 | func main() { 8 | dockerlaunch.Main() 9 | } 10 | -------------------------------------------------------------------------------- /one.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | package dockerlaunch 3 | 4 | import ( 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | ) 9 | 10 | func PidOne() error { 11 | c := make(chan os.Signal, 2048) 12 | signal.Notify(c, syscall.SIGCHLD) 13 | 14 | for range c { 15 | for { 16 | if pid, err := syscall.Wait4(-1, nil, syscall.WNOHANG, nil); err != nil || pid <= 0 { 17 | break 18 | } 19 | } 20 | } 21 | 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /scripts/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | cd $(dirname $0)/.. 5 | 6 | arch="$1" 7 | 8 | rm -rf build 9 | mkdir -p build 10 | 11 | cp /etc/ssl/certs/ca-certificates.crt ./build/ 12 | cp ./assets/base-files_${arch}.tar.gz ./build/base-files.tar.gz 13 | tar -xf ./assets/docker-$(echo $DOCKER_VERSION | sed -e 's/^v//')_${arch}.tgz -C ./build --strip-components=1 14 | 15 | strip_bin=$(which strip) 16 | if [ "${arch}" == "arm" ]; then 17 | export GOARM=6 18 | export CGO_ENABLED=1 19 | export CC=/usr/bin/arm-linux-gnueabihf-gcc 20 | strip_bin=/usr/bin/arm-linux-gnueabihf-strip 21 | fi 22 | if [ "${arch}" == "arm64" ]; then 23 | export GOARM= 24 | export CGO_ENABLED=1 25 | export CC=/usr/bin/aarch64-linux-gnu-gcc 26 | strip_bin=/usr/bin/aarch64-linux-gnu-strip 27 | fi 28 | 29 | GOARCH=${arch} go build -ldflags "-linkmode external -extldflags -static" -o build/dockerlaunch ./main 30 | ${strip_bin} --strip-all build/dockerlaunch 31 | -------------------------------------------------------------------------------- /scripts/ci: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0) 5 | 6 | : ${ARCH:='amd64 arm arm64'} 7 | 8 | for arch in ${ARCH}; do 9 | ./build ${arch} 10 | ./package ${arch} 11 | done 12 | 13 | if [ -z "$NO_TEST" ]; then 14 | ./test 15 | fi 16 | -------------------------------------------------------------------------------- /scripts/common: -------------------------------------------------------------------------------- 1 | IMAGE=${IMAGE:-rancher/docker:${VERSION}} 2 | -------------------------------------------------------------------------------- /scripts/crosstools.list: -------------------------------------------------------------------------------- 1 | deb http://emdebian.org/tools/debian/ jessie main 2 | -------------------------------------------------------------------------------- /scripts/install-libs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | toolchains="arm-linux-gnueabihf aarch64-linux-gnu" 5 | libs="libselinux libsepol pcre3" 6 | 7 | cd /usr/local/src 8 | for i in $libs; do 9 | apt-get build-dep -y $i 10 | apt-get source -y $i 11 | done 12 | for TOOLCHAIN in $toolchains; do 13 | apt-get install -y gcc-${TOOLCHAIN} g++-${TOOLCHAIN} 14 | cd /usr/local/src/pcre3-* 15 | autoreconf 16 | CC=${TOOLCHAIN}-gcc CXX=${TOOLCHAIN}-g++ ./configure --host=${TOOLCHAIN} --prefix=/usr/${TOOLCHAIN} 17 | make -j$(nproc) 18 | make install && make distclean 19 | cd /usr/local/src/libselinux-* 20 | CC=${TOOLCHAIN}-gcc CXX=${TOOLCHAIN}-g++ make CFLAGS=-Wall 21 | make PREFIX=/usr/${TOOLCHAIN} DESTDIR=/usr/${TOOLCHAIN} install && make clean 22 | cd /usr/local/src/libsepol-* 23 | CC=${TOOLCHAIN}-gcc CXX=${TOOLCHAIN}-g++ make CFLAGS=-Wall 24 | make PREFIX=/usr/${TOOLCHAIN} DESTDIR=/usr/${TOOLCHAIN} install && make clean 25 | done 26 | -------------------------------------------------------------------------------- /scripts/package: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0)/.. 5 | 6 | arch="$1" 7 | 8 | . ./scripts/common 9 | 10 | [ "${arch}" == "amd64" ] || IMAGE=${IMAGE}_${arch} 11 | docker build -t ${IMAGE} -f Dockerfile . 12 | 13 | echo Built ${IMAGE} 14 | -------------------------------------------------------------------------------- /scripts/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd $(dirname $0)/.. 5 | 6 | . ./scripts/common 7 | 8 | mkdir -p build/test-cache 9 | ID=$(docker run -d --privileged -e DOCKER_LAUNCH_DEBUG=true -v /lib/modules/$(uname -r):/lib/modules/$(uname -r) $IMAGE daemon -s $(docker info | grep 'Storage Driver' | cut -f2 -d:)) 10 | docker logs -f $ID & 11 | trap "docker rm -fv $ID" EXIT 12 | docker exec -i $ID docker build -t test-build git://github.com/rancher/tiny-build.git 13 | docker exec -i $ID docker version 14 | docker exec -i $ID docker info 15 | -------------------------------------------------------------------------------- /selinux/selinux_linux.go: -------------------------------------------------------------------------------- 1 | package selinux 2 | 3 | // #cgo pkg-config: libselinux 4 | // #include 5 | import "C" 6 | 7 | func SetFileContext(path string, context string) (int, error) { 8 | ret, err := C.setfilecon(C.CString(path), C.CString(context)) 9 | return int(ret), err 10 | } 11 | -------------------------------------------------------------------------------- /trash.yml: -------------------------------------------------------------------------------- 1 | package: github.com/rancher/docker-from-scratch 2 | 3 | import: 4 | - package: github.com/Sirupsen/logrus 5 | version: 3cb248e9df77413d58a6330dde84236d04c197d5 6 | 7 | - package: github.com/docker/docker 8 | version: v1.9.1 9 | subpackages: 10 | - pkg/ioutils 11 | - pkg/mount 12 | 13 | - package: github.com/docker/libnetwork 14 | version: 077b0764e4926509c9e6213ae7b110de48494810 15 | subpackages: 16 | - resolvconf 17 | 18 | - package: github.com/j-keck/arping 19 | version: 4f4d2c8983a18e2c9c63a3f339bc9a998c4557bc 20 | 21 | - package: github.com/rancher/netconf 22 | version: bf95fd720be9de4f7aa3a4a529b70f2865dd0fc7 23 | 24 | - package: github.com/ryanuber/go-glob 25 | version: 0067a9abd927e50aed5190662702f81231413ae0 26 | 27 | - package: github.com/stretchr/testify 28 | version: a1f97990ddc16022ec7610326dd9bce31332c116 29 | subpackages: 30 | - assert 31 | - require 32 | 33 | - package: github.com/vishvananda/netlink 34 | version: edcd99c0881a4de0fdb3818af6b24f4ee6948464 35 | 36 | - package: github.com/flynn/go-shlex 37 | version: 3f9db97f856818214da2e1057f8ad84803971cff 38 | -------------------------------------------------------------------------------- /util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | func GetValue(index int, args []string) string { 8 | val := args[index] 9 | parts := strings.SplitN(val, "=", 2) 10 | if len(parts) == 1 { 11 | if len(args) > index+1 { 12 | return args[index+1] 13 | } else { 14 | return "" 15 | } 16 | } else { 17 | return parts[1] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /util/util_linux.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package util 4 | 5 | import ( 6 | "os" 7 | "syscall" 8 | 9 | "github.com/docker/docker/pkg/mount" 10 | ) 11 | 12 | func mountProc() error { 13 | if _, err := os.Stat("/proc/self/mountinfo"); os.IsNotExist(err) { 14 | if _, err := os.Stat("/proc"); os.IsNotExist(err) { 15 | if err = os.Mkdir("/proc", 0755); err != nil { 16 | return err 17 | } 18 | } 19 | 20 | if err := syscall.Mount("none", "/proc", "proc", 0, ""); err != nil { 21 | return err 22 | } 23 | } 24 | 25 | return nil 26 | } 27 | 28 | func Mount(device, directory, fsType, options string) error { 29 | if err := mountProc(); err != nil { 30 | return nil 31 | } 32 | 33 | if _, err := os.Stat(directory); os.IsNotExist(err) { 34 | err = os.MkdirAll(directory, 0755) 35 | if err != nil { 36 | return err 37 | } 38 | } 39 | 40 | return mount.Mount(device, directory, fsType, options) 41 | } 42 | -------------------------------------------------------------------------------- /util/util_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestNoPanic(t *testing.T) { 10 | assert := require.New(t) 11 | args := []string{"daemon", "--log-opt", "max-size=25m", "--log-opt", "max-file=2", "-s", "overlay", "-G", "docker", "-H", "unix:///var/run/docker.sock", "--userland-proxy=false", "--tlsverify", "--tlscacert=ca.pem", "--tlscert=server-cert.pem", "--tlskey=server-key.pem", "-H=0.0.0.0:2376"} 12 | for i, v := range args { 13 | if v == "-H=0.0.0.0:2376" { 14 | assert.Equal("0.0.0.0:2376", GetValue(i, args)) 15 | } 16 | if v == "-H" { 17 | assert.Equal("unix:///var/run/docker.sock", GetValue(i, args)) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/.gitignore: -------------------------------------------------------------------------------- 1 | logrus 2 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.2 4 | - 1.3 5 | - 1.4 6 | - tip 7 | install: 8 | - go get -t ./... 9 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.8.4 2 | 3 | formatter/text: fix data race (#218) 4 | 5 | # 0.8.3 6 | 7 | logrus/core: fix entry log level (#208) 8 | logrus/core: improve performance of text formatter by 40% 9 | logrus/core: expose `LevelHooks` type 10 | logrus/core: add support for DragonflyBSD and NetBSD 11 | formatter/text: print structs more verbosely 12 | 13 | # 0.8.2 14 | 15 | logrus: fix more Fatal family functions 16 | 17 | # 0.8.1 18 | 19 | logrus: fix not exiting on `Fatalf` and `Fatalln` 20 | 21 | # 0.8.0 22 | 23 | logrus: defaults to stderr instead of stdout 24 | hooks/sentry: add special field for `*http.Request` 25 | formatter/text: ignore Windows for colors 26 | 27 | # 0.7.3 28 | 29 | formatter/\*: allow configuration of timestamp layout 30 | 31 | # 0.7.2 32 | 33 | formatter/text: Add configuration option for time format (#158) 34 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simon Eskildsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/entry_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestEntryPanicln(t *testing.T) { 12 | errBoom := fmt.Errorf("boom time") 13 | 14 | defer func() { 15 | p := recover() 16 | assert.NotNil(t, p) 17 | 18 | switch pVal := p.(type) { 19 | case *Entry: 20 | assert.Equal(t, "kaboom", pVal.Message) 21 | assert.Equal(t, errBoom, pVal.Data["err"]) 22 | default: 23 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 24 | } 25 | }() 26 | 27 | logger := New() 28 | logger.Out = &bytes.Buffer{} 29 | entry := NewEntry(logger) 30 | entry.WithField("err", errBoom).Panicln("kaboom") 31 | } 32 | 33 | func TestEntryPanicf(t *testing.T) { 34 | errBoom := fmt.Errorf("boom again") 35 | 36 | defer func() { 37 | p := recover() 38 | assert.NotNil(t, p) 39 | 40 | switch pVal := p.(type) { 41 | case *Entry: 42 | assert.Equal(t, "kaboom true", pVal.Message) 43 | assert.Equal(t, errBoom, pVal.Data["err"]) 44 | default: 45 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 46 | } 47 | }() 48 | 49 | logger := New() 50 | logger.Out = &bytes.Buffer{} 51 | entry := NewEntry(logger) 52 | entry.WithField("err", errBoom).Panicf("kaboom %v", true) 53 | } 54 | 55 | func TestEntryLogLevel(t *testing.T) { 56 | out := &bytes.Buffer{} 57 | logger := New() 58 | logger.Out = out 59 | logger.Level = DebugLevel 60 | entry := NewEntry(logger) 61 | assert.Equal(t, DebugLevel, entry.Level) 62 | entry.Level = WarnLevel 63 | entry.Info("it should not be displayed") 64 | assert.Equal(t, "", out.String()) 65 | entry.Warn("it should be displayed") 66 | assert.Contains(t, out.String(), "it should be displayed") 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "time" 4 | 5 | const DefaultTimestampFormat = time.RFC3339 6 | 7 | // The Formatter interface is used to implement a custom Formatter. It takes an 8 | // `Entry`. It exposes all the fields, including the default ones: 9 | // 10 | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. 11 | // * `entry.Data["time"]`. The timestamp. 12 | // * `entry.Data["level"]. The level the entry was logged at. 13 | // 14 | // Any additional fields added with `WithField` or `WithFields` are also in 15 | // `entry.Data`. Format is expected to return an array of bytes which are then 16 | // logged to `logger.Out`. 17 | type Formatter interface { 18 | Format(*Entry) ([]byte, error) 19 | } 20 | 21 | // This is to not silently overwrite `time`, `msg` and `level` fields when 22 | // dumping it. If this code wasn't there doing: 23 | // 24 | // logrus.WithField("level", 1).Info("hello") 25 | // 26 | // Would just silently drop the user provided level. Instead with this code 27 | // it'll logged as: 28 | // 29 | // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} 30 | // 31 | // It's not exported because it's still using Data in an opinionated way. It's to 32 | // avoid code duplication between the two default formatters. 33 | func prefixFieldClashes(data Fields) { 34 | _, ok := data["time"] 35 | if ok { 36 | data["fields.time"] = data["time"] 37 | } 38 | 39 | _, ok = data["msg"] 40 | if ok { 41 | data["fields.msg"] = data["msg"] 42 | } 43 | 44 | _, ok = data["level"] 45 | if ok { 46 | data["fields.level"] = data["level"] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/formatter_bench_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | // smallFields is a small size data set for benchmarking 10 | var smallFields = Fields{ 11 | "foo": "bar", 12 | "baz": "qux", 13 | "one": "two", 14 | "three": "four", 15 | } 16 | 17 | // largeFields is a large size data set for benchmarking 18 | var largeFields = Fields{ 19 | "foo": "bar", 20 | "baz": "qux", 21 | "one": "two", 22 | "three": "four", 23 | "five": "six", 24 | "seven": "eight", 25 | "nine": "ten", 26 | "eleven": "twelve", 27 | "thirteen": "fourteen", 28 | "fifteen": "sixteen", 29 | "seventeen": "eighteen", 30 | "nineteen": "twenty", 31 | "a": "b", 32 | "c": "d", 33 | "e": "f", 34 | "g": "h", 35 | "i": "j", 36 | "k": "l", 37 | "m": "n", 38 | "o": "p", 39 | "q": "r", 40 | "s": "t", 41 | "u": "v", 42 | "w": "x", 43 | "y": "z", 44 | "this": "will", 45 | "make": "thirty", 46 | "entries": "yeah", 47 | } 48 | 49 | var errorFields = Fields{ 50 | "foo": fmt.Errorf("bar"), 51 | "baz": fmt.Errorf("qux"), 52 | } 53 | 54 | func BenchmarkErrorTextFormatter(b *testing.B) { 55 | doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields) 56 | } 57 | 58 | func BenchmarkSmallTextFormatter(b *testing.B) { 59 | doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields) 60 | } 61 | 62 | func BenchmarkLargeTextFormatter(b *testing.B) { 63 | doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields) 64 | } 65 | 66 | func BenchmarkSmallColoredTextFormatter(b *testing.B) { 67 | doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields) 68 | } 69 | 70 | func BenchmarkLargeColoredTextFormatter(b *testing.B) { 71 | doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields) 72 | } 73 | 74 | func BenchmarkSmallJSONFormatter(b *testing.B) { 75 | doBenchmark(b, &JSONFormatter{}, smallFields) 76 | } 77 | 78 | func BenchmarkLargeJSONFormatter(b *testing.B) { 79 | doBenchmark(b, &JSONFormatter{}, largeFields) 80 | } 81 | 82 | func doBenchmark(b *testing.B, formatter Formatter, fields Fields) { 83 | entry := &Entry{ 84 | Time: time.Time{}, 85 | Level: InfoLevel, 86 | Message: "message", 87 | Data: fields, 88 | } 89 | var d []byte 90 | var err error 91 | for i := 0; i < b.N; i++ { 92 | d, err = formatter.Format(entry) 93 | if err != nil { 94 | b.Fatal(err) 95 | } 96 | b.SetBytes(int64(len(d))) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/hook_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | type TestHook struct { 10 | Fired bool 11 | } 12 | 13 | func (hook *TestHook) Fire(entry *Entry) error { 14 | hook.Fired = true 15 | return nil 16 | } 17 | 18 | func (hook *TestHook) Levels() []Level { 19 | return []Level{ 20 | DebugLevel, 21 | InfoLevel, 22 | WarnLevel, 23 | ErrorLevel, 24 | FatalLevel, 25 | PanicLevel, 26 | } 27 | } 28 | 29 | func TestHookFires(t *testing.T) { 30 | hook := new(TestHook) 31 | 32 | LogAndAssertJSON(t, func(log *Logger) { 33 | log.Hooks.Add(hook) 34 | assert.Equal(t, hook.Fired, false) 35 | 36 | log.Print("test") 37 | }, func(fields Fields) { 38 | assert.Equal(t, hook.Fired, true) 39 | }) 40 | } 41 | 42 | type ModifyHook struct { 43 | } 44 | 45 | func (hook *ModifyHook) Fire(entry *Entry) error { 46 | entry.Data["wow"] = "whale" 47 | return nil 48 | } 49 | 50 | func (hook *ModifyHook) Levels() []Level { 51 | return []Level{ 52 | DebugLevel, 53 | InfoLevel, 54 | WarnLevel, 55 | ErrorLevel, 56 | FatalLevel, 57 | PanicLevel, 58 | } 59 | } 60 | 61 | func TestHookCanModifyEntry(t *testing.T) { 62 | hook := new(ModifyHook) 63 | 64 | LogAndAssertJSON(t, func(log *Logger) { 65 | log.Hooks.Add(hook) 66 | log.WithField("wow", "elephant").Print("test") 67 | }, func(fields Fields) { 68 | assert.Equal(t, fields["wow"], "whale") 69 | }) 70 | } 71 | 72 | func TestCanFireMultipleHooks(t *testing.T) { 73 | hook1 := new(ModifyHook) 74 | hook2 := new(TestHook) 75 | 76 | LogAndAssertJSON(t, func(log *Logger) { 77 | log.Hooks.Add(hook1) 78 | log.Hooks.Add(hook2) 79 | 80 | log.WithField("wow", "elephant").Print("test") 81 | }, func(fields Fields) { 82 | assert.Equal(t, fields["wow"], "whale") 83 | assert.Equal(t, hook2.Fired, true) 84 | }) 85 | } 86 | 87 | type ErrorHook struct { 88 | Fired bool 89 | } 90 | 91 | func (hook *ErrorHook) Fire(entry *Entry) error { 92 | hook.Fired = true 93 | return nil 94 | } 95 | 96 | func (hook *ErrorHook) Levels() []Level { 97 | return []Level{ 98 | ErrorLevel, 99 | } 100 | } 101 | 102 | func TestErrorHookShouldntFireOnInfo(t *testing.T) { 103 | hook := new(ErrorHook) 104 | 105 | LogAndAssertJSON(t, func(log *Logger) { 106 | log.Hooks.Add(hook) 107 | log.Info("test") 108 | }, func(fields Fields) { 109 | assert.Equal(t, hook.Fired, false) 110 | }) 111 | } 112 | 113 | func TestErrorHookShouldFireOnError(t *testing.T) { 114 | hook := new(ErrorHook) 115 | 116 | LogAndAssertJSON(t, func(log *Logger) { 117 | log.Hooks.Add(hook) 118 | log.Error("test") 119 | }, func(fields Fields) { 120 | assert.Equal(t, hook.Fired, true) 121 | }) 122 | } 123 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/hooks.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | // A hook to be fired when logging on the logging levels returned from 4 | // `Levels()` on your implementation of the interface. Note that this is not 5 | // fired in a goroutine or a channel with workers, you should handle such 6 | // functionality yourself if your call is non-blocking and you don't wish for 7 | // the logging calls for levels returned from `Levels()` to block. 8 | type Hook interface { 9 | Levels() []Level 10 | Fire(*Entry) error 11 | } 12 | 13 | // Internal type for storing the hooks on a logger instance. 14 | type LevelHooks map[Level][]Hook 15 | 16 | // Add a hook to an instance of logger. This is called with 17 | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. 18 | func (hooks LevelHooks) Add(hook Hook) { 19 | for _, level := range hook.Levels() { 20 | hooks[level] = append(hooks[level], hook) 21 | } 22 | } 23 | 24 | // Fire all the hooks for the passed level. Used by `entry.log` to fire 25 | // appropriate hooks for a log entry. 26 | func (hooks LevelHooks) Fire(level Level, entry *Entry) error { 27 | for _, hook := range hooks[level] { 28 | if err := hook.Fire(entry); err != nil { 29 | return err 30 | } 31 | } 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/json_formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type JSONFormatter struct { 9 | // TimestampFormat sets the format used for marshaling timestamps. 10 | TimestampFormat string 11 | } 12 | 13 | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { 14 | data := make(Fields, len(entry.Data)+3) 15 | for k, v := range entry.Data { 16 | switch v := v.(type) { 17 | case error: 18 | // Otherwise errors are ignored by `encoding/json` 19 | // https://github.com/Sirupsen/logrus/issues/137 20 | data[k] = v.Error() 21 | default: 22 | data[k] = v 23 | } 24 | } 25 | prefixFieldClashes(data) 26 | 27 | timestampFormat := f.TimestampFormat 28 | if timestampFormat == "" { 29 | timestampFormat = DefaultTimestampFormat 30 | } 31 | 32 | data["time"] = entry.Time.Format(timestampFormat) 33 | data["msg"] = entry.Message 34 | data["level"] = entry.Level.String() 35 | 36 | serialized, err := json.Marshal(data) 37 | if err != nil { 38 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 39 | } 40 | return append(serialized, '\n'), nil 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/json_formatter_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestErrorNotLost(t *testing.T) { 11 | formatter := &JSONFormatter{} 12 | 13 | b, err := formatter.Format(WithField("error", errors.New("wild walrus"))) 14 | if err != nil { 15 | t.Fatal("Unable to format entry: ", err) 16 | } 17 | 18 | entry := make(map[string]interface{}) 19 | err = json.Unmarshal(b, &entry) 20 | if err != nil { 21 | t.Fatal("Unable to unmarshal formatted entry: ", err) 22 | } 23 | 24 | if entry["error"] != "wild walrus" { 25 | t.Fatal("Error field not set") 26 | } 27 | } 28 | 29 | func TestErrorNotLostOnFieldNotNamedError(t *testing.T) { 30 | formatter := &JSONFormatter{} 31 | 32 | b, err := formatter.Format(WithField("omg", errors.New("wild walrus"))) 33 | if err != nil { 34 | t.Fatal("Unable to format entry: ", err) 35 | } 36 | 37 | entry := make(map[string]interface{}) 38 | err = json.Unmarshal(b, &entry) 39 | if err != nil { 40 | t.Fatal("Unable to unmarshal formatted entry: ", err) 41 | } 42 | 43 | if entry["omg"] != "wild walrus" { 44 | t.Fatal("Error field not set") 45 | } 46 | } 47 | 48 | func TestFieldClashWithTime(t *testing.T) { 49 | formatter := &JSONFormatter{} 50 | 51 | b, err := formatter.Format(WithField("time", "right now!")) 52 | if err != nil { 53 | t.Fatal("Unable to format entry: ", err) 54 | } 55 | 56 | entry := make(map[string]interface{}) 57 | err = json.Unmarshal(b, &entry) 58 | if err != nil { 59 | t.Fatal("Unable to unmarshal formatted entry: ", err) 60 | } 61 | 62 | if entry["fields.time"] != "right now!" { 63 | t.Fatal("fields.time not set to original time field") 64 | } 65 | 66 | if entry["time"] != "0001-01-01T00:00:00Z" { 67 | t.Fatal("time field not set to current time, was: ", entry["time"]) 68 | } 69 | } 70 | 71 | func TestFieldClashWithMsg(t *testing.T) { 72 | formatter := &JSONFormatter{} 73 | 74 | b, err := formatter.Format(WithField("msg", "something")) 75 | if err != nil { 76 | t.Fatal("Unable to format entry: ", err) 77 | } 78 | 79 | entry := make(map[string]interface{}) 80 | err = json.Unmarshal(b, &entry) 81 | if err != nil { 82 | t.Fatal("Unable to unmarshal formatted entry: ", err) 83 | } 84 | 85 | if entry["fields.msg"] != "something" { 86 | t.Fatal("fields.msg not set to original msg field") 87 | } 88 | } 89 | 90 | func TestFieldClashWithLevel(t *testing.T) { 91 | formatter := &JSONFormatter{} 92 | 93 | b, err := formatter.Format(WithField("level", "something")) 94 | if err != nil { 95 | t.Fatal("Unable to format entry: ", err) 96 | } 97 | 98 | entry := make(map[string]interface{}) 99 | err = json.Unmarshal(b, &entry) 100 | if err != nil { 101 | t.Fatal("Unable to unmarshal formatted entry: ", err) 102 | } 103 | 104 | if entry["fields.level"] != "something" { 105 | t.Fatal("fields.level not set to original level field") 106 | } 107 | } 108 | 109 | func TestJSONEntryEndsWithNewline(t *testing.T) { 110 | formatter := &JSONFormatter{} 111 | 112 | b, err := formatter.Format(WithField("level", "something")) 113 | if err != nil { 114 | t.Fatal("Unable to format entry: ", err) 115 | } 116 | 117 | if b[len(b)-1] != '\n' { 118 | t.Fatal("Expected JSON log entry to end with a newline") 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/logrus.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | // Fields type, used to pass to `WithFields`. 9 | type Fields map[string]interface{} 10 | 11 | // Level type 12 | type Level uint8 13 | 14 | // Convert the Level to a string. E.g. PanicLevel becomes "panic". 15 | func (level Level) String() string { 16 | switch level { 17 | case DebugLevel: 18 | return "debug" 19 | case InfoLevel: 20 | return "info" 21 | case WarnLevel: 22 | return "warning" 23 | case ErrorLevel: 24 | return "error" 25 | case FatalLevel: 26 | return "fatal" 27 | case PanicLevel: 28 | return "panic" 29 | } 30 | 31 | return "unknown" 32 | } 33 | 34 | // ParseLevel takes a string level and returns the Logrus log level constant. 35 | func ParseLevel(lvl string) (Level, error) { 36 | switch lvl { 37 | case "panic": 38 | return PanicLevel, nil 39 | case "fatal": 40 | return FatalLevel, nil 41 | case "error": 42 | return ErrorLevel, nil 43 | case "warn", "warning": 44 | return WarnLevel, nil 45 | case "info": 46 | return InfoLevel, nil 47 | case "debug": 48 | return DebugLevel, nil 49 | } 50 | 51 | var l Level 52 | return l, fmt.Errorf("not a valid logrus Level: %q", lvl) 53 | } 54 | 55 | // These are the different logging levels. You can set the logging level to log 56 | // on your instance of logger, obtained with `logrus.New()`. 57 | const ( 58 | // PanicLevel level, highest level of severity. Logs and then calls panic with the 59 | // message passed to Debug, Info, ... 60 | PanicLevel Level = iota 61 | // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the 62 | // logging level is set to Panic. 63 | FatalLevel 64 | // ErrorLevel level. Logs. Used for errors that should definitely be noted. 65 | // Commonly used for hooks to send errors to an error tracking service. 66 | ErrorLevel 67 | // WarnLevel level. Non-critical entries that deserve eyes. 68 | WarnLevel 69 | // InfoLevel level. General operational entries about what's going on inside the 70 | // application. 71 | InfoLevel 72 | // DebugLevel level. Usually only enabled when debugging. Very verbose logging. 73 | DebugLevel 74 | ) 75 | 76 | // Won't compile if StdLogger can't be realized by a log.Logger 77 | var _ StdLogger = &log.Logger{} 78 | 79 | // StdLogger is what your logrus-enabled library should take, that way 80 | // it'll accept a stdlib logger and a logrus logger. There's no standard 81 | // interface, this is the closest we get, unfortunately. 82 | type StdLogger interface { 83 | Print(...interface{}) 84 | Printf(string, ...interface{}) 85 | Println(...interface{}) 86 | 87 | Fatal(...interface{}) 88 | Fatalf(string, ...interface{}) 89 | Fatalln(...interface{}) 90 | 91 | Panic(...interface{}) 92 | Panicf(string, ...interface{}) 93 | Panicln(...interface{}) 94 | } 95 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd dragonfly 2 | 3 | package logrus 4 | 5 | import "syscall" 6 | 7 | const ioctlReadTermios = syscall.TIOCGETA 8 | 9 | type Termios syscall.Termios 10 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_linux.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TCGETS 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_notwindows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build linux darwin freebsd openbsd netbsd dragonfly 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | // IsTerminal returns true if the given file descriptor is a terminal. 16 | func IsTerminal() bool { 17 | fd := syscall.Stdout 18 | var termios Termios 19 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 20 | return err == 0 21 | } 22 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/terminal_windows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build windows 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 16 | 17 | var ( 18 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 19 | ) 20 | 21 | // IsTerminal returns true if the given file descriptor is a terminal. 22 | func IsTerminal() bool { 23 | fd := syscall.Stdout 24 | var st uint32 25 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 26 | return r != 0 && e == 0 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/text_formatter_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestQuoting(t *testing.T) { 11 | tf := &TextFormatter{DisableColors: true} 12 | 13 | checkQuoting := func(q bool, value interface{}) { 14 | b, _ := tf.Format(WithField("test", value)) 15 | idx := bytes.Index(b, ([]byte)("test=")) 16 | cont := bytes.Contains(b[idx+5:], []byte{'"'}) 17 | if cont != q { 18 | if q { 19 | t.Errorf("quoting expected for: %#v", value) 20 | } else { 21 | t.Errorf("quoting not expected for: %#v", value) 22 | } 23 | } 24 | } 25 | 26 | checkQuoting(false, "abcd") 27 | checkQuoting(false, "v1.0") 28 | checkQuoting(false, "1234567890") 29 | checkQuoting(true, "/foobar") 30 | checkQuoting(true, "x y") 31 | checkQuoting(true, "x,y") 32 | checkQuoting(false, errors.New("invalid")) 33 | checkQuoting(true, errors.New("invalid argument")) 34 | } 35 | 36 | func TestTimestampFormat(t *testing.T) { 37 | checkTimeStr := func(format string) { 38 | customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format} 39 | customStr, _ := customFormatter.Format(WithField("test", "test")) 40 | timeStart := bytes.Index(customStr, ([]byte)("time=")) 41 | timeEnd := bytes.Index(customStr, ([]byte)("level=")) 42 | timeStr := customStr[timeStart+5 : timeEnd-1] 43 | if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' { 44 | timeStr = timeStr[1 : len(timeStr)-1] 45 | } 46 | if format == "" { 47 | format = time.RFC3339 48 | } 49 | _, e := time.Parse(format, (string)(timeStr)) 50 | if e != nil { 51 | t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e) 52 | } 53 | } 54 | 55 | checkTimeStr("2006-01-02T15:04:05.000000000Z07:00") 56 | checkTimeStr("Mon Jan _2 15:04:05 2006") 57 | checkTimeStr("") 58 | } 59 | 60 | // TODO add tests for sorting etc., this requires a parser for the text 61 | // formatter output. 62 | -------------------------------------------------------------------------------- /vendor/github.com/Sirupsen/logrus/writer.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "runtime" 7 | ) 8 | 9 | func (logger *Logger) Writer() *io.PipeWriter { 10 | reader, writer := io.Pipe() 11 | 12 | go logger.writerScanner(reader) 13 | runtime.SetFinalizer(writer, writerFinalizer) 14 | 15 | return writer 16 | } 17 | 18 | func (logger *Logger) writerScanner(reader *io.PipeReader) { 19 | scanner := bufio.NewScanner(reader) 20 | for scanner.Scan() { 21 | logger.Print(scanner.Text()) 22 | } 23 | if err := scanner.Err(); err != nil { 24 | logger.Errorf("Error while reading from Writer: %s", err) 25 | } 26 | reader.Close() 27 | } 28 | 29 | func writerFinalizer(writer *io.PipeWriter) { 30 | writer.Close() 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/.dockerignore: -------------------------------------------------------------------------------- 1 | bundles 2 | .gopath 3 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/.gitignore: -------------------------------------------------------------------------------- 1 | # Docker project generated files to ignore 2 | # if you want to ignore files created by your editor/tools, 3 | # please consider a global .gitignore https://help.github.com/articles/ignoring-files 4 | *.exe 5 | *.exe~ 6 | *.orig 7 | *.rej 8 | *.test 9 | .*.swp 10 | .DS_Store 11 | .bashrc 12 | .dotcloud 13 | .flymake* 14 | .git/ 15 | .gopath/ 16 | .hg/ 17 | .vagrant* 18 | Vagrantfile 19 | a.out 20 | autogen/ 21 | bin 22 | build_src 23 | bundles/ 24 | docker/docker 25 | docs/AWS_S3_BUCKET 26 | docs/GITCOMMIT 27 | docs/GIT_BRANCH 28 | docs/VERSION 29 | docs/_build 30 | docs/_static 31 | docs/_templates 32 | docs/changed-files 33 | # generated by man/md2man-all.sh 34 | man/man1 35 | man/man5 36 | man/man8 37 | pyenv 38 | vendor/pkg/ 39 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/Dockerfile.gccgo: -------------------------------------------------------------------------------- 1 | # This file describes the standard way to build Docker, using docker 2 | # 3 | # Usage: 4 | # 5 | # # Assemble the full dev environment. This is slow the first time. 6 | # docker build -t docker -f Dockerfile.gccgo . 7 | # 8 | 9 | FROM gcc:5.2 10 | 11 | # Packaged dependencies 12 | RUN apt-get update && apt-get install -y \ 13 | apparmor \ 14 | aufs-tools \ 15 | btrfs-tools \ 16 | build-essential \ 17 | curl \ 18 | git \ 19 | iptables \ 20 | net-tools \ 21 | libapparmor-dev \ 22 | libcap-dev \ 23 | libsqlite3-dev \ 24 | mercurial \ 25 | parallel \ 26 | python-mock \ 27 | python-pip \ 28 | python-websocket \ 29 | --no-install-recommends 30 | 31 | # Get lvm2 source for compiling statically 32 | RUN git clone -b v2_02_103 https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 33 | # see https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags 34 | 35 | # Compile and install lvm2 36 | RUN cd /usr/local/lvm2 \ 37 | && ./configure --enable-static_link \ 38 | && make device-mapper \ 39 | && make install_device-mapper 40 | # see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL 41 | 42 | # Install lxc 43 | ENV LXC_VERSION 1.1.2 44 | RUN mkdir -p /usr/src/lxc \ 45 | && curl -sSL https://linuxcontainers.org/downloads/lxc/lxc-${LXC_VERSION}.tar.gz | tar -v -C /usr/src/lxc/ -xz --strip-components=1 46 | RUN cd /usr/src/lxc \ 47 | && ./configure \ 48 | && make \ 49 | && make install \ 50 | && ldconfig 51 | 52 | ENV GOPATH /go:/go/src/github.com/docker/docker/vendor 53 | 54 | # Get the "docker-py" source so we can run their integration tests 55 | ENV DOCKER_PY_COMMIT 139850f3f3b17357bab5ba3edfb745fb14043764 56 | RUN git clone https://github.com/docker/docker-py.git /docker-py \ 57 | && cd /docker-py \ 58 | && git checkout -q $DOCKER_PY_COMMIT 59 | 60 | # Add an unprivileged user to be used for tests which need it 61 | RUN groupadd -r docker 62 | RUN useradd --create-home --gid docker unprivilegeduser 63 | 64 | VOLUME /var/lib/docker 65 | WORKDIR /go/src/github.com/docker/docker 66 | ENV DOCKER_BUILDTAGS apparmor selinux 67 | 68 | # Wrap all commands in the "docker-in-docker" script to allow nested containers 69 | ENTRYPOINT ["hack/dind"] 70 | 71 | # Upload docker source 72 | COPY . /go/src/github.com/docker/docker 73 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/Dockerfile.simple: -------------------------------------------------------------------------------- 1 | # docker build -t docker:simple -f Dockerfile.simple . 2 | # docker run --rm docker:simple hack/make.sh dynbinary 3 | # docker run --rm --privileged docker:simple hack/dind hack/make.sh test-unit 4 | # docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration-cli 5 | 6 | # This represents the bare minimum required to build and test Docker. 7 | 8 | FROM debian:jessie 9 | 10 | # compile and runtime deps 11 | # https://github.com/docker/docker/blob/master/project/PACKAGERS.md#build-dependencies 12 | # https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies 13 | RUN apt-get update && apt-get install -y --no-install-recommends \ 14 | btrfs-tools \ 15 | curl \ 16 | gcc \ 17 | git \ 18 | golang \ 19 | libdevmapper-dev \ 20 | libsqlite3-dev \ 21 | \ 22 | ca-certificates \ 23 | e2fsprogs \ 24 | iptables \ 25 | procps \ 26 | xfsprogs \ 27 | xz-utils \ 28 | \ 29 | aufs-tools \ 30 | lxc \ 31 | && rm -rf /var/lib/apt/lists/* 32 | 33 | ENV AUTO_GOPATH 1 34 | WORKDIR /usr/src/docker 35 | COPY . /usr/src/docker 36 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all binary build cross default docs docs-build docs-shell shell test test-unit test-integration-cli test-docker-py validate 2 | 3 | # env vars passed through directly to Docker's build scripts 4 | # to allow things like `make DOCKER_CLIENTONLY=1 binary` easily 5 | # `docs/sources/contributing/devenvironment.md ` and `project/PACKAGERS.md` have some limited documentation of some of these 6 | DOCKER_ENVS := \ 7 | -e BUILDFLAGS \ 8 | -e DOCKER_CLIENTONLY \ 9 | -e DOCKER_DEBUG \ 10 | -e DOCKER_EXECDRIVER \ 11 | -e DOCKER_EXPERIMENTAL \ 12 | -e DOCKER_REMAP_ROOT \ 13 | -e DOCKER_GRAPHDRIVER \ 14 | -e DOCKER_STORAGE_OPTS \ 15 | -e DOCKER_USERLANDPROXY \ 16 | -e TESTDIRS \ 17 | -e TESTFLAGS \ 18 | -e TIMEOUT 19 | # note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds 20 | 21 | # to allow `make BIND_DIR=. shell` or `make BIND_DIR= test` 22 | # (default to no bind mount if DOCKER_HOST is set) 23 | # note: BINDDIR is supported for backwards-compatibility here 24 | BIND_DIR := $(if $(BINDDIR),$(BINDDIR),$(if $(DOCKER_HOST),,bundles)) 25 | DOCKER_MOUNT := $(if $(BIND_DIR),-v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/docker/docker/$(BIND_DIR)") 26 | 27 | 28 | GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null) 29 | DOCKER_IMAGE := docker-dev$(if $(GIT_BRANCH),:$(GIT_BRANCH)) 30 | DOCKER_DOCS_IMAGE := docker-docs$(if $(GIT_BRANCH),:$(GIT_BRANCH)) 31 | 32 | DOCKER_RUN_DOCKER := docker run --rm -it --privileged $(DOCKER_ENVS) $(DOCKER_MOUNT) "$(DOCKER_IMAGE)" 33 | 34 | DOCKER_RUN_DOCS := docker run --rm -it $(DOCS_MOUNT) -e AWS_S3_BUCKET -e NOCACHE 35 | 36 | # for some docs workarounds (see below in "docs-build" target) 37 | GITCOMMIT := $(shell git rev-parse --short HEAD 2>/dev/null) 38 | 39 | default: binary 40 | 41 | all: build 42 | $(DOCKER_RUN_DOCKER) hack/make.sh 43 | 44 | binary: build 45 | $(DOCKER_RUN_DOCKER) hack/make.sh binary 46 | 47 | cross: build 48 | $(DOCKER_RUN_DOCKER) hack/make.sh binary cross 49 | 50 | deb: build 51 | $(DOCKER_RUN_DOCKER) hack/make.sh binary build-deb 52 | 53 | rpm: build 54 | $(DOCKER_RUN_DOCKER) hack/make.sh binary build-rpm 55 | 56 | test: build 57 | $(DOCKER_RUN_DOCKER) hack/make.sh binary cross test-unit test-integration-cli test-docker-py 58 | 59 | test-unit: build 60 | $(DOCKER_RUN_DOCKER) hack/make.sh test-unit 61 | 62 | test-integration-cli: build 63 | $(DOCKER_RUN_DOCKER) hack/make.sh binary test-integration-cli 64 | 65 | test-docker-py: build 66 | $(DOCKER_RUN_DOCKER) hack/make.sh binary test-docker-py 67 | 68 | validate: build 69 | $(DOCKER_RUN_DOCKER) hack/make.sh validate-dco validate-gofmt validate-pkg validate-lint validate-test validate-toml validate-vet 70 | 71 | shell: build 72 | $(DOCKER_RUN_DOCKER) bash 73 | 74 | build: bundles 75 | docker build -t "$(DOCKER_IMAGE)" . 76 | 77 | bundles: 78 | mkdir bundles 79 | 80 | docs: 81 | $(MAKE) -C docs docs 82 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/NOTICE: -------------------------------------------------------------------------------- 1 | Docker 2 | Copyright 2012-2015 Docker, Inc. 3 | 4 | This product includes software developed at Docker, Inc. (https://www.docker.com). 5 | 6 | This product contains software (https://github.com/kr/pty) developed 7 | by Keith Rarick, licensed under the MIT License. 8 | 9 | The following is courtesy of our legal counsel: 10 | 11 | 12 | Use and transfer of Docker may be subject to certain restrictions by the 13 | United States and other governments. 14 | It is your responsibility to ensure that your use and/or transfer does not 15 | violate applicable laws. 16 | 17 | For more information, please see https://www.bis.doc.gov 18 | 19 | See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. 20 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/VERSION: -------------------------------------------------------------------------------- 1 | 1.9.1 2 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/README.md: -------------------------------------------------------------------------------- 1 | pkg/ is a collection of utility packages used by the Docker project without being specific to its internals. 2 | 3 | Utility packages are kept separate from the docker core codebase to keep it as small and concise as possible. 4 | If some utilities grow larger and their APIs stabilize, they may be moved to their own repository under the 5 | Docker organization, to facilitate re-use by other projects. However that is not the priority. 6 | 7 | The directory `pkg` is named after the same directory in the camlistore project. Since Brad is a core 8 | Go maintainer, we thought it made sense to copy his methods for organizing Go code :) Thanks Brad! 9 | 10 | Because utility packages are small and neatly separated from the rest of the codebase, they are a good 11 | place to start for aspiring maintainers and contributors. Get in touch if you want to help maintain them! 12 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | const maxCap = 1e6 4 | 5 | // BytesPipe is io.ReadWriter which works similarly to pipe(queue). 6 | // All written data could be read only once. Also BytesPipe is allocating 7 | // and releasing new byte slices to adjust to current needs, so there won't be 8 | // overgrown buffer after high load peak. 9 | // BytesPipe isn't goroutine-safe, caller must synchronize it if needed. 10 | type BytesPipe struct { 11 | buf [][]byte // slice of byte-slices of buffered data 12 | lastRead int // index in the first slice to a read point 13 | bufLen int // length of data buffered over the slices 14 | } 15 | 16 | // NewBytesPipe creates new BytesPipe, initialized by specified slice. 17 | // If buf is nil, then it will be initialized with slice which cap is 64. 18 | // buf will be adjusted in a way that len(buf) == 0, cap(buf) == cap(buf). 19 | func NewBytesPipe(buf []byte) *BytesPipe { 20 | if cap(buf) == 0 { 21 | buf = make([]byte, 0, 64) 22 | } 23 | return &BytesPipe{ 24 | buf: [][]byte{buf[:0]}, 25 | } 26 | } 27 | 28 | // Write writes p to BytesPipe. 29 | // It can allocate new []byte slices in a process of writing. 30 | func (bp *BytesPipe) Write(p []byte) (n int, err error) { 31 | for { 32 | // write data to the last buffer 33 | b := bp.buf[len(bp.buf)-1] 34 | // copy data to the current empty allocated area 35 | n := copy(b[len(b):cap(b)], p) 36 | // increment buffered data length 37 | bp.bufLen += n 38 | // include written data in last buffer 39 | bp.buf[len(bp.buf)-1] = b[:len(b)+n] 40 | 41 | // if there was enough room to write all then break 42 | if len(p) == n { 43 | break 44 | } 45 | 46 | // more data: write to the next slice 47 | p = p[n:] 48 | // allocate slice that has twice the size of the last unless maximum reached 49 | nextCap := 2 * cap(bp.buf[len(bp.buf)-1]) 50 | if maxCap < nextCap { 51 | nextCap = maxCap 52 | } 53 | // add new byte slice to the buffers slice and continue writing 54 | bp.buf = append(bp.buf, make([]byte, 0, nextCap)) 55 | } 56 | return 57 | } 58 | 59 | func (bp *BytesPipe) len() int { 60 | return bp.bufLen - bp.lastRead 61 | } 62 | 63 | // Read reads bytes from BytesPipe. 64 | // Data could be read only once. 65 | func (bp *BytesPipe) Read(p []byte) (n int, err error) { 66 | for { 67 | read := copy(p, bp.buf[0][bp.lastRead:]) 68 | n += read 69 | bp.lastRead += read 70 | if bp.len() == 0 { 71 | // we have read everything. reset to the beginning. 72 | bp.lastRead = 0 73 | bp.bufLen -= len(bp.buf[0]) 74 | bp.buf[0] = bp.buf[0][:0] 75 | break 76 | } 77 | // break if everything was read 78 | if len(p) == read { 79 | break 80 | } 81 | // more buffered data and more asked. read from next slice. 82 | p = p[read:] 83 | bp.lastRead = 0 84 | bp.bufLen -= len(bp.buf[0]) 85 | bp.buf[0] = nil // throw away old slice 86 | bp.buf = bp.buf[1:] // switch to next 87 | } 88 | return 89 | } 90 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/fmt.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | // FprintfIfNotEmpty prints the string value if it's not empty 9 | func FprintfIfNotEmpty(w io.Writer, format, value string) (int, error) { 10 | if value != "" { 11 | return fmt.Fprintf(w, format, value) 12 | } 13 | return 0, nil 14 | } 15 | 16 | // FprintfIfTrue prints the boolean value if it's true 17 | func FprintfIfTrue(w io.Writer, format string, ok bool) (int, error) { 18 | if ok { 19 | return fmt.Fprintf(w, format, ok) 20 | } 21 | return 0, nil 22 | } 23 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/fmt_test.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import "testing" 4 | 5 | func TestFprintfIfNotEmpty(t *testing.T) { 6 | wc := NewWriteCounter(&NopWriter{}) 7 | n, _ := FprintfIfNotEmpty(wc, "foo%s", "") 8 | 9 | if wc.Count != 0 || n != 0 { 10 | t.Errorf("Wrong count: %v vs. %v vs. 0", wc.Count, n) 11 | } 12 | 13 | n, _ = FprintfIfNotEmpty(wc, "foo%s", "bar") 14 | if wc.Count != 6 || n != 6 { 15 | t.Errorf("Wrong count: %v vs. %v vs. 6", wc.Count, n) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/scheduler.go: -------------------------------------------------------------------------------- 1 | // +build !gccgo 2 | 3 | package ioutils 4 | 5 | func callSchedulerIfNecessary() { 6 | } 7 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/scheduler_gccgo.go: -------------------------------------------------------------------------------- 1 | // +build gccgo 2 | 3 | package ioutils 4 | 5 | import ( 6 | "runtime" 7 | ) 8 | 9 | func callSchedulerIfNecessary() { 10 | //allow or force Go scheduler to switch context, without explicitly 11 | //forcing this will make it hang when using gccgo implementation 12 | runtime.Gosched() 13 | } 14 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package ioutils 4 | 5 | import "io/ioutil" 6 | 7 | // TempDir on Unix systems is equivalent to ioutil.TempDir. 8 | func TempDir(dir, prefix string) (string, error) { 9 | return ioutil.TempDir(dir, prefix) 10 | } 11 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package ioutils 4 | 5 | import ( 6 | "io/ioutil" 7 | 8 | "github.com/docker/docker/pkg/longpath" 9 | ) 10 | 11 | // TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format. 12 | func TempDir(dir, prefix string) (string, error) { 13 | tempDir, err := ioutil.TempDir(dir, prefix) 14 | if err != nil { 15 | return "", err 16 | } 17 | return longpath.AddPrefix(tempDir), nil 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/writeflusher.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | "net/http" 7 | "sync" 8 | ) 9 | 10 | // WriteFlusher wraps the Write and Flush operation ensuring that every write 11 | // is a flush. In addition, the Close method can be called to intercept 12 | // Read/Write calls if the targets lifecycle has already ended. 13 | type WriteFlusher struct { 14 | mu sync.Mutex 15 | w io.Writer 16 | flusher http.Flusher 17 | flushed bool 18 | closed error 19 | 20 | // TODO(stevvooe): Use channel for closed instead, remove mutex. Using a 21 | // channel will allow one to properly order the operations. 22 | } 23 | 24 | var errWriteFlusherClosed = errors.New("writeflusher: closed") 25 | 26 | func (wf *WriteFlusher) Write(b []byte) (n int, err error) { 27 | wf.mu.Lock() 28 | defer wf.mu.Unlock() 29 | if wf.closed != nil { 30 | return 0, wf.closed 31 | } 32 | 33 | n, err = wf.w.Write(b) 34 | wf.flush() // every write is a flush. 35 | return n, err 36 | } 37 | 38 | // Flush the stream immediately. 39 | func (wf *WriteFlusher) Flush() { 40 | wf.mu.Lock() 41 | defer wf.mu.Unlock() 42 | 43 | wf.flush() 44 | } 45 | 46 | // flush the stream immediately without taking a lock. Used internally. 47 | func (wf *WriteFlusher) flush() { 48 | if wf.closed != nil { 49 | return 50 | } 51 | 52 | wf.flushed = true 53 | wf.flusher.Flush() 54 | } 55 | 56 | // Flushed returns the state of flushed. 57 | // If it's flushed, return true, or else it return false. 58 | func (wf *WriteFlusher) Flushed() bool { 59 | // BUG(stevvooe): Remove this method. Its use is inherently racy. Seems to 60 | // be used to detect whether or a response code has been issued or not. 61 | // Another hook should be used instead. 62 | wf.mu.Lock() 63 | defer wf.mu.Unlock() 64 | 65 | return wf.flushed 66 | } 67 | 68 | // Close closes the write flusher, disallowing any further writes to the 69 | // target. After the flusher is closed, all calls to write or flush will 70 | // result in an error. 71 | func (wf *WriteFlusher) Close() error { 72 | wf.mu.Lock() 73 | defer wf.mu.Unlock() 74 | 75 | if wf.closed != nil { 76 | return wf.closed 77 | } 78 | 79 | wf.closed = errWriteFlusherClosed 80 | return nil 81 | } 82 | 83 | // NewWriteFlusher returns a new WriteFlusher. 84 | func NewWriteFlusher(w io.Writer) *WriteFlusher { 85 | var flusher http.Flusher 86 | if f, ok := w.(http.Flusher); ok { 87 | flusher = f 88 | } else { 89 | flusher = &NopFlusher{} 90 | } 91 | return &WriteFlusher{w: w, flusher: flusher} 92 | } 93 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/writers.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import "io" 4 | 5 | // NopWriter represents a type which write operation is nop. 6 | type NopWriter struct{} 7 | 8 | func (*NopWriter) Write(buf []byte) (int, error) { 9 | return len(buf), nil 10 | } 11 | 12 | type nopWriteCloser struct { 13 | io.Writer 14 | } 15 | 16 | func (w *nopWriteCloser) Close() error { return nil } 17 | 18 | // NopWriteCloser returns a nopWriteCloser. 19 | func NopWriteCloser(w io.Writer) io.WriteCloser { 20 | return &nopWriteCloser{w} 21 | } 22 | 23 | // NopFlusher represents a type which flush opetatin is nop. 24 | type NopFlusher struct{} 25 | 26 | // Flush is a nop operation. 27 | func (f *NopFlusher) Flush() {} 28 | 29 | type writeCloserWrapper struct { 30 | io.Writer 31 | closer func() error 32 | } 33 | 34 | func (r *writeCloserWrapper) Close() error { 35 | return r.closer() 36 | } 37 | 38 | // NewWriteCloserWrapper returns a new io.WriteCloser. 39 | func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser { 40 | return &writeCloserWrapper{ 41 | Writer: r, 42 | closer: closer, 43 | } 44 | } 45 | 46 | // WriteCounter wraps a concrete io.Writer and hold a count of the number 47 | // of bytes written to the writer during a "session". 48 | // This can be convenient when write return is masked 49 | // (e.g., json.Encoder.Encode()) 50 | type WriteCounter struct { 51 | Count int64 52 | Writer io.Writer 53 | } 54 | 55 | // NewWriteCounter returns a new WriteCounter. 56 | func NewWriteCounter(w io.Writer) *WriteCounter { 57 | return &WriteCounter{ 58 | Writer: w, 59 | } 60 | } 61 | 62 | func (wc *WriteCounter) Write(p []byte) (count int, err error) { 63 | count, err = wc.Writer.Write(p) 64 | wc.Count += int64(count) 65 | return 66 | } 67 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/ioutils/writers_test.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import ( 4 | "bytes" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestWriteCloserWrapperClose(t *testing.T) { 10 | called := false 11 | writer := bytes.NewBuffer([]byte{}) 12 | wrapper := NewWriteCloserWrapper(writer, func() error { 13 | called = true 14 | return nil 15 | }) 16 | if err := wrapper.Close(); err != nil { 17 | t.Fatal(err) 18 | } 19 | if !called { 20 | t.Fatalf("writeCloserWrapper should have call the anonymous function.") 21 | } 22 | } 23 | 24 | func TestNopWriteCloser(t *testing.T) { 25 | writer := bytes.NewBuffer([]byte{}) 26 | wrapper := NopWriteCloser(writer) 27 | if err := wrapper.Close(); err != nil { 28 | t.Fatal("NopWriteCloser always return nil on Close.") 29 | } 30 | 31 | } 32 | 33 | func TestNopWriter(t *testing.T) { 34 | nw := &NopWriter{} 35 | l, err := nw.Write([]byte{'c'}) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | if l != 1 { 40 | t.Fatalf("Expected 1 got %d", l) 41 | } 42 | } 43 | 44 | func TestWriteCounter(t *testing.T) { 45 | dummy1 := "This is a dummy string." 46 | dummy2 := "This is another dummy string." 47 | totalLength := int64(len(dummy1) + len(dummy2)) 48 | 49 | reader1 := strings.NewReader(dummy1) 50 | reader2 := strings.NewReader(dummy2) 51 | 52 | var buffer bytes.Buffer 53 | wc := NewWriteCounter(&buffer) 54 | 55 | reader1.WriteTo(wc) 56 | reader2.WriteTo(wc) 57 | 58 | if wc.Count != totalLength { 59 | t.Errorf("Wrong count: %d vs. %d", wc.Count, totalLength) 60 | } 61 | 62 | if buffer.String() != dummy1+dummy2 { 63 | t.Error("Wrong message written") 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/longpath/longpath.go: -------------------------------------------------------------------------------- 1 | // longpath introduces some constants and helper functions for handling long paths 2 | // in Windows, which are expected to be prepended with `\\?\` and followed by either 3 | // a drive letter, a UNC server\share, or a volume identifier. 4 | 5 | package longpath 6 | 7 | import ( 8 | "strings" 9 | ) 10 | 11 | // Prefix is the longpath prefix for Windows file paths. 12 | const Prefix = `\\?\` 13 | 14 | // AddPrefix will add the Windows long path prefix to the path provided if 15 | // it does not already have it. 16 | func AddPrefix(path string) string { 17 | if !strings.HasPrefix(path, Prefix) { 18 | if strings.HasPrefix(path, `\\`) { 19 | // This is a UNC path, so we need to add 'UNC' to the path as well. 20 | path = Prefix + `UNC` + path[1:] 21 | } else { 22 | path = Prefix + path 23 | } 24 | } 25 | return path 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/longpath/longpath_test.go: -------------------------------------------------------------------------------- 1 | package longpath 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestStandardLongPath(t *testing.T) { 9 | c := `C:\simple\path` 10 | longC := AddPrefix(c) 11 | if !strings.EqualFold(longC, `\\?\C:\simple\path`) { 12 | t.Errorf("Wrong long path returned. Original = %s ; Long = %s", c, longC) 13 | } 14 | } 15 | 16 | func TestUNCLongPath(t *testing.T) { 17 | c := `\\server\share\path` 18 | longC := AddPrefix(c) 19 | if !strings.EqualFold(longC, `\\?\UNC\server\share\path`) { 20 | t.Errorf("Wrong UNC long path returned. Original = %s ; Long = %s", c, longC) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/flags.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | // Parse fstab type mount options into mount() flags 8 | // and device specific data 9 | func parseOptions(options string) (int, string) { 10 | var ( 11 | flag int 12 | data []string 13 | ) 14 | 15 | flags := map[string]struct { 16 | clear bool 17 | flag int 18 | }{ 19 | "defaults": {false, 0}, 20 | "ro": {false, RDONLY}, 21 | "rw": {true, RDONLY}, 22 | "suid": {true, NOSUID}, 23 | "nosuid": {false, NOSUID}, 24 | "dev": {true, NODEV}, 25 | "nodev": {false, NODEV}, 26 | "exec": {true, NOEXEC}, 27 | "noexec": {false, NOEXEC}, 28 | "sync": {false, SYNCHRONOUS}, 29 | "async": {true, SYNCHRONOUS}, 30 | "dirsync": {false, DIRSYNC}, 31 | "remount": {false, REMOUNT}, 32 | "mand": {false, MANDLOCK}, 33 | "nomand": {true, MANDLOCK}, 34 | "atime": {true, NOATIME}, 35 | "noatime": {false, NOATIME}, 36 | "diratime": {true, NODIRATIME}, 37 | "nodiratime": {false, NODIRATIME}, 38 | "bind": {false, BIND}, 39 | "rbind": {false, RBIND}, 40 | "unbindable": {false, UNBINDABLE}, 41 | "runbindable": {false, RUNBINDABLE}, 42 | "private": {false, PRIVATE}, 43 | "rprivate": {false, RPRIVATE}, 44 | "shared": {false, SHARED}, 45 | "rshared": {false, RSHARED}, 46 | "slave": {false, SLAVE}, 47 | "rslave": {false, RSLAVE}, 48 | "relatime": {false, RELATIME}, 49 | "norelatime": {true, RELATIME}, 50 | "strictatime": {false, STRICTATIME}, 51 | "nostrictatime": {true, STRICTATIME}, 52 | } 53 | 54 | for _, o := range strings.Split(options, ",") { 55 | // If the option does not exist in the flags table or the flag 56 | // is not supported on the platform, 57 | // then it is a data value for a specific fs type 58 | if f, exists := flags[o]; exists && f.flag != 0 { 59 | if f.clear { 60 | flag &= ^f.flag 61 | } else { 62 | flag |= f.flag 63 | } 64 | } else { 65 | data = append(data, o) 66 | } 67 | } 68 | return flag, strings.Join(data, ",") 69 | } 70 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/flags_freebsd.go: -------------------------------------------------------------------------------- 1 | // +build freebsd,cgo 2 | 3 | package mount 4 | 5 | /* 6 | #include 7 | */ 8 | import "C" 9 | 10 | const ( 11 | // RDONLY will mount the filesystem as read-only. 12 | RDONLY = C.MNT_RDONLY 13 | 14 | // NOSUID will not allow set-user-identifier or set-group-identifier bits to 15 | // take effect. 16 | NOSUID = C.MNT_NOSUID 17 | 18 | // NOEXEC will not allow execution of any binaries on the mounted file system. 19 | NOEXEC = C.MNT_NOEXEC 20 | 21 | // SYNCHRONOUS will allow any I/O to the file system to be done synchronously. 22 | SYNCHRONOUS = C.MNT_SYNCHRONOUS 23 | 24 | // NOATIME will not update the file access time when reading from a file. 25 | NOATIME = C.MNT_NOATIME 26 | ) 27 | 28 | // These flags are unsupported. 29 | const ( 30 | BIND = 0 31 | DIRSYNC = 0 32 | MANDLOCK = 0 33 | NODEV = 0 34 | NODIRATIME = 0 35 | UNBINDABLE = 0 36 | RUNBINDABLE = 0 37 | PRIVATE = 0 38 | RPRIVATE = 0 39 | SHARED = 0 40 | RSHARED = 0 41 | SLAVE = 0 42 | RSLAVE = 0 43 | RBIND = 0 44 | RELATIVE = 0 45 | RELATIME = 0 46 | REMOUNT = 0 47 | STRICTATIME = 0 48 | ) 49 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/flags_linux.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | const ( 8 | // RDONLY will mount the file system read-only. 9 | RDONLY = syscall.MS_RDONLY 10 | 11 | // NOSUID will not allow set-user-identifier or set-group-identifier bits to 12 | // take effect. 13 | NOSUID = syscall.MS_NOSUID 14 | 15 | // NODEV will not interpret character or block special devices on the file 16 | // system. 17 | NODEV = syscall.MS_NODEV 18 | 19 | // NOEXEC will not allow execution of any binaries on the mounted file system. 20 | NOEXEC = syscall.MS_NOEXEC 21 | 22 | // SYNCHRONOUS will allow I/O to the file system to be done synchronously. 23 | SYNCHRONOUS = syscall.MS_SYNCHRONOUS 24 | 25 | // DIRSYNC will force all directory updates within the file system to be done 26 | // synchronously. This affects the following system calls: creat, link, 27 | // unlink, symlink, mkdir, rmdir, mknod and rename. 28 | DIRSYNC = syscall.MS_DIRSYNC 29 | 30 | // REMOUNT will attempt to remount an already-mounted file system. This is 31 | // commonly used to change the mount flags for a file system, especially to 32 | // make a readonly file system writeable. It does not change device or mount 33 | // point. 34 | REMOUNT = syscall.MS_REMOUNT 35 | 36 | // MANDLOCK will force mandatory locks on a filesystem. 37 | MANDLOCK = syscall.MS_MANDLOCK 38 | 39 | // NOATIME will not update the file access time when reading from a file. 40 | NOATIME = syscall.MS_NOATIME 41 | 42 | // NODIRATIME will not update the directory access time. 43 | NODIRATIME = syscall.MS_NODIRATIME 44 | 45 | // BIND remounts a subtree somewhere else. 46 | BIND = syscall.MS_BIND 47 | 48 | // RBIND remounts a subtree and all possible submounts somewhere else. 49 | RBIND = syscall.MS_BIND | syscall.MS_REC 50 | 51 | // UNBINDABLE creates a mount which cannot be cloned through a bind operation. 52 | UNBINDABLE = syscall.MS_UNBINDABLE 53 | 54 | // RUNBINDABLE marks the entire mount tree as UNBINDABLE. 55 | RUNBINDABLE = syscall.MS_UNBINDABLE | syscall.MS_REC 56 | 57 | // PRIVATE creates a mount which carries no propagation abilities. 58 | PRIVATE = syscall.MS_PRIVATE 59 | 60 | // RPRIVATE marks the entire mount tree as PRIVATE. 61 | RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC 62 | 63 | // SLAVE creates a mount which receives propagation from its master, but not 64 | // vice versa. 65 | SLAVE = syscall.MS_SLAVE 66 | 67 | // RSLAVE marks the entire mount tree as SLAVE. 68 | RSLAVE = syscall.MS_SLAVE | syscall.MS_REC 69 | 70 | // SHARED creates a mount which provides the ability to create mirrors of 71 | // that mount such that mounts and unmounts within any of the mirrors 72 | // propagate to the other mirrors. 73 | SHARED = syscall.MS_SHARED 74 | 75 | // RSHARED marks the entire mount tree as SHARED. 76 | RSHARED = syscall.MS_SHARED | syscall.MS_REC 77 | 78 | // RELATIME updates inode access times relative to modify or change time. 79 | RELATIME = syscall.MS_RELATIME 80 | 81 | // STRICTATIME allows to explicitly request full atime updates. This makes 82 | // it possible for the kernel to default to relatime or noatime but still 83 | // allow userspace to override it. 84 | STRICTATIME = syscall.MS_STRICTATIME 85 | ) 86 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/flags_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd freebsd,!cgo 2 | 3 | package mount 4 | 5 | // These flags are unsupported. 6 | const ( 7 | BIND = 0 8 | DIRSYNC = 0 9 | MANDLOCK = 0 10 | NOATIME = 0 11 | NODEV = 0 12 | NODIRATIME = 0 13 | NOEXEC = 0 14 | NOSUID = 0 15 | UNBINDABLE = 0 16 | RUNBINDABLE = 0 17 | PRIVATE = 0 18 | RPRIVATE = 0 19 | SHARED = 0 20 | RSHARED = 0 21 | SLAVE = 0 22 | RSLAVE = 0 23 | RBIND = 0 24 | RELATIME = 0 25 | RELATIVE = 0 26 | REMOUNT = 0 27 | STRICTATIME = 0 28 | SYNCHRONOUS = 0 29 | RDONLY = 0 30 | ) 31 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mount.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // GetMounts retrieves a list of mounts for the current running process. 8 | func GetMounts() ([]*Info, error) { 9 | return parseMountTable() 10 | } 11 | 12 | // Mounted looks at /proc/self/mountinfo to determine of the specified 13 | // mountpoint has been mounted 14 | func Mounted(mountpoint string) (bool, error) { 15 | entries, err := parseMountTable() 16 | if err != nil { 17 | return false, err 18 | } 19 | 20 | // Search the table for the mountpoint 21 | for _, e := range entries { 22 | if e.Mountpoint == mountpoint { 23 | return true, nil 24 | } 25 | } 26 | return false, nil 27 | } 28 | 29 | // Mount will mount filesystem according to the specified configuration, on the 30 | // condition that the target path is *not* already mounted. Options must be 31 | // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See 32 | // flags.go for supported option flags. 33 | func Mount(device, target, mType, options string) error { 34 | flag, _ := parseOptions(options) 35 | if flag&REMOUNT != REMOUNT { 36 | if mounted, err := Mounted(target); err != nil || mounted { 37 | return err 38 | } 39 | } 40 | return ForceMount(device, target, mType, options) 41 | } 42 | 43 | // ForceMount will mount a filesystem according to the specified configuration, 44 | // *regardless* if the target path is not already mounted. Options must be 45 | // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See 46 | // flags.go for supported option flags. 47 | func ForceMount(device, target, mType, options string) error { 48 | flag, data := parseOptions(options) 49 | if err := mount(device, target, mType, uintptr(flag), data); err != nil { 50 | return err 51 | } 52 | return nil 53 | } 54 | 55 | // Unmount will unmount the target filesystem, so long as it is mounted. 56 | func Unmount(target string) error { 57 | if mounted, err := Mounted(target); err != nil || !mounted { 58 | return err 59 | } 60 | return ForceUnmount(target) 61 | } 62 | 63 | // ForceUnmount will force an unmount of the target filesystem, regardless if 64 | // it is mounted or not. 65 | func ForceUnmount(target string) (err error) { 66 | // Simple retry logic for unmount 67 | for i := 0; i < 10; i++ { 68 | if err = unmount(target, 0); err == nil { 69 | return nil 70 | } 71 | time.Sleep(100 * time.Millisecond) 72 | } 73 | return 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mount_test.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "testing" 7 | ) 8 | 9 | func TestMountOptionsParsing(t *testing.T) { 10 | options := "noatime,ro,size=10k" 11 | 12 | flag, data := parseOptions(options) 13 | 14 | if data != "size=10k" { 15 | t.Fatalf("Expected size=10 got %s", data) 16 | } 17 | 18 | expectedFlag := NOATIME | RDONLY 19 | 20 | if flag != expectedFlag { 21 | t.Fatalf("Expected %d got %d", expectedFlag, flag) 22 | } 23 | } 24 | 25 | func TestMounted(t *testing.T) { 26 | tmp := path.Join(os.TempDir(), "mount-tests") 27 | if err := os.MkdirAll(tmp, 0777); err != nil { 28 | t.Fatal(err) 29 | } 30 | defer os.RemoveAll(tmp) 31 | 32 | var ( 33 | sourceDir = path.Join(tmp, "source") 34 | targetDir = path.Join(tmp, "target") 35 | sourcePath = path.Join(sourceDir, "file.txt") 36 | targetPath = path.Join(targetDir, "file.txt") 37 | ) 38 | 39 | os.Mkdir(sourceDir, 0777) 40 | os.Mkdir(targetDir, 0777) 41 | 42 | f, err := os.Create(sourcePath) 43 | if err != nil { 44 | t.Fatal(err) 45 | } 46 | f.WriteString("hello") 47 | f.Close() 48 | 49 | f, err = os.Create(targetPath) 50 | if err != nil { 51 | t.Fatal(err) 52 | } 53 | f.Close() 54 | 55 | if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil { 56 | t.Fatal(err) 57 | } 58 | defer func() { 59 | if err := Unmount(targetDir); err != nil { 60 | t.Fatal(err) 61 | } 62 | }() 63 | 64 | mounted, err := Mounted(targetDir) 65 | if err != nil { 66 | t.Fatal(err) 67 | } 68 | if !mounted { 69 | t.Fatalf("Expected %s to be mounted", targetDir) 70 | } 71 | if _, err := os.Stat(targetDir); err != nil { 72 | t.Fatal(err) 73 | } 74 | } 75 | 76 | func TestMountReadonly(t *testing.T) { 77 | tmp := path.Join(os.TempDir(), "mount-tests") 78 | if err := os.MkdirAll(tmp, 0777); err != nil { 79 | t.Fatal(err) 80 | } 81 | defer os.RemoveAll(tmp) 82 | 83 | var ( 84 | sourceDir = path.Join(tmp, "source") 85 | targetDir = path.Join(tmp, "target") 86 | sourcePath = path.Join(sourceDir, "file.txt") 87 | targetPath = path.Join(targetDir, "file.txt") 88 | ) 89 | 90 | os.Mkdir(sourceDir, 0777) 91 | os.Mkdir(targetDir, 0777) 92 | 93 | f, err := os.Create(sourcePath) 94 | if err != nil { 95 | t.Fatal(err) 96 | } 97 | f.WriteString("hello") 98 | f.Close() 99 | 100 | f, err = os.Create(targetPath) 101 | if err != nil { 102 | t.Fatal(err) 103 | } 104 | f.Close() 105 | 106 | if err := Mount(sourceDir, targetDir, "none", "bind,ro"); err != nil { 107 | t.Fatal(err) 108 | } 109 | defer func() { 110 | if err := Unmount(targetDir); err != nil { 111 | t.Fatal(err) 112 | } 113 | }() 114 | 115 | f, err = os.OpenFile(targetPath, os.O_RDWR, 0777) 116 | if err == nil { 117 | t.Fatal("Should not be able to open a ro file as rw") 118 | } 119 | } 120 | 121 | func TestGetMounts(t *testing.T) { 122 | mounts, err := GetMounts() 123 | if err != nil { 124 | t.Fatal(err) 125 | } 126 | 127 | root := false 128 | for _, entry := range mounts { 129 | if entry.Mountpoint == "/" { 130 | root = true 131 | } 132 | } 133 | 134 | if !root { 135 | t.Fatal("/ should be mounted at least") 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mounter_freebsd.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | /* 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | */ 11 | import "C" 12 | 13 | import ( 14 | "fmt" 15 | "strings" 16 | "syscall" 17 | "unsafe" 18 | ) 19 | 20 | func allocateIOVecs(options []string) []C.struct_iovec { 21 | out := make([]C.struct_iovec, len(options)) 22 | for i, option := range options { 23 | out[i].iov_base = unsafe.Pointer(C.CString(option)) 24 | out[i].iov_len = C.size_t(len(option) + 1) 25 | } 26 | return out 27 | } 28 | 29 | func mount(device, target, mType string, flag uintptr, data string) error { 30 | isNullFS := false 31 | 32 | xs := strings.Split(data, ",") 33 | for _, x := range xs { 34 | if x == "bind" { 35 | isNullFS = true 36 | } 37 | } 38 | 39 | options := []string{"fspath", target} 40 | if isNullFS { 41 | options = append(options, "fstype", "nullfs", "target", device) 42 | } else { 43 | options = append(options, "fstype", mType, "from", device) 44 | } 45 | rawOptions := allocateIOVecs(options) 46 | for _, rawOption := range rawOptions { 47 | defer C.free(rawOption.iov_base) 48 | } 49 | 50 | if errno := C.nmount(&rawOptions[0], C.uint(len(options)), C.int(flag)); errno != 0 { 51 | reason := C.GoString(C.strerror(*C.__error())) 52 | return fmt.Errorf("Failed to call nmount: %s", reason) 53 | } 54 | return nil 55 | } 56 | 57 | func unmount(target string, flag int) error { 58 | return syscall.Unmount(target, flag) 59 | } 60 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mounter_linux.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | func mount(device, target, mType string, flag uintptr, data string) error { 8 | if err := syscall.Mount(device, target, mType, flag, data); err != nil { 9 | return err 10 | } 11 | 12 | // If we have a bind mount or remount, remount... 13 | if flag&syscall.MS_BIND == syscall.MS_BIND && flag&syscall.MS_RDONLY == syscall.MS_RDONLY { 14 | return syscall.Mount(device, target, mType, flag|syscall.MS_REMOUNT, data) 15 | } 16 | return nil 17 | } 18 | 19 | func unmount(target string, flag int) error { 20 | return syscall.Unmount(target, flag) 21 | } 22 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mounter_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd freebsd,!cgo 2 | 3 | package mount 4 | 5 | func mount(device, target, mType string, flag uintptr, data string) error { 6 | panic("Not implemented") 7 | } 8 | 9 | func unmount(target string, flag int) error { 10 | panic("Not implemented") 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mountinfo.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | // Info reveals information about a particular mounted filesystem. This 4 | // struct is populated from the content in the /proc//mountinfo file. 5 | type Info struct { 6 | // ID is a unique identifier of the mount (may be reused after umount). 7 | ID int 8 | 9 | // Parent indicates the ID of the mount parent (or of self for the top of the 10 | // mount tree). 11 | Parent int 12 | 13 | // Major indicates one half of the device ID which identifies the device class. 14 | Major int 15 | 16 | // Minor indicates one half of the device ID which identifies a specific 17 | // instance of device. 18 | Minor int 19 | 20 | // Root of the mount within the filesystem. 21 | Root string 22 | 23 | // Mountpoint indicates the mount point relative to the process's root. 24 | Mountpoint string 25 | 26 | // Opts represents mount-specific options. 27 | Opts string 28 | 29 | // Optional represents optional fields. 30 | Optional string 31 | 32 | // Fstype indicates the type of filesystem, such as EXT3. 33 | Fstype string 34 | 35 | // Source indicates filesystem specific information or "none". 36 | Source string 37 | 38 | // VfsOpts represents per super block options. 39 | VfsOpts string 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go: -------------------------------------------------------------------------------- 1 | package mount 2 | 3 | /* 4 | #include 5 | #include 6 | #include 7 | */ 8 | import "C" 9 | 10 | import ( 11 | "fmt" 12 | "reflect" 13 | "unsafe" 14 | ) 15 | 16 | // Parse /proc/self/mountinfo because comparing Dev and ino does not work from 17 | // bind mounts. 18 | func parseMountTable() ([]*Info, error) { 19 | var rawEntries *C.struct_statfs 20 | 21 | count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT)) 22 | if count == 0 { 23 | return nil, fmt.Errorf("Failed to call getmntinfo") 24 | } 25 | 26 | var entries []C.struct_statfs 27 | header := (*reflect.SliceHeader)(unsafe.Pointer(&entries)) 28 | header.Cap = count 29 | header.Len = count 30 | header.Data = uintptr(unsafe.Pointer(rawEntries)) 31 | 32 | var out []*Info 33 | for _, entry := range entries { 34 | var mountinfo Info 35 | mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0]) 36 | mountinfo.Source = C.GoString(&entry.f_mntfromname[0]) 37 | mountinfo.Fstype = C.GoString(&entry.f_fstypename[0]) 38 | out = append(out, &mountinfo) 39 | } 40 | return out, nil 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package mount 4 | 5 | import ( 6 | "bufio" 7 | "fmt" 8 | "io" 9 | "os" 10 | "strings" 11 | ) 12 | 13 | const ( 14 | /* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue 15 | (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) 16 | 17 | (1) mount ID: unique identifier of the mount (may be reused after umount) 18 | (2) parent ID: ID of parent (or of self for the top of the mount tree) 19 | (3) major:minor: value of st_dev for files on filesystem 20 | (4) root: root of the mount within the filesystem 21 | (5) mount point: mount point relative to the process's root 22 | (6) mount options: per mount options 23 | (7) optional fields: zero or more fields of the form "tag[:value]" 24 | (8) separator: marks the end of the optional fields 25 | (9) filesystem type: name of filesystem of the form "type[.subtype]" 26 | (10) mount source: filesystem specific information or "none" 27 | (11) super options: per super block options*/ 28 | mountinfoFormat = "%d %d %d:%d %s %s %s %s" 29 | ) 30 | 31 | // Parse /proc/self/mountinfo because comparing Dev and ino does not work from 32 | // bind mounts 33 | func parseMountTable() ([]*Info, error) { 34 | f, err := os.Open("/proc/self/mountinfo") 35 | if err != nil { 36 | return nil, err 37 | } 38 | defer f.Close() 39 | 40 | return parseInfoFile(f) 41 | } 42 | 43 | func parseInfoFile(r io.Reader) ([]*Info, error) { 44 | var ( 45 | s = bufio.NewScanner(r) 46 | out = []*Info{} 47 | ) 48 | 49 | for s.Scan() { 50 | if err := s.Err(); err != nil { 51 | return nil, err 52 | } 53 | 54 | var ( 55 | p = &Info{} 56 | text = s.Text() 57 | optionalFields string 58 | ) 59 | 60 | if _, err := fmt.Sscanf(text, mountinfoFormat, 61 | &p.ID, &p.Parent, &p.Major, &p.Minor, 62 | &p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil { 63 | return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err) 64 | } 65 | // Safe as mountinfo encodes mountpoints with spaces as \040. 66 | index := strings.Index(text, " - ") 67 | postSeparatorFields := strings.Fields(text[index+3:]) 68 | if len(postSeparatorFields) < 3 { 69 | return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text) 70 | } 71 | 72 | if optionalFields != "-" { 73 | p.Optional = optionalFields 74 | } 75 | 76 | p.Fstype = postSeparatorFields[0] 77 | p.Source = postSeparatorFields[1] 78 | p.VfsOpts = strings.Join(postSeparatorFields[2:], " ") 79 | out = append(out, p) 80 | } 81 | return out, nil 82 | } 83 | 84 | // PidMountInfo collects the mounts for a specific process ID. If the process 85 | // ID is unknown, it is better to use `GetMounts` which will inspect 86 | // "/proc/self/mountinfo" instead. 87 | func PidMountInfo(pid int) ([]*Info, error) { 88 | f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid)) 89 | if err != nil { 90 | return nil, err 91 | } 92 | defer f.Close() 93 | 94 | return parseInfoFile(f) 95 | } 96 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/mountinfo_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd freebsd,!cgo 2 | 3 | package mount 4 | 5 | import ( 6 | "fmt" 7 | "runtime" 8 | ) 9 | 10 | func parseMountTable() ([]*Info, error) { 11 | return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 12 | } 13 | -------------------------------------------------------------------------------- /vendor/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package mount 4 | 5 | // MakeShared ensures a mounted filesystem has the SHARED mount option enabled. 6 | // See the supported options in flags.go for further reference. 7 | func MakeShared(mountPoint string) error { 8 | return ensureMountedAs(mountPoint, "shared") 9 | } 10 | 11 | // MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled. 12 | // See the supported options in flags.go for further reference. 13 | func MakeRShared(mountPoint string) error { 14 | return ensureMountedAs(mountPoint, "rshared") 15 | } 16 | 17 | // MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled. 18 | // See the supported options in flags.go for further reference. 19 | func MakePrivate(mountPoint string) error { 20 | return ensureMountedAs(mountPoint, "private") 21 | } 22 | 23 | // MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option 24 | // enabled. See the supported options in flags.go for further reference. 25 | func MakeRPrivate(mountPoint string) error { 26 | return ensureMountedAs(mountPoint, "rprivate") 27 | } 28 | 29 | // MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled. 30 | // See the supported options in flags.go for further reference. 31 | func MakeSlave(mountPoint string) error { 32 | return ensureMountedAs(mountPoint, "slave") 33 | } 34 | 35 | // MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled. 36 | // See the supported options in flags.go for further reference. 37 | func MakeRSlave(mountPoint string) error { 38 | return ensureMountedAs(mountPoint, "rslave") 39 | } 40 | 41 | // MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option 42 | // enabled. See the supported options in flags.go for further reference. 43 | func MakeUnbindable(mountPoint string) error { 44 | return ensureMountedAs(mountPoint, "unbindable") 45 | } 46 | 47 | // MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount 48 | // option enabled. See the supported options in flags.go for further reference. 49 | func MakeRUnbindable(mountPoint string) error { 50 | return ensureMountedAs(mountPoint, "runbindable") 51 | } 52 | 53 | func ensureMountedAs(mountPoint, options string) error { 54 | mounted, err := Mounted(mountPoint) 55 | if err != nil { 56 | return err 57 | } 58 | 59 | if !mounted { 60 | if err := Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil { 61 | return err 62 | } 63 | } 64 | mounted, err = Mounted(mountPoint) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | return ForceMount("", mountPoint, "none", options) 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | bin/ 6 | 7 | # Folders 8 | integration-tmp/ 9 | _obj 10 | _test 11 | 12 | # Architecture specific extensions/prefixes 13 | *.[568vq] 14 | [568vq].out 15 | 16 | *.cgo1.go 17 | *.cgo2.c 18 | _cgo_defun.c 19 | _cgo_gotypes.go 20 | _cgo_export.* 21 | 22 | _testmain.go 23 | 24 | *.exe 25 | *.test 26 | *.prof 27 | cmd/dnet/dnet 28 | 29 | # Coverage 30 | *.tmp 31 | *.coverprofile 32 | 33 | # IDE files and folders 34 | .project 35 | .settings/ 36 | 37 | libnetworkbuild.created 38 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM golang:1.4-cross 2 | RUN apt-get update && apt-get -y install iptables 3 | RUN go get github.com/tools/godep \ 4 | github.com/golang/lint/golint \ 5 | golang.org/x/tools/cmd/vet \ 6 | golang.org/x/tools/cmd/goimports \ 7 | golang.org/x/tools/cmd/cover\ 8 | github.com/mattn/goveralls 9 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/MAINTAINERS: -------------------------------------------------------------------------------- 1 | # Libnetwork maintainers file 2 | # 3 | # This file describes who runs the docker/libnetwork project and how. 4 | # This is a living document - if you see something out of date or missing, speak up! 5 | # 6 | # It is structured to be consumable by both humans and programs. 7 | # To extract its contents programmatically, use any TOML-compliant parser. 8 | # 9 | # This file is compiled into the MAINTAINERS file in docker/opensource. 10 | # 11 | [Org] 12 | [Org."Core maintainers"] 13 | people = [ 14 | "aboch", 15 | "LK4D4", 16 | "icecrime", 17 | "mrjana", 18 | "mavenugo", 19 | ] 20 | 21 | [people] 22 | 23 | # A reference list of all people associated with the project. 24 | # All other sections should refer to people by their canonical key 25 | # in the people section. 26 | 27 | # ADD YOURSELF HERE IN ALPHABETICAL ORDER 28 | 29 | [people.aboch] 30 | Name = "Alessandro Boch" 31 | Email = "aboch@docker.com" 32 | GitHub = "aboch" 33 | 34 | [people.LK4D4] 35 | Name = "Alexandr Morozov" 36 | Email = "lk4d4@docker.com" 37 | GitHub = "LK4D4" 38 | 39 | [people.icecrime] 40 | Name = "Arnaud Porterie" 41 | Email = "arnaud@docker.com" 42 | GitHub = "icecrime" 43 | 44 | [people.mrjana] 45 | Name = "Jana Radhakrishnan" 46 | Email = "mrjana@docker.com" 47 | GitHub = "mrjana" 48 | 49 | [people.mavenugo] 50 | Name = "Madhu Venugopal" 51 | Email = "madhu@docker.com" 52 | GitHub = "mavenugo" 53 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/README.md: -------------------------------------------------------------------------------- 1 | # libnetwork - networking for containers 2 | 3 | [![Circle CI](https://circleci.com/gh/docker/libnetwork/tree/master.svg?style=svg)](https://circleci.com/gh/docker/libnetwork/tree/master) [![Coverage Status](https://coveralls.io/repos/docker/libnetwork/badge.svg)](https://coveralls.io/r/docker/libnetwork) [![GoDoc](https://godoc.org/github.com/docker/libnetwork?status.svg)](https://godoc.org/github.com/docker/libnetwork) 4 | 5 | Libnetwork provides a native Go implementation for connecting containers 6 | 7 | The goal of libnetwork is to deliver a robust Container Network Model that provides a consistent programming interface and the required network abstractions for applications. 8 | 9 | #### Design 10 | Please refer to the [design](docs/design.md) for more information. 11 | 12 | #### Using libnetwork 13 | 14 | There are many networking solutions available to suit a broad range of use-cases. libnetwork uses a driver / plugin model to support all of these solutions while abstracting the complexity of the driver implementations by exposing a simple and consistent Network Model to users. 15 | 16 | 17 | ```go 18 | // Select and configure the network driver 19 | networkType := "bridge" 20 | 21 | // Create a new controller instance 22 | driverOptions := options.Generic{} 23 | genericOption := make(map[string]interface{}) 24 | genericOption[netlabel.GenericData] = driverOptions 25 | controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption)) 26 | if err != nil { 27 | return 28 | } 29 | 30 | // Create a network for containers to join. 31 | // NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can use. 32 | network, err := controller.NewNetwork(networkType, "network1") 33 | if err != nil { 34 | return 35 | } 36 | 37 | // For each new container: allocate IP and interfaces. The returned network 38 | // settings will be used for container infos (inspect and such), as well as 39 | // iptables rules for port publishing. This info is contained or accessible 40 | // from the returned endpoint. 41 | ep, err := network.CreateEndpoint("Endpoint1") 42 | if err != nil { 43 | return 44 | } 45 | 46 | // Create the sandbox for the container. 47 | // NewSandbox accepts Variadic optional arguments which libnetwork can use. 48 | sbx, err := controller.NewSandbox("container1", 49 | libnetwork.OptionHostname("test"), 50 | libnetwork.OptionDomainname("docker.io")) 51 | 52 | // A sandbox can join the endpoint via the join api. 53 | err = ep.Join(sbx) 54 | if err != nil { 55 | return 56 | } 57 | 58 | // libnetwork client can check the endpoint's operational data via the Info() API 59 | epInfo, err := ep.DriverInfo() 60 | mapData, ok := epInfo[netlabel.PortMap] 61 | if ok { 62 | portMapping, ok := mapData.([]types.PortBinding) 63 | if ok { 64 | fmt.Printf("Current port mapping for endpoint %s: %v", ep.Name(), portMapping) 65 | } 66 | } 67 | ``` 68 | 69 | ## Future 70 | Please refer to [roadmap](ROADMAP.md) for more information. 71 | 72 | ## Contributing 73 | 74 | Want to hack on libnetwork? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply. 75 | 76 | ## Copyright and license 77 | Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons. 78 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/ROADMAP.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | This document defines the high-level goals of the libnetwork project. See [Project Planning](#project-planning) for information on Releases. 4 | 5 | ## Long-term Goal 6 | 7 | libnetwork project will follow Docker and Linux philosophy of delivering small, highly modular and composable tools that works well independently. 8 | libnetwork aims to satisfy that composable need for Networking in Containers. 9 | 10 | ## Short-term Goals 11 | 12 | - Modularize the networking logic in Docker Engine and libcontainer in to a single, reusable library 13 | - Replace the networking subsystem of Docker Engine, with libnetwork 14 | - Define a flexible model that allows local and remote drivers to provide networking to containers 15 | - Provide a stand-alone tool "dnet" for managing and testing libnetwork 16 | 17 | Project Planning 18 | ================ 19 | 20 | [Project Pages](https://github.com/docker/libnetwork/wiki) define the goals for each Milestone and identify the release-relationship to the Docker Platform. 21 | -------------------------------------------------------------------------------- /vendor/github.com/docker/libnetwork/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | $consul=<