diff options
Diffstat (limited to 'contrib/cirrus/lib.sh')
-rw-r--r-- | contrib/cirrus/lib.sh | 262 |
1 files changed, 148 insertions, 114 deletions
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 334202aa9..737ca3c01 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -18,9 +18,8 @@ if type -P go &> /dev/null then # required for go 1.12+ export GOCACHE="${GOCACHE:-$HOME/.cache/go-build}" - eval "$(go env)" - # required by make and other tools - export $(go env | cut -d '=' -f 1) + # called processes like `make` and other tools need these vars. + eval "export $(go env)" # Ensure compiled tooling is reachable export PATH="$PATH:$GOPATH/bin" @@ -46,6 +45,7 @@ fi # Defaults when not running under CI export CI="${CI:-false}" CIRRUS_CI="${CIRRUS_CI:-false}" +DEST_BRANCH="${DEST_BRANCH:-master}" CONTINUOUS_INTEGRATION="${CONTINUOUS_INTEGRATION:-false}" CIRRUS_REPO_NAME=${CIRRUS_REPO_NAME:-libpod} CIRRUS_BASE_SHA=${CIRRUS_BASE_SHA:-unknown$(date +%s)} # difficult to reliably discover @@ -55,21 +55,32 @@ PACKER_VER="1.3.5" # CSV of cache-image names to build (see $PACKER_BASE/libpod_images.json) # Base-images rarely change, define them here so they're out of the way. -PACKER_BUILDS="${PACKER_BUILDS:-ubuntu-18,fedora-29,fedora-28}" +export PACKER_BUILDS="${PACKER_BUILDS:-ubuntu-18,fedora-30,fedora-29}" # Google-maintained base-image names -UBUNTU_BASE_IMAGE="ubuntu-1804-bionic-v20181203a" +export UBUNTU_BASE_IMAGE="ubuntu-1804-bionic-v20181203a" # Manually produced base-image names (see $SCRIPT_BASE/README.md) -FEDORA_BASE_IMAGE="fedora-cloud-base-29-1-2-1541789245" -# FEDORA_BASE_IMAGE: "fedora-cloud-base-30-1-2-1556821664" -PRIOR_FEDORA_BASE_IMAGE="fedora-cloud-base-28-1-1-1544474897" -# PRIOR_FEDORA_BASE_IMAGE="fedora-cloud-base-29-1-2-1541789245" -BUILT_IMAGE_SUFFIX="${BUILT_IMAGE_SUFFIX:--$CIRRUS_REPO_NAME-${CIRRUS_BUILD_ID}}" +export FEDORA_BASE_IMAGE="fedora-cloud-base-30-1-2-1559164849" +export PRIOR_FEDORA_BASE_IMAGE="fedora-cloud-base-29-1-2-1559164849" +export BUILT_IMAGE_SUFFIX="${BUILT_IMAGE_SUFFIX:--$CIRRUS_REPO_NAME-${CIRRUS_BUILD_ID}}" +# IN_PODMAN container image +IN_PODMAN_IMAGE="quay.io/libpod/in_podman:latest" + +# Avoid getting stuck waiting for user input +export DEBIAN_FRONTEND="noninteractive" +SUDOAPTGET="ooe.sh sudo -E apt-get -qq --yes" +SUDOAPTADD="ooe.sh sudo -E add-apt-repository --yes" +# Short-cuts for retrying/timeout calls +LILTO="timeout_attempt_delay_command 24s 5 30s" +BIGTO="timeout_attempt_delay_command 300s 5 30s" # Safe env. vars. to transfer from root -> $ROOTLESS_USER (go env handled separetly) -ROOTLESS_ENV_RE='(CIRRUS_.+)|(ROOTLESS_.+)|(.+_IMAGE.*)|(.+_BASE)|(.*DIRPATH)|(.*FILEPATH)|(SOURCE.*)|(DEPEND.*)|(.+_DEPS_.+)|(OS_REL.*)|(.+_ENV_RE)|(TRAVIS)|(CI.+)' +ROOTLESS_ENV_RE='(CIRRUS_.+)|(ROOTLESS_.+)|(.+_IMAGE.*)|(.+_BASE)|(.*DIRPATH)|(.*FILEPATH)|(SOURCE.*)|(DEPEND.*)|(.+_DEPS_.+)|(OS_REL.*)|(.+_ENV_RE)|(TRAVIS)|(CI.+)|(TEST_REMOTE.*)' # Unsafe env. vars for display SECRET_ENV_RE='(IRCID)|(ACCOUNT)|(^GC[EP]..+)|(SSH)' +# Names of systemd units which should never be running +EVIL_UNITS="cron crond atd apt-daily-upgrade apt-daily fstrim motd-news systemd-tmpfiles-clean" + SPECIALMODE="${SPECIALMODE:-none}" TEST_REMOTE_CLIENT="${TEST_REMOTE_CLIENT:-false}" export CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-podman} @@ -114,6 +125,30 @@ req_env_var() { done } +item_test() { + ITEM="$1" + shift + TEST_ARGS="$@" + req_env_var ITEM TEST_ARGS + + if ERR=$(test "$@" 2>&1) + then + echo "ok $ITEM" + return 0 + else + RET=$? + echo -n "not ok $ITEM: $TEST_ARGS" + if [[ -z "$ERR" ]] + then + echo "" + else # test command itself failed + echo -n ":" # space follows :'s in $ERR + echo "$ERR" | cut -d : -f 4- # omit filename, line number, and command + fi + return $RET + fi +} + show_env_vars() { echo "Showing selection of environment variable definitions:" _ENV_VAR_NAMES=$(awk 'BEGIN{for(v in ENVIRON) print v}' | \ @@ -124,9 +159,6 @@ show_env_vars() { # Supports older BASH versions printf " ${_env_var_name}=%q\n" "$(printenv $_env_var_name)" done - echo "" - echo "##### $(go version) #####" - echo "" } die() { @@ -136,6 +168,11 @@ die() { exit ${1:-1} } +warn() { + echo ">>>>> ${2:-WARNING (but no message given!) in ${FUNCNAME[1]}()}" > /dev/stderr + echo ${1:-1} > /dev/stdout +} + bad_os_id_ver() { echo "Unknown/Unsupported distro. $OS_RELEASE_ID and/or version $OS_RELEASE_VER for $(basename $0)" exit 42 @@ -145,6 +182,35 @@ stub() { echo "STUB: Pretending to do $1" } +timeout_attempt_delay_command() { + TIMEOUT=$1 + ATTEMPTS=$2 + DELAY=$3 + shift 3 + STDOUTERR=$(mktemp -p '' $(basename $0)_XXXXX) + req_env_var ATTEMPTS DELAY + echo "Retrying $ATTEMPTS times with a $DELAY delay, and $TIMEOUT timeout for command: $@" + for (( COUNT=1 ; COUNT <= $ATTEMPTS ; COUNT++ )) + do + echo "##### (attempt #$COUNT)" &>> "$STDOUTERR" + if timeout --foreground $TIMEOUT "$@" &>> "$STDOUTERR" + then + echo "##### (success after #$COUNT attempts)" &>> "$STDOUTERR" + break + else + echo "##### (failed with exit: $?)" &>> "$STDOUTERR" + sleep $DELAY + fi + done + cat "$STDOUTERR" + rm -f "$STDOUTERR" + if (( COUNT > $ATTEMPTS )) + then + echo "##### (exceeded $ATTEMPTS attempts)" + exit 125 + fi +} + ircmsg() { req_env_var CIRRUS_TASK_ID IRCID [[ -n "$*" ]] || die 9 "ircmsg() invoked without message text argument" @@ -159,7 +225,7 @@ ircmsg() { } setup_rootless() { - req_env_var ROOTLESS_USER GOSRC + req_env_var ROOTLESS_USER GOSRC SECRET_ENV_RE ROOTLESS_ENV_RE # Only do this once if passwd --status $ROOTLESS_USER @@ -208,13 +274,32 @@ setup_rootless() { # Works with older versions of bash printf "${_env_var_name}=%q\n" "$(printenv $_env_var_name)" >> "/home/$ROOTLESS_USER/.bashrc" done + + echo "Ensure the systems ssh process is up and running within 5 minutes" + systemctl start sshd + NOW=$(date +%s) + TIMEOUT=$(date --date '+5 minutes' +%s) + while [[ "$(date +%s)" -lt "$TIMEOUT" ]] + do + if timeout --foreground -k 1s 1s \ + ssh $ROOTLESS_USER@localhost \ + -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no \ + true + then + break + else + sleep 2s + fi + done + [[ "$(date +%s)" -lt "$TIMEOUT" ]] || \ + die 11 "Timeout exceeded waiting for localhost ssh capability" } # Helper/wrapper script to only show stderr/stdout on non-zero exit install_ooe() { req_env_var SCRIPT_BASE echo "Installing script to mask stdout/stderr unless non-zero exit." - sudo install -D -m 755 "/tmp/libpod/$SCRIPT_BASE/ooe.sh" /usr/local/bin/ooe.sh + sudo install -D -m 755 "$GOSRC/$SCRIPT_BASE/ooe.sh" /usr/local/bin/ooe.sh } # Grab a newer version of git from software collections @@ -231,110 +316,58 @@ EOF sudo chmod 755 /usr/bin/git } -install_cni_plugins() { - echo "Installing CNI Plugins from commit $CNI_COMMIT" - req_env_var GOPATH CNI_COMMIT - DEST="$GOPATH/src/github.com/containernetworking/plugins" - rm -rf "$DEST" - ooe.sh git clone "https://github.com/containernetworking/plugins.git" "$DEST" - cd "$DEST" - ooe.sh git checkout -q "$CNI_COMMIT" - ooe.sh ./build.sh - sudo mkdir -p /usr/libexec/cni - sudo cp bin/* /usr/libexec/cni +install_test_configs(){ + echo "Installing cni config, policy and registry config" + req_env_var GOSRC + sudo install -D -m 755 $GOSRC/cni/87-podman-bridge.conflist \ + /etc/cni/net.d/87-podman-bridge.conflist + sudo install -D -m 755 $GOSRC/test/policy.json \ + /etc/containers/policy.json + sudo install -D -m 755 $GOSRC/test/registries.conf \ + /etc/containers/registries.conf } -install_runc_from_git(){ - req_env_var GOPATH OS_RELEASE_ID RUNC_COMMIT - wd=$(pwd) - DEST="$GOPATH/src/github.com/opencontainers/runc" - rm -rf "$DEST" - ooe.sh git clone https://github.com/opencontainers/runc.git "$DEST" - cd "$DEST" - ooe.sh git fetch origin --tags - ooe.sh git checkout -q "$RUNC_COMMIT" - if [[ "${OS_RELEASE_ID}" == "ubuntu" ]] +# Remove all files (except conmon, for now) provided by the distro version of podman. +# Except conmon, for now as it's expected to eventually be packaged separately. +# All VM cache-images used for testing include the distro podman because (1) it's +# required for podman-in-podman testing and (2) it somewhat simplifies the task +# of pulling in necessary prerequisites packages as the set can change over time. +# For general CI testing however, calling this function makes sure the system +# can only run the compiled source version. +remove_packaged_podman_files(){ + echo "Removing packaged podman files to prevent conflicts with source build and testing." + req_env_var OS_RELEASE_ID + if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]] then - ooe.sh make static BUILDTAGS="seccomp apparmor" + LISTING_CMD="sudo -E dpkg-query -L podman" else - ooe.sh make BUILDTAGS="seccomp selinux" + LISTING_CMD='sudo rpm -ql podman' fi - sudo install -m 755 runc /usr/bin/runc - cd $wd -} -install_runc(){ - echo "Installing RunC from commit $RUNC_COMMIT" - echo "Platform is $OS_RELEASE_ID" - req_env_var GOPATH RUNC_COMMIT OS_RELEASE_ID - if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]]; then - echo "Running make install.libseccomp.sudo for ubuntu" - if ! [[ -d "/tmp/libpod" ]] - then - echo "Expecting a copy of libpod repository in /tmp/libpod" - exit 5 - fi - mkdir -p "$GOPATH/src/github.com/containers/" - # Symlinks don't work with Go - cp -a /tmp/libpod "$GOPATH/src/github.com/containers/" - cd "$GOPATH/src/github.com/containers/libpod" - ooe.sh sudo make install.libseccomp.sudo - fi - install_runc_from_git -} - -install_buildah() { - echo "Installing buildah from latest upstream master" - req_env_var GOPATH - DEST="$GOPATH/src/github.com/containers/buildah" - rm -rf "$DEST" - ooe.sh git clone https://github.com/containers/buildah "$DEST" - cd "$DEST" - ooe.sh make - ooe.sh sudo make install -} - -# Requires $GOPATH and $CONMON_COMMIT to be set -install_conmon(){ - echo "Installing conmon from commit $CONMON_COMMIT" - req_env_var GOPATH CONMON_COMMIT - DEST="$GOPATH/src/github.com/containers/conmon.git" - rm -rf "$DEST" - ooe.sh git clone https://github.com/containers/conmon.git "$DEST" - cd "$DEST" - ooe.sh git fetch origin --tags - ooe.sh git checkout -q "$CONMON_COMMIT" - ooe.sh make - sudo install -D -m 755 bin/conmon /usr/libexec/podman/conmon -} - -install_criu(){ - echo "Installing CRIU" - echo "Installing CRIU from commit $CRIU_COMMIT" - echo "Platform is $OS_RELEASE_ID" - req_env_var CRIU_COMMIT - - if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]]; then - ooe.sh sudo -E add-apt-repository -y ppa:criu/ppa - ooe.sh sudo -E apt-get -qq -y update - ooe.sh sudo -E apt-get -qq -y install criu - elif [[ "$OS_RELEASE_ID" =~ "fedora" ]]; then - echo "Using CRIU from distribution" - else - DEST="/tmp/criu" - rm -rf "$DEST" - ooe.sh git clone https://github.com/checkpoint-restore/criu.git "$DEST" - cd $DEST - ooe.sh git fetch origin --tags - ooe.sh git checkout -q "$CRIU_COMMIT" - ooe.sh make - sudo install -D -m 755 criu/criu /usr/sbin/ - fi + # yum/dnf/dpkg may list system directories, only remove files + $LISTING_CMD | while read fullpath + do + # TODO: This can go away when conmon gets it's own package + if [[ -d "$fullpath" ]] || [[ $(basename "$fullpath") == "conmon" ]] ; then continue; fi + ooe.sh sudo rm -vf "$fullpath" + done } -install_varlink() { - echo "Installing varlink from the cheese-factory" - ooe.sh sudo -H pip3 install varlink +systemd_banish(){ + echo "Disabling periodic services that could destabilize testing:" + set +e # Not all of these exist on every platform + for unit in $EVIL_UNITS + do + echo "Banishing $unit (ignoring errors)" + ( + sudo systemctl stop $unit + sudo systemctl disable $unit + sudo systemctl disable $unit.timer + sudo systemctl mask $unit + sudo systemctl mask $unit.timer + ) &> /dev/null + done + set -e } _finalize(){ @@ -342,12 +375,12 @@ _finalize(){ set +e # make errors non-fatal echo "Removing leftover giblets from cloud-init" cd / - sudo rm -rf /var/lib/cloud/instance? + sudo rm -rf /var/lib/cloud/instanc* sudo rm -rf /root/.ssh/* sudo rm -rf /home/* sudo rm -rf /tmp/* sudo rm -rf /tmp/.??* - sync + sudo sync sudo fstrim -av } @@ -370,6 +403,7 @@ rh_finalize(){ ubuntu_finalize(){ set +e # Don't fail at the very end echo "Resetting to fresh-state for usage as cloud-image." + $LILTO $SUDOAPTGET autoremove sudo rm -rf /var/cache/apt _finalize } |