123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- #!/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
- }
- version_check() {
- required=$1
- actual=$2
- err_prefix=$3
- 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)
- 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
- }
- docker_version_check() {
- ver=$(docker version -f '{{.Server.Version}}')
- version_check "1.9" $ver
- }
- run_test() {
- backend=$1
- if [ -e "$backend" ]; then
- echo "Reading custom conf from $backend"
- flannel_conf=`cat "$backend"`
- else
- 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"
- do
- sleep 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
- 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
- if [ $? -ne 0 ]; then
- exit 1
- fi
- echo flannels running
- # wait an arbitrary amount to have flannels come up
- sleep 5
- # 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 &&
- ip link add name dummy0 type dummy && \
- ip addr add $FLANNEL_SUBNET dev dummy0 && \
- ip link set dummy0 up && \
- echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
- 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
- echo "Test for backend=$backend: exit=$exit_code"
- # 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
- docker stop flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
- 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
- echo "------ flannel client (one doing the ping) log -------"
- docker logs flannel-e2e-test-flannel2
- echo
- fi
- docker rm flannel-e2e-test-flannel1 flannel-e2e-test-flannel2 >/dev/null
- return $exit_code
- }
- multi_test() {
- 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"
- do
- sleep 1
- done
- while ! docker run --rm -it $ETCD_IMG etcdctl --endpoints=$etcd_endpt set /hostgw/network/config "$flannel_conf_host_gw"
- do
- sleep 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
- # Start the hosts
- docker run --name=flannel-host$host -d -it --privileged --entrypoint /bin/sh $flannel_img
- # Start two flanneld instances
- docker exec -d flannel-host$host sh -c "/opt/bin/flanneld -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 -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
- # 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 '\
- source /vxlan.env &&
- ip link add name dummy_vxlan type dummy && \
- ip addr add $FLANNEL_SUBNET dev dummy_vxlan && \
- ip link set dummy_vxlan up && \
- echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
- hostgw_ping_dest=$(docker exec flannel-host1 /bin/sh -c '\
- source /hostgw.env &&
- ip link add name dummy_hostgw type dummy && \
- ip addr add $FLANNEL_SUBNET dev dummy_hostgw && \
- ip link set dummy_hostgw up && \
- echo $FLANNEL_SUBNET | cut -f 1 -d "/" ')
- # 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
|