Advertisement
Guest User

Untitled

a guest
Oct 26th, 2016
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 76.33 KB | None | 0 0
  1. #!/bin/sh
  2. set -e
  3.  
  4. [ -n "$WEAVE_DEBUG" ] && set -x
  5.  
  6. SCRIPT_VERSION="1.7.2"
  7. IMAGE_VERSION=latest
  8. [ "$SCRIPT_VERSION" = "(unreleased version)" ] || IMAGE_VERSION=$SCRIPT_VERSION
  9. IMAGE_VERSION=${WEAVE_VERSION:-$IMAGE_VERSION}
  10.  
  11. # - Docker versions prior to 1.6 cannot pull images from DockerHub
  12. # - The weavexec image embeds a Docker 1.6.2 client. Docker will give
  13. # a "client is newer than server error" if the daemon has an older
  14. # API version, which could be confusing if the user's Docker client
  15. # is correctly matched with that older version.
  16. #
  17. # We therefore check that the user's Docker *client* is >= 1.6
  18. MIN_DOCKER_VERSION=1.6.0
  19.  
  20. # These are needed for remote execs, hence we introduce them here
  21. DOCKERHUB_USER=${DOCKERHUB_USER:-weaveworks}
  22. BASE_EXEC_IMAGE=$DOCKERHUB_USER/weaveexec
  23. EXEC_IMAGE=$BASE_EXEC_IMAGE:$IMAGE_VERSION
  24. WEAVEDB_IMAGE=$DOCKERHUB_USER/weavedb
  25. PROXY_HOST=${PROXY_HOST:-$(echo "${DOCKER_HOST#tcp://}" | cut -s -d: -f1)}
  26. PROXY_HOST=${PROXY_HOST:-127.0.0.1}
  27. DOCKER_CLIENT_HOST=${DOCKER_CLIENT_HOST:-$DOCKER_HOST}
  28.  
  29. # Define some regular expressions for matching addresses.
  30. # The regexp here is far from precise, but good enough.
  31. IP_REGEXP="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
  32. CIDR_REGEXP="$IP_REGEXP/[0-9]{1,2}"
  33.  
  34. ######################################################################
  35. # helpers that run locally, even without --local
  36. ######################################################################
  37.  
  38. usage_no_exit() {
  39. cat >&2 <<EOF
  40. Usage:
  41.  
  42. weave --help | help
  43. setup
  44. version
  45.  
  46. weave launch <same arguments as 'weave launch-router'>
  47. launch-router [--password <pass>] [--trusted-subnets <cidr>,...]
  48. [--host <ip_address>]
  49. [--name <mac>] [--nickname <nickname>]
  50. [--no-restart] [--resume] [--no-discovery] [--no-dns]
  51. [--ipalloc-init <mode>]
  52. [--ipalloc-range <cidr> [--ipalloc-default-subnet <cidr>]]
  53. [--log-level=debug|info|warning|error]
  54. <peer> ...
  55. launch-proxy [-H <endpoint>] [--without-dns] [--no-multicast-route]
  56. [--no-rewrite-hosts] [--no-default-ipalloc] [--no-restart]
  57. [--hostname-from-label <labelkey>]
  58. [--hostname-match <regexp>]
  59. [--hostname-replacement <replacement>]
  60. [--rewrite-inspect]
  61. [--log-level=debug|info|warning|error]
  62. launch-plugin [--no-restart] [--no-multicast-route]
  63. [--log-level=debug|info|warning|error]
  64.  
  65. weave prime
  66.  
  67. weave env [--restore]
  68. config
  69. dns-args
  70.  
  71. weave connect [--replace] [<peer> ...]
  72. forget <peer> ...
  73.  
  74. weave run [--without-dns] [--no-rewrite-hosts] [--no-multicast-route]
  75. [<addr> ...] <docker run args> ...
  76. start [<addr> ...] <container_id>
  77. attach [<addr> ...] <container_id>
  78. detach [<addr> ...] <container_id>
  79. restart <container_id>
  80.  
  81. weave expose [<addr> ...] [-h <fqdn>]
  82. hide [<addr> ...]
  83.  
  84. weave dns-add [<ip_address> ...] <container_id> [-h <fqdn>] |
  85. <ip_address> ... -h <fqdn>
  86. dns-remove [<ip_address> ...] <container_id> [-h <fqdn>] |
  87. <ip_address> ... -h <fqdn>
  88. dns-lookup <unqualified_name>
  89.  
  90. weave status [targets | connections | peers | dns | ipam]
  91. report [-f <format>]
  92. ps [<container_id> ...]
  93.  
  94. weave stop
  95. stop-router
  96. stop-proxy
  97. stop-plugin
  98.  
  99. weave reset [--force]
  100. rmpeer <peer_id> ...
  101.  
  102.  
  103. where <peer> = <ip_address_or_fqdn>[:<port>]
  104. <cidr> = <ip_address>/<routing_prefix_length>
  105. <addr> = [ip:]<cidr> | net:<cidr> | net:default
  106. <endpoint> = [tcp://][<ip_address>]:<port> | [unix://]/path/to/socket
  107. <peer_id> = <nickname> | <weave internal peer ID>
  108. <mode> = consensus[=<count>] | seed=<mac>,... | observer
  109. EOF
  110. }
  111.  
  112. usage() {
  113. usage_no_exit
  114. exit 1
  115. }
  116.  
  117. handle_help_arg() {
  118. if [ "$1" = "--help" ] ; then
  119. usage_no_exit
  120. exit 0
  121. fi
  122. }
  123.  
  124. docker_sock_options() {
  125. # Pass through DOCKER_HOST if it is a Unix socket;
  126. # a TCP socket may be secured by TLS, in which case we can't use it
  127. if echo "$DOCKER_HOST" | grep -q "^unix://" >/dev/null; then
  128. echo "-v ${DOCKER_HOST#unix://}:${DOCKER_HOST#unix://} -e DOCKER_HOST"
  129. else
  130. echo "-v /var/run/docker.sock:/var/run/docker.sock"
  131. fi
  132. }
  133.  
  134. docker_run_options() {
  135. echo --privileged --net=host $(docker_sock_options)
  136. }
  137.  
  138. exec_options() {
  139. case "$1" in
  140. setup|setup-cni|launch|launch-router)
  141. echo -v /:/host -e HOST_ROOT=/host
  142. ;;
  143. esac
  144. }
  145.  
  146. exec_remote() {
  147. docker $DOCKER_CLIENT_ARGS run --rm \
  148. $(docker_run_options) \
  149. --pid=host \
  150. $(exec_options "$@") \
  151. -e DOCKERHUB_USER="$DOCKERHUB_USER" \
  152. -e WEAVE_VERSION \
  153. -e WEAVE_DEBUG \
  154. -e WEAVE_DOCKER_ARGS \
  155. -e WEAVEPROXY_DOCKER_ARGS \
  156. -e WEAVEPLUGIN_DOCKER_ARGS \
  157. -e WEAVE_PASSWORD \
  158. -e WEAVE_PORT \
  159. -e WEAVE_HTTP_ADDR \
  160. -e WEAVE_CONTAINER_NAME \
  161. -e WEAVE_MTU \
  162. -e WEAVE_NO_FASTDP \
  163. -e WEAVE_NO_BRIDGED_FASTDP \
  164. -e WEAVE_NO_PLUGIN \
  165. -e DOCKER_BRIDGE \
  166. -e DOCKER_CLIENT_HOST="$DOCKER_CLIENT_HOST" \
  167. -e DOCKER_CLIENT_ARGS \
  168. -e PROXY_HOST="$PROXY_HOST" \
  169. -e COVERAGE \
  170. -e CHECKPOINT_DISABLE \
  171. -e AWSVPC \
  172. $WEAVEEXEC_DOCKER_ARGS $EXEC_IMAGE --local "$@"
  173. }
  174.  
  175. # Given $1 and $2 as semantic version numbers like 3.1.2, return [ $1 < $2 ]
  176. version_lt() {
  177. VERSION_MAJOR=${1%.*.*}
  178. REST=${1%.*} VERSION_MINOR=${REST#*.}
  179. VERSION_PATCH=${1#*.*.}
  180.  
  181. MIN_VERSION_MAJOR=${2%.*.*}
  182. REST=${2%.*} MIN_VERSION_MINOR=${REST#*.}
  183. MIN_VERSION_PATCH=${2#*.*.}
  184.  
  185. if [ \( "$VERSION_MAJOR" -lt "$MIN_VERSION_MAJOR" \) -o \
  186. \( "$VERSION_MAJOR" -eq "$MIN_VERSION_MAJOR" -a \
  187. \( "$VERSION_MINOR" -lt "$MIN_VERSION_MINOR" -o \
  188. \( "$VERSION_MINOR" -eq "$MIN_VERSION_MINOR" -a \
  189. \( "$VERSION_PATCH" -lt "$MIN_VERSION_PATCH" \) \) \) \) ] ; then
  190. return 0
  191. fi
  192. return 1
  193. }
  194.  
  195. check_docker_version() {
  196. if ! DOCKER_VERSION=$(docker -v | sed -n -e 's|^Docker version \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p') || [ -z "$DOCKER_VERSION" ] ; then
  197. echo "ERROR: Unable to parse docker version" >&2
  198. exit 1
  199. fi
  200.  
  201. if version_lt $DOCKER_VERSION $MIN_DOCKER_VERSION ; then
  202. echo "ERROR: weave requires Docker version $MIN_DOCKER_VERSION or later; you are running $DOCKER_VERSION" >&2
  203. exit 1
  204. fi
  205. }
  206.  
  207. is_cidr() {
  208. echo "$1" | grep -E "^$CIDR_REGEXP$" >/dev/null
  209. }
  210.  
  211. collect_cidr_args() {
  212. CIDR_ARGS=""
  213. CIDR_ARG_COUNT=0
  214. while [ "$1" = "net:default" ] || is_cidr "$1" || is_cidr "${1#ip:}" || is_cidr "${1#net:}" ; do
  215. CIDR_ARGS="$CIDR_ARGS ${1#ip:}"
  216. CIDR_ARG_COUNT=$((CIDR_ARG_COUNT + 1))
  217. shift 1
  218. done
  219. }
  220.  
  221. dns_arg_count() {
  222. if [ "$1" = "--with-dns" -o "$1" = "--without-dns" ] ; then
  223. echo 1
  224. else
  225. echo 0
  226. fi
  227. }
  228.  
  229. extra_hosts_args() {
  230. DNS_EXTRA_HOSTS=
  231. DNS_EXTRA_HOSTS_ARGS=
  232. while [ $# -gt 0 ] ; do
  233. case "$1" in
  234. --add-host)
  235. DNS_EXTRA_HOSTS="$2 $DNS_EXTRA_HOSTS"
  236. DNS_EXTRA_HOSTS_ARGS="--add-host=$2 $DNS_EXTRA_HOSTS_ARGS"
  237. shift
  238. ;;
  239. --add-host=*)
  240. DNS_EXTRA_HOSTS="${1#*=} $DNS_EXTRA_HOSTS"
  241. DNS_EXTRA_HOSTS_ARGS="--add-host=${1#*=} $DNS_EXTRA_HOSTS_ARGS"
  242. ;;
  243. esac
  244. shift
  245. done
  246. }
  247.  
  248. kill_container() {
  249. docker kill $1 >/dev/null 2>&1 || true
  250. }
  251.  
  252. ######################################################################
  253. # main
  254. ######################################################################
  255.  
  256. check_docker_version
  257.  
  258. [ "$1" = "--local" ] && shift 1 && IS_LOCAL=1
  259.  
  260. # "--help|help" are special because we always want to process them
  261. # at the client end.
  262. handle_help_arg "$1" || handle_help_arg "--$1"
  263.  
  264. if [ "$1" = "version" -a -z "$IS_LOCAL" ] ; then
  265. # non-local "version" is special because we want to show the
  266. # version of the script executed by the user rather than what is
  267. # embedded in weaveexec.
  268. echo "weave script $SCRIPT_VERSION"
  269. elif [ "$1" = "env" -a "$2" = "--restore" ] ; then
  270. # "env --restore" is special because we always want to process it
  271. # at the client end.
  272. if [ "${ORIG_DOCKER_HOST-unset}" = "unset" ] ; then
  273. echo "Nothing to restore. This is most likely because there was no preceding invocation of 'eval \$(weave env)' in this shell." >&2
  274. exit 1
  275. else
  276. echo "DOCKER_HOST=$ORIG_DOCKER_HOST"
  277. exit 0
  278. fi
  279. elif [ "$1" = "run" -a -z "$IS_LOCAL" ] ; then
  280. # non-local "run" is a special case because we want to use docker
  281. # directly, rather than the docker in $EXEC_IMAGE remotely. That's
  282. # because we are passing arbitrary arguments on to docker run, and
  283. # we can't rely on our baked-in docker to support those arguments.
  284. shift 1
  285.  
  286. handle_help_arg "$1"
  287. [ "$1" = "--without-dns" ] || DNS_ARGS=$(exec_remote dns-args "$@" || true)
  288. shift $(dns_arg_count "$@")
  289.  
  290. REWRITE_HOSTS=1
  291. NO_MULTICAST_ROUTE=
  292. while [ $# -gt 0 ]; do
  293. case "$1" in
  294. --no-rewrite-hosts)
  295. REWRITE_HOSTS=
  296. ;;
  297. --no-multicast-route)
  298. NO_MULTICAST_ROUTE=1
  299. ;;
  300. *)
  301. break
  302. ;;
  303. esac
  304. shift
  305. done
  306.  
  307. [ -n "$REWRITE_HOSTS" ] && extra_hosts_args "$@" && DNS_EXTRA_HOSTS_ARGS="--rewrite-hosts $DNS_EXTRA_HOSTS_ARGS"
  308. [ -n "$NO_MULTICAST_ROUTE" ] && ATTACH_ARGS="--no-multicast-route"
  309.  
  310. collect_cidr_args "$@"
  311. shift $CIDR_ARG_COUNT
  312. CONTAINER=$(docker $DOCKER_CLIENT_ARGS run -e WEAVE_CIDR=none $DNS_ARGS -d "$@")
  313. if ! exec_remote attach $CIDR_ARGS $DNS_EXTRA_HOSTS_ARGS $ATTACH_ARGS $CONTAINER >/dev/null ; then
  314. kill_container $CONTAINER
  315. exit 1
  316. fi
  317. echo $CONTAINER
  318. exit 0
  319. fi
  320.  
  321. if [ -z "$IS_LOCAL" ] ; then
  322. exec_remote "$@"
  323. exit $?
  324. fi
  325.  
  326. ######################################################################
  327. # main (remote and --local) - settings
  328. ######################################################################
  329.  
  330. # Default restart policy for router/proxy/plugin
  331. RESTART_POLICY="--restart=always"
  332. BASE_IMAGE=$DOCKERHUB_USER/weave
  333. IMAGE=$BASE_IMAGE:$IMAGE_VERSION
  334. CONTAINER_NAME=${WEAVE_CONTAINER_NAME:-weave}
  335.  
  336. BASE_PLUGIN_IMAGE=$DOCKERHUB_USER/plugin
  337. PLUGIN_IMAGE=$BASE_PLUGIN_IMAGE:$IMAGE_VERSION
  338. PLUGIN_CONTAINER_NAME=weaveplugin
  339. # Note VOLUMES_CONTAINER which is for weavewait should change when you upgrade Weave
  340. VOLUMES_CONTAINER_NAME=weavevolumes-$IMAGE_VERSION
  341. # DB files should remain when you upgrade, so version number not included in name
  342. DB_CONTAINER_NAME=${CONTAINER_NAME}db
  343.  
  344. DOCKER_BRIDGE=${DOCKER_BRIDGE:-docker0}
  345. BRIDGE=weave
  346. # This value is overridden when the datapath is used unbridged
  347. DATAPATH=datapath
  348. CONTAINER_IFNAME=ethwe
  349. BRIDGE_IFNAME=v${CONTAINER_IFNAME}-bridge
  350. DATAPATH_IFNAME=v${CONTAINER_IFNAME}-datapath
  351. PCAP_IFNAME=v${CONTAINER_IFNAME}-pcap
  352. PORT=${WEAVE_PORT:-6783}
  353. HTTP_ADDR=${WEAVE_HTTP_ADDR:-127.0.0.1:6784}
  354. PROXY_PORT=12375
  355. PROXY_CONTAINER_NAME=weaveproxy
  356. COVERAGE_ARGS=""
  357. [ -n "$COVERAGE" ] && COVERAGE_ARGS="-test.coverprofile=/home/weave/cover.prof --"
  358.  
  359. ######################################################################
  360. # general helpers; independent of docker and weave
  361. ######################################################################
  362.  
  363. # utility function to check whether a command can be executed by the shell
  364. # see http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script
  365. command_exists() {
  366. command -v $1 >/dev/null 2>&1
  367. }
  368.  
  369. fractional_sleep() {
  370. case $1 in
  371. *.*)
  372. if [ -z "$NO_FRACTIONAL_SLEEP" ] ; then
  373. sleep $1 >/dev/null 2>&1 && return 0
  374. NO_FRACTIONAL_SLEEP=1
  375. fi
  376. sleep $((${1%.*} + 1))
  377. ;;
  378. *)
  379. sleep $1
  380. ;;
  381. esac
  382. }
  383.  
  384. run_iptables() {
  385. # -w is recent addition to iptables
  386. if [ -z "$CHECKED_IPTABLES_W" ] ; then
  387. iptables -S -w >/dev/null 2>&1 && IPTABLES_W=-w
  388. CHECKED_IPTABLES_W=1
  389. fi
  390.  
  391. iptables $IPTABLES_W "$@"
  392. }
  393.  
  394. # Add a rule to iptables, if it doesn't exist already
  395. add_iptables_rule() {
  396. IPTABLES_TABLE="$1"
  397. shift 1
  398. if ! run_iptables -t $IPTABLES_TABLE -C "$@" >/dev/null 2>&1 ; then
  399. run_iptables -t $IPTABLES_TABLE -A "$@" >/dev/null
  400. fi
  401. }
  402.  
  403. # Insert a rule in iptables, if it doesn't exist already
  404. insert_iptables_rule() {
  405. IPTABLES_TABLE="$1"
  406. shift 1
  407. if ! run_iptables -t $IPTABLES_TABLE -C "$@" >/dev/null 2>&1 ; then
  408. run_iptables -t $IPTABLES_TABLE -I "$@" >/dev/null
  409. fi
  410. }
  411.  
  412. # Delete a rule from iptables, if it exist
  413. delete_iptables_rule() {
  414. IPTABLES_TABLE="$1"
  415. shift 1
  416. if run_iptables -t $IPTABLES_TABLE -C "$@" >/dev/null 2>&1 ; then
  417. run_iptables -t $IPTABLES_TABLE -D "$@" >/dev/null
  418. fi
  419. }
  420.  
  421. # Configure the ARP cache parameters for the given interface. This
  422. # makes containers react more quickly to a change in the MAC address
  423. # associated with an IP address.
  424. configure_arp_cache() {
  425. $2 sh -c "echo 5 >/proc/sys/net/ipv4/neigh/$1/base_reachable_time &&
  426. echo 2 >/proc/sys/net/ipv4/neigh/$1/delay_first_probe_time &&
  427. echo 1 >/proc/sys/net/ipv4/neigh/$1/ucast_solicit"
  428. }
  429.  
  430. # Send out an ARP announcement
  431. # (https://tools.ietf.org/html/rfc5227#page-15) to update ARP cache
  432. # entries across the weave network. We do this in addition to
  433. # configure_arp_cache because a) with those ARP cache settings it
  434. # still takes a few seconds to correct a stale ARP mapping, and b)
  435. # there is a kernel bug that means that the base_reachable_time
  436. # setting is not promptly obeyed
  437. # (<https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4bf6980dd0328530783fd657c776e3719b421d30>>).
  438. arp_update() {
  439. # It's not the end of the world if this doesn't run - we configure
  440. # ARP caches so that stale entries will be noticed quickly.
  441. ! command_exists arping || $3 arping -U -q -I $1 -c 1 ${2%/*}
  442. }
  443.  
  444. # Generate a MAC value from a stdin containing six space separated
  445. # 2-digit hexadecimal numbers.
  446. mac_from_hex() {
  447. # In the first byte of the MAC, the 'multicast' bit should be
  448. # clear and 'locally administered' bit should be set. All other
  449. # bits should be random.
  450. read a b c d e f && printf "%02x:$b:$c:$d:$e:$f" $((0x$a & ~1 | 2))
  451. }
  452.  
  453. mac_from_file() {
  454. UUID=$(cat $1 2>/dev/null) || return 1
  455. # We salt the input just as a precaution to avoid clashes with
  456. # other applications who might have had the bright idea of
  457. # generating MACs in the same way.
  458. echo "9oBJ0Jmip-$UUID" | sha256sum | sed 's/\(..\)/\1 /g' | cut -c1-17 | mac_from_hex
  459. }
  460.  
  461. # Generate a random MAC value
  462. random_mac() {
  463. od -txC -An -N6 /dev/urandom | mac_from_hex
  464. }
  465.  
  466. ######################################################################
  467. # weave and docker specific helpers
  468. ######################################################################
  469.  
  470. check_docker_server_api_version() {
  471. # Cope with various versions of `docker version` output format
  472. if ! DOCKER_API_VERSION=$(docker version -f '{{.Server.APIVersion}}' 2> /dev/null ) ; then
  473. if ! DOCKER_API_VERSION=$(docker version -f '{{.Server.ApiVersion}}' 2> /dev/null ) ; then
  474. if ! DOCKER_API_VERSION=$(docker version | sed -n -e 's|^Server API version: *\([0-9][0-9]*\.[0-9][0-9]\).*|\1|p') || [ -z "$DOCKER_API_VERSION" ] ; then
  475. echo "ERROR: Unable to determine docker version" >&2
  476. exit 1
  477. fi
  478. fi
  479. fi
  480.  
  481. if version_lt ${DOCKER_API_VERSION}.0 ${1}.0 ; then
  482. return 1
  483. fi
  484. }
  485.  
  486. util_op() {
  487. if command_exists weaveutil ; then
  488. weaveutil "$@"
  489. else
  490. docker run --rm --privileged --net=host --pid=host $(docker_sock_options) \
  491. --entrypoint=/usr/bin/weaveutil $EXEC_IMAGE "$@"
  492. fi
  493. }
  494.  
  495. check_forwarding_rules() {
  496. if run_iptables -C FORWARD -j REJECT --reject-with icmp-host-prohibited > /dev/null 2>&1; then
  497. cat >&2 <<EOF
  498. WARNING: existing iptables rule
  499.  
  500. '-A FORWARD -j REJECT --reject-with icmp-host-prohibited'
  501.  
  502. will block name resolution via weaveDNS - please reconfigure your firewall.
  503. EOF
  504. fi
  505. }
  506.  
  507. enforce_docker_bridge_addr_assign_type() {
  508. if ! ADDR_ASSIGN_TYPE=$(cat /sys/class/net/$DOCKER_BRIDGE/addr_assign_type 2>/dev/null) ; then
  509. echo "Could not determine address assignment type of $DOCKER_BRIDGE" >&2
  510. return
  511. fi
  512. # From include/uapi/linux/netdevice.h
  513. # #define NET_ADDR_PERM 0 /* address is permanent (default) */
  514. # #define NET_ADDR_RANDOM 1 /* address is generated randomly */
  515. # #define NET_ADDR_STOLEN 2 /* address is stolen from other device */
  516. # #define NET_ADDR_SET 3 /* address is set using dev_set_mac_address() */
  517. if [ $ADDR_ASSIGN_TYPE != 3 ] ; then
  518. echo "Setting $DOCKER_BRIDGE MAC (mitigate https://github.com/docker/docker/issues/14908)" >&2
  519. ip link set dev $DOCKER_BRIDGE address $(random_mac) || true
  520. fi
  521. }
  522.  
  523. # Detect the current bridge/datapath state. When invoked, the values of
  524. # $BRIDGE and $DATAPATH are expected to be distinct. $BRIDGE_TYPE and
  525. # $DATAPATH are set correctly on success; failure indicates that the
  526. # bridge/datapath devices have yet to be configured. If netdevs do exist
  527. # but are in an inconsistent state the script aborts with an error.
  528. detect_bridge_type() {
  529. BRIDGE_TYPE=
  530. if [ -d /sys/class/net/$DATAPATH ] ; then
  531. # Unfortunately there's no simple way to positively check whether
  532. # $DATAPATH is an ODP netdev so we have to make sure it isn't
  533. # a bridge instead (and that $BRIDGE is).
  534. if [ ! -d /sys/class/net/$DATAPATH/bridge -a -d /sys/class/net/$BRIDGE/bridge ] ; then
  535. BRIDGE_TYPE=bridged_fastdp
  536. else
  537. echo "Inconsistent bridge state detected. Please do 'weave reset' and try again." >&2
  538. exit 1
  539. fi
  540. elif [ -d /sys/class/net/$BRIDGE ] ; then
  541. if [ -d /sys/class/net/$BRIDGE/bridge ] ; then
  542. BRIDGE_TYPE=bridge
  543. else
  544. BRIDGE_TYPE=fastdp
  545. # The datapath is the bridge when there is no intermediary
  546. DATAPATH="$BRIDGE"
  547. fi
  548. else
  549. # No bridge/datapath devices configured
  550. return 1
  551. fi
  552.  
  553. # WEAVE_MTU may have been specified when the bridge was
  554. # created (perhaps implicitly with WEAVE_NO_FASTDP). So take
  555. # the MTU from the bridge unless it is explicitly specified
  556. # for this invocation.
  557. MTU=${WEAVE_MTU:-$(cat /sys/class/net/$BRIDGE/mtu)}
  558. }
  559.  
  560. create_bridge() {
  561. if ! detect_bridge_type ; then
  562. BRIDGE_TYPE=bridge
  563. if [ -z "$WEAVE_NO_FASTDP" ] ; then
  564. BRIDGE_TYPE=bridged_fastdp
  565. if [ -n "$WEAVE_NO_BRIDGED_FASTDP" ] ; then
  566. BRIDGE_TYPE=fastdp
  567. # The datapath is the bridge when there is no intermediary
  568. DATAPATH="$BRIDGE"
  569. fi
  570. if util_op create-datapath $DATAPATH ; then
  571. : # ODP datapath created successfully
  572. elif [ $? = 17 ] ; then
  573. # Exit status of 17 means the kernel doesn't have ODP
  574. BRIDGE_TYPE=bridge
  575. else
  576. return 1
  577. fi
  578. fi
  579.  
  580. init_$BRIDGE_TYPE
  581.  
  582. # Drop traffic from Docker bridge to Weave; it can break
  583. # subnet isolation
  584. if [ "$DOCKER_BRIDGE" != "$BRIDGE" ] ; then
  585. # Note using -I to insert ahead of Docker's bridge rules
  586. run_iptables -t filter -I FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP
  587. fi
  588.  
  589. [ -n "$DOCKER_BRIDGE_IP" ] || docker_bridge_ip
  590.  
  591. # forbid traffic to the Weave port from other containers
  592. add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p tcp --dst $DOCKER_BRIDGE_IP --dport $PORT -j DROP
  593. add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dst $DOCKER_BRIDGE_IP --dport $PORT -j DROP
  594. add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dst $DOCKER_BRIDGE_IP --dport $(($PORT + 1)) -j DROP
  595.  
  596. # let DNS traffic to weaveDNS, since otherwise it might get blocked by the likes of UFW
  597. add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT
  598. add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT
  599.  
  600. if [ "$2" = "--expect-npc" ] ; then # matches usage in weave-kube launch.sh
  601. # Steer traffic via the NPC
  602. run_iptables -N WEAVE-NPC >/dev/null 2>&1 || true
  603. add_iptables_rule filter FORWARD -o $BRIDGE -j WEAVE-NPC
  604. add_iptables_rule filter FORWARD -o $BRIDGE -j LOG --log-prefix=WEAVE-NPC:
  605. add_iptables_rule filter FORWARD -o $BRIDGE -j DROP
  606. else
  607. # Work around the situation where there are no rules allowing traffic
  608. # across our bridge. E.g. ufw
  609. add_iptables_rule filter FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT
  610. fi
  611.  
  612. # create a chain for masquerading
  613. run_iptables -t nat -N WEAVE >/dev/null 2>&1 || true
  614. add_iptables_rule nat POSTROUTING -j WEAVE
  615. else
  616. if [ -n "$LAUNCHING_ROUTER" ] ; then
  617. if [ "$BRIDGE_TYPE" = bridge -a -z "$WEAVE_NO_FASTDP" ] &&
  618. util_op check-datapath $DATAPATH 2>/dev/null ; then
  619. cat <<EOF >&2
  620. WEAVE_NO_FASTDP is not set, but there is already a bridge present of
  621. the wrong type for fast datapath. Please do 'weave reset' to remove
  622. the bridge first.
  623. EOF
  624. return 1
  625. fi
  626. if [ "$BRIDGE_TYPE" != bridge -a -n "$WEAVE_NO_FASTDP" ] ; then
  627. cat <<EOF >&2
  628. WEAVE_NO_FASTDP is set, but there is already a weave fast datapath
  629. bridge present. Please do 'weave reset' to remove the bridge first.
  630. EOF
  631. return 1
  632. fi
  633. fi
  634. fi
  635.  
  636. [ "$1" = "--without-ethtool" -o -n "$AWSVPC" ] || ethtool_tx_off_$BRIDGE_TYPE $BRIDGE
  637.  
  638. ip link set dev $BRIDGE up
  639.  
  640. # Configure the ARP cache parameters on the bridge interface for
  641. # the sake of 'weave expose'
  642. configure_arp_cache $BRIDGE
  643. }
  644.  
  645. expose_ip() {
  646. ipam_cidrs allocate_no_check_alive weave:expose $CIDR_ARGS
  647. for CIDR in $ALL_CIDRS ; do
  648. if ! ip addr show dev $BRIDGE | grep -qF $CIDR ; then
  649. ip addr add dev $BRIDGE $CIDR
  650. arp_update $BRIDGE $CIDR || true
  651. # Remove a default route installed by the kernel, because awsvpc
  652. # has installed it as well
  653. if [ -n "$AWSVPC" ]; then
  654. RCIDR=$(ip route list exact $CIDR proto kernel | head -n1 | cut -d' ' -f1)
  655. [ -n "$RCIDR" ] && ip route del dev $BRIDGE proto kernel $RCIDR
  656. fi
  657. fi
  658. [ -z "$FQDN" ] || when_weave_running put_dns_fqdn_no_check_alive weave:expose $FQDN $CIDR
  659. done
  660. }
  661.  
  662. expose_nat() {
  663. for CIDR in $ALL_CIDRS ; do
  664. add_iptables_rule nat WEAVE -s $CIDR -d 224.0.0.0/4 -j RETURN
  665. add_iptables_rule nat WEAVE -d $CIDR ! -s $CIDR -j MASQUERADE
  666. add_iptables_rule nat WEAVE -s $CIDR ! -d $CIDR -j MASQUERADE
  667. done
  668. }
  669.  
  670. # create veth with ends $1-$2, and then invoke $3..., removing the
  671. # veth on failure. No-op of veth already exists.
  672. create_veth() {
  673. VETHL=$1
  674. VETHR=$2
  675. shift 2
  676.  
  677. ip link show $VETHL >/dev/null 2>&1 && ip link show $VETHR >/dev/null 2>&1 && return 0
  678.  
  679. ip link add name $VETHL mtu $MTU type veth peer name $VETHR mtu $MTU || return 1
  680.  
  681. if ! ip link set $VETHL up || ! ip link set $VETHR up || ! "$@" ; then
  682. ip link del $VETHL >/dev/null 2>&1 || true
  683. ip link del $VETHR >/dev/null 2>&1 || true
  684. return 1
  685. fi
  686. }
  687.  
  688. init_fastdp() {
  689. # GCE has the lowest underlay network MTU we're likely to encounter on
  690. # a local network, at 1460 bytes. To get the overlay MTU from that we
  691. # subtract 20 bytes for the outer IPv4 header, 8 bytes for the outer
  692. # UDP header, 8 bytes for the vxlan header, and 14 bytes for the inner
  693. # ethernet header.
  694. MTU=${WEAVE_MTU:-1410}
  695.  
  696. # create_bridge already created the datapath netdev
  697. ip link set dev $DATAPATH mtu $MTU
  698. }
  699.  
  700. init_bridge_prep() {
  701. # Observe any MTU that is already set
  702. [ -n "$MTU" ] || MTU=${WEAVE_MTU:-65535}
  703.  
  704. ip link add name $BRIDGE type bridge
  705.  
  706. # Derive the bridge MAC from the system (aka bios) UUID, or,
  707. # failing that, the hypervisor UUID. Elsewhere we in turn derive
  708. # the peer name from that, which we want to be stable across
  709. # reboots but otherwise unique. The system/hypervisor UUID fits
  710. # that bill, unlike, say, /etc/machine-id, which is often
  711. # identical on VMs created from cloned filesystems. If we cannot
  712. # determine the system/hypervisor UUID we just generate a random MAC.
  713. MAC=$(mac_from_file /sys/class/dmi/id/product_uuid) || \
  714. MAC=$(mac_from_file /sys/hypervisor/uuid) || \
  715. MAC=$(random_mac)
  716.  
  717. ip link set dev $BRIDGE address $MAC
  718.  
  719. # Attempting to set the bridge MTU to a high value directly
  720. # fails. Bridges take the lowest MTU of their interfaces. So
  721. # instead we create a temporary interface with the desired
  722. # MTU, attach that to the bridge, and then remove it again.
  723. ip link add name v${CONTAINER_IFNAME}du mtu $MTU type dummy
  724. ip link set dev v${CONTAINER_IFNAME}du master $BRIDGE
  725. ip link del dev v${CONTAINER_IFNAME}du
  726. }
  727.  
  728. init_bridge() {
  729. init_bridge_prep
  730. create_veth $BRIDGE_IFNAME $PCAP_IFNAME add_iface_bridge $BRIDGE_IFNAME
  731. }
  732.  
  733. init_bridged_fastdp() {
  734. # Initialise the datapath as normal. NB sets MTU for use below
  735. init_fastdp
  736.  
  737. # Initialise the bridge using fast datapath MTU
  738. init_bridge_prep
  739.  
  740. # Create linking veth pair
  741. create_veth $BRIDGE_IFNAME $DATAPATH_IFNAME configure_veth_bridged_fastdp
  742.  
  743. # Finally, bring the datapath up
  744. ip link set dev $DATAPATH up
  745. }
  746.  
  747. configure_veth_bridged_fastdp() {
  748. add_iface_fastdp $DATAPATH_IFNAME || return 1
  749. add_iface_bridge $BRIDGE_IFNAME || return 1
  750. }
  751.  
  752. ethtool_tx_off_fastdp() {
  753. true
  754. }
  755.  
  756. ethtool_tx_off_bridge() {
  757. ethtool -K $1 tx off >/dev/null
  758. }
  759.  
  760. ethtool_tx_off_bridged_fastdp() {
  761. true
  762. }
  763.  
  764. destroy_bridge() {
  765. # It's important that detect_bridge_type has not been called so
  766. # we have distinct values for $BRIDGE and $DATAPATH. Make best efforts
  767. # to remove netdevs of any type with those names so `weave reset` can
  768. # recover from inconsistent states.
  769. for NETDEV in $BRIDGE $DATAPATH ; do
  770. if [ -d /sys/class/net/$NETDEV ] ; then
  771. if [ -d /sys/class/net/$NETDEV/bridge ] ; then
  772. ip link del $NETDEV
  773. else
  774. util_op delete-datapath $NETDEV
  775. fi
  776. fi
  777. done
  778.  
  779. # Remove any lingering bridged fastdp, pcap and attach-bridge veths
  780. for VETH in $(ip -o link show | grep -o v${CONTAINER_IFNAME}[^:@]*) ; do
  781. ip link del $VETH >/dev/null 2>&1 || true
  782. done
  783.  
  784. if [ "$DOCKER_BRIDGE" != "$BRIDGE" ] ; then
  785. run_iptables -t filter -D FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP 2>/dev/null || true
  786. fi
  787.  
  788. [ -n "$DOCKER_BRIDGE_IP" ] || docker_bridge_ip
  789.  
  790. run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT >/dev/null 2>&1 || true
  791. run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT >/dev/null 2>&1 || true
  792.  
  793. run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p tcp --dst $DOCKER_BRIDGE_IP --dport $PORT -j DROP >/dev/null 2>&1 || true
  794. run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p udp --dst $DOCKER_BRIDGE_IP --dport $PORT -j DROP >/dev/null 2>&1 || true
  795. run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p udp --dst $DOCKER_BRIDGE_IP --dport $(($PORT + 1)) -j DROP >/dev/null 2>&1 || true
  796.  
  797. run_iptables -t filter -D FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT 2>/dev/null || true
  798. run_iptables -t nat -F WEAVE >/dev/null 2>&1 || true
  799. run_iptables -t nat -D POSTROUTING -j WEAVE >/dev/null 2>&1 || true
  800. run_iptables -t nat -D POSTROUTING -o $BRIDGE -j ACCEPT >/dev/null 2>&1 || true
  801. run_iptables -t nat -X WEAVE >/dev/null 2>&1 || true
  802. }
  803.  
  804. docker_bridge_ip() {
  805. DOCKER_BRIDGE_IP=$(ip -4 addr show dev $DOCKER_BRIDGE | grep -m1 -o 'inet [.0-9]*') || return 1
  806. DOCKER_BRIDGE_IP=${DOCKER_BRIDGE_IP#inet }
  807. }
  808.  
  809. do_or_die() {
  810. CONTAINER="$1"
  811. shift 1
  812. if ! "$@" ; then
  813. kill_container $CONTAINER
  814. exit 1
  815. fi
  816. }
  817.  
  818. add_iface_fastdp() {
  819. util_op add-datapath-interface $DATAPATH $1
  820. }
  821.  
  822. add_iface_bridge() {
  823. ip link set $1 master $BRIDGE
  824. }
  825.  
  826. add_iface_bridged_fastdp() {
  827. add_iface_bridge "$@"
  828. }
  829.  
  830. attach_bridge() {
  831. bridge="$1"
  832. LOCAL_IFNAME=v${CONTAINER_IFNAME}bl$bridge
  833. GUEST_IFNAME=v${CONTAINER_IFNAME}bg$bridge
  834.  
  835. create_veth $LOCAL_IFNAME $GUEST_IFNAME configure_veth_attached_bridge
  836. }
  837.  
  838. configure_veth_attached_bridge() {
  839. add_iface_$BRIDGE_TYPE $LOCAL_IFNAME || return 1
  840. ip link set $GUEST_IFNAME master $bridge
  841. }
  842.  
  843. router_opts_fastdp() {
  844. echo "--datapath $DATAPATH"
  845. }
  846.  
  847. router_opts_bridge() {
  848. echo "--iface $PCAP_IFNAME"
  849. }
  850.  
  851. router_opts_bridged_fastdp() {
  852. router_opts_fastdp "$@"
  853. }
  854.  
  855. ask_version() {
  856. if check_running $1 2>/dev/null ; then
  857. DOCKERIMAGE=$(docker inspect --format='{{.Image}}' $1 )
  858. elif ! DOCKERIMAGE=$(docker inspect --format='{{.Id}}' $2 2>/dev/null) ; then
  859. echo "Unable to find $2 image." >&2
  860. fi
  861. [ -n "$DOCKERIMAGE" ] && docker run --rm --net=none -e WEAVE_CIDR=none $3 $DOCKERIMAGE $COVERAGE_ARGS --version
  862. }
  863.  
  864. attach() {
  865. ATTACH_ARGS=""
  866. [ -n "$NO_MULTICAST_ROUTE" ] && ATTACH_ARGS="--no-multicast-route"
  867. # Relying on AWSVPC being set in 'ipam_cidrs allocate', except for 'weave restart'
  868. [ -n "$AWSVPC" ] && ATTACH_ARGS="--no-multicast-route --keep-tx-on"
  869. util_op attach-container $ATTACH_ARGS $CONTAINER $BRIDGE $MTU "$@"
  870. }
  871.  
  872. ######################################################################
  873. # functions for interacting with containers
  874. ######################################################################
  875.  
  876. # Check that a container for component $1 named $2 with image $3 is not running
  877. check_not_running() {
  878. RUN_STATUS=$(docker inspect --format='{{.State.Running}} {{.State.Status}} {{.Config.Image}}' $2 2>/dev/null) || true
  879. case ${RUN_STATUS%:*} in
  880. "true restarting $3")
  881. echo "$2 is restarting; you can stop it with 'weave stop-$1'." >&2
  882. return 3
  883. ;;
  884. "true "*" $3")
  885. echo "$2 is already running; you can stop it with 'weave stop-$1'." >&2
  886. return 1
  887. ;;
  888. "false "*" $3")
  889. docker rm $2 >/dev/null
  890. ;;
  891. true*)
  892. echo "Found another running container named '$2'. Aborting." >&2
  893. return 2
  894. ;;
  895. false*)
  896. echo "Found another container named '$2'. Aborting." >&2
  897. return 2
  898. ;;
  899. esac
  900. }
  901.  
  902. stop() {
  903. docker stop $1 >/dev/null 2>&1 || echo "$2 is not running." >&2
  904. }
  905.  
  906. # Given a container name or short ID in $1, ensure the specified
  907. # container exists and then print its full ID to stdout. If
  908. # it doesn't exist, print an error to stderr and
  909. # return with an indicative non-zero exit code.
  910. container_id() {
  911. if ! docker inspect --format='{{.Id}}' $1 2>/dev/null ; then
  912. echo "Error: No such container: $1" >&2
  913. return 1
  914. fi
  915. }
  916.  
  917. http_call() {
  918. addr="$1"
  919. http_verb="$2"
  920. url="$3"
  921. shift 3
  922. CURL_TMPOUT=/tmp/weave_curl_out_$$
  923. HTTP_CODE=$(curl -o $CURL_TMPOUT -w '%{http_code}' --connect-timeout 3 -s -S -X $http_verb "$@" http://$addr$url) || return $?
  924. case "$HTTP_CODE" in
  925. 2??) # 2xx -> not an error; output response on stdout
  926. [ -f $CURL_TMPOUT ] && cat $CURL_TMPOUT
  927. retval=0
  928. ;;
  929. 404) # treat as error but swallow response
  930. retval=4
  931. ;;
  932. *) # anything else is an error; output response on stderr
  933. [ -f $CURL_TMPOUT ] && cat $CURL_TMPOUT >&2
  934. retval=1
  935. esac
  936. rm -f $CURL_TMPOUT
  937. return $retval
  938. }
  939.  
  940. http_call_unix() {
  941. container="$1"
  942. socket="$2"
  943. http_verb="$3"
  944. url="$4"
  945. shift 4
  946. # NB: requires curl >= 7.40
  947. output=$(docker exec $container curl -s -S -X $http_verb --unix-socket $socket "$@" http:$url) || return 1
  948. # in some docker versions, `docker exec` does not fail when the executed command fails
  949. [ -n "$output" ] || return 1
  950. echo $output
  951. }
  952.  
  953. call_weave() {
  954. TMPERR=/tmp/call_weave_err_$$
  955. retval=0
  956. http_call $HTTP_ADDR "$@" 2>$TMPERR || retval=$?
  957. if [ $retval -ne 0 ] ; then
  958. check_running $CONTAINER_NAME && cat $TMPERR >&2
  959. fi
  960. rm -f $TMPERR
  961. return $retval
  962. }
  963.  
  964. death_msg() {
  965. echo "The $1 container has died. Consult the container logs for further details."
  966. }
  967.  
  968. # Wait until container $1 is alive enough to respond to "GET /status"
  969. # http request
  970. wait_for_status() {
  971. container="$1"
  972. shift
  973. while true ; do
  974. "$@" GET /status >/dev/null 2>&1 && return 0
  975. if ! check_running $container >/dev/null 2>&1 ; then
  976. kill_container $container # stop it restarting
  977. echo $(death_msg $container) >&2
  978. return 1
  979. fi
  980. fractional_sleep 0.1
  981. done
  982. }
  983.  
  984. # Call $1 for all containers, passing container ID, all MACs and all IPs
  985. with_container_addresses() {
  986. COMMAND=$1
  987. shift 1
  988.  
  989. CONTAINER_ADDRS=$(util_op container-addrs $BRIDGE "$@") || return 1
  990. echo "$CONTAINER_ADDRS" | while read CONTAINER_ID CONTAINER_IFACE CONTAINER_MAC CONTAINER_IPS; do
  991. $COMMAND "$CONTAINER_ID" "$CONTAINER_IFACE" "$CONTAINER_MAC" "$CONTAINER_IPS"
  992. done
  993. }
  994.  
  995. echo_addresses() {
  996. echo $1 $3 $4
  997. }
  998.  
  999. echo_ips() {
  1000. for CIDR in $4; do
  1001. echo ${CIDR%/*}
  1002. done
  1003. }
  1004.  
  1005. echo_cidrs() {
  1006. echo $4
  1007. }
  1008.  
  1009. peer_args() {
  1010. res=''
  1011. sep=''
  1012. for p in "$@" ; do
  1013. res="$res${sep}peer=$p"
  1014. sep="&"
  1015. done
  1016. echo "$res"
  1017. }
  1018.  
  1019. ######################################################################
  1020. # CNI helpers
  1021. ######################################################################
  1022.  
  1023. create_cni_script() {
  1024. cat >"$1" <<EOF
  1025. #!/bin/sh
  1026. [ -z "\$CNI_NETNS" -o \$(echo "\$CNI_NETNS" | grep "^/proc/") ] || \\
  1027. EXTRA_VOLUMES="-v \$(dirname \$CNI_NETNS):\$(dirname \$CNI_NETNS)"
  1028. docker run --rm $(docker_run_options) --pid=host -i \\
  1029. -e CNI_VERSION -e CNI_COMMAND -e CNI_CONTAINERID -e CNI_NETNS \\
  1030. -e CNI_IFNAME -e CNI_ARGS -e CNI_PATH \\
  1031. -v /etc/cni:/etc/cni -v /opt/cni:/opt/cni \$EXTRA_VOLUMES \\
  1032. $PLUGIN_IMAGE $COVERAGE_ARGS $2
  1033. EOF
  1034. chmod a+x "$1"
  1035. }
  1036.  
  1037. create_cni_config() {
  1038. cat >"$1" <<EOF
  1039. {
  1040. "name": "weave",
  1041. "type": "weave-net"
  1042. }
  1043. EOF
  1044. }
  1045.  
  1046. setup_cni() {
  1047. if [ -d $HOST_ROOT/opt/cni/bin ] ; then
  1048. create_cni_script $HOST_ROOT/opt/cni/bin/weave-net --cni-net
  1049. create_cni_script $HOST_ROOT/opt/cni/bin/weave-ipam --cni-ipam
  1050. fi
  1051. if [ -d $HOST_ROOT/etc/cni/net.d -a ! -f $HOST_ROOT/etc/cni/net.d/10-weave.conf ] ; then
  1052. create_cni_config $HOST_ROOT/etc/cni/net.d/10-weave.conf
  1053. fi
  1054. }
  1055.  
  1056. ######################################################################
  1057. # weaveDNS helpers
  1058. ######################################################################
  1059.  
  1060. dns_args() {
  1061. retval=0
  1062. # NB: this is memoized
  1063. DNS_DOMAIN=${DNS_DOMAIN:-$(call_weave GET /domain 2>/dev/null)} || retval=$?
  1064. [ "$retval" -eq 4 ] && return 0
  1065. DNS_DOMAIN=${DNS_DOMAIN:-weave.local.}
  1066.  
  1067. NAME_ARG=""
  1068. HOSTNAME_SPECIFIED=
  1069. DNS_SEARCH_SPECIFIED=
  1070. WITHOUT_DNS=
  1071. while [ $# -gt 0 ] ; do
  1072. case "$1" in
  1073. --with-dns)
  1074. echo "Warning: $1 is deprecated; it is on by default" >&2
  1075. ;;
  1076. --without-dns)
  1077. WITHOUT_DNS=1
  1078. ;;
  1079. --name)
  1080. NAME_ARG="$2"
  1081. shift
  1082. ;;
  1083. --name=*)
  1084. NAME_ARG="${1#*=}"
  1085. ;;
  1086. -h|--hostname|--hostname=*)
  1087. HOSTNAME_SPECIFIED=1
  1088. ;;
  1089. --dns-search|--dns-search=*)
  1090. DNS_SEARCH_SPECIFIED=1
  1091. ;;
  1092. esac
  1093. shift
  1094. done
  1095. [ -n "$WITHOUT_DNS" ] && return 0
  1096.  
  1097. docker_bridge_ip
  1098. DNS_ARGS="--dns=$DOCKER_BRIDGE_IP"
  1099. if [ -n "$NAME_ARG" -a -z "$HOSTNAME_SPECIFIED" ] ; then
  1100. HOSTNAME="$NAME_ARG.${DNS_DOMAIN%.}"
  1101. if [ ${#HOSTNAME} -gt 64 ] ; then
  1102. echo "Container name too long to be used as hostname" >&2
  1103. else
  1104. DNS_ARGS="$DNS_ARGS --hostname=$HOSTNAME"
  1105. HOSTNAME_SPECIFIED=1
  1106. fi
  1107. fi
  1108. if [ -z "$DNS_SEARCH_SPECIFIED" ] ; then
  1109. if [ -z "$HOSTNAME_SPECIFIED" ] ; then
  1110. DNS_ARGS="$DNS_ARGS --dns-search=$DNS_DOMAIN"
  1111. else
  1112. DNS_ARGS="$DNS_ARGS --dns-search=."
  1113. fi
  1114. fi
  1115. }
  1116.  
  1117. etc_hosts_contents() {
  1118. FQDN=$1
  1119. shift
  1120. NAME=${FQDN%%.*}
  1121. HOSTNAMES="$NAME"
  1122. [ "$NAME" = "$FQDN" -o "$NAME." = "$FQDN" ] || HOSTNAMES="${FQDN%.} $HOSTNAMES"
  1123.  
  1124. echo "# created by Weave - BEGIN"
  1125. echo "# container hostname"
  1126. for CIDR in $ALL_CIDRS ; do
  1127. echo "${CIDR%/*} $HOSTNAMES"
  1128. done
  1129. echo
  1130. echo "# static names added with --add-host"
  1131. for EXTRA_HOST in "$@" ; do
  1132. echo "${EXTRA_HOST#*:} ${EXTRA_HOST%:*}"
  1133. done
  1134.  
  1135. cat <<-EOF
  1136.  
  1137. # default localhost entries
  1138. 127.0.0.1 localhost
  1139. ::1 ip6-localhost ip6-loopback
  1140. fe00::0 ip6-localnet
  1141. ff00::0 ip6-mcastprefix
  1142. ff02::1 ip6-allnodes
  1143. ff02::2 ip6-allrouters
  1144. EOF
  1145.  
  1146. echo "# created by Weave - END"
  1147. }
  1148.  
  1149. rewrite_etc_hosts() {
  1150. HOSTS_PATH_AND_FQDN=$(docker inspect -f '{{.HostsPath}} {{.Config.Hostname}}.{{.Config.Domainname}}' $CONTAINER) || return 1
  1151. HOSTS=${HOSTS_PATH_AND_FQDN% *}
  1152. FQDN=${HOSTS_PATH_AND_FQDN#* }
  1153. CONTAINERS_PATH=$(dirname $HOSTS)
  1154. MNT=/container
  1155. MNT_HOSTS=$MNT/$(basename $HOSTS)
  1156. CONTENTS="$(etc_hosts_contents $FQDN "$@")"
  1157. # rewrite /etc/hosts, unlinking the file (so Docker does not modify it again) but
  1158. # leaving it with valid contents...
  1159. docker run --rm --net=none -e WEAVE_CIDR=none --privileged \
  1160. -v $CONTAINERS_PATH:$MNT \
  1161. --entrypoint=sh \
  1162. $EXEC_IMAGE -c "echo '$CONTENTS' > $MNT_HOSTS && rm -f $MNT_HOSTS && echo '$CONTENTS' > $MNT_HOSTS"
  1163. }
  1164.  
  1165. # Print an error to stderr and return with an indicative exit status
  1166. # if the container $1 does not exist or isn't running.
  1167. check_running() {
  1168. if ! STATUS=$(docker inspect --format='{{.State.Running}} {{.State.Restarting}}' $1 2>/dev/null) ; then
  1169. echo "$1 container is not present. Have you launched it?" >&2
  1170. return 1
  1171. elif [ "$STATUS" = "true true" ] ; then
  1172. echo "$1 container is restarting." >&2
  1173. return 2
  1174. elif [ "$STATUS" != "true false" ] ; then
  1175. echo "$1 container is not running." >&2
  1176. return 2
  1177. fi
  1178. }
  1179.  
  1180. # Execute $@ only if the weave container is running
  1181. when_weave_running() {
  1182. ! check_running $CONTAINER_NAME 2>/dev/null || "$@"
  1183. }
  1184.  
  1185. # Iff the container in $1 has an FQDN, invoke $2 as a command passing
  1186. # the container as the first argument, the FQDN as the second argument
  1187. # and $3.. as additional arguments
  1188. with_container_fqdn() {
  1189. CONT="$1"
  1190. COMMAND="$2"
  1191. shift 2
  1192.  
  1193. CONT_FQDN=$(docker inspect --format='{{.Config.Hostname}}.{{.Config.Domainname}}' $CONT 2>/dev/null) || return 0
  1194. CONT_NAME=${CONT_FQDN%%.*}
  1195. [ "$CONT_NAME" = "$CONT_FQDN" -o "$CONT_NAME." = "$CONT_FQDN" ] || $COMMAND "$CONT" "$CONT_FQDN" "$@"
  1196. }
  1197.  
  1198. # Register FQDN in $2 as names for addresses $3.. under full container ID $1
  1199. put_dns_fqdn() {
  1200. CHECK_ALIVE="-d check-alive=true"
  1201. put_dns_fqdn_helper "$@"
  1202. }
  1203.  
  1204. put_dns_fqdn_no_check_alive() {
  1205. CHECK_ALIVE=
  1206. put_dns_fqdn_helper "$@"
  1207. }
  1208.  
  1209. put_dns_fqdn_helper() {
  1210. CONTAINER_ID="$1"
  1211. FQDN="$2"
  1212. shift 2
  1213.  
  1214. for ADDR in "$@" ; do
  1215. call_weave PUT /name/$CONTAINER_ID/${ADDR%/*} --data-urlencode fqdn=$FQDN $CHECK_ALIVE || true
  1216. done
  1217. }
  1218.  
  1219. # Delete all names for addresses $3.. under full container ID $1
  1220. delete_dns() {
  1221. CONTAINER_ID="$1"
  1222. shift 1
  1223.  
  1224. for ADDR in "$@" ; do
  1225. call_weave DELETE /name/$CONTAINER_ID/${ADDR%/*} || true
  1226. done
  1227. }
  1228.  
  1229. # Delete any FQDNs $2 from addresses $3.. under full container ID $1
  1230. delete_dns_fqdn() {
  1231. CONTAINER_ID="$1"
  1232. FQDN="$2"
  1233. shift 2
  1234.  
  1235. for ADDR in "$@" ; do
  1236. call_weave DELETE /name/$CONTAINER_ID/${ADDR%/*}?fqdn=$FQDN || true
  1237. done
  1238. }
  1239.  
  1240. is_ip() {
  1241. echo "$1" | grep -E "^$IP_REGEXP$" >/dev/null
  1242. }
  1243.  
  1244. collect_ip_args() {
  1245. IP_ARGS=""
  1246. IP_COUNT=0
  1247. while is_ip "$1" ; do
  1248. IP_ARGS="$IP_ARGS $1"
  1249. IP_COUNT=$((IP_COUNT + 1))
  1250. shift 1
  1251. done
  1252. }
  1253.  
  1254. collect_dns_add_remove_args() {
  1255. collect_ip_args "$@"
  1256. shift $IP_COUNT
  1257. [ $# -gt 0 -a "$1" != "-h" ] && C="$1" && shift 1
  1258. [ $# -eq 2 -a "$1" = "-h" ] && FQDN="$2" && shift 2
  1259. [ $# -eq 0 -a \( -n "$C" -o \( $IP_COUNT -gt 0 -a -n "$FQDN" \) \) ] || usage
  1260. check_running $CONTAINER_NAME
  1261. if [ -n "$C" ] ; then
  1262. check_running $C
  1263. CONTAINER=$(container_id $C)
  1264. [ $IP_COUNT -gt 0 ] || IP_ARGS=$(with_container_addresses echo_ips $CONTAINER)
  1265. fi
  1266. }
  1267.  
  1268. ######################################################################
  1269. # IP Allocation Management helpers
  1270. ######################################################################
  1271.  
  1272. check_overlap() {
  1273. util_op netcheck $1 $BRIDGE
  1274. }
  1275.  
  1276. # Claim addresses for a container in IPAM. Expects to be called from
  1277. # with_container_addresses.
  1278. ipam_reclaim() {
  1279. CONTAINER_ID="$1"
  1280. # The weave IP addresses of containers attached by the plugin are
  1281. # recorded specially in IPAM, since the container id is not know
  1282. # at the time.
  1283. [ "$2" = "$CONTAINER_IFNAME" ] || CONTAINER_ID="_"
  1284. for CIDR in $4 ; do
  1285. http_call $HTTP_ADDR PUT "/ip/$CONTAINER_ID/$CIDR?noErrorOnUnknown=true&?check-alive=true" || true
  1286. done
  1287. }
  1288.  
  1289. ipam_reclaim_no_check_alive() {
  1290. for CIDR in $4 ; do
  1291. http_call $HTTP_ADDR PUT /ip/$1/$CIDR?noErrorOnUnknown=true || true
  1292. done
  1293. }
  1294.  
  1295. detect_awsvpc() {
  1296. # Ignoring errors here: if we cannot detect AWSVPC we will skip the relevant
  1297. # steps, because "attach" should work without the weave router running.
  1298. [ "$(call_weave GET /ipinfo/tracker)" != "awsvpc" ] || AWSVPC=1
  1299. }
  1300.  
  1301. # Call IPAM as necessary to lookup or allocate addresses
  1302. #
  1303. # $1 is one of 'lookup', 'allocate' or 'allocate_no_check_alive', $2
  1304. # is the full container id. The remaining args are previously parsed
  1305. # CIDR_ARGS.
  1306. #
  1307. # Populates ALL_CIDRS and IPAM_CIDRS
  1308. ipam_cidrs() {
  1309. case $1 in
  1310. lookup)
  1311. METHOD=GET
  1312. CHECK_ALIVE=
  1313. ;;
  1314. allocate)
  1315. METHOD=POST
  1316. CHECK_ALIVE="?check-alive=true"
  1317. detect_awsvpc
  1318. if [ -n "$AWSVPC" -a $# -gt 2 ] ; then
  1319. echo "Error: no IP addresses or subnets may be specified in AWSVPC mode" >&2
  1320. return 1
  1321. fi
  1322. ;;
  1323. allocate_no_check_alive)
  1324. METHOD=POST
  1325. CHECK_ALIVE=
  1326. ;;
  1327. esac
  1328. CONTAINER_ID="$2"
  1329. shift 2
  1330. ALL_CIDRS=""
  1331. IPAM_CIDRS=""
  1332. # If no addresses passed in, select the default subnet
  1333. [ $# -gt 0 ] || set -- net:default
  1334. for arg in "$@" ; do
  1335. if [ "${arg%:*}" = "net" ] ; then
  1336. if [ "$arg" = "net:default" ] ; then
  1337. IPAM_URL=/ip/$CONTAINER_ID
  1338. else
  1339. IPAM_URL=/ip/$CONTAINER_ID/"${arg#net:}"
  1340. fi
  1341. retval=0
  1342. CIDR=$(call_weave $METHOD $IPAM_URL$CHECK_ALIVE) || retval=$?
  1343. if [ $retval -eq 4 -a "$METHOD" = "POST" ] ; then
  1344. echo "IP address allocation must be enabled to use 'net:'" >&2
  1345. return 1
  1346. fi
  1347. [ $retval -gt 0 ] && return $retval
  1348. IPAM_CIDRS="$IPAM_CIDRS $CIDR"
  1349. ALL_CIDRS="$ALL_CIDRS $CIDR"
  1350. else
  1351. if [ "$METHOD" = "POST" ] ; then
  1352. # Assignment of a plain IP address; warn if it clashes but carry on
  1353. check_overlap $arg || true
  1354. # Abort on failure, but not 4 (=404), which means IPAM is disabled
  1355. when_weave_running http_call $HTTP_ADDR PUT /ip/$CONTAINER_ID/$arg$CHECK_ALIVE || [ $? -eq 4 ] || return 1
  1356. fi
  1357. ALL_CIDRS="$ALL_CIDRS $arg"
  1358. fi
  1359. done
  1360. }
  1361.  
  1362. ipam_cidrs_or_die() {
  1363. if ! ipam_cidrs "$@" ; then
  1364. kill_container $2
  1365. exit 1
  1366. fi
  1367. }
  1368.  
  1369. show_addrs() {
  1370. addrs=
  1371. for cidr in "$@" ; do
  1372. addrs="$addrs ${cidr%/*}"
  1373. done
  1374. echo $addrs
  1375. }
  1376.  
  1377. ######################################################################
  1378. # weave proxy helpers
  1379. ######################################################################
  1380.  
  1381. docker_client_args() {
  1382. while [ $# -gt 0 ]; do
  1383. case "$1" in
  1384. -H|--host)
  1385. DOCKER_CLIENT_HOST="$2"
  1386. shift
  1387. ;;
  1388. -H=*|--host=*)
  1389. DOCKER_CLIENT_HOST="${1#*=}"
  1390. ;;
  1391. esac
  1392. shift
  1393. done
  1394. }
  1395.  
  1396. # TODO: Handle relative paths for args
  1397. # TODO: Handle args with spaces
  1398. tls_arg() {
  1399. PROXY_VOLUMES="$PROXY_VOLUMES -v $2:/home/weave/tls/$3.pem:ro"
  1400. PROXY_ARGS="$PROXY_ARGS $1 /home/weave/tls/$3.pem"
  1401. }
  1402.  
  1403. # TODO: Handle relative paths for args
  1404. # TODO: Handle args with spaces
  1405. host_arg() {
  1406. PROXY_HOST="$1"
  1407. if [ "$PROXY_HOST" != "${PROXY_HOST#unix://}" ]; then
  1408. host=$(dirname ${PROXY_HOST#unix://})
  1409. if [ "$host" = "${host#/}" ]; then
  1410. echo "When launching the proxy, unix sockets must be specified as an absolute path." >&2
  1411. exit 1
  1412. fi
  1413. PROXY_VOLUMES="$PROXY_VOLUMES -v /var/run/weave:/var/run/weave"
  1414. fi
  1415. PROXY_ARGS="$PROXY_ARGS -H $1"
  1416. }
  1417.  
  1418. proxy_parse_args() {
  1419. while [ $# -gt 0 ]; do
  1420. case "$1" in
  1421. -H)
  1422. host_arg "$2"
  1423. shift
  1424. ;;
  1425. -H=*)
  1426. host_arg "${1#*=}"
  1427. ;;
  1428. -no-detect-tls|--no-detect-tls)
  1429. PROXY_TLS_DETECTION_DISABLED=1
  1430. ;;
  1431. -tls|--tls|-tlsverify|--tlsverify)
  1432. PROXY_TLS_ENABLED=1
  1433. PROXY_ARGS="$PROXY_ARGS $1"
  1434. ;;
  1435. --tlscacert)
  1436. tls_arg "$1" "$2" ca
  1437. shift
  1438. ;;
  1439. --tlscacert=*)
  1440. tls_arg "${1%%=*}" "${1#*=}" ca
  1441. ;;
  1442. --tlscert)
  1443. tls_arg "$1" "$2" cert
  1444. shift
  1445. ;;
  1446. --tlscert=*)
  1447. tls_arg "${1%%=*}" "${1#*=}" cert
  1448. ;;
  1449. --tlskey)
  1450. tls_arg "$1" "$2" key
  1451. shift
  1452. ;;
  1453. --tlskey=*)
  1454. tls_arg "${1%%=*}" "${1#*=}" key
  1455. ;;
  1456. --no-restart)
  1457. RESTART_POLICY=
  1458. ;;
  1459. *)
  1460. PROXY_ARGS="$PROXY_ARGS $1"
  1461. ;;
  1462. esac
  1463. shift
  1464. done
  1465. }
  1466.  
  1467. proxy_args() {
  1468. PROXY_VOLUMES=""
  1469. PROXY_ARGS=""
  1470. PROXY_TLS_ENABLED=""
  1471. PROXY_TLS_DETECTION_DISABLED=""
  1472. PROXY_HOST=""
  1473. proxy_parse_args "$@"
  1474.  
  1475. if [ -z "$PROXY_TLS_ENABLED" -a -z "$PROXY_TLS_DETECTION_DISABLED" ] ; then
  1476. if ! DOCKER_TLS_ARGS=$(util_op docker-tls-args) ; then
  1477. echo -n "Warning: unable to detect proxy TLS configuration. To enable TLS, " >&2
  1478. echo -n "launch the proxy with 'weave launch-proxy' and supply TLS options. " >&2
  1479. echo "To suppress this warning, supply the '--no-detect-tls' option." >&2
  1480. else
  1481. proxy_parse_args $DOCKER_TLS_ARGS
  1482. fi
  1483. fi
  1484. if [ -z "$PROXY_HOST" ] ; then
  1485. case "$DOCKER_CLIENT_HOST" in
  1486. ""|unix://*)
  1487. PROXY_HOST="unix:///var/run/weave/weave.sock"
  1488. ;;
  1489. *)
  1490. PROXY_HOST="tcp://0.0.0.0:$PROXY_PORT"
  1491. ;;
  1492. esac
  1493. host_arg "$PROXY_HOST"
  1494. fi
  1495. }
  1496.  
  1497. proxy_addrs() {
  1498. if addr="$(http_call_unix $PROXY_CONTAINER_NAME status.sock GET /status 2>/dev/null)" ; then
  1499. echo "$addr" | sed "s/0.0.0.0/$PROXY_HOST/g"
  1500.  
  1501. else
  1502. echo "$PROXY_CONTAINER_NAME container is not present. Have you launched it?" >&2
  1503. return 1
  1504. fi
  1505. }
  1506.  
  1507. proxy_addr() {
  1508. addr=$(proxy_addrs) || return 1
  1509. echo "$addr" | cut -d ' ' -f1
  1510. }
  1511.  
  1512. warn_if_stopping_proxy_in_env() {
  1513. if PROXY_ADDR=$(proxy_addr 2>/dev/null) ; then
  1514. [ "$PROXY_ADDR" != "$DOCKER_CLIENT_HOST" ] || echo "WARNING: It appears that your environment is configured to use the Weave Docker API proxy. Stopping it will break this and subsequent docker invocations. To restore your environment, run 'eval \$(weave env --restore)'."
  1515. fi
  1516. }
  1517.  
  1518. ######################################################################
  1519. # launch helpers
  1520. ######################################################################
  1521.  
  1522. common_launch_args() {
  1523. args=""
  1524. while [ $# -gt 0 ] ; do
  1525. case "$1" in
  1526. --no-restart)
  1527. args="$args $1"
  1528. ;;
  1529. --log-level)
  1530. [ $# -gt 1 ] || usage
  1531. args="$args $1 $2"
  1532. shift
  1533. ;;
  1534. --log-level=*)
  1535. args="$args $1"
  1536. ;;
  1537. esac
  1538. shift
  1539. done
  1540. echo "$args"
  1541. }
  1542.  
  1543. launch_router() {
  1544. LAUNCHING_ROUTER=1
  1545. check_forwarding_rules
  1546. enforce_docker_bridge_addr_assign_type
  1547.  
  1548. # backward compatibility...
  1549. if is_cidr "$1" ; then
  1550. echo "WARNING: $1 parameter ignored; 'weave launch' no longer takes a CIDR as the first parameter" >&2
  1551. shift 1
  1552. fi
  1553.  
  1554. CONTAINER_PORT=$PORT
  1555. ARGS=
  1556. IPRANGE=
  1557. IPRANGE_SPECIFIED=
  1558.  
  1559. docker_bridge_ip
  1560. DNS_ROUTER_OPTS="--dns-listen-address $DOCKER_BRIDGE_IP:53"
  1561. NO_DNS_OPT=
  1562.  
  1563. while [ $# -gt 0 ] ; do
  1564. case "$1" in
  1565. -password|--password)
  1566. [ $# -gt 1 ] || usage
  1567. WEAVE_PASSWORD="$2"
  1568. export WEAVE_PASSWORD
  1569. shift
  1570. ;;
  1571. --password=*)
  1572. WEAVE_PASSWORD="${1#*=}"
  1573. export WEAVE_PASSWORD
  1574. ;;
  1575. -port|--port)
  1576. [ $# -gt 1 ] || usage
  1577. CONTAINER_PORT="$2"
  1578. shift
  1579. ;;
  1580. --port=*)
  1581. CONTAINER_PORT="${1#*=}"
  1582. ;;
  1583. -iprange|--iprange|--ipalloc-range)
  1584. [ $# -gt 1 ] || usage
  1585. IPRANGE="$2"
  1586. IPRANGE_SPECIFIED=1
  1587. shift
  1588. ;;
  1589. --ipalloc-range=*)
  1590. IPRANGE="${1#*=}"
  1591. IPRANGE_SPECIFIED=1
  1592. ;;
  1593. --no-dns)
  1594. DNS_ROUTER_OPTS=
  1595. NO_DNS_OPT="--no-dns"
  1596. ;;
  1597. --no-restart)
  1598. RESTART_POLICY=
  1599. ;;
  1600. --awsvpc)
  1601. AWSVPC_ARGS="--awsvpc"
  1602. AWSVPC=1
  1603. ;;
  1604. *)
  1605. ARGS="$ARGS '$(echo "$1" | sed "s|'|'\"'\"'|g")'"
  1606. ;;
  1607. esac
  1608. shift
  1609. done
  1610. eval "set -- $ARGS"
  1611.  
  1612. setup_cni
  1613. create_bridge
  1614. # We set the router name to the bridge MAC, which in turn is
  1615. # derived from the system UUID (if available), and thus stable
  1616. # across reboots.
  1617. PEERNAME=$(cat /sys/class/net/$BRIDGE/address)
  1618.  
  1619. if [ -z "$IPRANGE_SPECIFIED" ] ; then
  1620. IPRANGE="10.32.0.0/12"
  1621. if ! check_overlap $IPRANGE ; then
  1622. echo "ERROR: Default --ipalloc-range $IPRANGE overlaps with existing route on host." >&2
  1623. echo "You must pick another range and set it on all hosts." >&2
  1624. exit 1
  1625. fi
  1626. else
  1627. if [ -n "$AWSVPC" -a -z "$IPRANGE" ] ; then
  1628. echo "ERROR: Empty --ipalloc-range is not compatible with --awsvpc." >&2
  1629. exit 1
  1630. fi
  1631. if [ -n "$IPRANGE" ] && ! check_overlap $IPRANGE ; then
  1632. echo "WARNING: Specified --ipalloc-range $IPRANGE overlaps with existing route on host." >&2
  1633. echo "Unless this is deliberate, you must pick another range and set it on all hosts." >&2
  1634. fi
  1635. fi
  1636.  
  1637. # Create a data-only container for persistence data
  1638. if ! docker inspect -f ' ' $DB_CONTAINER_NAME > /dev/null 2>&1 ; then
  1639. protect_against_docker_hang
  1640. docker create -v /weavedb --name=$DB_CONTAINER_NAME \
  1641. --label=weavevolumes $WEAVEDB_IMAGE >/dev/null
  1642. fi
  1643.  
  1644. RESOLV_CONF=$(chroot ${HOST_ROOT:-/} readlink -f /etc/resolv.conf)
  1645. RESOLV_CONF_DIR=$(dirname "$RESOLV_CONF")
  1646. RESOLV_CONF_BASE=$(basename "$RESOLV_CONF")
  1647.  
  1648. # Set WEAVE_DOCKER_ARGS in the environment in order to supply
  1649. # additional parameters, such as resource limits, to docker
  1650. # when launching the weave container.
  1651. ROUTER_CONTAINER=$(docker run -d --name=$CONTAINER_NAME \
  1652. $(docker_run_options) \
  1653. $RESTART_POLICY \
  1654. --volumes-from $DB_CONTAINER_NAME \
  1655. -v $RESOLV_CONF_DIR:/var/run/weave/etc \
  1656. -e WEAVE_PASSWORD \
  1657. -e CHECKPOINT_DISABLE \
  1658. $WEAVE_DOCKER_ARGS $IMAGE $COVERAGE_ARGS \
  1659. --port $CONTAINER_PORT --name "$PEERNAME" --nickname "$(hostname)" \
  1660. $(router_opts_$BRIDGE_TYPE) \
  1661. --ipalloc-range "$IPRANGE" \
  1662. --dns-effective-listen-address $DOCKER_BRIDGE_IP \
  1663. $DNS_ROUTER_OPTS $NO_DNS_OPT \
  1664. $AWSVPC_ARGS \
  1665. --http-addr $HTTP_ADDR \
  1666. --resolv-conf "/var/run/weave/etc/$RESOLV_CONF_BASE" \
  1667. "$@")
  1668. wait_for_status $CONTAINER_NAME http_call $HTTP_ADDR
  1669. setup_awsvpc
  1670. populate_router
  1671. }
  1672.  
  1673. setup_awsvpc() {
  1674. if [ -n "$AWSVPC" ]; then
  1675. # Set proxy_arp on the bridge, so that it could accept packets destined
  1676. # to containers within the same subnet but running on remote hosts.
  1677. # Without it, exact routes on each container are required.
  1678. echo 1 >/proc/sys/net/ipv4/conf/$BRIDGE/proxy_arp
  1679. # Avoid delaying the first ARP request. Also, setting it to 0 avoids
  1680. # placing the request into a bounded queue as it can be seen:
  1681. # https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/net/ipv4/arp.c?id=refs/tags/v4.6.1#n819
  1682. echo 0 >/proc/sys/net/ipv4/neigh/$BRIDGE/proxy_delay
  1683. expose_ip
  1684. fi
  1685. }
  1686.  
  1687. # Recreate the parameter values that are set when the router is first launched
  1688. fetch_router_args() {
  1689. CONTAINER_ARGS=$(docker inspect -f '{{.Args}}' $CONTAINER_NAME) || return 1
  1690. IPRANGE=$(echo $CONTAINER_ARGS | grep -o -e '-ipalloc-range [^ ]*') || true
  1691. NO_DNS_OPT=$(echo $CONTAINER_ARGS | grep -o -e '--no-dns') || true
  1692. }
  1693.  
  1694. populate_router() {
  1695. if [ -n "$IPRANGE" ] ; then
  1696. # Tell the newly-started weave IP allocator about existing weave IPs
  1697. # In the case of AWSVPC, we do expose before calling populate_router
  1698. [ -n "$AWSVPC" ] || with_container_addresses ipam_reclaim_no_check_alive weave:expose
  1699. with_container_addresses ipam_reclaim $(docker ps -q --no-trunc)
  1700. fi
  1701. if [ -z "$NO_DNS_OPT" ] ; then
  1702. # Tell the newly-started weaveDNS about existing weave IPs
  1703. for CONTAINER in $(docker ps -q --no-trunc) ; do
  1704. if CONTAINER_IPS=$(with_container_addresses echo_ips $CONTAINER) && [ -n "$CONTAINER_IPS" ] ; then
  1705. with_container_fqdn $CONTAINER put_dns_fqdn $CONTAINER_IPS
  1706. fi
  1707. done
  1708. fi
  1709. }
  1710.  
  1711. stop_router() {
  1712. stop $CONTAINER_NAME "Weave"
  1713. conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true
  1714. }
  1715.  
  1716. launch_proxy() {
  1717. # Set WEAVEPROXY_DOCKER_ARGS in the environment in order to supply
  1718. # additional parameters, such as resource limits, to docker
  1719. # when launching the weaveproxy container.
  1720. docker_client_args $DOCKER_CLIENT_ARGS
  1721. proxy_args "$@"
  1722. mkdir -p /var/run/weave
  1723. # Create a data-only container to mount the weavewait files from
  1724. if ! docker inspect -f ' ' $VOLUMES_CONTAINER_NAME > /dev/null 2>&1 ; then
  1725. protect_against_docker_hang
  1726. docker create -v /w -v /w-noop -v /w-nomcast --name=$VOLUMES_CONTAINER_NAME \
  1727. --label=weavevolumes --entrypoint=/bin/false $EXEC_IMAGE >/dev/null
  1728. fi
  1729. detect_awsvpc
  1730. [ -n "$AWSVPC" ] && PROXY_ARGS="$PROXY_ARGS --no-multicast-route"
  1731. PROXY_CONTAINER=$(docker run -d --name=$PROXY_CONTAINER_NAME \
  1732. $(docker_run_options) \
  1733. $RESTART_POLICY \
  1734. --pid=host \
  1735. $PROXY_VOLUMES \
  1736. --volumes-from $VOLUMES_CONTAINER_NAME \
  1737. -v /var/run/weave:/var/run/weave \
  1738. -e DOCKER_BRIDGE \
  1739. -e WEAVE_DEBUG \
  1740. -e COVERAGE \
  1741. -e WEAVE_HTTP_ADDR \
  1742. -e EXEC_IMAGE=$EXEC_IMAGE \
  1743. --entrypoint=/home/weave/weaveproxy \
  1744. $WEAVEPROXY_DOCKER_ARGS $EXEC_IMAGE $COVERAGE_ARGS $PROXY_ARGS)
  1745. wait_for_status $PROXY_CONTAINER_NAME http_call_unix $PROXY_CONTAINER_NAME status.sock
  1746. }
  1747.  
  1748. stop_proxy() {
  1749. warn_if_stopping_proxy_in_env
  1750. stop $PROXY_CONTAINER_NAME "Proxy"
  1751. }
  1752.  
  1753. launch_plugin_if_not_running() {
  1754. while [ $# -gt 0 ]; do
  1755. case "$1" in
  1756. --no-restart)
  1757. RESTART_POLICY=
  1758. ;;
  1759. *)
  1760. break
  1761. ;;
  1762. esac
  1763. shift
  1764. done
  1765.  
  1766. retval=0
  1767. check_not_running plugin $PLUGIN_CONTAINER_NAME $BASE_PLUGIN_IMAGE || retval=$?
  1768. # If an existing plugin is running (we start it with restart=always), return its ID
  1769. [ $retval = 1 ] && PLUGIN_CONTAINER=$(container_id $PLUGIN_CONTAINER_NAME) && return 0
  1770. # Any other kind of error code from check_not_running is a failure.
  1771. [ $retval -gt 0 ] && return $retval
  1772.  
  1773. if ! PLUGIN_CONTAINER=$(docker run -d --name=$PLUGIN_CONTAINER_NAME \
  1774. $(docker_run_options) \
  1775. $RESTART_POLICY \
  1776. --pid=host \
  1777. -v /run/docker/plugins:/run/docker/plugins \
  1778. -e WEAVE_HTTP_ADDR \
  1779. $WEAVEPLUGIN_DOCKER_ARGS $PLUGIN_IMAGE $COVERAGE_ARGS \
  1780. "$@") ; then
  1781. return 1
  1782. fi
  1783. wait_for_status $PLUGIN_CONTAINER_NAME http_call_unix $PLUGIN_CONTAINER_NAME status.sock
  1784. WEAVE_IPAM_SUBNET=$(call_weave GET /ipinfo/defaultsubnet)
  1785. util_op create-plugin-network weave weavemesh $WEAVE_IPAM_SUBNET
  1786. }
  1787.  
  1788. plugin_disabled() {
  1789. [ -n "$WEAVE_NO_PLUGIN" ] || ! check_docker_server_api_version 1.21
  1790. }
  1791.  
  1792. stop_plugin() {
  1793. util_op remove-plugin-network weave || true
  1794. stop $PLUGIN_CONTAINER_NAME "Plugin"
  1795. }
  1796.  
  1797. protect_against_docker_hang() {
  1798. # If the plugin is not running, remove its socket so Docker doesn't try to talk to it
  1799. if ! check_running $PLUGIN_CONTAINER_NAME 2>/dev/null ; then
  1800. rm -f /run/docker/plugins/weave.sock /run/docker/plugins/weavemesh.sock
  1801. fi
  1802. }
  1803.  
  1804. ######################################################################
  1805. # argument deprecation handling
  1806. ######################################################################
  1807.  
  1808. deprecation_warning() {
  1809. echo "Warning: ${1%=*} is deprecated; please use $2" >&2
  1810. }
  1811.  
  1812. deprecation_warnings() {
  1813. while [ $# -gt 0 ]; do
  1814. case "$1" in
  1815. -password|-password=*)
  1816. deprecation_warning $1 "--password"
  1817. [ "$1" = "-password" ] && shift
  1818. ;;
  1819. --password)
  1820. shift
  1821. ;;
  1822. -nickname|-nickname=*)
  1823. deprecation_warning $1 "--nickname"
  1824. [ "$1" = "-nickname" ] && shift
  1825. ;;
  1826. --nickname)
  1827. shift
  1828. ;;
  1829. -nodiscovery|--nodiscovery)
  1830. deprecation_warning $1 "--no-discovery"
  1831. ;;
  1832. -iprange|--iprange|-iprange=*|--iprange=*)
  1833. deprecation_warning $1 "--ipalloc-range"
  1834. [ ${1#--} = "iprange" ] && shift
  1835. ;;
  1836. --ipalloc-range)
  1837. shift
  1838. ;;
  1839. -ipsubnet|--ipsubnet|-ipsubnet=*|--ipsubnet=*)
  1840. deprecation_warning $1 "--ipalloc-default-subnet"
  1841. [ ${1#--} = "ipsubnet" ] && shift
  1842. ;;
  1843. --ipalloc-default-subnet)
  1844. shift
  1845. ;;
  1846. -initpeercount|--initpeercount|-initpeercount=*|--initpeercount=*)
  1847. deprecation_warning $1 "--ipalloc-init consensus=<count>"
  1848. [ ${1#--} = "initpeercount" ] && shift
  1849. ;;
  1850. --init-peer-count|--init-peer-count=*)
  1851. deprecation_warning $1 "--ipalloc-init consensus=<count>"
  1852. [ ${1#--} = "init-peer-count" ] && shift
  1853. shift
  1854. ;;
  1855. -no-default-ipam|--no-default-ipam)
  1856. deprecation_warning $1 "--no-default-ipalloc"
  1857. ;;
  1858. --with-dns)
  1859. echo "Warning: $1 has been removed; DNS is on by default" >&2
  1860. ;;
  1861. esac
  1862. shift
  1863. done
  1864. }
  1865.  
  1866. ######################################################################
  1867. # main (remote and --local)
  1868. ######################################################################
  1869.  
  1870. [ $(id -u) = 0 ] || {
  1871. echo "weave must be run as 'root' when run locally" >&2
  1872. exit 1
  1873. }
  1874.  
  1875. uname -s -r | sed -n -e 's|^\([^ ]*\) \([0-9][0-9]*\)\.\([0-9][0-9]*\).*|\1 \2 \3|p' | {
  1876. if ! read sys maj min ; then
  1877. echo "ERROR: Unable to parse operating system version $(uname -s -r)" >&2
  1878. exit 1
  1879. fi
  1880.  
  1881. if [ "$sys" != 'Linux' ] ; then
  1882. echo "ERROR: Operating systems other than Linux are not supported (you have $(uname -s -r))" >&2
  1883. exit 1
  1884. fi
  1885.  
  1886. if ! [ \( "$maj" -eq 3 -a "$min" -ge 8 \) -o "$maj" -gt 3 ] ; then
  1887. echo "WARNING: Linux kernel version 3.8 or newer is required (you have ${maj}.${min})" >&2
  1888. fi
  1889. }
  1890.  
  1891. if ! command_exists ip ; then
  1892. echo "ERROR: ip utility is missing. Please install it." >&2
  1893. exit 1
  1894. fi
  1895.  
  1896. if ! ip netns list >/dev/null 2>&1 ; then
  1897. echo "ERROR: $(ip -V) does not support network namespaces." >&2
  1898. echo " Please install iproute2-ss111010 or later." >&2
  1899. exit 1
  1900. fi
  1901.  
  1902. if ! command_exists nsenter ; then
  1903. echo "ERROR: nsenter utility missing. Please install it." >&2
  1904. exit 1
  1905. fi
  1906.  
  1907. [ $# -gt 0 ] || usage
  1908. COMMAND=$1
  1909. shift 1
  1910.  
  1911. handle_help_arg "$1"
  1912.  
  1913. case "$COMMAND" in
  1914. setup)
  1915. for img in $IMAGE $EXEC_IMAGE $PLUGIN_IMAGE $WEAVEDB_IMAGE ; do
  1916. docker pull $img
  1917. done
  1918. setup_cni
  1919. ;;
  1920. setup-cni)
  1921. setup_cni
  1922. ;;
  1923. version)
  1924. [ $# -eq 0 ] || usage
  1925. ask_version $CONTAINER_NAME $IMAGE || true
  1926. ask_version $PROXY_CONTAINER_NAME $EXEC_IMAGE --entrypoint=/home/weave/weaveproxy || true
  1927. ask_version $PLUGIN_CONTAINER_NAME $PLUGIN_IMAGE || true
  1928. ;;
  1929. # intentionally undocumented since it assumes knowledge of weave
  1930. # internals
  1931. create-bridge)
  1932. if [ "$1" != "--force" ] ; then
  1933. cat 1>&2 <<EOF
  1934. WARNING: 'weave create-bridge' is deprecated. Instead use 'weave attach-bridge'
  1935. to link the docker and weave bridges after both docker and weave have been
  1936. started. Note that, unlike 'weave create-bridge', 'weave attach-bridge' is
  1937. compatible with fast data path.
  1938. EOF
  1939. # This subcommand may be run without the docker daemon, but
  1940. # fastdp needs to run the router container to setup the ODP
  1941. # bridge, hence:
  1942. if [ -z "$WEAVE_NO_FASTDP" ] ; then
  1943. cat 1>&2 <<EOF
  1944.  
  1945. ERROR: 'weave create-bridge' is not compatible with fast data path. If you
  1946. really want to do this please set the WEAVE_NO_FASTDP environment variable.
  1947. EOF
  1948. exit 1
  1949. fi
  1950. else
  1951. shift 1
  1952. fi
  1953. create_bridge --without-ethtool "$@"
  1954. ;;
  1955. attach-bridge)
  1956. if detect_bridge_type ; then
  1957. attach_bridge ${1:-$DOCKER_BRIDGE}
  1958. insert_iptables_rule nat POSTROUTING -o $BRIDGE -j ACCEPT
  1959. else
  1960. echo "Weave bridge not found. Please run 'weave launch' and try again" >&2
  1961. exit 1
  1962. fi
  1963. ;;
  1964. bridge-type)
  1965. detect_bridge_type && echo $BRIDGE_TYPE
  1966. ;;
  1967. launch)
  1968. deprecation_warnings "$@"
  1969. check_not_running router $CONTAINER_NAME $BASE_IMAGE
  1970. check_not_running proxy $PROXY_CONTAINER_NAME $BASE_EXEC_IMAGE
  1971. check_not_running plugin $PLUGIN_CONTAINER_NAME $BASE_PLUGIN_IMAGE
  1972. COMMON_ARGS=$(common_launch_args "$@")
  1973. launch_router "$@"
  1974. launch_proxy $COMMON_ARGS
  1975. plugin_disabled || launch_plugin_if_not_running $COMMON_ARGS
  1976. ;;
  1977. launch-router)
  1978. deprecation_warnings "$@"
  1979. check_not_running router $CONTAINER_NAME $BASE_IMAGE
  1980. launch_router "$@"
  1981. echo $ROUTER_CONTAINER
  1982. ;;
  1983. attach-router)
  1984. check_running $CONTAINER_NAME
  1985. enforce_docker_bridge_addr_assign_type
  1986. # We cannot use detect_awsvpc here, because HTTP server might not be started
  1987. ! docker inspect -f '{{.Config.Cmd}}' $CONTAINER_NAME | grep -q -- "--awsvpc" || AWSVPC=1
  1988. create_bridge
  1989. fetch_router_args
  1990. wait_for_status $CONTAINER_NAME http_call $HTTP_ADDR
  1991. setup_awsvpc
  1992. populate_router
  1993. ;;
  1994. launch-proxy)
  1995. deprecation_warnings "$@"
  1996. check_not_running proxy $PROXY_CONTAINER_NAME $BASE_EXEC_IMAGE
  1997. launch_proxy "$@"
  1998. echo $PROXY_CONTAINER
  1999. ;;
  2000. launch-plugin)
  2001. if ! check_running $CONTAINER_NAME 2>/dev/null ; then
  2002. echo "ERROR:" $CONTAINER_NAME "container must be running before plugin can be launched" >&2
  2003. exit 1
  2004. fi
  2005. launch_plugin_if_not_running "$@"
  2006. echo $PLUGIN_CONTAINER
  2007. ;;
  2008. env|proxy-env)
  2009. [ "$COMMAND" = "env" ] || deprecation_warning "$COMMAND" "'weave env'"
  2010. if PROXY_ADDR=$(proxy_addr) ; then
  2011. [ "$PROXY_ADDR" = "$DOCKER_CLIENT_HOST" ] || RESTORE="ORIG_DOCKER_HOST=$DOCKER_CLIENT_HOST"
  2012. echo "export DOCKER_HOST=$PROXY_ADDR $RESTORE"
  2013. fi
  2014. ;;
  2015. config|proxy-config)
  2016. [ "$COMMAND" = "config" ] || deprecation_warning "$COMMAND" "'weave config'"
  2017. PROXY_ADDR=$(proxy_addr) && echo "-H=$PROXY_ADDR"
  2018. ;;
  2019. connect)
  2020. [ $# -gt 0 ] || usage
  2021. [ "$1" = "--replace" ] && replace="-d replace=true" && shift
  2022. call_weave POST /connect $replace -d $(peer_args "$@")
  2023. ;;
  2024. forget)
  2025. [ $# -gt 0 ] || usage
  2026. call_weave POST /forget -d $(peer_args "$@")
  2027. ;;
  2028. status)
  2029. res=0
  2030. SUB_STATUS=
  2031. STATUS_URL="/status"
  2032. SUB_COMMAND="$@"
  2033. while [ $# -gt 0 ] ; do
  2034. SUB_STATUS=1
  2035. STATUS_URL="$STATUS_URL/$1"
  2036. shift
  2037. done
  2038. [ -n "$SUB_STATUS" ] || echo
  2039. call_weave GET $STATUS_URL || res=$?
  2040. if [ $res -eq 4 ] ; then
  2041. echo "Invalid 'weave status' sub-command: $SUB_COMMAND" >&2
  2042. usage
  2043. fi
  2044. if [ -z "$SUB_STATUS" ] && check_running $PROXY_CONTAINER_NAME 2>/dev/null && PROXY_ADDRS=$(proxy_addrs) ; then
  2045. echo
  2046. echo " Service: proxy"
  2047. echo " Address: $PROXY_ADDRS"
  2048. fi
  2049. if [ -z "$SUB_STATUS" ] && check_running $PLUGIN_CONTAINER_NAME 2>/dev/null ; then
  2050. echo
  2051. echo " Service: plugin"
  2052. echo " DriverName: weave"
  2053. fi
  2054. [ -n "$SUB_STATUS" ] || echo
  2055. [ $res -eq 0 ]
  2056. ;;
  2057. report)
  2058. if [ $# -gt 0 ] ; then
  2059. [ $# -eq 2 -a "$1" = "-f" ] || usage
  2060. call_weave GET /report --get --data-urlencode "format=$2"
  2061. else
  2062. call_weave GET /report -H 'Accept: application/json'
  2063. fi
  2064. ;;
  2065. run)
  2066. dns_args "$@"
  2067. shift $(dns_arg_count "$@")
  2068. REWRITE_HOSTS=1
  2069. NO_MULTICAST_ROUTE=
  2070. while [ $# -gt 0 ]; do
  2071. case "$1" in
  2072. --no-rewrite-hosts)
  2073. REWRITE_HOSTS=
  2074. ;;
  2075. --no-multicast-route)
  2076. NO_MULTICAST_ROUTE=1
  2077. ;;
  2078. *)
  2079. break
  2080. ;;
  2081. esac
  2082. shift
  2083. done
  2084. collect_cidr_args "$@"
  2085. shift $CIDR_ARG_COUNT
  2086. CONTAINER=$(docker run -e WEAVE_CIDR=none $DNS_ARGS -d "$@")
  2087. create_bridge
  2088. ipam_cidrs_or_die allocate $CONTAINER $CIDR_ARGS
  2089. [ -n "$REWRITE_HOSTS" ] && extra_hosts_args "$@" && rewrite_etc_hosts $DNS_EXTRA_HOSTS
  2090. do_or_die $CONTAINER attach $ALL_CIDRS
  2091. when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
  2092. echo $CONTAINER
  2093. ;;
  2094. dns-args)
  2095. dns_args "$@"
  2096. echo -n $DNS_ARGS
  2097. ;;
  2098. docker-bridge-ip)
  2099. docker_bridge_ip
  2100. echo -n $DOCKER_BRIDGE_IP
  2101. ;;
  2102. start)
  2103. collect_cidr_args "$@"
  2104. shift $CIDR_ARG_COUNT
  2105. [ $# -eq 1 ] || usage
  2106. RES=$(docker start $1)
  2107. CONTAINER=$(container_id $1)
  2108. create_bridge
  2109. ipam_cidrs_or_die allocate $CONTAINER $CIDR_ARGS
  2110. do_or_die $CONTAINER attach $ALL_CIDRS
  2111. when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
  2112. echo $RES
  2113. ;;
  2114. attach)
  2115. DNS_EXTRA_HOSTS=
  2116. REWRITE_HOSTS=
  2117. NO_MULTICAST_ROUTE=
  2118. collect_cidr_args "$@"
  2119. shift $CIDR_ARG_COUNT
  2120. while [ $# -gt 0 ]; do
  2121. case "$1" in
  2122. --rewrite-hosts)
  2123. REWRITE_HOSTS=1
  2124. ;;
  2125. --add-host)
  2126. DNS_EXTRA_HOSTS="$2 $DNS_EXTRA_HOSTS"
  2127. shift
  2128. ;;
  2129. --add-host=*)
  2130. DNS_EXTRA_HOSTS="${1#*=} $DNS_EXTRA_HOSTS"
  2131. ;;
  2132. --no-multicast-route)
  2133. NO_MULTICAST_ROUTE=1
  2134. ;;
  2135. *)
  2136. break
  2137. ;;
  2138. esac
  2139. shift
  2140. done
  2141. [ $# -eq 1 ] || usage
  2142. CONTAINER=$(container_id $1)
  2143. create_bridge
  2144. ipam_cidrs allocate $CONTAINER $CIDR_ARGS
  2145. [ -n "$REWRITE_HOSTS" ] && rewrite_etc_hosts $DNS_EXTRA_HOSTS
  2146. attach $ALL_CIDRS >/dev/null
  2147. when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
  2148. show_addrs $ALL_CIDRS
  2149. ;;
  2150. detach)
  2151. collect_cidr_args "$@"
  2152. shift $CIDR_ARG_COUNT
  2153. [ $# -eq 1 ] || usage
  2154. CONTAINER=$(container_id $1)
  2155. ipam_cidrs lookup $CONTAINER $CIDR_ARGS
  2156. util_op detach-container $CONTAINER $ALL_CIDRS >/dev/null
  2157. when_weave_running with_container_fqdn $CONTAINER delete_dns_fqdn $ALL_CIDRS
  2158. for CIDR in $IPAM_CIDRS ; do
  2159. call_weave DELETE /ip/$CONTAINER/${CIDR%/*}
  2160. done
  2161. show_addrs $ALL_CIDRS
  2162. ;;
  2163. restart)
  2164. [ $# -ge 1 ] || usage
  2165. create_bridge
  2166. ALL_CIDRS=$(with_container_addresses echo_cidrs $1)
  2167. RES=$(docker restart $1)
  2168. CONTAINER=$(container_id $1)
  2169. for CIDR in $ALL_CIDRS ; do
  2170. call_weave PUT /ip/$CONTAINER/$CIDR?check-alive=true
  2171. done
  2172. detect_awsvpc
  2173. do_or_die $CONTAINER attach $ALL_CIDRS
  2174. when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
  2175. echo $RES
  2176. ;;
  2177. dns-add)
  2178. collect_dns_add_remove_args "$@"
  2179. FN=put_dns_fqdn
  2180. [ -z "$CONTAINER" ] && CONTAINER=weave:extern && FN=put_dns_fqdn_no_check_alive
  2181. if [ -n "$FQDN" ] ; then
  2182. $FN $CONTAINER $FQDN $IP_ARGS
  2183. else
  2184. with_container_fqdn $CONTAINER $FN $IP_ARGS
  2185. fi
  2186. ;;
  2187. dns-remove)
  2188. collect_dns_add_remove_args "$@"
  2189. [ -z "$CONTAINER" ] && CONTAINER=weave:extern
  2190. if [ -n "$FQDN" ] ; then
  2191. delete_dns_fqdn $CONTAINER $FQDN $IP_ARGS
  2192. else
  2193. delete_dns $CONTAINER $IP_ARGS
  2194. fi
  2195. ;;
  2196. dns-lookup)
  2197. [ $# -eq 1 ] || usage
  2198. docker_bridge_ip
  2199. dig @$DOCKER_BRIDGE_IP +short $1
  2200. ;;
  2201. expose)
  2202. collect_cidr_args "$@"
  2203. shift $CIDR_ARG_COUNT
  2204. if [ $# -eq 0 ] ; then
  2205. FQDN=""
  2206. else
  2207. [ $# -eq 2 -a "$1" = "-h" ] || usage
  2208. FQDN="$2"
  2209. fi
  2210. create_bridge --without-ethtool
  2211. expose_ip
  2212. expose_nat
  2213. show_addrs $ALL_CIDRS
  2214. ;;
  2215. hide)
  2216. collect_cidr_args "$@"
  2217. shift $CIDR_ARG_COUNT
  2218. ipam_cidrs lookup weave:expose $CIDR_ARGS
  2219. create_bridge --without-ethtool
  2220. for CIDR in $ALL_CIDRS ; do
  2221. if ip addr show dev $BRIDGE | grep -qF $CIDR ; then
  2222. ip addr del dev $BRIDGE $CIDR
  2223. delete_iptables_rule nat WEAVE -d $CIDR ! -s $CIDR -j MASQUERADE
  2224. delete_iptables_rule nat WEAVE -s $CIDR ! -d $CIDR -j MASQUERADE
  2225. when_weave_running delete_dns weave:expose $CIDR
  2226. fi
  2227. done
  2228. for CIDR in $IPAM_CIDRS ; do
  2229. call_weave DELETE /ip/weave:expose/${CIDR%/*}
  2230. done
  2231. show_addrs $ALL_CIDRS
  2232. ;;
  2233. ps)
  2234. [ $# -eq 0 ] && CONTAINERS="weave:expose $(docker ps -q)" || CONTAINERS="$@"
  2235. with_container_addresses echo_addresses $CONTAINERS
  2236. ;;
  2237. stop)
  2238. [ $# -eq 0 ] || usage
  2239. plugin_disabled || stop_plugin
  2240. stop_router
  2241. stop_proxy
  2242. ;;
  2243. stop-router)
  2244. [ $# -eq 0 ] || usage
  2245. stop_router
  2246. ;;
  2247. stop-proxy)
  2248. [ $# -eq 0 ] || usage
  2249. stop_proxy
  2250. ;;
  2251. stop-plugin)
  2252. [ $# -eq 0 ] || usage
  2253. stop_plugin
  2254. ;;
  2255. reset)
  2256. [ $# -eq 0 ] || [ $# -eq 1 -a "$1" = "--force" ] || usage
  2257. plugin_disabled || util_op remove-plugin-network weave || true
  2258. warn_if_stopping_proxy_in_env
  2259. res=0
  2260. [ "$1" = "--force" ] || check_running $CONTAINER_NAME 2>/dev/null || res=$?
  2261. case $res in
  2262. 0)
  2263. call_weave DELETE /peer >/dev/null 2>&1 || true
  2264. fractional_sleep 0.5 # Allow some time for broadcast updates to go out
  2265. ;;
  2266. 1)
  2267. # No such container; assume user already did reset
  2268. ;;
  2269. 2)
  2270. echo "ERROR: weave is not running; unable to remove from cluster." >&2
  2271. echo "Re-launch weave before reset or use --force to override." >&2
  2272. exit 1
  2273. ;;
  2274. esac
  2275. for NAME in $PLUGIN_CONTAINER_NAME $CONTAINER_NAME $PROXY_CONTAINER_NAME ; do
  2276. docker stop $NAME >/dev/null 2>&1 || true
  2277. docker rm -f $NAME >/dev/null 2>&1 || true
  2278. done
  2279. protect_against_docker_hang
  2280. VOLUME_CONTAINERS=$(docker ps -qa --filter label=weavevolumes)
  2281. [ -n "$VOLUME_CONTAINERS" ] && docker rm -v $VOLUME_CONTAINERS >/dev/null 2>&1 || true
  2282. conntrack -D -p udp --dport $PORT >/dev/null 2>&1 || true
  2283. destroy_bridge
  2284. for LOCAL_IFNAME in $(ip link show | grep v${CONTAINER_IFNAME}pl | cut -d ' ' -f 2 | tr -d ':') ; do
  2285. ip link del ${LOCAL_IFNAME%@*} >/dev/null 2>&1 || true
  2286. done
  2287. ;;
  2288. rmpeer)
  2289. [ $# -gt 0 ] || usage
  2290. res=0
  2291. for PEER in "$@" ; do
  2292. call_weave DELETE /peer/$PEER || res=1
  2293. done
  2294. [ $res -eq 0 ]
  2295. ;;
  2296. launch-dns)
  2297. echo "The 'launch-dns' command has been removed; DNS is launched as part of 'launch' and 'launch-router'." >&2
  2298. exit 0
  2299. ;;
  2300. stop-dns)
  2301. echo "The 'stop-dns command has been removed; DNS is stopped as part of 'stop' and 'stop-router'." >&2
  2302. exit 0
  2303. ;;
  2304. prime)
  2305. call_weave GET /ring
  2306. ;;
  2307. *)
  2308. echo "Unknown weave command '$COMMAND'" >&2
  2309. usage
  2310. ;;
  2311. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement