From 93f16d91ce79a24449c23791a336ab67d85af477 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 17 Mar 2015 17:31:06 +0000 Subject: [PATCH] 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