github.com/AbhinandanKurakure/podman/v3@v3.4.10/test/system/500-networking.bats (about) 1 #!/usr/bin/env bats -*- bats -*- 2 # 3 # Test podman local networking 4 # 5 6 load helpers 7 8 @test "podman network - basic tests" { 9 heading="*NETWORK*ID*NAME*VERSION*PLUGINS*" 10 run_podman network ls 11 if [[ ${output} != ${heading} ]]; then 12 die "network ls expected heading is not available" 13 fi 14 15 run_podman network ls --noheading 16 if [[ ${output} = ${heading} ]]; then 17 die "network ls --noheading did not remove heading: $output" 18 fi 19 } 20 21 # Copied from tsweeney's https://github.com/containers/podman/issues/4827 22 @test "podman networking: port on localhost" { 23 random_1=$(random_string 30) 24 random_2=$(random_string 30) 25 26 HOST_PORT=$(random_free_port) 27 SERVER=http://127.0.0.1:$HOST_PORT 28 29 # Create a test file with random content 30 INDEX1=$PODMAN_TMPDIR/hello.txt 31 echo $random_1 > $INDEX1 32 33 # Bind-mount this file with a different name to a container running httpd 34 run_podman run -d --name myweb -p "$HOST_PORT:80" \ 35 -v $INDEX1:/var/www/index.txt:Z \ 36 -w /var/www \ 37 $IMAGE /bin/busybox-extras httpd -f -p 80 38 cid=$output 39 40 # In that container, create a second file, using exec and redirection 41 run_podman exec -i myweb sh -c "cat > index2.txt" <<<"$random_2" 42 # ...verify its contents as seen from container. 43 run_podman exec -i myweb cat /var/www/index2.txt 44 is "$output" "$random_2" "exec cat index2.txt" 45 46 # Verify http contents: curl from localhost 47 run curl -s $SERVER/index.txt 48 is "$output" "$random_1" "curl 127.0.0.1:/index.txt" 49 run curl -s $SERVER/index2.txt 50 is "$output" "$random_2" "curl 127.0.0.1:/index2.txt" 51 52 # Verify http contents: wget from a second container 53 run_podman run --rm --net=host $IMAGE wget -qO - $SERVER/index.txt 54 is "$output" "$random_1" "podman wget /index.txt" 55 run_podman run --rm --net=host $IMAGE wget -qO - $SERVER/index2.txt 56 is "$output" "$random_2" "podman wget /index2.txt" 57 58 # Tests #4889 - two-argument form of "podman ports" was broken 59 run_podman port myweb 60 is "$output" "80/tcp -> 0.0.0.0:$HOST_PORT" "port <cid>" 61 run_podman port myweb 80 62 is "$output" "0.0.0.0:$HOST_PORT" "port <cid> 80" 63 run_podman port myweb 80/tcp 64 is "$output" "0.0.0.0:$HOST_PORT" "port <cid> 80/tcp" 65 66 run_podman 125 port myweb 99/tcp 67 is "$output" 'Error: failed to find published port "99/tcp"' 68 69 # Clean up 70 run_podman stop -t 1 myweb 71 run_podman rm myweb 72 } 73 74 # Issue #5466 - port-forwarding doesn't work with this option and -d 75 @test "podman networking: port with --userns=keep-id" { 76 for cidr in "" "$(random_rfc1918_subnet).0/24"; do 77 myport=$(random_free_port 52000-52999) 78 if [[ -z $cidr ]]; then 79 # regex to match that we are in 10.X subnet 80 match="10\..*" 81 else 82 # Issue #9828 make sure a custom slir4netns cidr also works 83 network_arg="--network slirp4netns:cidr=$cidr" 84 # slirp4netns interface ip is always .100 85 match="${cidr%.*}.100" 86 fi 87 88 # Container will exit as soon as 'nc' receives input 89 # We use '-n -v' to give us log messages showing an incoming connection 90 # and its IP address; the purpose of that is guaranteeing that the 91 # remote IP is not 127.0.0.1 (podman PR #9052). 92 # We could get more parseable output by using $NCAT_REMOTE_ADDR, 93 # but busybox nc doesn't support that. 94 run_podman run -d --userns=keep-id $network_arg -p 127.0.0.1:$myport:$myport \ 95 $IMAGE nc -l -n -v -p $myport 96 cid="$output" 97 98 wait_for_output "listening on .*:$myport .*" $cid 99 100 # emit random string, and check it 101 teststring=$(random_string 30) 102 echo "$teststring" | nc 127.0.0.1 $myport 103 104 run_podman logs $cid 105 # Sigh. We can't check line-by-line, because 'nc' output order is 106 # unreliable. We usually get the 'connect to' line before the random 107 # string, but sometimes we get it after. So, just do substring checks. 108 is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port" 109 110 # This is the truly important check: make sure the remote IP is not 127.X. 111 is "$output" \ 112 ".*connect to \[::ffff:$match*\]:$myport from \[::ffff:$match\]:.*" \ 113 "nc -v shows remote IP address is not 127.0.0.1" 114 is "$output" ".*${teststring}.*" "test string received on container" 115 116 # Clean up 117 run_podman wait $cid 118 run_podman rm $cid 119 done 120 } 121 122 @test "podman run with slirp4ns assigns correct addresses to /etc/hosts" { 123 CIDR="$(random_rfc1918_subnet)" 124 local conname=con-$(random_string 10) 125 run_podman run --rm --network slirp4netns:cidr="${CIDR}.0/24" \ 126 --name $conname --hostname $conname $IMAGE cat /etc/hosts 127 is "$output" ".*${CIDR}.2 host.containers.internal" "host.containers.internal should be the cidr+2 address" 128 is "$output" ".*${CIDR}.100 $conname $conname" "$conname should be the cidr+100 address" 129 } 130 131 @test "podman run with slirp4ns adds correct dns address to resolv.conf" { 132 CIDR="$(random_rfc1918_subnet)" 133 run_podman run --rm --network slirp4netns:cidr="${CIDR}.0/24" \ 134 $IMAGE grep "${CIDR}" /etc/resolv.conf 135 is "$output" "nameserver ${CIDR}.3" "resolv.conf should have slirp4netns cidr+3 as a nameserver" 136 } 137 138 @test "podman run with slirp4ns assigns correct ip address container" { 139 CIDR="$(random_rfc1918_subnet)" 140 run_podman run --rm --network slirp4netns:cidr="${CIDR}.0/24" \ 141 $IMAGE sh -c "ip address | grep ${CIDR}" 142 is "$output" ".*inet ${CIDR}.100/24 \+" "container should have slirp4netns cidr+100 assigned to interface" 143 } 144 145 # "network create" now works rootless, with the help of a special container 146 @test "podman network create" { 147 # Deliberately use a fixed port, not random_open_port, because of #10806 148 myport=54322 149 150 local mynetname=testnet-$(random_string 10) 151 local mysubnet=$(random_rfc1918_subnet) 152 153 run_podman network create --subnet "${mysubnet}.0/24" $mynetname 154 is "$output" ".*/cni/net.d/$mynetname.conflist" "output of 'network create'" 155 156 # (Assert that output is formatted, not a one-line blob: #8011) 157 run_podman network inspect $mynetname 158 if [[ "${#lines[*]}" -lt 5 ]]; then 159 die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011" 160 fi 161 162 run_podman run --rm --network $mynetname $IMAGE ip a 163 is "$output" ".* inet ${mysubnet}\.2/24 brd ${mysubnet}\.255 " \ 164 "sdfsdf" 165 166 run_podman run -d --network $mynetname -p 127.0.0.1:$myport:$myport \ 167 $IMAGE nc -l -n -v -p $myport 168 cid="$output" 169 170 # FIXME: debugging for #11871 171 run_podman exec $cid cat /etc/resolv.conf 172 if is_rootless && ! is_remote; then 173 run_podman unshare --rootless-cni cat /etc/resolv.conf 174 fi 175 ps uxww 176 177 # check that dns is working inside the container 178 run_podman exec $cid nslookup google.com 179 180 # emit random string, and check it 181 teststring=$(random_string 30) 182 echo "$teststring" | nc 127.0.0.1 $myport 183 184 run_podman logs $cid 185 # Sigh. We can't check line-by-line, because 'nc' output order is 186 # unreliable. We usually get the 'connect to' line before the random 187 # string, but sometimes we get it after. So, just do substring checks. 188 is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port" 189 190 # This is the truly important check: make sure the remote IP is 191 # in the 172.X range, not 127.X. 192 is "$output" \ 193 ".*connect to \[::ffff:172\..*\]:$myport from \[::ffff:172\..*\]:.*" \ 194 "nc -v shows remote IP address in 172.X space (not 127.0.0.1)" 195 is "$output" ".*${teststring}.*" "test string received on container" 196 197 # Cannot create network with the same name 198 run_podman 125 network create $mynetname 199 is "$output" "Error: the network name $mynetname is already used" \ 200 "Trying to create an already-existing network" 201 202 run_podman rm $cid 203 run_podman network rm $mynetname 204 run_podman 1 network rm $mynetname 205 } 206 207 @test "podman network reload" { 208 skip_if_remote "podman network reload does not have remote support" 209 210 random_1=$(random_string 30) 211 HOST_PORT=$(random_free_port) 212 SERVER=http://127.0.0.1:$HOST_PORT 213 214 # Create a test file with random content 215 INDEX1=$PODMAN_TMPDIR/hello.txt 216 echo $random_1 > $INDEX1 217 218 # use default network for root 219 local netname=podman 220 # for rootless we have to create a custom network since there is no default network 221 if is_rootless; then 222 netname=testnet-$(random_string 10) 223 run_podman network create $netname 224 is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" 225 fi 226 227 # Bind-mount this file with a different name to a container running httpd 228 run_podman run -d --name myweb -p "$HOST_PORT:80" \ 229 --network $netname \ 230 -v $INDEX1:/var/www/index.txt:Z \ 231 -w /var/www \ 232 $IMAGE /bin/busybox-extras httpd -f -p 80 233 cid=$output 234 235 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" 236 ip="$output" 237 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" 238 mac="$output" 239 240 # Verify http contents: curl from localhost 241 run curl -s $SERVER/index.txt 242 is "$output" "$random_1" "curl 127.0.0.1:/index.txt" 243 244 # rootless cannot modify iptables 245 if ! is_rootless; then 246 # flush the CNI iptables here 247 run iptables -t nat -F CNI-HOSTPORT-DNAT 248 249 # check that we cannot curl (timeout after 5 sec) 250 run timeout 5 curl -s $SERVER/index.txt 251 if [ "$status" -ne 124 ]; then 252 die "curl did not timeout, status code: $status" 253 fi 254 fi 255 256 # reload the network to recreate the iptables rules 257 run_podman network reload $cid 258 is "$output" "$cid" "Output does not match container ID" 259 260 # check that we still have the same mac and ip 261 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" 262 is "$output" "$ip" "IP address changed after podman network reload" 263 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" 264 is "$output" "$mac" "MAC address changed after podman network reload" 265 266 # check that we can still curl 267 run curl -s $SERVER/index.txt 268 is "$output" "$random_1" "curl 127.0.0.1:/index.txt" 269 270 # make sure --all is working and that this 271 # cmd also works if the iptables still exists 272 run_podman network reload --all 273 is "$output" "$cid" "Output does not match container ID" 274 275 # check that we can still curl 276 run curl -s $SERVER/index.txt 277 is "$output" "$random_1" "curl 127.0.0.1:/index.txt" 278 279 # cleanup the container 280 run_podman rm -f $cid 281 282 if is_rootless; then 283 run_podman network rm -f $netname 284 fi 285 } 286 287 @test "podman rootless cni adds /usr/sbin to PATH" { 288 is_rootless || skip "only meaningful for rootless" 289 290 local mynetname=testnet-$(random_string 10) 291 run_podman network create $mynetname 292 293 # Test that rootless cni adds /usr/sbin to $PATH 294 # iptables is located under /usr/sbin and is needed for the CNI plugins. 295 # Debian doesn't add /usr/sbin to $PATH for rootless users so we have to add it. 296 PATH=/usr/local/bin:/usr/bin run_podman run --rm --network $mynetname $IMAGE ip addr 297 is "$output" ".*eth0.*" "Interface eth0 not found in ip addr output" 298 299 run_podman network rm -f $mynetname 300 } 301 302 @test "podman ipv6 in /etc/resolv.conf" { 303 ipv6_regex='([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})(%\w+)?' 304 305 # Make sure to read the correct /etc/resolv.conf file in case of systemd-resolved. 306 resolve_file=$(readlink -f /etc/resolv.conf) 307 if [[ "$resolve_file" == "/run/systemd/resolve/stub-resolv.conf" ]]; then 308 resolve_file="/run/systemd/resolve/resolv.conf" 309 fi 310 311 # If the host doesn't have an ipv6 in resolv.conf skip this test. 312 # We should never modify resolv.conf on the host. 313 if ! grep -E "$ipv6_regex" "$resolve_file"; then 314 skip "This test needs an ipv6 nameserver in $resolve_file" 315 fi 316 317 # ipv4 slirp 318 run_podman run --rm --network slirp4netns:enable_ipv6=false $IMAGE cat /etc/resolv.conf 319 if grep -E "$ipv6_regex" <<< $output; then 320 die "resolv.conf contains a ipv6 nameserver" 321 fi 322 323 # ipv6 slirp 324 run_podman run --rm --network slirp4netns:enable_ipv6=true $IMAGE cat /etc/resolv.conf 325 # "is" does not like the ipv6 regex 326 if ! grep -E "$ipv6_regex" <<< $output; then 327 die "resolv.conf does not contain a ipv6 nameserver" 328 fi 329 330 # ipv4 cni 331 local mysubnet=$(random_rfc1918_subnet) 332 local netname=testnet-$(random_string 10) 333 334 run_podman network create --subnet $mysubnet.0/24 $netname 335 is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" 336 337 run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf 338 if grep -E "$ipv6_regex" <<< $output; then 339 die "resolv.conf contains a ipv6 nameserver" 340 fi 341 342 run_podman network rm -f $netname 343 344 # ipv6 cni 345 mysubnet=fd00:4:4:4:4::/64 346 netname=testnet-$(random_string 10) 347 348 run_podman network create --subnet $mysubnet $netname 349 is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" 350 351 run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf 352 # "is" does not like the ipv6 regex 353 if ! grep -E "$ipv6_regex" <<< $output; then 354 die "resolv.conf does not contain a ipv6 nameserver" 355 fi 356 357 run_podman network rm -f $netname 358 } 359 360 # Test for https://github.com/containers/podman/issues/10052 361 @test "podman network connect/disconnect with port forwarding" { 362 random_1=$(random_string 30) 363 HOST_PORT=$(random_free_port) 364 SERVER=http://127.0.0.1:$HOST_PORT 365 366 # Create a test file with random content 367 INDEX1=$PODMAN_TMPDIR/hello.txt 368 echo $random_1 > $INDEX1 369 370 local netname=testnet-$(random_string 10) 371 run_podman network create $netname 372 is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" 373 374 local netname2=testnet2-$(random_string 10) 375 run_podman network create $netname2 376 is "$output" ".*/cni/net.d/$netname2.conflist" "output of 'network create'" 377 378 # First, run a container in background to ensure that the rootless cni ns 379 # is not destroyed after network disconnect. 380 run_podman run -d --network $netname $IMAGE top 381 background_cid=$output 382 383 # Run a httpd container on first network with exposed port 384 run_podman run -d -p "$HOST_PORT:80" \ 385 --network $netname \ 386 -v $INDEX1:/var/www/index.txt:Z \ 387 -w /var/www \ 388 $IMAGE /bin/busybox-extras httpd -f -p 80 389 cid=$output 390 391 # Verify http contents: curl from localhost 392 run curl --max-time 3 -s $SERVER/index.txt 393 is "$output" "$random_1" "curl 127.0.0.1:/index.txt" 394 395 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" 396 ip="$output" 397 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" 398 mac="$output" 399 400 run_podman network disconnect $netname $cid 401 is "$output" "" "Output should be empty (no errors)" 402 403 # check that we cannot curl (timeout after 3 sec) 404 run curl --max-time 3 -s $SERVER/index.txt 405 if [ "$status" -eq 0 ]; then 406 die "curl did not fail, it should have timed out or failed with non zero exit code" 407 fi 408 409 run_podman network connect $netname $cid 410 is "$output" "" "Output should be empty (no errors)" 411 412 # curl should work again 413 run curl --max-time 3 -s $SERVER/index.txt 414 is "$output" "$random_1" "curl 127.0.0.1:/index.txt should work again" 415 416 # check that we have a new ip and mac 417 # if the ip is still the same this whole test turns into a nop 418 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" 419 if [[ "$output" == "$ip" ]]; then 420 die "IP address did not change after podman network disconnect/connect" 421 fi 422 run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" 423 if [[ "$output" == "$mac" ]]; then 424 die "MAC address did not change after podman network disconnect/connect" 425 fi 426 427 # Disconnect/reconnect of a container *with no ports* should succeed quietly 428 run_podman network disconnect $netname $background_cid 429 is "$output" "" "disconnect of container with no open ports" 430 run_podman network connect $netname $background_cid 431 is "$output" "" "(re)connect of container with no open ports" 432 433 # connect a second network 434 run_podman network connect $netname2 $cid 435 is "$output" "" "Output should be empty (no errors)" 436 437 # curl should work 438 run curl --max-time 3 -s $SERVER/index.txt 439 is "$output" "$random_1" "curl 127.0.0.1:/index.txt should work" 440 441 # disconnect the first network 442 run_podman network disconnect $netname $cid 443 444 # curl should still work 445 run curl --max-time 3 -s $SERVER/index.txt 446 is "$output" "$random_1" "curl 127.0.0.1:/index.txt should still work" 447 448 # cleanup 449 run_podman stop -t 0 $cid $background_cid 450 run_podman rm -f $cid $background_cid 451 run_podman network rm -f $netname $netname2 452 } 453 454 @test "podman network after restart" { 455 random_1=$(random_string 30) 456 457 HOST_PORT=$(random_free_port) 458 SERVER=http://127.0.0.1:$HOST_PORT 459 460 # Create a test file with random content 461 INDEX1=$PODMAN_TMPDIR/hello.txt 462 echo $random_1 > $INDEX1 463 464 local netname=testnet-$(random_string 10) 465 run_podman network create $netname 466 is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" 467 468 for network in "slirp4netns" "$netname"; do 469 # Start container with the restart always policy 470 run_podman run -d --name myweb -p "$HOST_PORT:80" \ 471 --restart always \ 472 --network $network \ 473 -v $INDEX1:/var/www/index.txt:Z \ 474 -w /var/www \ 475 $IMAGE /bin/busybox-extras httpd -f -p 80 476 cid=$output 477 478 # Tests #10310: podman will restart slirp4netns on container restart 479 run_podman container inspect --format "{{.State.Pid}}" $cid 480 pid=$output 481 482 # Kill the process; podman restart policy will bring up a new container. 483 # -9 is crucial: busybox httpd ignores all other signals. 484 kill -9 $pid 485 # Wait for process to exit 486 retries=30 487 while kill -0 $pid; do 488 sleep 0.5 489 retries=$((retries - 1)) 490 if [[ $retries -eq 0 ]]; then 491 die "Process $pid (container $cid) refused to die" 492 fi 493 done 494 495 # Wait for container to restart 496 retries=20 497 while :;do 498 run_podman container inspect --format "{{.State.Pid}}" $cid 499 # pid is 0 as long as the container is not running 500 if [[ $output -ne 0 ]]; then 501 if [[ $output == $pid ]]; then 502 die "This should never happen! Restarted container has same PID ($output) as killed one!" 503 fi 504 break 505 fi 506 sleep 0.5 507 retries=$((retries - 1)) 508 if [[ $retries -eq 0 ]]; then 509 die "Timed out waiting for container to restart" 510 fi 511 done 512 513 # Verify http contents again: curl from localhost 514 # Use retry since it can take a moment until the new container is ready 515 run curl --retry 2 -s $SERVER/index.txt 516 is "$output" "$random_1" "curl 127.0.0.1:/index.txt after auto restart" 517 518 run_podman restart $cid 519 # Verify http contents again: curl from localhost 520 # Use retry since it can take a moment until the new container is ready 521 run curl --retry 2 -s $SERVER/index.txt 522 is "$output" "$random_1" "curl 127.0.0.1:/index.txt after podman restart" 523 524 run_podman stop -t 0 $cid 525 run_podman rm -f $cid 526 done 527 528 # Cleanup network 529 run_podman network rm $netname 530 } 531 532 # vim: filetype=sh