github.com/containers/podman/v4@v4.9.4/contrib/cirrus/lib.sh (about)

     1  
     2  
     3  # Library of common, shared utility functions.  This file is intended
     4  # to be sourced by other scripts, not called directly.
     5  
     6  # BEGIN Global export of all variables
     7  set -a
     8  
     9  # Due to differences across platforms and runtime execution environments,
    10  # handling of the (otherwise) default shell setup is non-uniform.  Rather
    11  # than attempt to workaround differences, simply force-load/set required
    12  # items every time this library is utilized.
    13  USER="$(whoami)"
    14  HOME="$(getent passwd $USER | cut -d : -f 6)"
    15  # Some platforms set and make this read-only
    16  [[ -n "$UID" ]] || \
    17      UID=$(getent passwd $USER | cut -d : -f 3)
    18  
    19  # Automation library installed at image-build time,
    20  # defining $AUTOMATION_LIB_PATH in this file.
    21  if [[ -r "/etc/automation_environment" ]]; then
    22      source /etc/automation_environment
    23  fi
    24  # shellcheck disable=SC2154
    25  if [[ -n "$AUTOMATION_LIB_PATH" ]]; then
    26          # shellcheck source=/usr/share/automation/lib/common_lib.sh
    27          source $AUTOMATION_LIB_PATH/common_lib.sh
    28  else
    29      (
    30      echo "WARNING: It does not appear that containers/automation was installed."
    31      echo "         Functionality of most of this library will be negatively impacted"
    32      echo "         This ${BASH_SOURCE[0]} was loaded by ${BASH_SOURCE[1]}"
    33      ) > /dev/stderr
    34  fi
    35  
    36  # Managed by setup_environment.sh; holds task-specific definitions.
    37  if [[ -r "/etc/ci_environment" ]]; then source /etc/ci_environment; fi
    38  
    39  # This is normally set from .cirrus.yml but default is necessary when
    40  # running under hack/get_ci_vm.sh since it cannot infer the value.
    41  DISTRO_NV="${DISTRO_NV:-$OS_REL_VER}"
    42  
    43  # Essential default paths, many are overridden when executing under Cirrus-CI
    44  GOPATH="${GOPATH:-/var/tmp/go}"
    45  if type -P go &> /dev/null
    46  then
    47      # Cirrus-CI caches $GOPATH contents
    48      export GOCACHE="${GOCACHE:-$GOPATH/cache/go-build}"
    49      # called processes like `make` and other tools need these vars.
    50      eval "export $(go env)"
    51  
    52      # Ensure compiled tooling is reachable
    53      PATH="$PATH:$GOPATH/bin:$HOME/.local/bin"
    54  fi
    55  CIRRUS_WORKING_DIR="${CIRRUS_WORKING_DIR:-$(realpath $(dirname ${BASH_SOURCE[0]})/../../)}"
    56  GOSRC="${GOSRC:-$CIRRUS_WORKING_DIR}"
    57  PATH="$HOME/bin:/usr/local/bin:$PATH"
    58  LD_LIBRARY_PATH="/usr/local/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
    59  
    60  # Saves typing / in case location ever moves
    61  SCRIPT_BASE=${SCRIPT_BASE:-./contrib/cirrus}
    62  
    63  # Downloaded, but not installed packages.
    64  PACKAGE_DOWNLOAD_DIR=/var/cache/download
    65  
    66  # Log remote-client system test server output here
    67  PODMAN_SERVER_LOG=$CIRRUS_WORKING_DIR/podman-server.log
    68  
    69  # Defaults when not running under CI
    70  export CI="${CI:-false}"
    71  CIRRUS_CI="${CIRRUS_CI:-false}"
    72  CONTINUOUS_INTEGRATION="${CONTINUOUS_INTEGRATION:-false}"
    73  CIRRUS_REPO_NAME=${CIRRUS_REPO_NAME:-podman}
    74  # Cirrus only sets $CIRRUS_BASE_SHA properly for PRs, but $EPOCH_TEST_COMMIT
    75  # needs to be set from this value in order for `make validate` to run properly.
    76  # When running get_ci_vm.sh, most $CIRRUS_xyz variables are empty. Attempt
    77  # to accommodate both branch and get_ci_vm.sh testing by discovering the base
    78  # branch SHA value.
    79  # shellcheck disable=SC2154
    80  if [[ -z "$CIRRUS_BASE_SHA" ]] && [[ -z "$CIRRUS_TAG" ]]
    81  then  # Operating on a branch, or under `get_ci_vm.sh`
    82      showrun echo "branch or get_ci_vm (CIRRUS_BASE_SHA and CIRRUS_TAG are unset)"
    83      CIRRUS_BASE_SHA=$(git rev-parse ${UPSTREAM_REMOTE:-origin}/$DEST_BRANCH)
    84  elif [[ -z "$CIRRUS_BASE_SHA" ]]
    85  then  # Operating on a tag
    86      showrun echo "operating on tag"
    87      CIRRUS_BASE_SHA=$(git rev-parse HEAD)
    88  fi
    89  # The starting place for linting and code validation
    90  EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA"
    91  
    92  # Regex defining all CI-related env. vars. necessary for all possible
    93  # testing operations on all platforms and versions.  This is necessary
    94  # to avoid needlessly passing through global/system values across
    95  # contexts, such as host->container or root->rootless user
    96  #
    97  # List of envariables which must be EXACT matches
    98  PASSTHROUGH_ENV_EXACT='CGROUP_MANAGER|DEST_BRANCH|DISTRO_NV|GOCACHE|GOPATH|GOSRC|NETWORK_BACKEND|OCI_RUNTIME|ROOTLESS_USER|SCRIPT_BASE|SKIP_USERNS|EC2_INST_TYPE|PODMAN_DB|STORAGE_FS'
    99  
   100  # List of envariable patterns which must match AT THE BEGINNING of the name.
   101  PASSTHROUGH_ENV_ATSTART='CI|LANG|LC_|TEST'
   102  
   103  # List of envariable patterns which can match ANYWHERE in the name
   104  PASSTHROUGH_ENV_ANYWHERE='_NAME|_FQIN'
   105  
   106  # Unsafe env. vars for display
   107  SECRET_ENV_RE='ACCOUNT|GC[EP]..|SSH|PASSWORD|SECRET|TOKEN'
   108  
   109  # Type of filesystem used for cgroups
   110  CG_FS_TYPE="$(stat -f -c %T /sys/fs/cgroup)"
   111  
   112  # Set to 1 in all podman container images
   113  CONTAINER="${CONTAINER:-0}"
   114  
   115  # Without this, perl garbles "f39β" command-line args
   116  PERL_UNICODE=A
   117  
   118  # END Global export of all variables
   119  set +a
   120  
   121  lilto() { err_retry 8 1000 "" "$@"; }  # just over 4 minutes max
   122  bigto() { err_retry 7 5670 "" "$@"; }  # 12 minutes max
   123  
   124  setup_rootless() {
   125      req_env_vars GOPATH GOSRC SECRET_ENV_RE
   126  
   127      ROOTLESS_USER="${ROOTLESS_USER:-some${RANDOM}dude}"
   128      ROOTLESS_UID=""
   129  
   130      local rootless_uid
   131      local rootless_gid
   132      local env_var_val
   133      local akfilepath
   134      local sshcmd
   135  
   136      # Only do this once; established by setup_environment.sh
   137      # shellcheck disable=SC2154
   138      if passwd --status $ROOTLESS_USER
   139      then
   140          # Farm tests utilize the rootless user to simulate a "remote" podman instance.
   141      # Root still needs to own the repo. clone and all things under `$GOPATH`.  The
   142      # opposite is true for the lower-level podman e2e tests, the rootless user
   143      # runs them, and therefore needs permissions.
   144          if [[ $PRIV_NAME = "rootless" ]] && [[ "$TEST_FLAVOR" != "farm"  ]]; then
   145              msg "Updating $ROOTLESS_USER user permissions on possibly changed libpod code"
   146              chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
   147              return 0
   148          fi
   149      fi
   150      msg "************************************************************"
   151      msg "Setting up rootless user '$ROOTLESS_USER'"
   152      msg "************************************************************"
   153      cd $GOSRC || exit 1
   154      # Guarantee independence from specific values
   155      rootless_uid=$((1500 + RANDOM % 5000))
   156      ROOTLESS_UID=$rootless_uid
   157      rootless_gid=$((1500 + RANDOM % 5000))
   158      msg "creating $rootless_uid:$rootless_gid $ROOTLESS_USER user"
   159      showrun groupadd -g $rootless_gid $ROOTLESS_USER
   160      showrun useradd -g $rootless_gid -u $rootless_uid --no-user-group --create-home $ROOTLESS_USER
   161  
   162      echo "$ROOTLESS_USER ALL=(root) NOPASSWD: ALL" > /etc/sudoers.d/ci-rootless
   163  
   164      mkdir -p "$HOME/.ssh" "/home/$ROOTLESS_USER/.ssh"
   165  
   166      msg "Creating ssh key pairs"
   167      [[ -r "$HOME/.ssh/id_rsa" ]] || \
   168          ssh-keygen -t rsa -P "" -f "$HOME/.ssh/id_rsa"
   169      showrun ssh-keygen -t ed25519 -P "" -f "/home/$ROOTLESS_USER/.ssh/id_ed25519"
   170      showrun ssh-keygen -t rsa -P "" -f "/home/$ROOTLESS_USER/.ssh/id_rsa"
   171  
   172      msg "Set up authorized_keys"
   173      cat $HOME/.ssh/*.pub /home/$ROOTLESS_USER/.ssh/*.pub >> $HOME/.ssh/authorized_keys
   174      cat $HOME/.ssh/*.pub /home/$ROOTLESS_USER/.ssh/*.pub >> /home/$ROOTLESS_USER/.ssh/authorized_keys
   175  
   176      msg "Configure ssh file permissions"
   177      chmod -R 700 "$HOME/.ssh"
   178      chmod -R 700 "/home/$ROOTLESS_USER/.ssh"
   179      chown -R $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.ssh"
   180  
   181      # N/B: We're clobbering the known_hosts here on purpose.  There should
   182      # never be any non-localhost connections made from tests (using strict-mode).
   183      # If there are, it's either a security problem or a broken test, both of which
   184      # we want to lead to test failures.
   185      msg "   set up known_hosts for $USER"
   186      ssh-keyscan localhost > /root/.ssh/known_hosts
   187      msg "   set up known_hosts for $ROOTLESS_USER"
   188      # Maintain access-permission consistency with all other .ssh files.
   189      install -Z -m 700 -o $ROOTLESS_USER -g $ROOTLESS_USER \
   190          /root/.ssh/known_hosts /home/$ROOTLESS_USER/.ssh/known_hosts
   191  
   192      if [[ -n "$ROOTLESS_USER" ]]; then
   193          showrun echo "conditional setup for ROOTLESS_USER [=$ROOTLESS_USER]"
   194          # Make all future CI scripts aware of these values
   195          echo "ROOTLESS_USER=$ROOTLESS_USER" >> /etc/ci_environment
   196          echo "ROOTLESS_UID=$ROOTLESS_UID" >> /etc/ci_environment
   197      fi
   198  }
   199  
   200  install_test_configs() {
   201      msg "Installing ./test/registries.conf system-wide."
   202      install -v -D -m 644 ./test/registries.conf /etc/containers/
   203  }
   204  
   205  use_cni() {
   206      req_env_vars OS_RELEASE_ID PACKAGE_DOWNLOAD_DIR SCRIPT_BASE
   207      # Defined by common automation library
   208      # shellcheck disable=SC2154
   209      if [[ "$OS_RELEASE_ID" =~ "debian" ]]; then
   210          # Supporting it involves swapping the rpm & dnf commands below
   211          die "Testing debian w/ CNI networking currently not supported"
   212      fi
   213  
   214      msg "Forcing NETWORK_BACKEND=cni for all subsequent environments."
   215      echo "NETWORK_BACKEND=cni" >> /etc/ci_environment
   216      export NETWORK_BACKEND=cni
   217      # While it's possible a user may want both installed, for CNI CI testing
   218      # purposes we only care about backward-compatibility, not forward.
   219      # If both CNI & netavark are present, in some situations where --root
   220      # is used it's possible for podman to pick the "wrong" networking stack.
   221      msg "Force-removing netavark and aardvark-dns"
   222      # Other packages depend on nv/av, but we're testing with podman
   223      # binaries built from source, so it's safe to ignore these deps.
   224      #
   225      # Do not fail when netavark and aardvark-dns are not installed.
   226      for pkg in aardvark-dns netavark
   227      do
   228          [ -z "$(rpm -qa | grep $pkg)" ] && echo "$pkg not installed" || rpm -e --nodeps $pkg
   229      done
   230      msg "Installing default CNI configuration"
   231      showrun dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-plugins*
   232      cd $GOSRC || exit 1
   233      rm -rvf /etc/cni/net.d
   234      mkdir -p /etc/cni/net.d
   235      showrun install -v -D -m 644 ./cni/87-podman-bridge.conflist \
   236          /etc/cni/net.d/
   237      # This config must always sort last in the list of networks (podman picks
   238      # first one as the default).  This config prevents allocation of network
   239      # address space used by default in google cloud.
   240      # https://cloud.google.com/vpc/docs/vpc#ip-ranges
   241      showrun install -v -D -m 644 $SCRIPT_BASE/99-do-not-use-google-subnets.conflist \
   242          /etc/cni/net.d/
   243  }
   244  
   245  use_netavark() {
   246      req_env_vars OS_RELEASE_ID PRIOR_FEDORA_NAME DISTRO_NV
   247      local magickind repokind
   248      msg "Unsetting NETWORK_BACKEND for all subsequent environments."
   249      echo "export -n NETWORK_BACKEND" >> /etc/ci_environment
   250      echo "unset NETWORK_BACKEND" >> /etc/ci_environment
   251      export -n NETWORK_BACKEND
   252      unset NETWORK_BACKEND
   253      msg "Removing any/all CNI configuration"
   254      showrun rm -rvf /etc/cni/net.d/*
   255      # N/B: The CNI packages are still installed and available. This is
   256      # on purpose, since CI needs to verify the selection mechanisms are
   257      # functional when both are available.
   258  }
   259  
   260  # Remove all files provided by the distro version of podman.
   261  # All VM cache-images used for testing include the distro podman because (1) it's
   262  # required for podman-in-podman testing and (2) it somewhat simplifies the task
   263  # of pulling in necessary prerequisites packages as the set can change over time.
   264  # For general CI testing however, calling this function makes sure the system
   265  # can only run the compiled source version.
   266  remove_packaged_podman_files() {
   267      echo "Removing packaged podman files to prevent conflicts with source build and testing."
   268      req_env_vars OS_RELEASE_ID
   269  
   270      # If any binaries are resident they could cause unexpected pollution
   271      for unit in podman.socket podman-auto-update.timer
   272      do
   273          for state in enabled active
   274          do
   275              if systemctl --quiet is-$state $unit
   276              then
   277                  echo "Warning: $unit found $state prior to packaged-file removal"
   278                  showrun systemctl --quiet disable $unit || true
   279                  showrun systemctl --quiet stop $unit || true
   280              fi
   281          done
   282      done
   283  
   284      # OS_RELEASE_ID is defined by automation-library
   285      # shellcheck disable=SC2154
   286      if [[ "$OS_RELEASE_ID" =~ "debian" ]]
   287      then
   288          LISTING_CMD="dpkg-query -L podman"
   289      else
   290          LISTING_CMD="rpm -ql podman"
   291      fi
   292  
   293      # delete the podman socket in case it has been created previously.
   294      # Do so without running podman, lest that invocation initialize unwanted state.
   295      rm -f /run/podman/podman.sock  /run/user/$(id -u)/podman/podman.sock || true
   296  
   297      rm -f $(podman info --format "{{.Host.RemoteSocket.Path}}")
   298  
   299      # yum/dnf/dpkg may list system directories, only remove files
   300      $LISTING_CMD | while read fullpath
   301      do
   302          # Sub-directories may contain unrelated/valuable stuff
   303          if [[ -d "$fullpath" ]]; then continue; fi
   304          showrun ooe.sh rm -vf "$fullpath"
   305      done
   306  
   307      # Be super extra sure and careful vs performant and completely safe
   308      sync && echo 3 > /proc/sys/vm/drop_caches || true
   309  }
   310  
   311  showrun echo "finished"