From 8d12810446cee59578485bd60fb4227ed59b12e9 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Thu, 5 Feb 2015 12:53:08 +0000 Subject: [PATCH 01/10] Move weave script into tools image with its deps This rearrangement means that the `weave` command can be used remotely; and, as a side-effect, the script that does all the work is using executables in its own filesystem, rather than invoking them via docker. The remote weavetools is given a terminal so it can be interrupted. With the flag `--local`, the script will assume all its dependencies are available and run then and there. Without the flag, it will run via the weavetools image (adding the flag to the invocation). A choice here is whether to base the tools image on scratch and add all the deps, or base it on something else. I've used alpine linux, which itself is based on busybox. This gives us the usual tools (sed etc.) while keeping the image size small. Adding the docker binary adds substantially to the image size, but it cannot always be e.g., bind-mounted. To mitigate this image bloat, we might build or otherwise get a client-only docker executable, or write a special-purpose client, or indeed rewrite the driver script and use a client library. This also makes the dockerhub user part of the image names parameterised, to make it easier to test the release process in full. --- Makefile | 19 ++---------- tools/Dockerfile | 7 +++-- tools/build.sh | 62 --------------------------------------- weave | 75 +++++++++++++++++++++++++++--------------------- 4 files changed, 51 insertions(+), 112 deletions(-) delete mode 100644 tools/build.sh diff --git a/Makefile b/Makefile index e52bfb5c..bea93095 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ DOCKERHUB_USER=zettio WEAVE_VERSION=git-$(shell git rev-parse --short=12 HEAD) WEAVER_EXE=weaver/weaver WEAVEDNS_EXE=weavedns/weavedns -WEAVETOOLS_EXES=tools/bin WEAVER_IMAGE=$(DOCKERHUB_USER)/weave WEAVEDNS_IMAGE=$(DOCKERHUB_USER)/weavedns WEAVETOOLS_IMAGE=$(DOCKERHUB_USER)/weavetools @@ -38,18 +37,6 @@ $(WEAVER_EXE) $(WEAVEDNS_EXE): common/*.go $(WEAVER_EXE): router/*.go weaver/main.go $(WEAVEDNS_EXE): nameserver/*.go weavedns/main.go -build_weavetools_exes_in_container=yes - -$(WEAVETOOLS_EXES): tools/build.sh -ifdef build_weavetools_exes_in_container - $(SUDO) docker run --rm -t -v $(realpath $( $@ @@ -58,7 +45,8 @@ $(WEAVEDNS_EXPORT): weavedns/Dockerfile $(WEAVEDNS_EXE) $(SUDO) docker build -t $(WEAVEDNS_IMAGE) weavedns $(SUDO) docker save $(WEAVEDNS_IMAGE):latest > $@ -$(WEAVETOOLS_EXPORT): tools/Dockerfile $(WEAVETOOLS_EXES) +$(WEAVETOOLS_EXPORT): tools/Dockerfile weave + cp weave tools/weave $(SUDO) docker build -t $(WEAVETOOLS_IMAGE) tools $(SUDO) docker save $(WEAVETOOLS_IMAGE):latest > $@ @@ -77,9 +65,8 @@ publish: $(PUBLISH) clean: -$(SUDO) docker rmi $(WEAVER_IMAGE) $(WEAVEDNS_IMAGE) $(WEAVETOOLS_IMAGE) rm -f $(WEAVER_EXE) $(WEAVEDNS_EXE) $(WEAVER_EXPORT) $(WEAVEDNS_EXPORT) $(WEAVETOOLS_EXPORT) - $(SUDO) rm -rf $(WEAVETOOLS_EXES) build: $(SUDO) go clean -i net $(SUDO) go install -tags netgo std - $(MAKE) build_weavetools_exes_in_container= + $(MAKE) diff --git a/tools/Dockerfile b/tools/Dockerfile index f244fee7..563868d0 100644 --- a/tools/Dockerfile +++ b/tools/Dockerfile @@ -1,3 +1,6 @@ -FROM scratch +FROM gliderlabs/alpine MAINTAINER Weaveworks Inc -ADD ./bin /bin +WORKDIR /home/weave +RUN ["apk-install", "ethtool", "conntrack-tools", "curl", "iptables", "iproute2", "docker"] +ADD ./weave /home/weave/ +ENTRYPOINT ["/home/weave/weave"] diff --git a/tools/build.sh b/tools/build.sh deleted file mode 100644 index 87528a09..00000000 --- a/tools/build.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -# Show the progress of this script, in case it fails. -set -x -e - -sudo apt-get -y update -sudo apt-get -y install curl make pkg-config gcc bison flex - -BASEDIR=$(dirname $0) -mkdir -p "$BASEDIR"/bin - -copy_exe() { - if ldd $1 >/dev/null 2>&1 ; then - echo "ERROR: $1 was not linked statically." 2>&1 - exit 1 - fi - cp $1 "$BASEDIR"/bin/ -} - -# ethtool - -ETHTOOL=ethtool-3.16 - -rm -rf $ETHTOOL - -curl -s -S https://www.kernel.org/pub/software/network/ethtool/$ETHTOOL.tar.gz | tar xvz -(cd $ETHTOOL; ./configure LDFLAGS=-static && make) -copy_exe $ETHTOOL/ethtool - -# conntrack - -PACKAGES="libmnl-1.0.3 libnfnetlink-1.0.1 libnetfilter_cttimeout-1.0.0 libnetfilter_cthelper-1.0.0 libnetfilter_queue-1.0.2 libnetfilter_conntrack-1.0.4" -CONNTRACK=conntrack-tools-1.4.2 - -rm -rf $PACKAGES $CONNTRACK - -fetch() { - curl -s -S http://www.netfilter.org/projects/${1%-*}/files/$1.tar.bz2 | tar xj -} - -for PACKAGE in $PACKAGES; do - fetch $PACKAGE - (cd $PACKAGE; ./configure --disable-shared && make && sudo make install) -done - -fetch $CONNTRACK -(cd $CONNTRACK; ./configure --disable-shared && make && rm -f src/conntrack && make LDFLAGS=-all-static) -copy_exe $CONNTRACK/src/conntrack - -# curl - -CURL=curl-7.40.0 - -rm -rf $CURL - -curl -s -S http://curl.haxx.se/download/$CURL.tar.gz | tar xvz -(cd $CURL; ./configure --without-ssl --disable-shared && make && rm src/curl && make LDFLAGS=-all-static) -copy_exe $CURL/src/curl - -# - -touch "$BASEDIR"/bin diff --git a/weave b/weave index 89763f0f..ba2347fb 100755 --- a/weave +++ b/weave @@ -2,6 +2,15 @@ set -e SCRIPT_VERSION="(unreleased version)" +DOCKERHUB_USER=zettio + +if [ "$SCRIPT_VERSION" = "(unreleased version)" ] ; then + IMAGE_VERSION=latest +else + IMAGE_VERSION=$SCRIPT_VERSION +fi + +IMAGE_VERSION=${VERSION:-$IMAGE_VERSION} usage() { echo "Usage:" @@ -27,27 +36,40 @@ usage() { exit 1 } -[ $(id -u) = 0 ] || { - echo "weave must be run as 'root'" >&2 - exit 1 -} - [ $# -gt 0 ] || usage -if [ "$SCRIPT_VERSION" = "(unreleased version)" ] ; then - IMAGE_VERSION=latest -else - IMAGE_VERSION=$SCRIPT_VERSION -fi +# These are potentially used for remote execs, and have defaults, so +# we introduce them here +DOCKER_BRIDGE=${DOCKER_BRIDGE:-docker0} +PROCFS=${PROCFS:-/proc} -IMAGE_VERSION=${VERSION:-$IMAGE_VERSION} - -BASE_IMAGE=zettio/weave -BASE_DNS_IMAGE=zettio/weavedns -BASE_TOOLS_IMAGE=zettio/weavetools +BASE_IMAGE=$DOCKERHUB_USER/weave +BASE_DNS_IMAGE=$DOCKERHUB_USER/weavedns +BASE_TOOLS_IMAGE=$DOCKERHUB_USER/weavetools IMAGE=$BASE_IMAGE:$IMAGE_VERSION DNS_IMAGE=$BASE_DNS_IMAGE:$IMAGE_VERSION TOOLS_IMAGE=$BASE_TOOLS_IMAGE:$IMAGE_VERSION + +exec_remote() { + docker run -t --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /proc:/hostproc \ + -e PROCFS=/hostproc --privileged --net=host \ + $BASE_TOOLS_IMAGE --local "$@" +} + +if [ "$1" = "--local" ]; then + shift 1 +else + exec_remote "$@" + exit $? +fi + +[ $(id -u) = 0 ] || { + echo "weave must be run as 'root' when run locally" >&2 + exit 1 +} + CONTAINER_NAME=weave DNS_CONTAINER_NAME=weavedns BRIDGE=weave @@ -69,13 +91,6 @@ command_exists () { command -v $1 >/dev/null 2>&1 } -run_tool() { - TOOL_NET=$1 - TOOL_COMMAND=$2 - shift 2 - docker run --rm -t --privileged --net=$TOOL_NET $TOOLS_IMAGE /bin/$TOOL_COMMAND "$@" -} - is_cidr() { # The regexp here is far from precise, but good enough. echo "$1" | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$' >/dev/null @@ -164,11 +179,7 @@ create_bridge() { add_iptables_rule nat POSTROUTING -j WEAVE } if [ ! "$1" = "--without-ethtool" ] ; then - # disable offloading - we do this even when $BRIDGE already exists - # simply because it has the desirable side-effect of ensuring we - # have the $TOOLS_IMAGE and thus do not incur downloading-induced - # delays in more time-sensitive sections elsewhere. - run_tool host ethtool -K $BRIDGE tx off >/dev/null + ethtool -K $BRIDGE tx off >/dev/null fi ip link set dev $BRIDGE up @@ -253,7 +264,7 @@ connect_container_to_bridge() { return 1 fi - if ! run_tool host ethtool -K $GUEST_IFNAME tx off >/dev/null || + if ! ethtool -K $GUEST_IFNAME tx off >/dev/null || ! ip link set $LOCAL_IFNAME master $BRIDGE || ! ip link set $LOCAL_IFNAME up || ! ip link set $GUEST_IFNAME netns $NETNS ; then @@ -275,7 +286,7 @@ launch() { return 1 fi connect_container_to_bridge && - run_tool container:$CONTAINER ethtool -K eth0 tx off >/dev/null && + ip netns exec $NETNS ethtool -K eth0 tx off >/dev/null && ip netns exec $NETNS ip link set $CONTAINER_IFNAME up } @@ -357,7 +368,7 @@ http_call_ip() { http_verb="$3" url="$4" shift 4 - run_tool host curl -s -X $http_verb "$@" http://$ip:$port$url + curl -s -X $http_verb "$@" http://$ip:$port$url } # Perform operation $1 on container ID $2 to local DNS database at address $3 @@ -671,7 +682,7 @@ case "$COMMAND" in echo "Weave is not running." >&2 fi docker rm -f $CONTAINER_NAME >/dev/null 2>&1 || true - run_tool host conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true + conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true ;; stop-dns) [ $# -eq 0 ] || usage @@ -686,7 +697,7 @@ case "$COMMAND" in docker kill $DNS_CONTAINER_NAME >/dev/null 2>&1 || true docker rm -f $CONTAINER_NAME >/dev/null 2>&1 || true docker rm -f $DNS_CONTAINER_NAME >/dev/null 2>&1 || true - run_tool host conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true + conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true destroy_bridge for LOCAL_IFNAME in $(ip link show | grep v${CONTAINER_IFNAME}pl | cut -d ' ' -f 2 | tr -d ':') ; do ip link del $LOCAL_IFNAME From 0c8d9e8c038cd11b51c21e9b230419979415b611 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 10 Feb 2015 15:59:33 -0800 Subject: [PATCH 02/10] Use this form of apk, since the shortcut masks errors `apk-install` is a script that runs apk then tidies up. The problem is that it doesn't exit with an error if the install fails, which means that if some packages are unavailable at the time of building, it will still all go ahead. --- tools/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/Dockerfile b/tools/Dockerfile index 563868d0..abae662e 100644 --- a/tools/Dockerfile +++ b/tools/Dockerfile @@ -1,6 +1,7 @@ FROM gliderlabs/alpine MAINTAINER Weaveworks Inc WORKDIR /home/weave -RUN ["apk-install", "ethtool", "conntrack-tools", "curl", "iptables", "iproute2", "docker"] +RUN ["apk", "add", "--update", "ethtool", "conntrack-tools", "curl", "iptables", "iproute2", "docker"] +RUN ["sh", "-c", "rm -rf /var/cache/apk/*"] ADD ./weave /home/weave/ ENTRYPOINT ["/home/weave/weave"] From 019eeab896613d09639a7b90fef0768babeeaa49 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 10 Feb 2015 16:26:49 -0800 Subject: [PATCH 03/10] Pass environment variables to remote invocations --- weave | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/weave b/weave index ba2347fb..ee6bff5f 100755 --- a/weave +++ b/weave @@ -53,7 +53,11 @@ TOOLS_IMAGE=$BASE_TOOLS_IMAGE:$IMAGE_VERSION exec_remote() { docker run -t --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ - -v /proc:/hostproc \ + -v "$PROCFS":/hostproc \ + -e VERSION="$VERSION" \ + -e WEAVE_DOCKER_ARGS="$WEAVE_DOCKER_ARGS" \ + -e WEAVE_PASSWORD="$WEAVE_PASSWORD" \ + -e DOCKER_BRIDGE="$DOCKER_BRIDGE" \ -e PROCFS=/hostproc --privileged --net=host \ $BASE_TOOLS_IMAGE --local "$@" } @@ -78,8 +82,6 @@ MTU=65535 PORT=6783 HTTP_PORT=6784 DNS_HTTP_PORT=6785 -DOCKER_BRIDGE=${DOCKER_BRIDGE:-docker0} -PROCFS=${PROCFS:-/proc} COMMAND=$1 From b9353cdee4eded4c97fc3f8c1e926018e8fe16e5 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 17 Feb 2015 14:23:29 -0800 Subject: [PATCH 04/10] Mention using weave remotely in readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 89e51691..b3f686d1 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,9 @@ Ensure you are running Linux (kernel 3.5 or later) and have Docker CoreOS users see [here](https://github.com/fintanr/weave-gs/blob/master/coreos-simple/user-data) for an example of installing weave using cloud-config. +Weave respects the environment variable `DOCKER_HOST`, so you can run +it locally to control a weave network on a remote host. + ## Quick Start Screencast From 959c46b62a8761dd9edbd5f7fe032d0af6c1427c Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 24 Feb 2015 15:47:50 +0000 Subject: [PATCH 05/10] Version the weavetools image run remotely --- weave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weave b/weave index ee6bff5f..391cc49b 100755 --- a/weave +++ b/weave @@ -59,7 +59,7 @@ exec_remote() { -e WEAVE_PASSWORD="$WEAVE_PASSWORD" \ -e DOCKER_BRIDGE="$DOCKER_BRIDGE" \ -e PROCFS=/hostproc --privileged --net=host \ - $BASE_TOOLS_IMAGE --local "$@" + $TOOLS_IMAGE --local "$@" } if [ "$1" = "--local" ]; then From 795d0edc738d3e305dd64a8e2bb8e7979ea36e7f Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Wed, 25 Feb 2015 14:28:34 +0000 Subject: [PATCH 06/10] weavetools -> weaveexec This is to make a visible break with previous releases, such that a newly downloaded weave script will definitely work. Without this change in name, an existing weavetools image that doesn't include the script might be invoked, resulting in a confusing message for the user. --- .gitignore | 2 +- Makefile | 20 ++++++++++---------- site/building.md | 4 ++-- test/setup.sh | 2 +- weave | 20 ++++++++++---------- {tools => weaveexec}/Dockerfile | 0 6 files changed, 24 insertions(+), 24 deletions(-) rename {tools => weaveexec}/Dockerfile (100%) diff --git a/.gitignore b/.gitignore index 158060a2..be4346d1 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,4 @@ tools/build releases weave.tar weavedns.tar -weavetools.tar +weaveexec.tar diff --git a/Makefile b/Makefile index bea93095..c92ae8f6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PUBLISH=publish_weave publish_weavedns publish_weavetools +PUBLISH=publish_weave publish_weavedns publish_weaveexec .DEFAULT: all .PHONY: all update tests publish $(PUBLISH) clean prerequisites build @@ -12,12 +12,12 @@ WEAVER_EXE=weaver/weaver WEAVEDNS_EXE=weavedns/weavedns WEAVER_IMAGE=$(DOCKERHUB_USER)/weave WEAVEDNS_IMAGE=$(DOCKERHUB_USER)/weavedns -WEAVETOOLS_IMAGE=$(DOCKERHUB_USER)/weavetools +WEAVEEXEC_IMAGE=$(DOCKERHUB_USER)/weaveexec WEAVER_EXPORT=weave.tar WEAVEDNS_EXPORT=weavedns.tar -WEAVETOOLS_EXPORT=weavetools.tar +WEAVEEXEC_EXPORT=weaveexec.tar -all: $(WEAVER_EXPORT) $(WEAVEDNS_EXPORT) $(WEAVETOOLS_EXPORT) +all: $(WEAVER_EXPORT) $(WEAVEDNS_EXPORT) $(WEAVEEXEC_EXPORT) update: go get -u -f -v -tags -netgo ./$(dir $(WEAVER_EXE)) ./$(dir $(WEAVEDNS_EXE)) @@ -45,10 +45,10 @@ $(WEAVEDNS_EXPORT): weavedns/Dockerfile $(WEAVEDNS_EXE) $(SUDO) docker build -t $(WEAVEDNS_IMAGE) weavedns $(SUDO) docker save $(WEAVEDNS_IMAGE):latest > $@ -$(WEAVETOOLS_EXPORT): tools/Dockerfile weave - cp weave tools/weave - $(SUDO) docker build -t $(WEAVETOOLS_IMAGE) tools - $(SUDO) docker save $(WEAVETOOLS_IMAGE):latest > $@ +$(WEAVEEXEC_EXPORT): weaveexec/Dockerfile weave + cp weave weaveexec/weave + $(SUDO) docker build -t $(WEAVEEXEC_IMAGE) weaveexec + $(SUDO) docker save $(WEAVEEXEC_IMAGE):latest > $@ # Add more directories in here as more tests are created tests: @@ -63,8 +63,8 @@ $(PUBLISH): publish_%: publish: $(PUBLISH) clean: - -$(SUDO) docker rmi $(WEAVER_IMAGE) $(WEAVEDNS_IMAGE) $(WEAVETOOLS_IMAGE) - rm -f $(WEAVER_EXE) $(WEAVEDNS_EXE) $(WEAVER_EXPORT) $(WEAVEDNS_EXPORT) $(WEAVETOOLS_EXPORT) + -$(SUDO) docker rmi $(WEAVER_IMAGE) $(WEAVEDNS_IMAGE) $(WEAVEEXEC_IMAGE) + rm -f $(WEAVER_EXE) $(WEAVEDNS_EXE) $(WEAVER_EXPORT) $(WEAVEDNS_EXPORT) $(WEAVEEXEC_EXPORT) build: $(SUDO) go clean -i net diff --git a/site/building.md b/site/building.md index 509d54d4..915c03f5 100644 --- a/site/building.md +++ b/site/building.md @@ -50,8 +50,8 @@ $ make This will build the weave components and package them into three Docker images (`zettio/weave`, `zettio/weavedns`, and -`zettio/weavetools`). These are then exported (as -`weave.tar`, `weavedns.tar` and `weavetools.tar`). +`zettio/weaveexec`). These are then exported (as `weave.tar`, +`weavedns.tar` and `weaveexec.tar`). ## Building in a Docker container diff --git a/test/setup.sh b/test/setup.sh index 3c31863c..11b7767a 100755 --- a/test/setup.sh +++ b/test/setup.sh @@ -13,7 +13,7 @@ echo Copying weave images and script to hosts for HOST in $HOSTS; do docker_on $HOST load -i ../weave.tar docker_on $HOST load -i ../weavedns.tar - docker_on $HOST load -i ../weavetools.tar + docker_on $HOST load -i ../weaveexec.tar run_on $HOST mkdir -p `dirname $WEAVE` cat ../weave | run_on $HOST sh -c "cat > $WEAVE" cat ../bin/docker-ns | run_on $HOST sh -c "cat > $DOCKER_NS" diff --git a/weave b/weave index 391cc49b..64b388c9 100755 --- a/weave +++ b/weave @@ -45,10 +45,10 @@ PROCFS=${PROCFS:-/proc} BASE_IMAGE=$DOCKERHUB_USER/weave BASE_DNS_IMAGE=$DOCKERHUB_USER/weavedns -BASE_TOOLS_IMAGE=$DOCKERHUB_USER/weavetools +BASE_EXEC_IMAGE=$DOCKERHUB_USER/weaveexec IMAGE=$BASE_IMAGE:$IMAGE_VERSION DNS_IMAGE=$BASE_DNS_IMAGE:$IMAGE_VERSION -TOOLS_IMAGE=$BASE_TOOLS_IMAGE:$IMAGE_VERSION +EXEC_IMAGE=$BASE_EXEC_IMAGE:$IMAGE_VERSION exec_remote() { docker run -t --rm \ @@ -59,7 +59,7 @@ exec_remote() { -e WEAVE_PASSWORD="$WEAVE_PASSWORD" \ -e DOCKER_BRIDGE="$DOCKER_BRIDGE" \ -e PROCFS=/hostproc --privileged --net=host \ - $TOOLS_IMAGE --local "$@" + $EXEC_IMAGE --local "$@" } if [ "$1" = "--local" ]; then @@ -496,7 +496,7 @@ DOCKER_VERSION_PATCH=$(echo "$DOCKER_VERSION" | cut -d. -f 3) case "$COMMAND" in setup) - for img in $IMAGE $DNS_IMAGE $TOOLS_IMAGE ; do + for img in $IMAGE $DNS_IMAGE $EXEC_IMAGE ; do docker pull $img done ;; @@ -585,14 +585,14 @@ case "$COMMAND" in echo weave script $SCRIPT_VERSION ask_version $CONTAINER_NAME $IMAGE ask_version $DNS_CONTAINER_NAME $DNS_IMAGE - if ! TOOLS_IMAGE_ID=$(docker inspect --format='{{.Id}}' $TOOLS_IMAGE 2>/dev/null) ; then - echo "Unable to find $TOOLS_IMAGE image." >&2 + if ! EXEC_IMAGE_ID=$(docker inspect --format='{{.Id}}' $EXEC_IMAGE 2>/dev/null) ; then + echo "Unable to find $EXEC_IMAGE image." >&2 else - TOOLS_VERSION=$(docker images --no-trunc | grep $TOOLS_IMAGE_ID | grep -v latest | tr -s ' ' | cut -d ' ' -f 2 | tr "\n" ' ') - if [ -n "$TOOLS_VERSION" ] ; then - echo "weave tools $TOOLS_VERSION" + EXEC_VERSION=$(docker images --no-trunc | grep $EXEC_IMAGE_ID | grep -v latest | tr -s ' ' | cut -d ' ' -f 2 | tr "\n" ' ') + if [ -n "$EXEC_VERSION" ] ; then + echo "weave exec $EXEC_VERSION" else - echo "weave tools (unreleased version)" + echo "weave exec (unreleased version)" fi fi ;; diff --git a/tools/Dockerfile b/weaveexec/Dockerfile similarity index 100% rename from tools/Dockerfile rename to weaveexec/Dockerfile From 9fd468d743b98f4066d9afc50b4bec806c7eefc4 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Fri, 27 Feb 2015 17:52:05 +0000 Subject: [PATCH 07/10] Use weave remotely in smoke tests instead of via SSH --- test/100_cross_hosts_test.sh | 12 ++++++------ test/110_encryption_test.sh | 12 ++++++------ test/200_dns_test.sh | 10 +++++----- test/210_dns_multicast_test.sh | 16 ++++++++-------- test/220_dns_custom_test.sh | 10 +++++----- test/300_fallback_dns_test.sh | 6 +++--- test/config.sh | 9 ++++++++- test/setup.sh | 4 +--- 8 files changed, 42 insertions(+), 37 deletions(-) diff --git a/test/100_cross_hosts_test.sh b/test/100_cross_hosts_test.sh index 6073b581..7d95a519 100755 --- a/test/100_cross_hosts_test.sh +++ b/test/100_cross_hosts_test.sh @@ -8,16 +8,16 @@ C2=10.2.1.7 start_suite "Ping over cross-host weave network" for HOST in $HOST1 $HOST2; do - run_on $HOST sudo $WEAVE stop || true - run_on $HOST sudo $WEAVE stop-dns || true + weave_on $HOST stop || true + weave_on $HOST stop-dns || true docker_on $HOST rm -f c1 c2 || true done -run_on $HOST1 sudo $WEAVE launch -run_on $HOST2 sudo $WEAVE launch $HOST1 +weave_on $HOST1 launch +weave_on $HOST2 launch $HOST1 -run_on $HOST2 sudo $WEAVE run $C2/24 -t --name=c2 ubuntu -run_on $HOST1 sudo $WEAVE run $C1/24 -t --name=c1 ubuntu +weave_on $HOST2 run $C2/24 -t --name=c2 ubuntu +weave_on $HOST1 run $C1/24 -t --name=c1 ubuntu ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "ping -q -c 4 $C2 >&2 && echo ok") assert "echo $ok" "ok" diff --git a/test/110_encryption_test.sh b/test/110_encryption_test.sh index 9ac8a903..ecf1f857 100755 --- a/test/110_encryption_test.sh +++ b/test/110_encryption_test.sh @@ -8,16 +8,16 @@ C2=10.2.1.7 start_suite "Ping over encrypted cross-host weave network" for HOST in $HOST1 $HOST2; do - run_on $HOST sudo $WEAVE stop || true - run_on $HOST sudo $WEAVE stop-dns || true + weave_on $HOST stop || true + weave_on $HOST stop-dns || true docker_on $HOST rm -f c1 c2 || true done -run_on $HOST1 sudo $WEAVE launch -password notverysecure -run_on $HOST2 sudo $WEAVE launch -password notverysecure $HOST1 +weave_on $HOST1 launch -password notverysecure +weave_on $HOST2 launch -password notverysecure $HOST1 -run_on $HOST2 sudo $WEAVE run $C2/24 -t --name=c2 ubuntu -run_on $HOST1 sudo $WEAVE run $C1/24 -t --name=c1 ubuntu +weave_on $HOST2 run $C2/24 -t --name=c2 ubuntu +weave_on $HOST1 run $C1/24 -t --name=c1 ubuntu ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "ping -q -c 4 $C2 >&2 && echo ok") assert "echo $ok" "ok" diff --git a/test/200_dns_test.sh b/test/200_dns_test.sh index a918f699..a05ced4e 100755 --- a/test/200_dns_test.sh +++ b/test/200_dns_test.sh @@ -7,14 +7,14 @@ C2=10.2.0.34 start_suite "Resolve names on a single host" -run_on $HOST1 sudo $WEAVE stop || true -run_on $HOST1 sudo $WEAVE stop-dns || true -run_on $HOST1 sudo $WEAVE launch-dns 10.2.254.1/24 +weave_on $HOST1 stop || true +weave_on $HOST1 stop-dns || true +weave_on $HOST1 launch-dns 10.2.254.1/24 docker_on $HOST1 rm -f c1 c2 || true -run_on $HOST1 sudo $WEAVE run $C2/24 -t --name=c2 -h seetwo.weave.local ubuntu -run_on $HOST1 sudo $WEAVE run --with-dns $C1/24 -t --name=c1 aanand/docker-dnsutils /bin/sh +weave_on $HOST1 run $C2/24 -t --name=c2 -h seetwo.weave.local ubuntu +weave_on $HOST1 run --with-dns $C1/24 -t --name=c1 aanand/docker-dnsutils /bin/sh ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "dig +short seetwo.weave.local") assert "echo $ok" "$C2" diff --git a/test/210_dns_multicast_test.sh b/test/210_dns_multicast_test.sh index 2474c109..ef720f73 100755 --- a/test/210_dns_multicast_test.sh +++ b/test/210_dns_multicast_test.sh @@ -8,19 +8,19 @@ C2=10.2.3.34 start_suite "Resolve names across hosts" for host in $HOST1 $HOST2; do - run_on $host sudo $WEAVE stop || true - run_on $host sudo $WEAVE stop-dns || true + weave_on $host stop || true + weave_on $host stop-dns || true docker_on $host rm -f c1 c2 || true done -run_on $HOST1 sudo $WEAVE launch -run_on $HOST2 sudo $WEAVE launch $HOST1 +weave_on $HOST1 launch +weave_on $HOST2 launch $HOST1 -run_on $HOST1 sudo $WEAVE launch-dns 10.2.254.1/24 -debug -run_on $HOST2 sudo $WEAVE launch-dns 10.2.254.2/24 -debug +weave_on $HOST1 launch-dns 10.2.254.1/24 -debug +weave_on $HOST2 launch-dns 10.2.254.2/24 -debug -run_on $HOST2 sudo $WEAVE run $C2/24 -t --name=c2 -h seetwo.weave.local ubuntu -run_on $HOST1 sudo $WEAVE run --with-dns $C1/24 --name=c1 -t aanand/docker-dnsutils /bin/sh +weave_on $HOST2 run $C2/24 -t --name=c2 -h seetwo.weave.local ubuntu +weave_on $HOST1 run --with-dns $C1/24 --name=c1 -t aanand/docker-dnsutils /bin/sh ok=$(docker -H tcp://$HOST1:2375 exec -i c1 dig +short seetwo.weave.local) assert "echo $ok" "$C2" diff --git a/test/220_dns_custom_test.sh b/test/220_dns_custom_test.sh index 73c9d07e..835ebd98 100755 --- a/test/220_dns_custom_test.sh +++ b/test/220_dns_custom_test.sh @@ -7,14 +7,14 @@ C2=10.2.54.91 start_suite "Resolve names in custom domain" -run_on $HOST1 sudo $WEAVE stop || true -run_on $HOST1 sudo $WEAVE stop-dns || true -run_on $HOST1 sudo $WEAVE launch-dns 10.2.254.1/24 --localDomain foo.bar. +weave_on $HOST1 stop || true +weave_on $HOST1 stop-dns || true +weave_on $HOST1 launch-dns 10.2.254.1/24 --localDomain foo.bar. docker_on $HOST1 rm -f c1 c2 || true -run_on $HOST1 sudo $WEAVE run $C2/24 -t --name=c2 -h seetwo.foo.bar ubuntu -run_on $HOST1 sudo $WEAVE run --with-dns $C1/24 -t --name=c1 aanand/docker-dnsutils /bin/sh +weave_on $HOST1 run $C2/24 -t --name=c2 -h seetwo.foo.bar ubuntu +weave_on $HOST1 run --with-dns $C1/24 -t --name=c1 aanand/docker-dnsutils /bin/sh ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "dig +short seetwo.foo.bar.") assert "echo $ok" "$C2" diff --git a/test/300_fallback_dns_test.sh b/test/300_fallback_dns_test.sh index 5a2ba74f..49131c59 100755 --- a/test/300_fallback_dns_test.sh +++ b/test/300_fallback_dns_test.sh @@ -4,11 +4,11 @@ start_suite "Resolve a non-weave address" -run_on $HOST1 sudo $WEAVE stop-dns || true -run_on $HOST1 sudo $WEAVE launch-dns 10.2.254.1/24 -debug +weave_on $HOST1 stop-dns || true +weave_on $HOST1 launch-dns 10.2.254.1/24 -debug docker_on $HOST1 rm -f c1 || true -run_on $HOST1 sudo $WEAVE run --with-dns 10.2.1.5/24 --name=c1 -t aanand/docker-dnsutils /bin/sh +weave_on $HOST1 run --with-dns 10.2.1.5/24 --name=c1 -t aanand/docker-dnsutils /bin/sh ok=$(docker -H tcp://$HOST1:2375 exec -i c1 dig +short -t MX weave.works) assert "test -n \"$ok\" && echo pass" "pass" diff --git a/test/config.sh b/test/config.sh index 7acba9ec..071738cb 100644 --- a/test/config.sh +++ b/test/config.sh @@ -49,6 +49,13 @@ docker_on() { docker -H tcp://$host:2375 $@ } +weave_on() { + host=$1 + shift 1 + greyly echo "Weave on $host: $@" + DOCKER_HOST=tcp://$host:2375 $WEAVE $@ +} + start_suite() { whitely echo $@ } @@ -57,5 +64,5 @@ end_suite() { whitely assert_end } -WEAVE=./bin/weave +WEAVE=../weave DOCKER_NS=./bin/docker-ns diff --git a/test/setup.sh b/test/setup.sh index 11b7767a..f6a7cee8 100755 --- a/test/setup.sh +++ b/test/setup.sh @@ -14,10 +14,8 @@ for HOST in $HOSTS; do docker_on $HOST load -i ../weave.tar docker_on $HOST load -i ../weavedns.tar docker_on $HOST load -i ../weaveexec.tar - run_on $HOST mkdir -p `dirname $WEAVE` - cat ../weave | run_on $HOST sh -c "cat > $WEAVE" + run_on $HOST mkdir -p bin cat ../bin/docker-ns | run_on $HOST sh -c "cat > $DOCKER_NS" - run_on $HOST chmod a+x $WEAVE run_on $HOST chmod a+x $DOCKER_NS run_on $HOST sudo service docker restart done From 84ce0663f8ab6116cce1865e2cb9e735191d68cb Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Fri, 27 Feb 2015 17:53:05 +0000 Subject: [PATCH 08/10] Don't show env entries in command The form of `docker -e` without an equals sign passes them along from the environment without the value appearing in the command. --- weave | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/weave b/weave index 64b388c9..fc2a660e 100755 --- a/weave +++ b/weave @@ -54,10 +54,10 @@ exec_remote() { docker run -t --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$PROCFS":/hostproc \ - -e VERSION="$VERSION" \ - -e WEAVE_DOCKER_ARGS="$WEAVE_DOCKER_ARGS" \ - -e WEAVE_PASSWORD="$WEAVE_PASSWORD" \ - -e DOCKER_BRIDGE="$DOCKER_BRIDGE" \ + -e VERSION \ + -e WEAVE_DOCKER_ARGS \ + -e WEAVE_PASSWORD \ + -e DOCKER_BRIDGE \ -e PROCFS=/hostproc --privileged --net=host \ $EXEC_IMAGE --local "$@" } From 93f16d91ce79a24449c23791a336ab67d85af477 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 17 Mar 2015 17:31:06 +0000 Subject: [PATCH 09/10] Run `weave run` with the local docker We want to be compatible with whatever docker the user has; `weave run` is the only command that passes on arbitrary args to docker (i.e., that doesn't have a fixed set of docker features that it needs). To make this workable we still need to do some things on the remote host: the IP attachment and figuring out the DNS settings (since those may depend on the bridge IP). --- test/400_weave_local_test.sh | 19 +++++++++ test/Vagrantfile | 2 +- test/setup.sh | 3 +- weave | 77 +++++++++++++++++++++++------------- 4 files changed, 72 insertions(+), 29 deletions(-) create mode 100755 test/400_weave_local_test.sh diff --git a/test/400_weave_local_test.sh b/test/400_weave_local_test.sh new file mode 100755 index 00000000..52fcb741 --- /dev/null +++ b/test/400_weave_local_test.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +. ./config.sh + +start_suite "Run weave with --local" + +run_on $HOST1 sudo ./weave --local reset + +run_on $HOST1 sudo ./weave --local launch +assert_raises "docker_on $HOST1 ps | grep weave" 0 + +docker_on $HOST1 rm -f c1 || true +run_on $HOST1 sudo ./weave --local run 10.2.6.5/24 -ti --name=c1 ubuntu +ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "ifconfig | grep ethwe") +assert "test -n \"$ok\" && echo pass" "pass" + +docker_on $HOST1 rm -f c1 || true + +end_suite diff --git a/test/Vagrantfile b/test/Vagrantfile index dba4f411..92ade5e7 100644 --- a/test/Vagrantfile +++ b/test/Vagrantfile @@ -6,7 +6,7 @@ ip_prefix = "192.168.48" ip_suffix_base = 10 def configure_docker(host, hostname, ip) - pkgs = "lxc-docker" + pkgs = "lxc-docker ethtool" host.vm.box = "phusion/ubuntu-14.04-amd64" host.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/ubuntu-14.04-amd64-vbox.box" diff --git a/test/setup.sh b/test/setup.sh index f6a7cee8..fd7d1ff9 100755 --- a/test/setup.sh +++ b/test/setup.sh @@ -16,6 +16,7 @@ for HOST in $HOSTS; do docker_on $HOST load -i ../weaveexec.tar run_on $HOST mkdir -p bin cat ../bin/docker-ns | run_on $HOST sh -c "cat > $DOCKER_NS" - run_on $HOST chmod a+x $DOCKER_NS + cat ../weave | run_on $HOST sh -c "cat > ./weave" + run_on $HOST chmod a+x $DOCKER_NS ./weave run_on $HOST sudo service docker restart done diff --git a/weave b/weave index fc2a660e..b3b5bb7a 100755 --- a/weave +++ b/weave @@ -62,14 +62,19 @@ exec_remote() { $EXEC_IMAGE --local "$@" } +# "run" is a special case because we want to use docker directly, +# rather than the docker in $EXEC_IMAGE remotely. That's because we +# are passing arbitrary arguments on to docker run, and we can't rely +# on our baked-in docker to support those arguments. if [ "$1" = "--local" ]; then + LOCAL="$1" shift 1 -else +elif [ "$1" != "run" ]; then exec_remote "$@" exit $? fi -[ $(id -u) = 0 ] || { +[ $(id -u) = 0 ] || ([ "$1" = "run" ] && [ -z "$LOCAL" ]) || { echo "weave must be run as 'root' when run locally" >&2 exit 1 } @@ -87,6 +92,31 @@ COMMAND=$1 shift 1 +dns_args() { + if [ "$1" = "--with-dns" ] ; then + shift 1 + if [ \( "$DOCKER_VERSION_MAJOR" -lt 1 \) -o \ + \( "$DOCKER_VERSION_MAJOR" -eq 1 -a \ + "$DOCKER_VERSION_MINOR" -lt 2 \) ] ; then + echo "ERROR: The '--with-dns' option requires Docker 1.2.0 or later; you are running $DOCKER_VERSION" >&2 + exit 1 + fi + docker_bridge_ip + DNS_ARG="--dns $DOCKER_BRIDGE_IP" + DNS_SEARCH_ARG="--dns-search=." + for arg in "$@"; do + case $arg in + --dns-search=*) + DNS_SEARCH_ARG="" + ;; + *) + ;; + esac; + done + fi + DNS_ARGS="$DNS_ARG $DNS_SEARCH_ARG" +} + # utility function to check whether a command can be executed by the shell # see http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script command_exists () { @@ -598,36 +628,29 @@ case "$COMMAND" in ;; run) [ $# -gt 0 ] || usage - if [ "$1" = "--with-dns" ] ; then - shift 1 - if [ \( "$DOCKER_VERSION_MAJOR" -lt 1 \) -o \ - \( "$DOCKER_VERSION_MAJOR" -eq 1 -a \ - "$DOCKER_VERSION_MINOR" -lt 2 \) ] ; then - echo "ERROR: The '--with-dns' option requires Docker 1.2.0 or later; you are running $DOCKER_VERSION" >&2 - exit 1 - fi - docker_bridge_ip - DNS_ARG="--dns $DOCKER_BRIDGE_IP" - DNS_SEARCH_ARG="--dns-search=." - for arg in "$@"; do - case $arg in - --dns-search=*) - DNS_SEARCH_ARG="" - ;; - *) - ;; - esac; - done + if [ "$LOCAL" = "--local" ]; then + dns_args "$@" + else + DNS_ARGS=$(exec_remote dns-args "$@") + [ "$1" = "--with-dns" ] && shift 1 fi CIDR=$1 - validate_cidr $CIDR shift 1 - create_bridge - CONTAINER=$(docker run $DNS_ARG $DNS_SEARCH_ARG -d "$@") - with_container_netns $CONTAINER attach $CIDR >/dev/null - tell_dns PUT $CONTAINER $CIDR + validate_cidr $CIDR + CONTAINER=$(docker run $DNS_ARGS -d "$@") + if [ "$LOCAL" = "--local" ]; then + create_bridge + with_container_netns $CONTAINER attach $CIDR >/dev/null + tell_dns PUT $CONTAINER $CIDR + else + exec_remote attach $CIDR $CONTAINER + fi echo $CONTAINER ;; + dns-args) + dns_args "$@" + echo -n $DNS_ARGS + ;; start) [ $# -eq 2 ] || usage CIDR=$1 From 520c54f8dad1dad3c72319292fd5e540821e8a99 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Wed, 18 Mar 2015 12:08:35 +0000 Subject: [PATCH 10/10] Use a fixed (and old) version of the docker client As noted in #388 comment 76958961, we need the docker client to be as old as possible while supporting what weave needs to do. At the minute that means version 1.3.1. The `apk` package index does not have old versions of docker, so the most direct way of getting a docker executable is to download the specific version from https://get.docker.com. --- .gitignore | 1 + Makefile | 10 +++++++++- weaveexec/Dockerfile | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index be4346d1..2fd760f9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ releases weave.tar weavedns.tar weaveexec.tar +weaveexec/docker*.tgz diff --git a/Makefile b/Makefile index c92ae8f6..c9f0365b 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,10 @@ WEAVER_EXPORT=weave.tar WEAVEDNS_EXPORT=weavedns.tar WEAVEEXEC_EXPORT=weaveexec.tar +WEAVEEXEC_DOCKER_VERSION=1.3.1 +DOCKER_DISTRIB=weaveexec/docker-$(WEAVEEXEC_DOCKER_VERSION).tgz +DOCKER_DISTRIB_URL=https://get.docker.com/builds/Linux/x86_64/docker-$(WEAVEEXEC_DOCKER_VERSION).tgz + all: $(WEAVER_EXPORT) $(WEAVEDNS_EXPORT) $(WEAVEEXEC_EXPORT) update: @@ -45,11 +49,15 @@ $(WEAVEDNS_EXPORT): weavedns/Dockerfile $(WEAVEDNS_EXE) $(SUDO) docker build -t $(WEAVEDNS_IMAGE) weavedns $(SUDO) docker save $(WEAVEDNS_IMAGE):latest > $@ -$(WEAVEEXEC_EXPORT): weaveexec/Dockerfile weave +$(WEAVEEXEC_EXPORT): weaveexec/Dockerfile $(DOCKER_DISTRIB) weave cp weave weaveexec/weave + cp $(DOCKER_DISTRIB) weaveexec/docker.tgz $(SUDO) docker build -t $(WEAVEEXEC_IMAGE) weaveexec $(SUDO) docker save $(WEAVEEXEC_IMAGE):latest > $@ +$(DOCKER_DISTRIB): + curl -o $(DOCKER_DISTRIB) $(DOCKER_DISTRIB_URL) + # Add more directories in here as more tests are created tests: cd router; go test -cover -tags netgo diff --git a/weaveexec/Dockerfile b/weaveexec/Dockerfile index abae662e..408b3a75 100644 --- a/weaveexec/Dockerfile +++ b/weaveexec/Dockerfile @@ -1,7 +1,8 @@ FROM gliderlabs/alpine MAINTAINER Weaveworks Inc WORKDIR /home/weave -RUN ["apk", "add", "--update", "ethtool", "conntrack-tools", "curl", "iptables", "iproute2", "docker"] +RUN ["apk", "add", "--update", "ethtool", "conntrack-tools", "curl", "iptables", "iproute2"] RUN ["sh", "-c", "rm -rf /var/cache/apk/*"] ADD ./weave /home/weave/ +ADD ./docker.tgz / ENTRYPOINT ["/home/weave/weave"]