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.
This commit is contained in:
Michael Bridgen committed 2015-03-18 12:29:19 +00:00
1 parent e15f52b4cb
commit 8d12810446
4 files changed
+51 -112

No files matched your search

+3 -16
View File
@@ -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 $(<D)):/home/weave ubuntu sh /home/weave/build.sh
else
rm -rf tools/build
mkdir tools/build
cd tools/build && sh ../../$<
rm -rf tools/build
endif
$(WEAVER_EXPORT): weaver/Dockerfile $(WEAVER_EXE)
$(SUDO) docker build -t $(WEAVER_IMAGE) weaver
$(SUDO) docker save $(WEAVER_IMAGE):latest > $@
@@ -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)
+5 -2
View File
@@ -1,3 +1,6 @@
FROM scratch
FROM gliderlabs/alpine
MAINTAINER Weaveworks Inc <help@weave.works>
ADD ./bin /bin
WORKDIR /home/weave
RUN ["apk-install", "ethtool", "conntrack-tools", "curl", "iptables", "iproute2", "docker"]
ADD ./weave /home/weave/
ENTRYPOINT ["/home/weave/weave"]
-62
View File
@@ -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
+43 -32
View File
@@ -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