Explorar o código

Merge pull request #1005 from aanand/docker-in-docker

Run tests using Docker-in-Docker so we can test multiple versions
Ben Firshman %!s(int64=10) %!d(string=hai) anos
pai
achega
1e5b9dc2eb
Modificáronse 6 ficheiros con 186 adicións e 5 borrados
  1. 13 0
      CONTRIBUTING.md
  2. 24 1
      Dockerfile
  3. 88 0
      script/dind
  4. 15 4
      script/test
  5. 26 0
      script/test-versions
  6. 20 0
      script/wrapdocker

+ 13 - 0
CONTRIBUTING.md

@@ -24,8 +24,21 @@ that should get you started.
 
 ## Running the test suite
 
+Use the test script to run linting checks and then the full test suite:
+
     $ script/test
 
+Tests are run against a Docker daemon inside a container, so that we can test against multiple Docker versions. By default they'll run against only the latest Docker version - set the `DOCKER_VERSIONS` environment variable to "all" to run against all supported versions:
+
+    $ DOCKER_VERSIONS=all script/test
+
+Arguments to `script/test` are passed through to the `nosetests` executable, so you can specify a test directory, file, module, class or method:
+
+    $ script/test tests/unit
+    $ script/test tests/unit/cli_test.py
+    $ script/test tests.integration.service_test
+    $ script/test tests.integration.service_test:ServiceTest.test_containers
+
 ## Building binaries
 
 Linux:

+ 24 - 1
Dockerfile

@@ -1,5 +1,28 @@
 FROM debian:wheezy
-RUN apt-get update -qq && apt-get install -qy python python-pip python-dev git && apt-get clean
+
+RUN set -ex; \
+    apt-get update -qq; \
+    apt-get install -y \
+        python \
+        python-pip \
+        python-dev \
+        git \
+        apt-transport-https \
+        ca-certificates \
+        curl \
+        lxc \
+        iptables \
+    ; \
+    rm -rf /var/lib/apt/lists/*
+
+ENV ALL_DOCKER_VERSIONS 1.3.3 1.4.1 1.5.0
+
+RUN set -ex; \
+    for v in ${ALL_DOCKER_VERSIONS}; do \
+        curl https://get.docker.com/builds/Linux/x86_64/docker-$v -o /usr/local/bin/docker-$v; \
+        chmod +x /usr/local/bin/docker-$v; \
+    done
+
 RUN useradd -d /home/user -m -s /bin/bash user
 WORKDIR /code/
 

+ 88 - 0
script/dind

@@ -0,0 +1,88 @@
+#!/bin/bash
+set -e
+
+# DinD: a wrapper script which allows docker to be run inside a docker container.
+# Original version by Jerome Petazzoni <[email protected]>
+# See the blog post: http://blog.docker.com/2013/09/docker-can-now-run-within-docker/
+#
+# This script should be executed inside a docker container in privilieged mode
+# ('docker run --privileged', introduced in docker 0.6).
+
+# Usage: dind CMD [ARG...]
+
+# apparmor sucks and Docker needs to know that it's in a container (c) @tianon
+export container=docker
+
+# First, make sure that cgroups are mounted correctly.
+CGROUP=/cgroup
+
+mkdir -p "$CGROUP"
+
+if ! mountpoint -q "$CGROUP"; then
+	mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup $CGROUP || {
+		echo >&2 'Could not make a tmpfs mount. Did you use --privileged?'
+		exit 1
+	}
+fi
+
+if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then
+	mount -t securityfs none /sys/kernel/security || {
+		echo >&2 'Could not mount /sys/kernel/security.'
+		echo >&2 'AppArmor detection and -privileged mode might break.'
+	}
+fi
+
+# Mount the cgroup hierarchies exactly as they are in the parent system.
+for SUBSYS in $(cut -d: -f2 /proc/1/cgroup); do
+	mkdir -p "$CGROUP/$SUBSYS"
+	if ! mountpoint -q $CGROUP/$SUBSYS; then
+		mount -n -t cgroup -o "$SUBSYS" cgroup "$CGROUP/$SUBSYS"
+	fi
+
+	# The two following sections address a bug which manifests itself
+	# by a cryptic "lxc-start: no ns_cgroup option specified" when
+	# trying to start containers withina container.
+	# The bug seems to appear when the cgroup hierarchies are not
+	# mounted on the exact same directories in the host, and in the
+	# container.
+
+	# Named, control-less cgroups are mounted with "-o name=foo"
+	# (and appear as such under /proc/<pid>/cgroup) but are usually
+	# mounted on a directory named "foo" (without the "name=" prefix).
+	# Systemd and OpenRC (and possibly others) both create such a
+	# cgroup. To avoid the aforementioned bug, we symlink "foo" to
+	# "name=foo". This shouldn't have any adverse effect.
+	name="${SUBSYS#name=}"
+	if [ "$name" != "$SUBSYS" ]; then
+		ln -s "$SUBSYS" "$CGROUP/$name"
+	fi
+
+	# Likewise, on at least one system, it has been reported that
+	# systemd would mount the CPU and CPU accounting controllers
+	# (respectively "cpu" and "cpuacct") with "-o cpuacct,cpu"
+	# but on a directory called "cpu,cpuacct" (note the inversion
+	# in the order of the groups). This tries to work around it.
+	if [ "$SUBSYS" = 'cpuacct,cpu' ]; then
+		ln -s "$SUBSYS" "$CGROUP/cpu,cpuacct"
+	fi
+done
+
+# Note: as I write those lines, the LXC userland tools cannot setup
+# a "sub-container" properly if the "devices" cgroup is not in its
+# own hierarchy. Let's detect this and issue a warning.
+if ! grep -q :devices: /proc/1/cgroup; then
+	echo >&2 'WARNING: the "devices" cgroup should be in its own hierarchy.'
+fi
+if ! grep -qw devices /proc/1/cgroup; then
+	echo >&2 'WARNING: it looks like the "devices" cgroup is not mounted.'
+fi
+
+# Mount /tmp
+mount -t tmpfs none /tmp
+
+if [ $# -gt 0 ]; then
+	exec "$@"
+fi
+
+echo >&2 'ERROR: No command specified.'
+echo >&2 'You probably want to run hack/make.sh, or maybe a shell?'

+ 15 - 4
script/test

@@ -1,5 +1,16 @@
-#!/bin/sh
+#!/bin/bash
+# See CONTRIBUTING.md for usage.
+
 set -ex
-docker build -t docker-compose .
-docker run -v /var/run/docker.sock:/var/run/docker.sock --rm --entrypoint flake8 docker-compose compose
-docker run -v /var/run/docker.sock:/var/run/docker.sock --rm --entrypoint nosetests docker-compose $@
+
+TAG="docker-compose:$(git rev-parse --short HEAD)"
+
+docker build -t "$TAG" .
+docker run \
+  --rm \
+  --volume="/var/run/docker.sock:/var/run/docker.sock" \
+  -e DOCKER_VERSIONS \
+  -e "TAG=$TAG" \
+  --entrypoint="script/test-versions" \
+  "$TAG" \
+  "$@"

+ 26 - 0
script/test-versions

@@ -0,0 +1,26 @@
+#!/bin/bash
+# This should be run inside a container built from the Dockerfile
+# at the root of the repo - script/test will do it automatically.
+
+set -e
+
+>&2 echo "Running lint checks"
+flake8 compose
+
+if [ "$DOCKER_VERSIONS" == "" ]; then
+  DOCKER_VERSIONS="1.5.0"
+elif [ "$DOCKER_VERSIONS" == "all" ]; then
+  DOCKER_VERSIONS="$ALL_DOCKER_VERSIONS"
+fi
+
+for version in $DOCKER_VERSIONS; do
+  >&2 echo "Running tests against Docker $version"
+  docker-1.5.0 run \
+    --rm \
+    --privileged \
+    --volume="/var/lib/docker" \
+    -e "DOCKER_VERSION=$version" \
+    --entrypoint="script/dind" \
+    "$TAG" \
+    script/wrapdocker nosetests "$@"
+done

+ 20 - 0
script/wrapdocker

@@ -0,0 +1,20 @@
+#!/bin/bash
+
+if [ "$DOCKER_VERSION" == "" ]; then
+    DOCKER_VERSION="1.5.0"
+fi
+
+ln -s "/usr/local/bin/docker-$DOCKER_VERSION" "/usr/local/bin/docker"
+
+# If a pidfile is still around (for example after a container restart),
+# delete it so that docker can start.
+rm -rf /var/run/docker.pid
+docker -d $DOCKER_DAEMON_ARGS &>/var/log/docker.log &
+
+>&2 echo "Waiting for Docker to start..."
+while ! docker ps &>/dev/null; do
+    sleep 1
+done
+
+>&2 echo ">" "$@"
+exec "$@"