diff --git a/test/810_plugin_router_restart.sh b/test/810_plugin_router_restart.sh new file mode 100755 index 00000000..68ca1a44 --- /dev/null +++ b/test/810_plugin_router_restart.sh @@ -0,0 +1,24 @@ +#! /bin/bash + +. ./config.sh + +C1_NAME=c1.weave.local + +start_suite "Recovery of container details on router restart (via 'local' plugin)" + +weave_on $HOST1 launch +start_container_local_plugin $HOST1 --name=c1 --hostname=$C1_NAME +c1ip=$(container_ip $HOST1 c1) + +weave_on $HOST1 stop-router +weave_on $HOST1 launch-router + +assert "container_ip $HOST1 c1" "$c1ip" +assert "weave_on $HOST1 dns-lookup $C1_NAME" "$c1ip" + +# check that c1 IP has been reclaimed and doesn't get assigned to a +# fresh container +start_container $HOST1 --name=c2 +assert_raises "container_ip $HOST1 c2 | grep -v $c1ip" + +end_suite diff --git a/weave b/weave index 5f09dc04..66c3d5d5 100755 --- a/weave +++ b/weave @@ -833,8 +833,12 @@ setup_router_iface_bridged_fastdp() { setup_router_iface_fastdp "$@" } +container_in_host_ns() { + [ -h "$PROCFS/$CONTAINER_PID/ns/net" -a -h "/proc/self/ns/net" -a "$(readlink $PROCFS/$CONTAINER_PID/ns/net)" = "$(readlink /proc/self/ns/net)" ] +} + attach() { - if [ -h "$PROCFS/$CONTAINER_PID/ns/net" -a -h "/proc/self/ns/net" -a "$(readlink $PROCFS/$CONTAINER_PID/ns/net)" = "$(readlink /proc/self/ns/net)" ] ; then + if container_in_host_ns ; then echo "Container is running in the host network namespace, and therefore cannot be" >&2 echo "connected to weave. Perhaps the container was started with --net=host." >&2 return 1 @@ -895,8 +899,8 @@ detach() { netnsenter ip link del $CONTAINER_IFNAME type veth } -container_weave_addrs() { - netnsenter ip addr show dev $CONTAINER_IFNAME +container_ip_addr_show() { + ! container_in_host_ns && netnsenter ip addr show } ###################################################################### @@ -1027,6 +1031,17 @@ wait_for_status() { done } +# Parse the output of `ip addr show`, outputing weave addresses of kind $1 +addrs_from_ip_addr_show() { + while read first second rest ; do + if [ "$first" != "${first%:}" ] ; then + iname="${second%:}" + elif [ "$first" = "$1" -a \( "$iname" = "weave" -o "$iname" != "${iname#ethwe}" \) ] ; then + echo $second + fi + done +} + # Call $1 for all containers, passing container ID, all MACs and all IPs with_container_addresses() { COMMAND=$1 @@ -1035,12 +1050,14 @@ with_container_addresses() { if [ "$CONTAINER_ID" = "weave:expose" ] ; then ADDRS_CMD="ip addr show dev $BRIDGE" else - ADDRS_CMD="with_container_netns $CONTAINER_ID container_weave_addrs" + ADDRS_CMD="with_container_netns $CONTAINER_ID container_ip_addr_show" fi if CONTAINER_ADDRS=$($ADDRS_CMD 2>/dev/null) ; then - CONTAINER_MAC=$(echo "$CONTAINER_ADDRS" | grep -o 'link/ether .*' | cut -d ' ' -f 2) - CONTAINER_IPS=$(echo "$CONTAINER_ADDRS" | grep -o 'inet .*' | cut -d ' ' -f 2) - $COMMAND "$CONTAINER_ID" "$CONTAINER_MAC" "$CONTAINER_IPS" + CONTAINER_MAC=$(echo "$CONTAINER_ADDRS" | addrs_from_ip_addr_show 'link/ether') + CONTAINER_IPS=$(echo "$CONTAINER_ADDRS" | addrs_from_ip_addr_show 'inet') + if [ -n "$CONTAINER_MAC$CONTAINER_IPS" ] ; then + $COMMAND "$CONTAINER_ID" "$CONTAINER_MAC" "$CONTAINER_IPS" + fi fi done } @@ -1650,7 +1667,7 @@ attach_router() { if [ -z "$NO_DNS_OPT" ] ; then # Tell the newly-started weaveDNS about existing weave IPs for CONTAINER in $(docker ps -q --no-trunc) ; do - if CONTAINER_IPS=$(with_container_netns $CONTAINER container_weave_addrs 2>&1 | sed -n -e 's/inet \([^/]*\)\/\(.*\)/\1/p') ; then + if CONTAINER_IPS=$(with_container_netns $CONTAINER container_ip_addr_show 2>/dev/null | addrs_from_ip_addr_show 'inet') && [ -n "$CONTAINER_IPS" ] ; then with_container_fqdn $CONTAINER put_dns_fqdn $CONTAINER_IPS fi done