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