github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/contrib/cirrus/runner.sh (about)

     1  #!/bin/bash
     2  
     3  set -eo pipefail
     4  
     5  # This script runs in the Cirrus CI environment, invoked from .cirrus.yml .
     6  # It can also be invoked manually in a `hack/get_ci_cm.sh` environment,
     7  # documentation of said usage is TBI.
     8  #
     9  # The principal deciding factor is the $TEST_FLAVOR envariable: for any
    10  # given value 'xyz' there must be a function '_run_xyz' to handle that
    11  # test. Several other envariables are used to differentiate further,
    12  # most notably:
    13  #
    14  #    PODBIN_NAME  : "podman" (i.e. local) or "remote"
    15  #    TEST_ENVIRON : 'host', or 'container'; desired environment in which to run
    16  #    CONTAINER    : 1 if *currently* running inside a container, 0 if host
    17  #
    18  
    19  # shellcheck source=contrib/cirrus/lib.sh
    20  source $(dirname $0)/lib.sh
    21  
    22  function _run_ext_svc() {
    23      $SCRIPT_BASE/ext_svc_check.sh
    24  }
    25  
    26  function _run_automation() {
    27      $SCRIPT_BASE/cirrus_yaml_test.py
    28  
    29      req_env_vars CI DEST_BRANCH IMAGE_SUFFIX TEST_FLAVOR TEST_ENVIRON \
    30                   PODBIN_NAME PRIV_NAME DISTRO_NV CONTAINER USER HOME \
    31                   UID AUTOMATION_LIB_PATH SCRIPT_BASE OS_RELEASE_ID \
    32                   CG_FS_TYPE
    33      bigto ooe.sh dnf install -y ShellCheck  # small/quick addition
    34      $SCRIPT_BASE/shellcheck.sh
    35  }
    36  
    37  function _run_validate() {
    38      # git-validation tool fails if $EPOCH_TEST_COMMIT is empty
    39      # shellcheck disable=SC2154
    40      if [[ -n "$EPOCH_TEST_COMMIT" ]]; then
    41          make validate
    42      else
    43          warn "Skipping git-validation since \$EPOCH_TEST_COMMIT is empty"
    44      fi
    45  
    46  }
    47  
    48  function _run_unit() {
    49      _bail_if_test_can_be_skipped test/goecho test/version
    50  
    51      # shellcheck disable=SC2154
    52      if [[ "$PODBIN_NAME" != "podman" ]]; then
    53          # shellcheck disable=SC2154
    54          die "$TEST_FLAVOR: Unsupported PODBIN_NAME='$PODBIN_NAME'"
    55      fi
    56      make localunit
    57  }
    58  
    59  function _run_apiv2() {
    60      _bail_if_test_can_be_skipped test/apiv2
    61  
    62      (
    63          make localapiv2-bash
    64          source .venv/requests/bin/activate
    65          make localapiv2-python
    66      ) |& logformatter
    67  }
    68  
    69  function _run_compose() {
    70      _bail_if_test_can_be_skipped test/compose
    71  
    72      ./test/compose/test-compose |& logformatter
    73  }
    74  
    75  function _run_compose_v2() {
    76      _bail_if_test_can_be_skipped test/compose
    77  
    78      ./test/compose/test-compose |& logformatter
    79  }
    80  
    81  function _run_int() {
    82      _bail_if_test_can_be_skipped test/e2e
    83  
    84      dotest integration
    85  }
    86  
    87  function _run_sys() {
    88      _bail_if_test_can_be_skipped test/system
    89  
    90      dotest system
    91  }
    92  
    93  function _run_upgrade_test() {
    94      _bail_if_test_can_be_skipped test/upgrade
    95  
    96      bats test/upgrade |& logformatter
    97  }
    98  
    99  function _run_bud() {
   100      _bail_if_test_can_be_skipped test/buildah-bud
   101  
   102      ./test/buildah-bud/run-buildah-bud-tests |& logformatter
   103  }
   104  
   105  function _run_bindings() {
   106      # shellcheck disable=SC2155
   107      export PATH=$PATH:$GOSRC/hack
   108  
   109      # if logformatter sees this, it can link directly to failing source lines
   110      local gitcommit_magic=
   111      if [[ -n "$GIT_COMMIT" ]]; then
   112          gitcommit_magic="/define.gitCommit=${GIT_COMMIT}"
   113      fi
   114  
   115      # Subshell needed so logformatter will write output in cwd; if it runs in
   116      # the subdir, .cirrus.yml will not find the html'ized log
   117      (cd pkg/bindings/test && \
   118           echo "$gitcommit_magic" && \
   119           ginkgo -progress -trace -noColor -debug -timeout 30m -r -v) |& logformatter
   120  }
   121  
   122  function _run_docker-py() {
   123      source .venv/docker-py/bin/activate
   124      make run-docker-py-tests
   125  }
   126  
   127  function _run_endpoint() {
   128      make test-binaries
   129      make endpoint
   130  }
   131  
   132  exec_container() {
   133      local var_val
   134      local cmd
   135      # Required to be defined by caller
   136      # shellcheck disable=SC2154
   137      msg "Re-executing runner inside container: $CTR_FQIN"
   138      msg "************************************************************"
   139  
   140      req_env_vars CTR_FQIN TEST_ENVIRON CONTAINER SECRET_ENV_RE
   141  
   142      # Line-separated arguments which include shell-escaped special characters
   143      declare -a envargs
   144      while read -r var_val; do
   145          envargs+=("-e $var_val")
   146      done <<<"$(passthrough_envars)"
   147  
   148      # VM Images and Container images are built using (nearly) identical operations.
   149      set -x
   150      # shellcheck disable=SC2154
   151      exec podman run --rm --privileged --net=host --cgroupns=host \
   152          -v `mktemp -d -p /var/tmp`:/tmp:Z \
   153          -v /dev/fuse:/dev/fuse \
   154          -v "$GOPATH:$GOPATH:Z" \
   155          --workdir "$GOSRC" \
   156          -e "CONTAINER=1" \
   157          "${envargs[@]}" \
   158          $CTR_FQIN bash -c "$SCRIPT_BASE/setup_environment.sh && $SCRIPT_BASE/runner.sh"
   159  }
   160  
   161  function _run_swagger() {
   162      local upload_filename
   163      local upload_bucket
   164      local download_url
   165      local envvarsfile
   166      req_env_vars GCPJSON GCPNAME GCPPROJECT CTR_FQIN
   167  
   168      [[ -x /usr/local/bin/swagger ]] || \
   169          die "Expecting swagger binary to be present and executable."
   170  
   171      # The filename and bucket depend on the automation context
   172      #shellcheck disable=SC2154,SC2153
   173      if [[ -n "$CIRRUS_PR" ]]; then
   174          upload_bucket="libpod-pr-releases"
   175          upload_filename="swagger-pr$CIRRUS_PR.yaml"
   176      elif [[ -n "$CIRRUS_TAG" ]]; then
   177          upload_bucket="libpod-master-releases"
   178          upload_filename="swagger-$CIRRUS_TAG.yaml"
   179      elif [[ "$CIRRUS_BRANCH" == "main" ]]; then
   180          upload_bucket="libpod-master-releases"
   181          # readthedocs versioning uses "latest" for "main" (default) branch
   182          upload_filename="swagger-latest.yaml"
   183      elif [[ -n "$CIRRUS_BRANCH" ]]; then
   184          upload_bucket="libpod-master-releases"
   185          upload_filename="swagger-$CIRRUS_BRANCH.yaml"
   186      else
   187          die "Unknown execution context, expected a non-empty value for \$CIRRUS_TAG, \$CIRRUS_BRANCH, or \$CIRRUS_PR"
   188      fi
   189  
   190      # Swagger validation takes a significant amount of time
   191      msg "Pulling \$CTR_FQIN '$CTR_FQIN' (background process)"
   192      podman pull --quiet $CTR_FQIN &
   193  
   194      cd $GOSRC
   195      make swagger
   196  
   197      # Cirrus-CI Artifact instruction expects file here
   198      cp -v $GOSRC/pkg/api/swagger.yaml ./
   199  
   200      envvarsfile=$(mktemp -p '' .tmp_$(basename $0)_XXXXXXXX)
   201      trap "rm -f $envvarsfile" EXIT  # contains secrets
   202      # Warning: These values must _not_ be quoted, podman will not remove them.
   203      #shellcheck disable=SC2154
   204      cat <<eof >>$envvarsfile
   205  GCPJSON=$GCPJSON
   206  GCPNAME=$GCPNAME
   207  GCPPROJECT=$GCPPROJECT
   208  FROM_FILEPATH=$GOSRC/swagger.yaml
   209  TO_GCSURI=gs://$upload_bucket/$upload_filename
   210  eof
   211  
   212      msg "Waiting for backgrounded podman pull to complete..."
   213      wait %%
   214      podman run -it --rm --security-opt label=disable \
   215          --env-file=$envvarsfile \
   216          -v $GOSRC:$GOSRC:ro \
   217          --workdir $GOSRC \
   218          $CTR_FQIN
   219      rm -f $envvarsfile
   220  }
   221  
   222  function _run_consistency() {
   223      make vendor
   224      SUGGESTION="run 'make vendor' and commit all changes" ./hack/tree_status.sh
   225      make generate-bindings
   226      SUGGESTION="run 'make generate-bindings' and commit all changes" ./hack/tree_status.sh
   227      make completions
   228      SUGGESTION="run 'make completions' and commit all changes" ./hack/tree_status.sh
   229  }
   230  
   231  function _run_build() {
   232      # Ensure always start from clean-slate with all vendor modules downloaded
   233      make clean
   234      make vendor
   235      make podman-release  # includes podman, podman-remote, and docs
   236  }
   237  
   238  function _run_altbuild() {
   239      # We can skip all these steps for test-only PRs, but not doc-only ones
   240      _bail_if_test_can_be_skipped docs
   241  
   242      local -a arches
   243      local arch
   244      req_env_vars ALT_NAME
   245      # Defined in .cirrus.yml
   246      # shellcheck disable=SC2154
   247      msg "Performing alternate build: $ALT_NAME"
   248      msg "************************************************************"
   249      set -x
   250      cd $GOSRC
   251      case "$ALT_NAME" in
   252          *Each*)
   253              git fetch origin
   254              # The make-and-check-size script, introduced 2022-03-22 in #13518,
   255              # runs 'make' (the original purpose of this check) against
   256              # each commit, then checks image sizes to make sure that
   257              # none have grown beyond a given limit. That of course
   258              # requires a baseline, so our first step is to build the
   259              # branch point of the PR.
   260              local context_dir savedhead pr_base
   261              context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX)
   262              savedhead=$(git rev-parse HEAD)
   263              # Push to PR base. First run of the script will write size files
   264              pr_base=$(git merge-base origin/$DEST_BRANCH HEAD)
   265              git checkout $pr_base
   266              hack/make-and-check-size $context_dir
   267              # pop back to PR, and run incremental makes. Subsequent script
   268              # invocations will compare against original size.
   269              git checkout $savedhead
   270              git rebase $pr_base -x "hack/make-and-check-size $context_dir"
   271              rm -rf $context_dir
   272              ;;
   273          *Windows*)
   274              make podman-remote-release-windows_amd64.zip
   275              make podman.msi
   276              ;;
   277          *Without*)
   278              make build-no-cgo
   279              ;;
   280          *RPM*)
   281              make package
   282              ;;
   283          Alt*Cross)
   284              arches=(\
   285                  amd64
   286                  ppc64le
   287                  arm
   288                  arm64
   289                  386
   290                  s390x
   291                  mips
   292                  mipsle
   293                  mips64
   294                  mips64le)
   295              for arch in "${arches[@]}"; do
   296                  msg "Building release archive for $arch"
   297                  make podman-release-${arch}.tar.gz GOARCH=$arch
   298              done
   299              ;;
   300          *)
   301              die "Unknown/Unsupported \$$ALT_NAME '$ALT_NAME'"
   302      esac
   303  }
   304  
   305  function _run_release() {
   306      msg "podman info:"
   307      bin/podman info
   308  
   309      msg "Checking podman release (or potential release) criteria."
   310      # We're running under 'set -eo pipefail'; make sure this statement passes
   311      dev=$(bin/podman info |& grep -- -dev || echo -n '')
   312      if [[ -n "$dev" ]]; then
   313          die "Releases must never contain '-dev' in output of 'podman info' ($dev)"
   314      fi
   315  
   316      commit=$(bin/podman info --format='{{.Version.GitCommit}}' | tr -d '[:space:]')
   317      if [[ -z "$commit" ]]; then
   318          die "Releases must contain a non-empty Version.GitCommit in 'podman info'"
   319      fi
   320      msg "All OK"
   321  }
   322  
   323  
   324  function _run_gitlab() {
   325      rootless_uid=$(id -u)
   326      systemctl enable --now --user podman.socket
   327      export DOCKER_HOST=unix:///run/user/${rootless_uid}/podman/podman.sock
   328      export CONTAINER_HOST=$DOCKER_HOST
   329      cd $GOPATH/src/gitlab.com/gitlab-org/gitlab-runner
   330      set +e
   331      go test -v ./executors/docker |& tee $GOSRC/gitlab-runner-podman.log
   332      ret=$?
   333      set -e
   334      # This file is collected and parsed by Cirrus-CI so must be in $GOSRC
   335      cat $GOSRC/gitlab-runner-podman.log | \
   336          go-junit-report > $GOSRC/gitlab-runner-podman.xml
   337      return $ret
   338  }
   339  
   340  logformatter() {
   341      if [[ "$CI" == "true" ]]; then
   342          # Use similar format as human-friendly task name from .cirrus.yml
   343          # shellcheck disable=SC2154
   344          output_name="$TEST_FLAVOR-$PODBIN_NAME-$DISTRO_NV-$PRIV_NAME-$TEST_ENVIRON"
   345          # Requires stdin and stderr combined!
   346          cat - \
   347              |& awk --file "${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk" \
   348              |& "${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/logformatter" "$output_name"
   349      else
   350          # Assume script is run by a human, they want output immediately
   351          cat -
   352      fi
   353  }
   354  
   355  # Handle local|remote integration|system testing in a uniform way
   356  dotest() {
   357      local testsuite="$1"
   358      req_env_vars testsuite CONTAINER TEST_ENVIRON PRIV_NAME
   359  
   360      # shellcheck disable=SC2154
   361      if ((CONTAINER==0)) && [[ "$TEST_ENVIRON" == "container" ]]; then
   362          exec_container  # does not return
   363      fi;
   364  
   365      # containers/automation sets this to 0 for its dbg() function
   366      # but the e2e integration tests are also sensitive to it.
   367      unset DEBUG
   368  
   369      # shellcheck disable=SC2154
   370      local localremote="$PODBIN_NAME"
   371      case "$PODBIN_NAME" in
   372          podman)  localremote="local" ;;
   373      esac
   374  
   375      make ${localremote}${testsuite} PODMAN_SERVER_LOG=$PODMAN_SERVER_LOG \
   376          |& logformatter
   377  }
   378  
   379  # Optimization: will exit if the only PR diffs are under docs/ or tests/
   380  # with the exception of any given arguments. E.g., don't run e2e or upgrade
   381  # or bud tests if the only PR changes are in test/system.
   382  function _bail_if_test_can_be_skipped() {
   383      local head base diffs
   384  
   385      # Cirrus sets these for PRs but not branches or cron. In cron and branches,
   386      #we never want to skip.
   387      for v in CIRRUS_CHANGE_IN_REPO CIRRUS_PR DEST_BRANCH; do
   388          if [[ -z "${!v}" ]]; then
   389              msg "[ _cannot do selective skip: \$$v is undefined ]"
   390              return 0
   391          fi
   392      done
   393      # And if this one *is* defined, it means we're not in PR-land; don't skip.
   394      if [[ -n "$CIRRUS_TAG" ]]; then
   395          msg "[ _cannot do selective skip: \$CIRRUS_TAG is defined ]"
   396          return 0
   397      fi
   398  
   399      head=$CIRRUS_CHANGE_IN_REPO
   400      base=$(git merge-base $DEST_BRANCH $head)
   401      diffs=$(git diff --name-only $base $head)
   402  
   403      # If PR touches any files in an argument directory, we cannot skip
   404      for subdir in "$@"; do
   405          if egrep -q "^$subdir/" <<<"$diffs"; then
   406              return 0
   407          fi
   408      done
   409  
   410      # PR does not touch any files under our input directories. Now see
   411      # if the PR touches files outside of the following directories, by
   412      # filtering these out from the diff results.
   413      for subdir in docs test; do
   414          # || true needed because we're running with set -e
   415          diffs=$(egrep -v "^$subdir/" <<<"$diffs" || true)
   416      done
   417  
   418      # If we still have diffs, they indicate files outside of docs & test.
   419      # It is not safe to skip.
   420      if [[ -n "$diffs" ]]; then
   421          return 0
   422      fi
   423  
   424      msg "SKIPPING: This is a doc- and/or test-only PR with no changes under $*"
   425      exit 0
   426  }
   427  
   428  # Nearly every task in .cirrus.yml makes use of this shell script
   429  # wrapped by /usr/bin/time to collect runtime statistics.  Because the
   430  # --output option is used to log stats to a file, every child-process
   431  # inherits an open FD3 pointing at the log.  However, some testing
   432  # operations depend on making use of FD3, and so it must be explicitly
   433  # closed here (and for all further child-processes).
   434  # STATS_LOGFILE assumed empty/undefined outside of Cirrus-CI (.cirrus.yml)
   435  # shellcheck disable=SC2154
   436  exec 3<&-
   437  
   438  msg "************************************************************"
   439  # Required to be defined by caller
   440  # shellcheck disable=SC2154
   441  msg "Runner executing $TEST_FLAVOR $PODBIN_NAME-tests as $PRIV_NAME on $DISTRO_NV($OS_REL_VER)"
   442  if ((CONTAINER)); then
   443      # shellcheck disable=SC2154
   444      msg "Current environment container image: $CTR_FQIN"
   445  else
   446      # shellcheck disable=SC2154
   447      msg "Current environment VM image: $VM_IMAGE_NAME"
   448  fi
   449  msg "************************************************************"
   450  
   451  ((${SETUP_ENVIRONMENT:-0})) || \
   452      die "Expecting setup_environment.sh to have completed successfully"
   453  
   454  # shellcheck disable=SC2154
   455  if [[ "$PRIV_NAME" == "rootless" ]] && [[ "$UID" -eq 0 ]]; then
   456      # Remove /var/lib/cni, it is not required for rootless cni.
   457      # We have to test that it works without this directory.
   458      # https://github.com/containers/podman/issues/10857
   459      rm -rf /var/lib/cni
   460  
   461      # This must be done at the last second, otherwise `make` calls
   462      # in setup_environment (as root) will balk about ownership.
   463      msg "Recursively chowning \$GOPATH and \$GOSRC to $ROOTLESS_USER"
   464      if [[ $PRIV_NAME = "rootless" ]]; then
   465          chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
   466      fi
   467  
   468      req_env_vars ROOTLESS_USER
   469      msg "Re-executing runner through ssh as user '$ROOTLESS_USER'"
   470      msg "************************************************************"
   471      set -x
   472      exec ssh $ROOTLESS_USER@localhost \
   473              -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
   474              -o CheckHostIP=no $GOSRC/$SCRIPT_BASE/runner.sh
   475      # Does not return!
   476  fi
   477  # else: not running rootless, do nothing special
   478  
   479  cd "${GOSRC}/"
   480  
   481  handler="_run_${TEST_FLAVOR}"
   482  
   483  if [ "$(type -t $handler)" != "function" ]; then
   484      die "Unknown/Unsupported \$TEST_FLAVOR=$TEST_FLAVOR"
   485  fi
   486  
   487  $handler