|
@@ -1,44 +1,42 @@
|
|
|
#!/bin/bash
|
|
|
-# Uncomment to see what commands are being executed
|
|
|
-#set -x
|
|
|
-
|
|
|
-ETCD_IMG="quay.io/coreos/etcd:v3.0.3"
|
|
|
-FLANNEL_NET="10.10.0.0/16"
|
|
|
-
|
|
|
-usage() {
|
|
|
- echo "$0 FLANNEL-DOCKER-IMAGE"
|
|
|
- echo
|
|
|
- echo "Run end-to-end tests by bringing up two flannel instances"
|
|
|
- echo "and having them ping each other"
|
|
|
- echo
|
|
|
- echo "NOTE: this script depends on Docker 1.9.0 or higher"
|
|
|
- exit 1
|
|
|
+ETCD_IMG="${ETCD_IMG:-quay.io/coreos/etcd:v3.2.7}"
|
|
|
+ETCD_LOCATION="${ETCD_LOCATION:-etcd}"
|
|
|
+FLANNEL_NET="${FLANNEL_NET:-10.10.0.0/16}"
|
|
|
+TAG=`git describe --tags --dirty`
|
|
|
+FLANNEL_DOCKER_IMAGE="${FLANNEL_DOCKER_IMAGE:-quay.io/coreos/flannel:$TAG}"
|
|
|
+
|
|
|
+setup_suite() {
|
|
|
+ # Run etcd, killing any existing one that was running
|
|
|
+ docker_ip=$(ip -o -f inet addr show docker0 | grep -Po 'inet \K[\d.]+')
|
|
|
+ etcd_endpt="http://$docker_ip:2379"
|
|
|
+
|
|
|
+ # Start etcd
|
|
|
+ docker rm -f flannel-e2e-test-etcd >/dev/null 2>/dev/null
|
|
|
+ docker run --name=flannel-e2e-test-etcd -d -p 2379:2379 $ETCD_IMG $ETCD_LOCATION --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls $etcd_endpt >/dev/null
|
|
|
}
|
|
|
|
|
|
-version_check() {
|
|
|
- required=$1
|
|
|
- actual=$2
|
|
|
- err_prefix=$3
|
|
|
+teardown_suite() {
|
|
|
+ # Teardown the etcd server
|
|
|
+ docker rm -f flannel-e2e-test-etcd >/dev/null
|
|
|
+}
|
|
|
|
|
|
- req_maj=$(echo $required | cut -d . -f 1)
|
|
|
- req_min=$(echo $required | cut -d . -f 2)
|
|
|
- act_maj=$(echo $actual | cut -d . -f 1)
|
|
|
- act_min=$(echo $actual | cut -d . -f 2)
|
|
|
+setup() {
|
|
|
+ # rm any old flannel container that maybe running, ignore error as it might not exist
|
|
|
+ docker rm -f flannel-e2e-test-flannel1 >/dev/null 2>/dev/null
|
|
|
+ assert "docker run --name=flannel-e2e-test-flannel1 -d --privileged $FLANNEL_DOCKER_IMAGE --etcd-endpoints=$etcd_endpt -v 10 >/dev/null"
|
|
|
|
|
|
- if [ $act_maj -lt $req_maj ] || ( [ $act_maj -eq $req_maj ] && [ $act_min -lt $req_min ] ); then
|
|
|
- echo "$err_prefix: required=$required, found=$actual"
|
|
|
- exit 1
|
|
|
- fi
|
|
|
+ # rm any old flannel container that maybe running, ignore error as it might not exist
|
|
|
+ docker rm -f flannel-e2e-test-flannel2 >/dev/null 2>/dev/null
|
|
|
+ assert "docker run --name=flannel-e2e-test-flannel2 -d --privileged $FLANNEL_DOCKER_IMAGE --etcd-endpoints=$etcd_endpt -v 10 >/dev/null"
|
|
|
}
|
|
|
|
|
|
-docker_version_check() {
|
|
|
- ver=$(docker version -f '{{.Server.Version}}')
|
|
|
- version_check "1.9" $ver
|
|
|
+teardown() {
|
|
|
+ docker rm -f flannel-e2e-test-flannel1 >/dev/null 2>/dev/null
|
|
|
+ docker rm -f flannel-e2e-test-flannel2 >/dev/null 2>/dev/null
|
|
|
}
|
|
|
|
|
|
-run_test() {
|
|
|
- backend=$1
|
|
|
-
|
|
|
+write_config_etcd() {
|
|
|
+ local backend=$1
|
|
|
if [ -e "$backend" ]; then
|
|
|
echo "Reading custom conf from $backend"
|
|
|
flannel_conf=`cat "$backend"`
|
|
@@ -46,111 +44,112 @@ run_test() {
|
|
|
flannel_conf="{ \"Network\": \"$FLANNEL_NET\", \"Backend\": { \"Type\": \"${backend}\" } }"
|
|
|
fi
|
|
|
|
|
|
- # etcd might take a bit to come up
|
|
|
- while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /coreos.com/network/config "$flannel_conf"
|
|
|
+ # etcd might take a bit to come up - use a known etcd version so we know we have etcdctl available
|
|
|
+ while ! docker run --rm -it quay.io/coreos/etcd:v3.2.7 etcdctl --endpoints=$etcd_endpt set /coreos.com/network/config "$flannel_conf" >/dev/null
|
|
|
do
|
|
|
- sleep 1
|
|
|
+ sleep 0.1
|
|
|
done
|
|
|
+}
|
|
|
|
|
|
- echo flannel config written
|
|
|
-
|
|
|
- # rm any old flannel container that maybe running, ignore error as it might not exist
|
|
|
- docker rm -f flannel-e2e-test-flannel1 2>/dev/null
|
|
|
- docker run --name=flannel-e2e-test-flannel1 -d --privileged $flannel_img --etcd-endpoints=$etcd_endpt -v 10
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- # rm any old flannel container that maybe running, ignore error as it might not exist
|
|
|
- docker rm -f flannel-e2e-test-flannel2 2>/dev/null
|
|
|
- docker run --name=flannel-e2e-test-flannel2 -d --privileged $flannel_img --etcd-endpoints=$etcd_endpt -v 10
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- echo flannels running
|
|
|
-
|
|
|
- # wait an arbitrary amount to have flannels come up
|
|
|
- sleep 5
|
|
|
+create_ping_dest() {
|
|
|
+ # add a dummy interface with $FLANNEL_SUBNET so we have a known working IP to ping
|
|
|
+ for host_num in 1 2; do
|
|
|
+ while ! docker exec flannel-e2e-test-flannel$host_num ls /run/flannel/subnet.env >/dev/null 2>&1; do
|
|
|
+ sleep 0.1
|
|
|
+ done
|
|
|
|
|
|
- # add a dummy interface with $FLANNEL_SUBNET so we have a known working IP to ping
|
|
|
- ping_dest=$(docker "exec" --privileged flannel-e2e-test-flannel1 /bin/sh -c '\
|
|
|
- source /run/flannel/subnet.env &&
|
|
|
+ # Use declare to allow the host_num variable to be part of the ping_dest variable name. -g is needed to make it global
|
|
|
+ declare -g ping_dest$host_num=$(docker "exec" --privileged flannel-e2e-test-flannel$host_num /bin/sh -c '\
|
|
|
+ source /run/flannel/subnet.env && \
|
|
|
ip link add name dummy0 type dummy && \
|
|
|
- ip addr add $FLANNEL_SUBNET dev dummy0 && \
|
|
|
- ip link set dummy0 up && \
|
|
|
+ ip addr add $FLANNEL_SUBNET dev dummy0 && ip link set dummy0 up && \
|
|
|
echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
|
|
|
+ done
|
|
|
+}
|
|
|
|
|
|
- docker exec -it --privileged flannel-e2e-test-flannel2 /bin/ping -c 5 $ping_dest
|
|
|
- exit_code=$?
|
|
|
-
|
|
|
- # Uncomment to debug (you can nsenter)
|
|
|
- #if [ $exit_code -eq "1" ]; then
|
|
|
- # sleep 10000
|
|
|
- #fi
|
|
|
+test_vxlan_ping() {
|
|
|
+ write_config_etcd vxlan
|
|
|
+ create_ping_dest # creates ping_dest1 and ping_dest2 variables
|
|
|
+ pings
|
|
|
+}
|
|
|
|
|
|
- echo "Test for backend=$backend: exit=$exit_code"
|
|
|
+test_udp_ping() {
|
|
|
+ write_config_etcd udp
|
|
|
+ create_ping_dest # creates ping_dest1 and ping_dest2 variables
|
|
|
+ pings
|
|
|
+}
|
|
|
|
|
|
- # Perf test - run iperf server on flannel1 and client on flannel2
|
|
|
- if [ $exit_code -eq 0 ]; then
|
|
|
- docker rm -f flannel-e2e-test-flannel1-iperf 2>/dev/null
|
|
|
- docker run -d --name flannel-e2e-test-flannel1-iperf --net=container:flannel-e2e-test-flannel1 mlabbe/iperf3
|
|
|
- docker run --rm --net=container:flannel-e2e-test-flannel2 mlabbe/iperf3 -c $ping_dest
|
|
|
- fi
|
|
|
+test_host-gw_ping() {
|
|
|
+ write_config_etcd host-gw
|
|
|
+ create_ping_dest # creates ping_dest1 and ping_dest2 variables
|
|
|
+ pings
|
|
|
+}
|
|
|
|
|
|
- docker stop flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
|
|
|
+pings() {
|
|
|
+ # ping in both directions
|
|
|
+ assert "docker exec -it --privileged flannel-e2e-test-flannel1 /bin/ping -c 3 $ping_dest2" "Host 1 cannot ping host 2"
|
|
|
+ assert "docker exec -it --privileged flannel-e2e-test-flannel2 /bin/ping -c 3 $ping_dest1" "Host 2 cannot ping host 1"
|
|
|
+}
|
|
|
|
|
|
- if [ $exit_code -ne 0 ]; then
|
|
|
- # Print flannel logs to help debug
|
|
|
- echo "------ flannel server (one being pinged) log -------"
|
|
|
- docker logs flannel-e2e-test-flannel1
|
|
|
- echo
|
|
|
+# These perf tests don't actually assert on anything
|
|
|
+test_host-gw-perf() {
|
|
|
+ write_config_etcd host-gw
|
|
|
+ create_ping_dest
|
|
|
+ perf
|
|
|
+}
|
|
|
|
|
|
- echo "------ flannel client (one doing the ping) log -------"
|
|
|
- docker logs flannel-e2e-test-flannel2
|
|
|
- echo
|
|
|
- fi
|
|
|
+test_vxlan_perf() {
|
|
|
+ write_config_etcd vxlan
|
|
|
+ create_ping_dest
|
|
|
+ perf
|
|
|
+}
|
|
|
|
|
|
- docker rm flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
|
|
|
+test_udp_perf() {
|
|
|
+ write_config_etcd udp
|
|
|
+ create_ping_dest
|
|
|
+ perf
|
|
|
+}
|
|
|
|
|
|
- return $exit_code
|
|
|
+perf() {
|
|
|
+ # Perf test - run iperf server on flannel1 and client on flannel2
|
|
|
+ docker rm -f flannel-e2e-test-flannel1-iperf 2>/dev/null
|
|
|
+ docker run -d --name flannel-e2e-test-flannel1-iperf --net=container:flannel-e2e-test-flannel1 mlabbe/iperf3
|
|
|
+ docker run --rm --net=container:flannel-e2e-test-flannel2 mlabbe/iperf3 -c $ping_dest1
|
|
|
}
|
|
|
|
|
|
-multi_test() {
|
|
|
+test_multi() {
|
|
|
flannel_conf_vxlan='{"Network": "10.11.0.0/16", "Backend": {"Type": "vxlan"}}'
|
|
|
flannel_conf_host_gw='{"Network": "10.12.0.0/16", "Backend": {"Type": "host-gw"}}'
|
|
|
|
|
|
- # etcd might take a bit to come up
|
|
|
- while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /vxlan/network/config "$flannel_conf_vxlan"
|
|
|
+ while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /vxlan/network/config "$flannel_conf_vxlan" >/dev/null
|
|
|
do
|
|
|
- sleep 1
|
|
|
+ sleep 0.1
|
|
|
done
|
|
|
|
|
|
- while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw"
|
|
|
+ while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw" >/dev/null
|
|
|
do
|
|
|
- sleep 1
|
|
|
+ sleep 0.1
|
|
|
done
|
|
|
|
|
|
- echo flannel config written
|
|
|
-
|
|
|
for host in 1 2; do
|
|
|
- echo "=== Creating Host: $host ==============================================="
|
|
|
-
|
|
|
- # rm any old flannel container that maybe running, ignore error as it might not exist
|
|
|
- docker rm -f flannel-host$host 2>/dev/null
|
|
|
+ # rm any old flannel container, ignore error as it might not exist
|
|
|
+ docker rm -f flannel-host$host 2>/dev/null >/dev/null
|
|
|
|
|
|
# Start the hosts
|
|
|
- docker run --name=flannel-host$host -d -it --privileged --entrypoint /bin/sh $flannel_img
|
|
|
+ docker run --name=flannel-host$host -d -it --privileged --entrypoint /bin/sh $FLANNEL_DOCKER_IMAGE >/dev/null
|
|
|
|
|
|
# Start two flanneld instances
|
|
|
docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -v 10 -subnet-file /vxlan.env -etcd-prefix=/vxlan/network --etcd-endpoints=$etcd_endpt 2>vxlan.log"
|
|
|
docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -v 10 -subnet-file /hostgw.env -etcd-prefix=/hostgw/network --etcd-endpoints=$etcd_endpt 2>hostgw.log"
|
|
|
done
|
|
|
|
|
|
- echo flannels running
|
|
|
-
|
|
|
- # wait an arbitrary amount to have flannels come up
|
|
|
- sleep 1
|
|
|
+ for host in 1 2; do
|
|
|
+ for backend_type in vxlan hostgw; do
|
|
|
+ while ! docker exec flannel-host$host ls /$backend_type.env >/dev/null 2>&1; do
|
|
|
+ sleep 0.1
|
|
|
+ done
|
|
|
+ done
|
|
|
+ done
|
|
|
|
|
|
# add dummy interface on host1 only so we have a known working IP to ping then ping it from host2
|
|
|
vxlan_ping_dest=$(docker exec flannel-host1 /bin/sh -c '\
|
|
@@ -169,86 +168,8 @@ multi_test() {
|
|
|
|
|
|
# Send some pings from host2. Make sure we can send traffic over vxlan or directly.
|
|
|
# If a particular (wrong) interface is forced then pings should fail
|
|
|
- docker exec -it flannel-host2 ping -c 3 $hostgw_ping_dest && \
|
|
|
- docker exec -it flannel-host2 ping -c 3 $vxlan_ping_dest && \
|
|
|
- ! docker exec -it flannel-host2 ping -W 1 -c 1 -I flannel.1 $hostgw_ping_dest && \
|
|
|
- ! docker exec -it flannel-host2 ping -W 1 -c 1 -I eth0 $vxlan_ping_dest
|
|
|
- exit_code=$?
|
|
|
-
|
|
|
- # Uncomment to debug (you can nsenter)
|
|
|
- #if [ $exit_code -eq "1" ]; then
|
|
|
- # sleep 10000
|
|
|
- #fi
|
|
|
-
|
|
|
- echo "Test for multi-backend: exit=$exit_code"
|
|
|
-
|
|
|
-
|
|
|
- if [ $exit_code -ne 0 ]; then
|
|
|
- # Print flannel logs to help debug
|
|
|
- echo "------ flannel server (one being pinged) log -------"
|
|
|
- docker exec flannel-host1 sh -c 'cat *.log'
|
|
|
- echo
|
|
|
-
|
|
|
- echo "------ flannel client (one doing the ping) log -------"
|
|
|
- docker exec flannel-host2 sh -c 'cat *.log'
|
|
|
- echo
|
|
|
- fi
|
|
|
-
|
|
|
- docker rm -f flannel-host1 flannel-host2 >/dev/null
|
|
|
-
|
|
|
- return $exit_code
|
|
|
-}
|
|
|
-
|
|
|
-if [ $# -ne 1 ]; then
|
|
|
- usage
|
|
|
-fi
|
|
|
-
|
|
|
-flannel_img=$1
|
|
|
-
|
|
|
-# Check that docker is new enough
|
|
|
-docker_version_check
|
|
|
-
|
|
|
-docker0=$(ip -o -f inet addr show docker0 | grep -Po 'inet \K[\d.]+')
|
|
|
-etcd_endpt="http://$docker0:2379"
|
|
|
-
|
|
|
-docker rm -f flannel-e2e-test-etcd 2>/dev/null
|
|
|
-docker run --name=flannel-e2e-test-etcd -d -p 2379:2379 $ETCD_IMG etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls $etcd_endpt
|
|
|
-if [ $? -ne 0 ]; then
|
|
|
- exit 1
|
|
|
-fi
|
|
|
-
|
|
|
-echo etcd launched
|
|
|
-
|
|
|
-global_exit_code=0
|
|
|
-
|
|
|
-backends=${BACKEND:-"udp vxlan host-gw"}
|
|
|
-for backend in $backends; do
|
|
|
- echo
|
|
|
- echo "=== BACKEND: $backend ==============================================="
|
|
|
-
|
|
|
- if ! run_test $backend; then
|
|
|
- global_exit_code=1
|
|
|
- fi
|
|
|
-done
|
|
|
-
|
|
|
-echo "=== MULTI BACKEND ==============================================="
|
|
|
-if ! multi_test; then
|
|
|
- global_exit_code=1
|
|
|
-fi
|
|
|
-
|
|
|
-docker stop flannel-e2e-test-etcd >/dev/null
|
|
|
-
|
|
|
-if [ $global_exit_code -eq 0 ]; then
|
|
|
- echo
|
|
|
- echo "ALL TESTS PASSED"
|
|
|
-else
|
|
|
- # Print etcd logs to help debug
|
|
|
- echo "------ etcd log -------"
|
|
|
- docker logs $etcd
|
|
|
- echo
|
|
|
- echo "TEST(S) FAILED"
|
|
|
-fi
|
|
|
-
|
|
|
-docker rm flannel-e2e-test-etcd 2>/dev/null
|
|
|
-
|
|
|
-exit $global_exit_code
|
|
|
+ assert "docker exec -it flannel-host2 ping -c 3 $hostgw_ping_dest"
|
|
|
+ assert "docker exec -it flannel-host2 ping -c 3 $vxlan_ping_dest"
|
|
|
+ assert_fails "docker exec -it flannel-host2 ping -W 1 -c 1 -I flannel.1 $hostgw_ping_dest"
|
|
|
+ assert_fails "docker exec -it flannel-host2 ping -W 1 -c 1 -I eth0 $vxlan_ping_dest"
|
|
|
+}
|