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