github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/libnetwork/test/integration/dnet/helpers.bash (about)

     1  function get_docker_bridge_ip() {
     2      echo $(docker run --rm -it busybox ip route show | grep default | cut -d" " -f3)
     3  }
     4  
     5  function inst_id2port() {
     6      echo $((41000+${1}-1))
     7  }
     8  
     9  function dnet_container_name() {
    10      echo dnet-$1-$2
    11  }
    12  
    13  function dnet_container_ip() {
    14      docker inspect --format '{{.NetworkSettings.IPAddress}}' dnet-$1-$2
    15  }
    16  
    17  function get_sbox_id() {
    18      local line
    19  
    20      line=$(dnet_cmd $(inst_id2port ${1}) service ls | grep ${2})
    21      echo ${line} | cut -d" " -f5
    22  }
    23  
    24  function net_connect() {
    25  	local al gl
    26  	if [ -n "$4" ]; then
    27  	    if [ "${4}" != ":" ]; then
    28  		al="--alias=${4}"
    29  	    fi
    30  	fi
    31  	if [ -n "$5" ]; then
    32  	    gl="--alias=${5}"
    33  	fi
    34  	dnet_cmd $(inst_id2port ${1}) service publish $gl ${2}.${3}
    35  	dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3}
    36  }
    37  
    38  function net_disconnect() {
    39  	dnet_cmd $(inst_id2port ${1}) service detach ${2} ${2}.${3}
    40  	dnet_cmd $(inst_id2port ${1}) service unpublish ${2}.${3}
    41  }
    42  
    43  function start_consul() {
    44      stop_consul
    45      docker run -d \
    46  	   --name=pr_consul \
    47  	   -p 8500:8500 \
    48  	   -p 8300-8302:8300-8302/tcp \
    49  	   -p 8300-8302:8300-8302/udp \
    50  	   -h consul \
    51  	   progrium/consul -server -bootstrap
    52      sleep 2
    53  }
    54  
    55  function stop_consul() {
    56      echo "consul started"
    57      docker rm -f pr_consul || true
    58  }
    59  
    60  hrun() {
    61      local e E T oldIFS
    62      [[ ! "$-" =~ e ]] || e=1
    63      [[ ! "$-" =~ E ]] || E=1
    64      [[ ! "$-" =~ T ]] || T=1
    65      set +e
    66      set +E
    67      set +T
    68      output="$("$@" 2>&1)"
    69      status="$?"
    70      oldIFS=$IFS
    71      IFS=$'\n' lines=($output)
    72      [ -z "$e" ] || set -e
    73      [ -z "$E" ] || set -E
    74      [ -z "$T" ] || set -T
    75      IFS=$oldIFS
    76  }
    77  
    78  function wait_for_dnet() {
    79      local hport
    80  
    81      hport=$1
    82      echo "waiting on dnet to come up ..."
    83      for i in `seq 1 10`;
    84      do
    85  	hrun ./bin/dnet -H tcp://127.0.0.1:${hport} network ls
    86  	echo ${output}
    87  	if [ "$status" -eq 0 ]; then
    88  	    return
    89  	fi
    90  
    91  	if [[ "${lines[1]}" =~ .*EOF.* ]]
    92  	then
    93  	    docker logs ${2}
    94  	fi
    95  	echo "still waiting after ${i} seconds"
    96  	sleep 1
    97      done
    98  }
    99  
   100  function parse_discovery_str() {
   101      local d provider address
   102      discovery=$1
   103      provider=$(echo ${discovery} | cut -d":" -f1)
   104      address=$(echo ${discovery} | cut -d":" -f2):$(echo ${discovery} | cut -d":" -f3)
   105      address=${address:2}
   106      echo "${discovery} ${provider} ${address}"
   107  }
   108  
   109  function start_dnet() {
   110      local inst suffix name hport cport hopt store bridge_ip labels tomlfile nip
   111      local discovery provider address
   112  
   113      inst=$1
   114      shift
   115      suffix=$1
   116      shift
   117  
   118      store=$(echo $suffix | cut -d":" -f1)
   119      nip=$(echo $suffix | cut -s -d":" -f2)
   120  
   121  
   122      stop_dnet ${inst} ${store}
   123      name=$(dnet_container_name ${inst} ${store})
   124  
   125      hport=$((41000+${inst}-1))
   126      cport=2385
   127      hopt=""
   128  
   129      while [ -n "$1" ]
   130      do
   131  	if [[ "$1" =~ ^[0-9]+$ ]]
   132  	then
   133  	    hport=$1
   134  	    cport=$1
   135  	    hopt="-H tcp://0.0.0.0:${cport}"
   136  	else
   137  	    store=$1
   138  	fi
   139  	shift
   140      done
   141  
   142      bridge_ip=$(get_docker_bridge_ip)
   143  
   144      echo "start_dnet parsed values: " ${inst} ${suffix} ${name} ${hport} ${cport} ${hopt} ${store}
   145  
   146      mkdir -p /tmp/dnet/${name}
   147      tomlfile="/tmp/dnet/${name}/libnetwork.toml"
   148  
   149      # Try discovery URLs with or without path
   150      neigh_ip=""
   151      neighbors=""
   152      if [ "$store" = "zookeeper" ]; then
   153  	read discovery provider address < <(parse_discovery_str zk://${bridge_ip}:2182)
   154      elif [ "$store" = "etcd" ]; then
   155  	read discovery provider address < <(parse_discovery_str etcd://${bridge_ip}:42000/custom_prefix)
   156      elif [ "$store" = "consul" ]; then
   157  	read discovery provider address < <(parse_discovery_str consul://${bridge_ip}:8500/custom_prefix)
   158      else
   159  	if [ "$nip" != "" ]; then
   160  	    neighbors=${nip}
   161  	fi
   162  
   163  	discovery=""
   164  	provider=""
   165  	address=""
   166      fi
   167  
   168      if [ "$discovery" != "" ]; then
   169  	cat > ${tomlfile} <<EOF
   170  title = "LibNetwork Configuration file for ${name}"
   171  
   172  [daemon]
   173    debug = false
   174  [cluster]
   175    discovery = "${discovery}"
   176    Heartbeat = 10
   177  [scopes]
   178    [scopes.global]
   179      [scopes.global.client]
   180        provider = "${provider}"
   181        address = "${address}"
   182  EOF
   183      else
   184  	cat > ${tomlfile} <<EOF
   185  title = "LibNetwork Configuration file for ${name}"
   186  
   187  [daemon]
   188    debug = false
   189  [orchestration]
   190    agent = true
   191    bind = "eth0"
   192    peer = "${neighbors}"
   193  EOF
   194      fi
   195  
   196      cat ${tomlfile}
   197      docker run \
   198  	   -d \
   199  	   --hostname=$(echo ${name} | sed s/_/-/g) \
   200  	   --name=${name}  \
   201  	   --privileged \
   202  	   -p ${hport}:${cport} \
   203  	   -e _OVERLAY_HOST_MODE \
   204  	   -v $(pwd)/:/go/src/github.com/docker/libnetwork \
   205  	   -v /tmp:/tmp \
   206  	   -v $(pwd)/${TMPC_ROOT}:/scratch \
   207  	   -v /usr/local/bin/runc:/usr/local/bin/runc \
   208  	   -w /go/src/github.com/docker/libnetwork \
   209  	   mrjana/golang ./bin/dnet -d -D ${hopt} -c ${tomlfile}
   210  
   211      wait_for_dnet $(inst_id2port ${inst}) ${name}
   212  }
   213  
   214  function start_ovrouter() {
   215      local name=${1}
   216      local parent=${2}
   217  
   218      docker run \
   219  	   -d \
   220  	   --name=${name} \
   221  	   --net=container:${parent} \
   222  	   --volumes-from ${parent} \
   223  	   -w /go/src/github.com/docker/libnetwork \
   224  	   mrjana/golang ./cmd/ovrouter/ovrouter eth0
   225  }
   226  
   227  function stop_dnet() {
   228      local name
   229  
   230      name=$(dnet_container_name $1 $2)
   231      rm -rf /tmp/dnet/${name} || true
   232      docker rm -f ${name} || true
   233  }
   234  
   235  function dnet_cmd() {
   236      local hport
   237  
   238      hport=$1
   239      shift
   240      ./bin/dnet -H tcp://127.0.0.1:${hport} $*
   241  }
   242  
   243  function dnet_exec() {
   244      docker exec -it ${1} bash -c "trap \"echo SIGHUP\" SIGHUP; $2"
   245  }
   246  
   247  function runc() {
   248      local dnet
   249  
   250      dnet=${1}
   251      shift
   252      dnet_exec ${dnet} "cp /var/lib/docker/network/files/${1}*/* /scratch/rootfs/etc"
   253      dnet_exec ${dnet} "mkdir -p /var/run/netns"
   254      dnet_exec ${dnet} "touch /var/run/netns/c && mount -o bind /var/run/docker/netns/${1} /var/run/netns/c"
   255      dnet_exec ${dnet} "ip netns exec c unshare -fmuip --mount-proc chroot \"/scratch/rootfs\" /bin/sh -c \"/bin/mount -t proc proc /proc && ${2}\""
   256      dnet_exec ${dnet} "umount /var/run/netns/c && rm /var/run/netns/c"
   257  }
   258  
   259  function runc_nofail() {
   260      local dnet
   261  
   262      dnet=${1}
   263      shift
   264      dnet_exec ${dnet} "cp /var/lib/docker/network/files/${1}*/* /scratch/rootfs/etc"
   265      dnet_exec ${dnet} "mkdir -p /var/run/netns"
   266      dnet_exec ${dnet} "touch /var/run/netns/c && mount -o bind /var/run/docker/netns/${1} /var/run/netns/c"
   267      set +e
   268      dnet_exec ${dnet} "ip netns exec c unshare -fmuip --mount-proc chroot \"/scratch/rootfs\" /bin/sh -c \"/bin/mount -t proc proc /proc && ${2}\""
   269      status="$?"
   270      set -e
   271      dnet_exec ${dnet} "umount /var/run/netns/c && rm /var/run/netns/c"
   272  }
   273  
   274  function start_etcd() {
   275      local bridge_ip
   276      stop_etcd
   277  
   278      bridge_ip=$(get_docker_bridge_ip)
   279      docker run -d \
   280  	   --net=host \
   281  	   --name=dn_etcd \
   282  	   mrjana/etcd --listen-client-urls http://0.0.0.0:42000 \
   283  	   --advertise-client-urls http://${bridge_ip}:42000
   284      sleep 2
   285  }
   286  
   287  function stop_etcd() {
   288      docker rm -f dn_etcd || true
   289  }
   290  
   291  function start_zookeeper() {
   292      stop_zookeeper
   293      docker run -d \
   294  	   --name=zookeeper_server \
   295  	   -p 2182:2181 \
   296  	   -h zookeeper \
   297  	   dnephin/docker-zookeeper:3.4.6
   298      sleep 2
   299  }
   300  
   301  function stop_zookeeper() {
   302      echo "zookeeper started"
   303      docker rm -f zookeeper_server || true
   304  }
   305  
   306  function test_overlay() {
   307      dnet_suffix=$1
   308  
   309      echo $(docker ps)
   310  
   311      start=1
   312      end=3
   313      # Setup overlay network and connect containers to it
   314      if [ -z "${2}" -o "${2}" != "skip_add" ]; then
   315  	if [ -z "${2}" -o "${2}" != "internal" ]; then
   316  	    dnet_cmd $(inst_id2port 1) network create -d overlay multihost
   317  	else
   318  	    dnet_cmd $(inst_id2port 1) network create -d overlay --internal multihost
   319  	fi
   320      fi
   321  
   322      for i in `seq ${start} ${end}`;
   323      do
   324  	dnet_cmd $(inst_id2port $i) container create container_${i}
   325  	net_connect ${i} container_${i} multihost
   326      done
   327  
   328      # Now test connectivity between all the containers using service names
   329      for i in `seq ${start} ${end}`;
   330      do
   331  	if [ -z "${2}" -o "${2}" != "internal" ]; then
   332  	    runc $(dnet_container_name $i $dnet_suffix) $(get_sbox_id ${i} container_${i}) \
   333  		"ping -c 1 www.google.com"
   334  	else
   335  	    default_route=`runc $(dnet_container_name $i $dnet_suffix) $(get_sbox_id ${i} container_${i}) "ip route | grep default"`
   336  	    [ "$default_route" = "" ]
   337  	fi
   338  	for j in `seq ${start} ${end}`;
   339  	do
   340  	    if [ "$i" -eq "$j" ]; then
   341  		continue
   342  	    fi
   343  	    runc $(dnet_container_name $i $dnet_suffix) $(get_sbox_id ${i} container_${i}) \
   344  		 "ping -c 1 container_$j"
   345  	done
   346      done
   347  
   348      # Setup bridge network and connect containers to it
   349      if [ -z "${2}" -o "${2}" != "skip_add" ]; then
   350  	if [ -z "${2}" -o "${2}" != "internal" ]; then
   351  	    dnet_cmd $(inst_id2port 1) network create -d bridge br1
   352  	    dnet_cmd $(inst_id2port 1) network create -d bridge br2
   353  	    net_connect ${start} container_${start} br1
   354  	    net_connect ${start} container_${start} br2
   355  
   356  	    # Make sure external connectivity works
   357  	    runc $(dnet_container_name ${start} $dnet_suffix) $(get_sbox_id ${start} container_${start}) \
   358  		"ping -c 1 www.google.com"
   359  	    net_disconnect ${start} container_${start} br1
   360  	    net_disconnect ${start} container_${start} br2
   361  
   362  	    # Make sure external connectivity works
   363  	    runc $(dnet_container_name ${start} $dnet_suffix) $(get_sbox_id ${start} container_${start}) \
   364  		"ping -c 1 www.google.com"
   365  	    dnet_cmd $(inst_id2port 1) network rm br1
   366  	    dnet_cmd $(inst_id2port 1) network rm br2
   367  
   368  	    # Disconnect from overlay network
   369  	    net_disconnect ${start} container_${start} multihost
   370  
   371  	    # Connect to overlay network again
   372  	    net_connect ${start} container_${start} multihost
   373  
   374  	    # Make sure external connectivity still works
   375  	    runc $(dnet_container_name ${start} $dnet_suffix) $(get_sbox_id ${start} container_${start}) \
   376  		"ping -c 1 www.google.com"
   377  	fi
   378      fi
   379  
   380      # Teardown the container connections and the network
   381      for i in `seq ${start} ${end}`;
   382      do
   383  	net_disconnect ${i} container_${i} multihost
   384  	dnet_cmd $(inst_id2port $i) container rm container_${i}
   385      done
   386  
   387      if [ -z "${2}" -o "${2}" != "skip_rm" ]; then
   388  	dnet_cmd $(inst_id2port 2) network rm multihost
   389      fi
   390  }
   391  
   392  function check_etchosts() {
   393      local dnet sbid retval
   394      dnet=${1}
   395      shift
   396      sbid=${1}
   397      shift
   398  
   399      retval="true"
   400  
   401      for i in $*;
   402      do
   403  	run runc ${dnet} ${sbid} "cat /etc/hosts"
   404  	if [ "$status" -ne 0 ]; then
   405  	    retval="${output}"
   406  	    break
   407  	fi
   408  
   409  	line=$(echo ${output} | grep ${i})
   410  	if [ "${line}" == "" ]; then
   411  	    retval="false"
   412  	fi
   413      done
   414  
   415      echo ${retval}
   416  }
   417  
   418  function test_overlay_singlehost() {
   419      dnet_suffix=$1
   420      shift
   421  
   422      echo $(docker ps)
   423  
   424      start=1
   425      end=3
   426      # Setup overlay network and connect containers to it
   427      dnet_cmd $(inst_id2port 1) network create -d overlay multihost
   428      for i in `seq ${start} ${end}`;
   429      do
   430  	dnet_cmd $(inst_id2port 1) container create container_${i}
   431  	net_connect 1 container_${i} multihost
   432      done
   433  
   434      # Now test connectivity between all the containers using service names
   435      for i in `seq ${start} ${end}`;
   436      do
   437  	for j in `seq ${start} ${end}`;
   438  	do
   439  	    if [ "$i" -eq "$j" ]; then
   440  		continue
   441  	    fi
   442  	    runc $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 container_${i}) \
   443  		 "ping -c 1 container_$j"
   444  	done
   445      done
   446  
   447      # Teardown the container connections and the network
   448      for i in `seq ${start} ${end}`;
   449      do
   450  	net_disconnect 1 container_${i} multihost
   451  	dnet_cmd $(inst_id2port 1) container rm container_${i}
   452      done
   453  
   454      dnet_cmd $(inst_id2port 1) network rm multihost
   455  }
   456  
   457  function test_overlay_hostmode() {
   458      dnet_suffix=$1
   459      shift
   460  
   461      echo $(docker ps)
   462  
   463      start=1
   464      end=2
   465      # Setup overlay network and connect containers to it
   466      dnet_cmd $(inst_id2port 1) network create -d overlay multihost1
   467      dnet_cmd $(inst_id2port 1) network create -d overlay multihost2
   468      dnet_cmd $(inst_id2port 1) network ls
   469  
   470      for i in `seq ${start} ${end}`;
   471      do
   472  	dnet_cmd $(inst_id2port 1) container create mh1_${i}
   473  	net_connect 1 mh1_${i} multihost1
   474      done
   475  
   476      for i in `seq ${start} ${end}`;
   477      do
   478  	dnet_cmd $(inst_id2port 1) container create mh2_${i}
   479  	net_connect 1 mh2_${i} multihost2
   480      done
   481  
   482      # Now test connectivity between all the containers using service names
   483      for i in `seq ${start} ${end}`;
   484      do
   485  	for j in `seq ${start} ${end}`;
   486  	do
   487  	    if [ "$i" -eq "$j" ]; then
   488  		continue
   489  	    fi
   490  
   491  	    # Find the IP addresses of the j containers on both networks
   492  	    hrun runc $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 mh1_${i}) "nslookup mh1_$j"
   493  	    mh1_j_ip=$(echo ${output} | awk '{print $11}')
   494  
   495  	    hrun runc $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 mh2_${i}) "nslookup mh2_$j"
   496  	    mh2_j_ip=$(echo ${output} | awk '{print $11}')
   497  
   498  	    # Ping the j containers in the same network and ensure they are successful
   499  	    runc $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 mh1_${i}) \
   500  		 "ping -c 1 mh1_$j"
   501  	    runc $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 mh2_${i}) \
   502  		 "ping -c 1 mh2_$j"
   503  
   504  	    # Try pinging j container IPs from the container in the other network and make sure that they are not successful
   505  	    runc_nofail $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 mh1_${i}) "ping -c 1 ${mh2_j_ip}"
   506  	    [ "${status}" -ne 0 ]
   507  
   508  	    runc_nofail $(dnet_container_name 1 $dnet_suffix) $(get_sbox_id 1 mh2_${i}) "ping -c 1 ${mh1_j_ip}"
   509  	    [ "${status}" -ne 0 ]
   510  
   511  	    # Try pinging the j container IPS from the host(dnet container in this case) and make syre that they are not successful
   512  	    hrun docker exec -it $(dnet_container_name 1 $dnet_suffix) "ping -c 1 ${mh1_j_ip}"
   513  	    [ "${status}" -ne 0 ]
   514  
   515  	    hrun docker exec -it $(dnet_container_name 1 $dnet_suffix) "ping -c 1 ${mh2_j_ip}"
   516  	    [ "${status}" -ne 0 ]
   517  	done
   518      done
   519  
   520      # Teardown the container connections and the network
   521      for i in `seq ${start} ${end}`;
   522      do
   523  	net_disconnect 1 mh1_${i} multihost1
   524  	dnet_cmd $(inst_id2port 1) container rm mh1_${i}
   525      done
   526  
   527      for i in `seq ${start} ${end}`;
   528      do
   529  	net_disconnect 1 mh2_${i} multihost2
   530  	dnet_cmd $(inst_id2port 1) container rm mh2_${i}
   531      done
   532  
   533      dnet_cmd $(inst_id2port 1) network rm multihost1
   534      dnet_cmd $(inst_id2port 1) network rm multihost2
   535  }