From 3cdc3522be500a4f658134c8479e011b0d494623 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 5 Jun 2015 14:07:30 +0100 Subject: [PATCH] Don't overwrite CIDR_ARGS; write new variables ALL_CIDRS and IPAM_CIDRS Handle manual CIDRs and IPAM CIDRs separately, to avoid inconsistencies and misleading messages --- weave | 120 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/weave b/weave index ec7b34f8..8aa8c713 100755 --- a/weave +++ b/weave @@ -104,14 +104,14 @@ validate_cidr() { collect_cidr_args() { CIDR_ARGS="" - CIDR_COUNT=0 + CIDR_ARG_COUNT=0 while is_cidr "$1" || [ "$1" = "--subnet" ] ; do CIDR_ARGS="$CIDR_ARGS $1" - CIDR_COUNT=$((CIDR_COUNT + 1)) + CIDR_ARG_COUNT=$((CIDR_ARG_COUNT + 1)) # only accept 'default' after '--subnet', in case someone has a container called 'default' if [ "$1" = "--subnet" -a "$2" = "default" ] ; then CIDR_ARGS="$CIDR_ARGS $2" - CIDR_COUNT=$((CIDR_ARG_COUNT + 1)) + CIDR_ARG_COUNT=$((CIDR_ARG_COUNT + 1)) shift 1 fi shift 1 @@ -155,7 +155,7 @@ if [ "$1" = "run" ] ; then DNS_ARGS=$(exec_remote dns-args "$@") fi collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT CONTAINER=$(docker $DOCKER_CLIENT_ARGS run $DNS_ARGS -d "$@") exec_remote attach $CIDR_ARGS $CONTAINER echo $CONTAINER @@ -757,45 +757,46 @@ ipam_claim() { done } -# Pass all CIDRs to IPAM so that network addresses can be interpreted -# as subnets to allocate within. $1 is the full container id; following -# args are previously parsed CIDR_ARGS. +# Call IPAM as necessary to allocate addresses +# $1 is the full container id and following args are previously parsed CIDR_ARGS. +# Returns ALL_CIDRS and IPAM_CIDRS ipam_cidrs() { CONTAINER_ID="$1" shift 1 - if [ $# -gt 0 ] ; then - CIDR_ARGS="" - while [ $# -gt 0 ] ; do - if [ $# -gt 1 -a "$1" = "--subnet" ] ; then - shift 1 - if [ "$1" = "default" ] ; then - CIDR=$(http_call $CONTAINER_NAME $HTTP_PORT POST /ip/$CONTAINER_ID) - else - CIDR=$(http_call $CONTAINER_NAME $HTTP_PORT POST /ip/$CONTAINER_ID/$1) - fi - if [ "$CIDR" = "404 page not found" ] ; then - echo "IP address allocation must be enabled to use --subnet (use the -iprange option on 'weave launch')" >&2 - return 1 - fi - if ! is_cidr "$CIDR" ; then - echo "$CIDR" >&2 - return 1 - fi - CIDR_COUNT=$((CIDR_COUNT - 1)) - else - CIDR=$1 - fi - CIDR_ARGS="$CIDR_ARGS $CIDR" + ALL_CIDRS="" + IPAM_CIDRs="" + if [ $# -eq 0 ] ; then + # If no addresses passed in, get one in the default subnet + IPAM_CIDRS="$(http_call $CONTAINER_NAME $HTTP_PORT POST /ip/$CONTAINER_ID)" + if [ "$IPAM_CIDRS" = "404 page not found" ] ; then + echo "No IP address supplied (use the -iprange option on 'weave launch' to enable IP address allocation)" >&2 + return 1 + fi + ALL_CIDRS="$IPAM_CIDRS" + fi + while [ $# -gt 0 ] ; do + if [ $# -gt 1 -a "$1" = "--subnet" ] ; then shift 1 - done - return 0 - fi - # If no addresses passed in, get one in the default subnet - CIDR_ARGS="$(http_call $CONTAINER_NAME $HTTP_PORT POST /ip/$CONTAINER_ID)" - if [ "$CIDR_ARGS" = "404 page not found" ] ; then - echo "No IP address supplied (use the -iprange option on 'weave launch' to enable IP address allocation)" >&2 - return 1 - fi + if [ "$1" = "default" ] ; then + CIDR=$(http_call $CONTAINER_NAME $HTTP_PORT POST /ip/$CONTAINER_ID) + else + CIDR=$(http_call $CONTAINER_NAME $HTTP_PORT POST /ip/$CONTAINER_ID/$1) + fi + if [ "$CIDR" = "404 page not found" ] ; then + echo "IP address allocation must be enabled to use --subnet (use the -iprange option on 'weave launch')" >&2 + return 1 + fi + if ! is_cidr "$CIDR" ; then + echo "$CIDR" >&2 + return 1 + fi + IPAM_CIDRS="$IPAM_CIDRS $CIDR" + ALL_CIDRS="$ALL_CIDRS $CIDR" + else + ALL_CIDRS="$ALL_CIDRS $1" + fi + shift 1 + done } ###################################################################### @@ -1062,12 +1063,12 @@ case "$COMMAND" in dns_args "$@" fi collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT CONTAINER=$(docker run $DNS_ARGS -d "$@") create_bridge ipam_cidrs $CONTAINER $CIDR_ARGS - with_container_netns_or_die $CONTAINER attach $CIDR_ARGS - when_dns_running with_container_fqdn $CONTAINER put_dns_fqdn $CIDR_ARGS + with_container_netns_or_die $CONTAINER attach $ALL_CIDRS + when_dns_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS echo $CONTAINER ;; dns-args) @@ -1080,34 +1081,37 @@ case "$COMMAND" in ;; start) collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT [ $# -eq 1 ] || usage RES=$(docker start $1) CONTAINER=$(container_id $1) create_bridge ipam_cidrs $CONTAINER $CIDR_ARGS - with_container_netns_or_die $CONTAINER attach $CIDR_ARGS - when_dns_running with_container_fqdn $CONTAINER put_dns_fqdn $CIDR_ARGS + with_container_netns_or_die $CONTAINER attach $ALL_CIDRS + when_dns_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS echo $RES ;; attach) collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT [ $# -eq 1 ] || usage CONTAINER=$(container_id $1) create_bridge ipam_cidrs $CONTAINER $CIDR_ARGS - with_container_netns $CONTAINER attach $CIDR_ARGS >/dev/null - when_dns_running with_container_fqdn $CONTAINER put_dns_fqdn $CIDR_ARGS + with_container_netns $CONTAINER attach $ALL_CIDRS >/dev/null + when_dns_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS ;; detach) collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT [ $# -eq 1 ] || usage CONTAINER=$(container_id $1) ipam_cidrs $CONTAINER $CIDR_ARGS - with_container_netns $CONTAINER detach $CIDR_ARGS >/dev/null - when_dns_running with_container_fqdn $CONTAINER delete_dns_fqdn $CIDR_ARGS + with_container_netns $CONTAINER detach $ALL_CIDRS >/dev/null + when_dns_running with_container_fqdn $CONTAINER delete_dns_fqdn $ALL_CIDRS + for CIDR in $IPAM_CIDRS ; do + http_call $CONTAINER_NAME $HTTP_PORT DELETE /ip/$CONTAINER/${CIDR%/*} + done ;; dns-add) collect_ip_args "$@" @@ -1135,7 +1139,7 @@ case "$COMMAND" in ;; expose) collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT ipam_cidrs weave:expose $CIDR_ARGS if [ $# -eq 0 ] ; then FQDN="" @@ -1144,7 +1148,7 @@ case "$COMMAND" in FQDN="$2" fi create_bridge --without-ethtool - for CIDR in $CIDR_ARGS ; do + for CIDR in $ALL_CIDRS ; do if ! ip addr show dev $BRIDGE | grep -qF $CIDR ; then ip addr add dev $BRIDGE $CIDR arp_update $BRIDGE $CIDR @@ -1158,19 +1162,19 @@ case "$COMMAND" in ;; hide) collect_cidr_args "$@" - shift $CIDR_COUNT + shift $CIDR_ARG_COUNT ipam_cidrs weave:expose $CIDR_ARGS create_bridge --without-ethtool - for CIDR in $CIDR_ARGS ; do + for CIDR in $ALL_CIDRS ; do if ip addr show dev $BRIDGE | grep -qF $CIDR ; then ip addr del dev $BRIDGE $CIDR delete_iptables_rule nat WEAVE -d $CIDR ! -s $CIDR -j MASQUERADE delete_iptables_rule nat WEAVE -s $CIDR ! -d $CIDR -j MASQUERADE when_dns_running delete_dns 'weave:expose' $CIDR fi - # Tell IPAM we don't need this address, but ignore errors because - # the address might not have come from IPAM - http_call $CONTAINER_NAME $HTTP_PORT DELETE /ip/weave:expose/${CIDR%/*} >/dev/null 2>&1 || true + done + for CIDR in $IPAM_CIDRS ; do + http_call $CONTAINER_NAME $HTTP_PORT DELETE /ip/weave:expose/${CIDR%/*} done ;; stop)