From 3f797897461b7385cd586cb5aa7d0ae4b089a3cb Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 25 Aug 2015 11:09:16 +0100 Subject: [PATCH] Get the proxy to re-attach the weave router if it sees it restart --- proxy/proxy.go | 21 ++++++++++++++++++- test/640_proxy_restart_reattaches_test.sh | 8 ++++++-- weave | 25 +++++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index 10d0b72ce7..b406411d6b 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -105,7 +105,8 @@ func NewProxy(c Config) (*Proxy, error) { func (proxy *Proxy) AttachExistingContainers() { containers, _ := proxy.client.ListContainers(docker.ListContainersOptions{}) for _, cont := range containers { - if strings.HasPrefix(cont.Command, weaveWaitEntrypoint[0]) { + if strings.HasPrefix(cont.Command, weaveWaitEntrypoint[0]) || + strings.HasPrefix(cont.Command, "/home/weave/weaver") { proxy.ContainerStarted(cont.ID) } } @@ -257,6 +258,8 @@ func (proxy *Proxy) ContainerStarted(ident string) { // If this was a container we modified the entrypoint for, attach it to the network if containerShouldAttach(container) { proxy.attach(container) + } else if containerIsWeaveRouter(container) { + proxy.attachRouter(container) } proxy.notifyWaiters(container.ID) } @@ -265,6 +268,10 @@ func containerShouldAttach(container *docker.Container) bool { return len(container.Config.Entrypoint) > 0 && container.Config.Entrypoint[0] == weaveWaitEntrypoint[0] } +func containerIsWeaveRouter(container *docker.Container) bool { + return strings.HasPrefix(container.Config.Image, "weaveworks/weave") +} + func (proxy *Proxy) createWait(r *http.Request, ident string) { proxy.Lock() ch := make(chan struct{}) @@ -329,6 +336,18 @@ func (proxy *Proxy) attach(container *docker.Container) error { return nil } +func (proxy *Proxy) attachRouter(container *docker.Container) error { + Log.Infof("Attaching weave router container") + args := []string{"attach-router"} + if _, stderr, err := callWeave(args...); err != nil { + Log.Warningf("Attaching container %s to weave network failed: %s", container.ID, string(stderr)) + return errors.New(string(stderr)) + } else if len(stderr) > 0 { + Log.Warningf("Attaching container %s to weave network: %s", container.ID, string(stderr)) + } + return nil +} + func (proxy *Proxy) weaveCIDRsFromConfig(config *docker.Config, hostConfig *docker.HostConfig) ([]string, error) { netMode := "" if hostConfig != nil { diff --git a/test/640_proxy_restart_reattaches_test.sh b/test/640_proxy_restart_reattaches_test.sh index 428092f3af..e9befab81e 100755 --- a/test/640_proxy_restart_reattaches_test.sh +++ b/test/640_proxy_restart_reattaches_test.sh @@ -13,13 +13,18 @@ check_attached() { start_suite "Proxy restart reattaches networking to containers" -weave_on $HOST1 launch +WEAVE_DOCKER_ARGS=--restart=always WEAVEPROXY_DOCKER_ARGS=--restart=always weave_on $HOST1 launch proxy_start_container $HOST1 -e WEAVE_CIDR=$C2/24 -di --name=c2 --restart=always -h $NAME proxy_start_container_with_dns $HOST1 -e WEAVE_CIDR=$C1/24 -di --name=c1 --restart=always proxy docker_on $HOST1 restart -t=1 c2 check_attached +# Restart weave router +docker_on $HOST1 restart weave +sleep 1 +check_attached + # Kill outside of Docker so Docker will restart it run_on $HOST1 sudo kill -KILL $(docker_on $HOST1 inspect --format='{{.State.Pid}}' c2) sleep 1 @@ -28,7 +33,6 @@ check_attached # Restart docker itself, using different commands for systemd- and upstart-managed. run_on $HOST1 sh -c "command -v systemctl >/dev/null && sudo systemctl restart docker || sudo service docker restart" sleep 1 -weave_on $HOST1 launch check_attached end_suite diff --git a/weave b/weave index 7d093c6609..07208b422a 100755 --- a/weave +++ b/weave @@ -512,6 +512,10 @@ launch() { echo "Perhaps you are running the docker daemon with container networking disabled (-b=none)." >&2 return 1 fi + # No-op if already attached + if netnsenter ip link show $CONTAINER_IFNAME >/dev/null 2>&1 ; then + return 0 + fi connect_container_to_bridge && netnsenter ethtool -K eth0 tx off >/dev/null && netnsenter ip link set $CONTAINER_IFNAME up @@ -1177,6 +1181,17 @@ launch_router() { -e WEAVE_PASSWORD \ -e WEAVE_CIDR=none \ $WEAVE_DOCKER_ARGS $IMAGE $COVERAGE_ARGS --iface $CONTAINER_IFNAME --port $CONTAINER_PORT --name "$PEERNAME" --nickname "$(hostname)" --ipalloc-range "$IPRANGE" --dns-effective-listen-address "$DOCKER_BRIDGE_IP" "$@") +} + +# Recreate the parameter values that are set when the router is first launched +fetch_router_args() { + IPRANGE=$(docker inspect -f '{{.Args}}' $1 | grep -o -e '-ipalloc-range [^ ]*') + # This doesn't get back the right syntax, but it's enough for our purposes + DNS_PORT_MAPPING=$(docker inspect -f '{{with index .HostConfig.PortBindings "53/udp"}}{{.}}{{end}}' $1) +} + +attach_router() { + ROUTER_CONTAINER=$1 with_container_netns_or_die $ROUTER_CONTAINER launch wait_for_status $CONTAINER_NAME $HTTP_PORT if [ -n "$IPRANGE" ] ; then @@ -1345,14 +1360,24 @@ case "$COMMAND" in check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE COMMON_ARGS=$(common_launch_args "$@") launch_router "$@" + attach_router $CONTAINER_NAME launch_proxy $COMMON_ARGS ;; launch-router) deprecation_warnings "$@" check_not_running $CONTAINER_NAME $BASE_IMAGE launch_router "$@" + attach_router $CONTAINER_NAME echo $ROUTER_CONTAINER ;; + attach-router) + deprecation_warnings "$@" + check_running $CONTAINER_NAME + enforce_docker_bridge_addr_assign_type + create_bridge + fetch_router_args $CONTAINER_NAME + attach_router $CONTAINER_NAME + ;; launch-proxy) deprecation_warnings "$@" check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE