github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/upgrade/test-upgrade.bats (about) 1 # -*- bats -*- 2 3 load helpers 4 5 # Create a var-lib-containers dir for this podman. We need to bind-mount 6 # this into the container, and use --root and --runroot and --tmpdir 7 # options both in the container podman and out here: that's the only 8 # way to share image and container storage. 9 if [ -z "${PODMAN_UPGRADE_WORKDIR}" ]; then 10 # Much as I'd love a descriptive name like "podman-upgrade-tests.XXXXX", 11 # keep it short ("pu") because of the 100-character path length limit 12 # for UNIX sockets (needed by conmon) 13 export PODMAN_UPGRADE_WORKDIR=$(mktemp -d --tmpdir=${BATS_TMPDIR:-${TMPDIR:-/tmp}} pu.XXXXXX) 14 15 touch $PODMAN_UPGRADE_WORKDIR/status 16 fi 17 18 # Generate a set of random strings used for content verification 19 if [ -z "${RANDOM_STRING_1}" ]; then 20 export RANDOM_STRING_1=$(random_string 15) 21 export LABEL_CREATED=$(random_string 16) 22 export LABEL_FAILED=$(random_string 17) 23 export LABEL_RUNNING=$(random_string 18) 24 export HOST_PORT=$(random_free_port) 25 fi 26 27 # Version string of the podman we're actually testing, e.g. '3.0.0-dev-d1a26013' 28 PODMAN_VERSION=$($PODMAN version |awk '/^Version:/ { V=$2 } /^Git Commit:/ { G=$3 } END { print V "-" substr(G,0,8) }') 29 30 setup() { 31 skip_if_rootless 32 33 # The podman-in-podman image (old podman) 34 if [[ -z "$PODMAN_UPGRADE_FROM" ]]; then 35 echo "# \$PODMAN_UPGRADE_FROM is undefined (should be e.g. v1.9.0)" >&3 36 false 37 fi 38 39 if [ "$(< $PODMAN_UPGRADE_WORKDIR/status)" = "failed" ]; then 40 # FIXME: exit instead? 41 echo "*** setup failed - no point in running tests" 42 false 43 fi 44 45 # cgroup-manager=systemd does not work inside a container 46 export _PODMAN_TEST_OPTS="--cgroup-manager=cgroupfs --root=$PODMAN_UPGRADE_WORKDIR/root --runroot=$PODMAN_UPGRADE_WORKDIR/runroot --tmpdir=$PODMAN_UPGRADE_WORKDIR/tmp" 47 } 48 49 ############################################################################### 50 # BEGIN setup 51 52 @test "initial setup: start $PODMAN_UPGRADE_FROM containers" { 53 echo failed >| $PODMAN_UPGRADE_WORKDIR/status 54 55 OLD_PODMAN=quay.io/podman/stable:$PODMAN_UPGRADE_FROM 56 $PODMAN pull $OLD_PODMAN 57 58 # Shortcut name, because we're referencing it a lot 59 pmroot=$PODMAN_UPGRADE_WORKDIR 60 61 # WWW content to share 62 mkdir -p $pmroot/var/www 63 echo $RANDOM_STRING_1 >$pmroot/var/www/index.txt 64 65 # podman tmpdir 66 mkdir -p $pmroot/tmp 67 68 # 69 # Script to run >>OLD<< podman commands. 70 # 71 # These commands will be run inside a podman container. The "podman" 72 # command in this script will be the desired old-podman version. 73 # 74 pmscript=$pmroot/setup 75 cat >| $pmscript <<EOF 76 #!/bin/bash 77 78 # 79 # Argh! podman >= 3.4 something something namespace something, fails with 80 # Error: invalid config provided: cannot set hostname when running in the host UTS namespace: invalid configuration 81 # 82 # https://github.com/containers/podman/issues/11969#issuecomment-943386484 83 # 84 if grep -q utsns /etc/containers/containers.conf; then 85 sed -i -e '/^\utsns=/d' /etc/containers/containers.conf 86 fi 87 88 # events-backend=journald does not work inside a container 89 opts="--events-backend=file $_PODMAN_TEST_OPTS" 90 91 set -ex 92 93 # Try try again, because network flakiness makes this a point of failure 94 podman \$opts pull $IMAGE \ 95 || (sleep 10; podman \$opts pull $IMAGE) \ 96 || (sleep 30; podman \$opts pull $IMAGE) 97 98 99 podman \$opts create --name mycreatedcontainer --label mylabel=$LABEL_CREATED \ 100 $IMAGE false 101 102 podman \$opts run --name mydonecontainer $IMAGE echo ++$RANDOM_STRING_1++ 103 104 podman \$opts run --name myfailedcontainer --label mylabel=$LABEL_FAILED \ 105 $IMAGE sh -c 'exit 17' || true 106 107 podman \$opts run -d --name myrunningcontainer --label mylabel=$LABEL_RUNNING \ 108 --network bridge \ 109 -p $HOST_PORT:80 \ 110 -p 127.0.0.1:8080-8082:8080-8082 \ 111 -v $pmroot/var/www:/var/www \ 112 -w /var/www \ 113 --mac-address aa:bb:cc:dd:ee:ff \ 114 $IMAGE /bin/busybox-extras httpd -f -p 80 115 116 podman \$opts pod create --name mypod 117 118 podman \$opts network create --disable-dns mynetwork 119 120 echo READY 121 while :;do 122 if [ -e /stop ]; then 123 echo STOPPING 124 podman \$opts stop -t 0 myrunningcontainer || true 125 podman \$opts rm -f myrunningcontainer || true 126 # sigh, network rm fails with exec: "ip": executable file not found in $PATH 127 # we cannot change the images afterwards so we remove it manually (#11403) 128 # hardcode /etc/cni/net.d dir for now 129 podman \$opts network rm -f mynetwork || rm -f /etc/cni/net.d/mynetwork.conflist 130 exit 0 131 fi 132 sleep 0.5 133 done 134 EOF 135 chmod 555 $pmscript 136 137 # Clean up vestiges of previous run 138 $PODMAN rm -f podman_parent || true 139 140 # Not entirely a NOP! This is just so we get the /run/... mount points created on a CI VM 141 # Also use --network host to prevent any netavark/cni conflicts 142 $PODMAN run --rm --network host $OLD_PODMAN true 143 144 # Podman 4.0 might no longer use cni so /run/cni and /run/containers will no be created in this case 145 # Create directories manually to fix this. Also running with netavark can 146 # cause connectivity issues since cni and netavark should never be mixed. 147 mkdir -p /run/netns /run/cni /run/containers /var/lib/cni /etc/cni/net.d 148 149 # Containers-common around release 1-55 no-longer supplies this file 150 sconf=/etc/containers/storage.conf 151 v_sconf= 152 if [[ -e "$sconf" ]]; then 153 v_sconf="-v $sconf:$sconf" 154 fi 155 156 # 157 # Use new-podman to run the above script under old-podman. 158 # 159 # DO NOT USE run_podman HERE! That would use $_PODMAN_TEST_OPTS 160 # and would write into our shared test dir, which would then 161 # pollute it for use by old-podman. We must keep that pristine 162 # so old-podman is the first to write to it. 163 # 164 # mount /etc/containers/storage.conf to use the same storage settings as on the host 165 # mount /dev/shm because the container locks are stored there 166 # mount /var/lib/cni, /run/cni and /etc/cni/net.d for cni networking 167 # mount /run/containers for the dnsname plugin 168 # 169 $PODMAN run -d --name podman_parent --pid=host \ 170 --privileged \ 171 --net=host \ 172 --cgroupns=host \ 173 --pid=host \ 174 $v_sconf \ 175 -v /dev/fuse:/dev/fuse \ 176 -v /run/crun:/run/crun \ 177 -v /run/netns:/run/netns:rshared \ 178 -v /run/containers:/run/containers \ 179 -v /run/cni:/run/cni \ 180 -v /var/lib/cni:/var/lib/cni \ 181 -v /etc/cni/net.d:/etc/cni/net.d \ 182 -v /dev/shm:/dev/shm \ 183 -v $pmroot:$pmroot \ 184 $OLD_PODMAN $pmroot/setup 185 186 _PODMAN_TEST_OPTS= wait_for_ready podman_parent 187 188 echo OK >| $PODMAN_UPGRADE_WORKDIR/status 189 } 190 191 # END setup 192 ############################################################################### 193 # BEGIN actual tests 194 195 # This is a NOP; used only so the version string will show up in logs 196 @test "upgrade: $PODMAN_UPGRADE_FROM -> $PODMAN_VERSION" { 197 : 198 } 199 200 @test "info" { 201 # check network backend, since this is a old version we should use CNI 202 # when we start testing from 4.0 we should have netavark as backend 203 run_podman info --format '{{.Host.NetworkBackend}}' 204 is "$output" "cni" "correct network backend" 205 } 206 207 @test "images" { 208 run_podman images -a --format '{{.Names}}' 209 is "$output" "\[$IMAGE\]" "podman images" 210 } 211 212 @test "ps : one container running" { 213 run_podman ps --format '{{.Image}}--{{.Names}}' 214 is "$output" "$IMAGE--myrunningcontainer" "ps: one container running" 215 } 216 217 @test "ps -a : shows all containers" { 218 # IMPORTANT: we can't use --sort=created, because that requires #8427 219 # on the *creating* podman end. 220 run_podman ps -a \ 221 --format '{{.Names}}--{{.Status}}--{{.Ports}}--{{.Labels.mylabel}}' \ 222 --sort=names 223 is "${lines[0]}" ".*-infra--Created----<no value>" "infra container" 224 is "${lines[1]}" "mycreatedcontainer--Created----$LABEL_CREATED" "created" 225 is "${lines[2]}" "mydonecontainer--Exited (0).*----<no value>" "done" 226 is "${lines[3]}" "myfailedcontainer--Exited (17) .*----$LABEL_FAILED" "fail" 227 is "${lines[4]}" "myrunningcontainer--Up .*--0\.0\.0\.0:$HOST_PORT->80\/tcp, 127\.0\.0\.1\:8080-8082->8080-8082\/tcp--$LABEL_RUNNING" "running" 228 229 # For debugging: dump containers and IDs 230 if [[ -n "$PODMAN_UPGRADE_TEST_DEBUG" ]]; then 231 run_podman ps -a 232 for l in "${lines[@]}"; do 233 echo "# $l" >&3 234 done 235 fi 236 } 237 238 239 @test "inspect - all container status" { 240 tests=" 241 running | running | 0 242 created | created | 0 243 done | exited | 0 244 failed | exited | 17 245 " 246 while read cname state exitstatus; do 247 run_podman inspect --format '{{.State.Status}}--{{.State.ExitCode}}' my${cname}container 248 is "$output" "$state--$exitstatus" "status of my${cname}container" 249 done < <(parse_table "$tests") 250 } 251 252 @test "network - curl" { 253 run curl --max-time 3 -s 127.0.0.1:$HOST_PORT/index.txt 254 is "$output" "$RANDOM_STRING_1" "curl on running container" 255 } 256 257 # IMPORTANT: connect should happen before restart, we want to check 258 # if we can connect on an existing running container 259 @test "network - connect" { 260 skip_if_version_older 2.2.0 261 touch $PODMAN_UPGRADE_WORKDIR/ran-network-connect-test 262 263 run_podman network connect mynetwork myrunningcontainer 264 run_podman network disconnect podman myrunningcontainer 265 run curl --max-time 3 -s 127.0.0.1:$HOST_PORT/index.txt 266 is "$output" "$RANDOM_STRING_1" "curl on container with second network connected" 267 } 268 269 @test "network - restart" { 270 # restart the container and check if we can still use the port 271 272 # https://github.com/containers/podman/issues/13679 273 # The upgrade to podman4 changes the network db format. 274 # While it is compatible from 3.X to 4.0 it will fail the other way around. 275 # This can be the case when the cleanup process runs before the stop process 276 # can do the cleanup. 277 278 # Since there is no easy way to fix this and downgrading is not something 279 # we support, just fix this bug in the tests by manually calling 280 # network disconnect to teardown the netns. 281 if test -e $PODMAN_UPGRADE_WORKDIR/ran-network-connect-test; then 282 run_podman network disconnect mynetwork myrunningcontainer 283 fi 284 285 run_podman stop -t0 myrunningcontainer 286 287 # now connect again, do this before starting the container 288 if test -e $PODMAN_UPGRADE_WORKDIR/ran-network-connect-test; then 289 run_podman network connect mynetwork myrunningcontainer 290 fi 291 run_podman start myrunningcontainer 292 run curl --max-time 3 -s 127.0.0.1:$HOST_PORT/index.txt 293 is "$output" "$RANDOM_STRING_1" "curl on restarted container" 294 } 295 296 297 @test "logs" { 298 run_podman logs mydonecontainer 299 is "$output" "++$RANDOM_STRING_1++" "podman logs on stopped container" 300 } 301 302 @test "exec" { 303 run_podman exec myrunningcontainer cat /var/www/index.txt 304 is "$output" "$RANDOM_STRING_1" "exec into myrunningcontainer" 305 } 306 307 @test "load" { 308 # FIXME, is this really necessary? 309 skip "TBI. Not sure if there's any point to this." 310 } 311 312 @test "mount" { 313 skip "TBI" 314 } 315 316 @test "pods" { 317 run_podman pod inspect mypod 318 is "$output" ".*mypod.*" 319 320 run_podman pod start mypod 321 is "$output" "[0-9a-f]\\{64\\}" "podman pod start" 322 323 run_podman pod ps 324 is "$output" ".*mypod.*" "podman pod ps shows name" 325 is "$output" ".*Running.*" "podman pod ps shows running state" 326 327 run_podman pod stop mypod 328 is "$output" "[0-9a-f]\\{64\\}" "podman pod stop" 329 330 run_podman pod rm mypod 331 # FIXME: CI runs show this (non fatal) error: 332 # Error updating pod <ID> conmon cgroup PID limit: open /sys/fs/cgroup/libpod_parent/<ID>/conmon/pids.max: no such file or directory 333 # Investigate how to fix this (likely a race condition) 334 # Let's ignore the logrus messages for now 335 is "$output" ".*[0-9a-f]\\{64\\}" "podman pod rm" 336 } 337 338 # FIXME: commit? kill? network? pause? restart? top? volumes? What else? 339 340 341 @test "start" { 342 run_podman start -a mydonecontainer 343 is "$output" "++$RANDOM_STRING_1++" "start on already-run container" 344 } 345 346 @test "rm a stopped container" { 347 run_podman rm myfailedcontainer 348 is "$output" "[0-9a-f]\\{64\\}" "podman rm myfailedcontainer" 349 350 run_podman rm mydonecontainer 351 is "$output" "[0-9a-f]\\{64\\}" "podman rm mydonecontainer" 352 } 353 354 355 @test "stop and rm" { 356 run_podman stop myrunningcontainer 357 run_podman rm myrunningcontainer 358 } 359 360 @test "clean up parent" { 361 if [[ -n "$PODMAN_UPGRADE_TEST_DEBUG" ]]; then 362 skip "workdir is $PODMAN_UPGRADE_WORKDIR" 363 fi 364 365 # We're done with shared environment. By clearing this, we can now 366 # use run_podman for actions on the podman_parent container 367 unset _PODMAN_TEST_OPTS 368 369 # (Useful for debugging the 'rm -f' step below, which, when it fails, only 370 # gives a container ID. This 'ps' confirms that the CID is podman_parent) 371 run_podman ps -a 372 373 # Stop the container gracefully 374 run_podman exec podman_parent touch /stop 375 run_podman wait podman_parent 376 377 run_podman logs podman_parent 378 run_podman rm -f podman_parent 379 380 umount $PODMAN_UPGRADE_WORKDIR/root/overlay || true 381 382 rm -rf $PODMAN_UPGRADE_WORKDIR 383 } 384 385 # FIXME: now clean up