Files
podman/contrib/cirrus/runner.sh
Paul Holzinger 04dffbc2c7 cirrus: change alt arch task to only compile binaries
The current podman-release-%.tar.gz target does a lot more then just
checking if we can build for the given arch, in particular it first
builds a local podman-remote for the remote-docs.sh script. This makes
things slow as we compile several things and then builda and package the
docs. Given the docs are not arch specific there is realy no point in
doing all that work. All we care about is if the bianries can build on
other arches to catch compile issue for otherwise untested arches.

This should make the CI Alt Arch. tasks much faster.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2024-10-11 11:25:33 +02:00

515 lines
17 KiB
Bash
Executable File

#!/bin/bash
set -eo pipefail
# This script runs in the Cirrus CI environment, invoked from .cirrus.yml .
# It can also be invoked manually in a `hack/get_ci_cm.sh` environment,
# documentation of said usage is TBI.
#
# The principal deciding factor is the $TEST_FLAVOR envariable: for any
# given value 'xyz' there must be a function '_run_xyz' to handle that
# test. Several other envariables are used to differentiate further,
# most notably:
#
# PODBIN_NAME : "podman" (i.e. local) or "remote"
# TEST_ENVIRON : 'host', or 'container'; desired environment in which to run
# CONTAINER : 1 if *currently* running inside a container, 0 if host
#
# shellcheck source=contrib/cirrus/lib.sh
source $(dirname $0)/lib.sh
showrun echo "starting"
function _run_validate-source() {
# This target is only meant to be run on PRs.
# We need the following env vars set for the git diff check below.
req_env_vars CIRRUS_CHANGE_IN_REPO PR_BASE_SHA
showrun make validate-source
# make sure PRs have tests
showrun make tests-included
# make sure PRs have jira links (if needed for branch)
showrun make test-jira-links-included
# shellcheck disable=SC2154
head=$CIRRUS_CHANGE_IN_REPO
# shellcheck disable=SC2154
base=$PR_BASE_SHA
echo "_run_validate-source: head=$head base=$base"
diffs=$(git diff --name-only $base $head)
# If PR touches renovate config validate it, as the image is very big only do so when needed
if grep -E -q "^.github/renovate.json5" <<<"$diffs"; then
msg "Checking renovate config."
showrun podman run \
-v ./.github/renovate.json5:/usr/src/app/renovate.json5:z \
ghcr.io/renovatebot/renovate:latest \
renovate-config-validator
fi
}
function _run_unit() {
# shellcheck disable=SC2154
if [[ "$PODBIN_NAME" != "podman" ]]; then
# shellcheck disable=SC2154
die "$TEST_FLAVOR: Unsupported PODBIN_NAME='$PODBIN_NAME'"
fi
showrun make localunit
}
function _run_apiv2() {
(
showrun make localapiv2-bash
source .venv/requests/bin/activate
showrun make localapiv2-python
) |& logformatter
}
function _run_compose_v2() {
showrun ./test/compose/test-compose |& logformatter
}
function _run_int() {
dotest integration
}
function _run_sys() {
dotest system
}
function _run_upgrade_test() {
showrun bats test/upgrade |& logformatter
}
function _run_bud() {
showrun ./test/buildah-bud/run-buildah-bud-tests |& logformatter
}
function _run_bindings() {
# install ginkgo
showrun make .install.ginkgo
# if logformatter sees this, it can link directly to failing source lines
local gitcommit_magic=
if [[ -n "$GIT_COMMIT" ]]; then
gitcommit_magic="/define.gitCommit=${GIT_COMMIT}"
fi
(echo "$gitcommit_magic" && \
showrun make testbindings) |& logformatter
}
function _run_docker-py() {
source .venv/docker-py/bin/activate
showrun make run-docker-py-tests
}
function _run_endpoint() {
showrun make test-binaries
showrun make endpoint
}
function _run_farm() {
msg "Testing podman farm."
showrun bats test/farm |& logformatter
}
exec_container() {
local var_val
local cmd
# Required to be defined by caller
# shellcheck disable=SC2154
msg "Re-executing runner inside container: $CTR_FQIN"
msg "************************************************************"
req_env_vars CTR_FQIN TEST_ENVIRON CONTAINER SECRET_ENV_RE
# Line-separated arguments which include shell-escaped special characters
declare -a envargs
while read -r var; do
# Pass "-e VAR" on the command line, not "-e VAR=value". Podman can
# do a much better job of transmitting the value than we can,
# especially when value includes spaces.
envargs+=("-e" "$var")
done <<<"$(passthrough_envars)"
# VM Images and Container images are built using (nearly) identical operations.
set -x
env CONTAINERS_REGISTRIES_CONF=/dev/null bin/podman pull -q $CTR_FQIN
# shellcheck disable=SC2154
exec bin/podman run --rm --privileged --net=host --cgroupns=host \
-v `mktemp -d -p /var/tmp`:/var/tmp:Z \
--tmpfs /tmp:mode=1777 \
-v /dev/fuse:/dev/fuse \
-v "$GOPATH:$GOPATH:Z" \
--workdir "$GOSRC" \
-e "CONTAINER=1" \
"${envargs[@]}" \
$CTR_FQIN bash -c "$SCRIPT_BASE/setup_environment.sh && $SCRIPT_BASE/runner.sh"
}
function _run_swagger() {
local upload_filename
local upload_bucket
local download_url
local envvarsfile
req_env_vars GCPJSON GCPNAME GCPPROJECT CTR_FQIN
# The filename and bucket depend on the automation context
#shellcheck disable=SC2154,SC2153
if [[ -n "$CIRRUS_PR" ]]; then
upload_bucket="libpod-pr-releases"
upload_filename="swagger-pr$CIRRUS_PR.yaml"
elif [[ -n "$CIRRUS_TAG" ]]; then
upload_bucket="libpod-master-releases"
upload_filename="swagger-$CIRRUS_TAG.yaml"
elif [[ "$CIRRUS_BRANCH" == "main" ]]; then
upload_bucket="libpod-master-releases"
# readthedocs versioning uses "latest" for "main" (default) branch
upload_filename="swagger-latest.yaml"
elif [[ -n "$CIRRUS_BRANCH" ]]; then
upload_bucket="libpod-master-releases"
upload_filename="swagger-$CIRRUS_BRANCH.yaml"
else
die "Unknown execution context, expected a non-empty value for \$CIRRUS_TAG, \$CIRRUS_BRANCH, or \$CIRRUS_PR"
fi
# Swagger validation takes a significant amount of time
msg "Pulling \$CTR_FQIN '$CTR_FQIN' (background process)"
showrun bin/podman pull --quiet $CTR_FQIN &
cd $GOSRC
showrun make swagger
# Cirrus-CI Artifact instruction expects file here
cp -v $GOSRC/pkg/api/swagger.yaml ./
envvarsfile=$(mktemp -p '' .tmp_$(basename $0)_XXXXXXXX)
trap "rm -f $envvarsfile" EXIT # contains secrets
# Warning: These values must _not_ be quoted, podman will not remove them.
#shellcheck disable=SC2154
cat <<eof >>$envvarsfile
GCPJSON=$GCPJSON
GCPNAME=$GCPNAME
GCPPROJECT=$GCPPROJECT
FROM_FILEPATH=$GOSRC/swagger.yaml
TO_GCSURI=gs://$upload_bucket/$upload_filename
eof
msg "Waiting for backgrounded podman pull to complete..."
wait %%
showrun bin/podman run -it --rm --security-opt label=disable \
--env-file=$envvarsfile \
-v $GOSRC:$GOSRC:ro \
--workdir $GOSRC \
$CTR_FQIN
rm -f $envvarsfile
}
function _run_build() {
# Ensure always start from clean-slate with all vendor modules downloaded
showrun make clean
showrun make vendor
showrun make -j $(nproc) --output-sync=target podman-release # includes podman, podman-remote, and docs
# There's no reason to validate-binaries across multiple linux platforms
# shellcheck disable=SC2154
if [[ "$DISTRO_NV" =~ $FEDORA_NAME ]]; then
showrun make -j $(nproc) --output-sync=target validate-binaries
fi
# Last-minute confirmation that we're testing the desired runtime.
# This Can't Possibly Fail™ in regular CI; only when updating VMs.
# $CI_DESIRED_RUNTIME must be defined in .cirrus.yml.
req_env_vars CI_DESIRED_RUNTIME
runtime=$(bin/podman info --format '{{.Host.OCIRuntime.Name}}')
# shellcheck disable=SC2154
if [[ "$runtime" != "$CI_DESIRED_RUNTIME" ]]; then
die "Built podman is using '$runtime'; this CI environment requires $CI_DESIRED_RUNTIME"
fi
msg "Built podman is using expected runtime='$runtime'"
}
function _run_altbuild() {
local -a arches
local arch
req_env_vars ALT_NAME
# Var. defined in .cirrus.yml
# shellcheck disable=SC2154
msg "Performing alternate build: $ALT_NAME"
msg "************************************************************"
set -x
cd $GOSRC
case "$ALT_NAME" in
*Each*)
if [[ -z "$CIRRUS_PR" ]]; then
echo ".....only meaningful on PRs"
return
fi
showrun git fetch origin
# The make-and-check-size script, introduced 2022-03-22 in #13518,
# runs 'make' (the original purpose of this check) against
# each commit, then checks image sizes to make sure that
# none have grown beyond a given limit. That of course
# requires a baseline, so our first step is to build the
# branch point of the PR.
local context_dir savedhead pr_base
context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX)
savedhead=$(git rev-parse HEAD)
# Push to PR base. First run of the script will write size files
# shellcheck disable=SC2154
pr_base=$PR_BASE_SHA
showrun git checkout $pr_base
showrun hack/make-and-check-size $context_dir
# pop back to PR, and run incremental makes. Subsequent script
# invocations will compare against original size.
showrun git checkout $savedhead
showrun git rebase $pr_base -x "hack/make-and-check-size $context_dir"
rm -rf $context_dir
;;
*Windows*)
showrun make .install.pre-commit
showrun make lint GOOS=windows CGO_ENABLED=0
showrun make podman-remote-release-windows_amd64.zip
;;
*RPM*)
showrun make package
;;
Alt*x86*Cross)
_build_altbuild_archs "386"
;;
Alt*ARM*Cross)
_build_altbuild_archs "arm"
;;
Alt*Other*Cross)
arches=(\
ppc64le
s390x)
_build_altbuild_archs "${arches[@]}"
;;
Alt*MIPS*Cross)
arches=(\
mips
mipsle)
_build_altbuild_archs "${arches[@]}"
;;
Alt*MIPS64*Cross*)
arches=(\
mips64
mips64le)
_build_altbuild_archs "${arches[@]}"
;;
*)
die "Unknown/Unsupported \$$ALT_NAME '$ALT_NAME'"
esac
}
function _build_altbuild_archs() {
for arch in "$@"; do
msg "Building release archive for $arch"
showrun make cross-binaries GOARCH=$arch
done
}
function _run_release() {
msg "podman info:"
bin/podman info
msg "Checking podman release (or potential release) criteria."
# We're running under 'set -eo pipefail'; make sure this statement passes
dev=$(bin/podman info |& grep -- -dev || echo -n '')
if [[ -n "$dev" ]]; then
die "Releases must never contain '-dev' in output of 'podman info' ($dev)"
fi
commit=$(bin/podman info --format='{{.Version.GitCommit}}' | tr -d '[:space:]')
if [[ -z "$commit" ]]; then
die "Releases must contain a non-empty Version.GitCommit in 'podman info'"
fi
msg "All OK"
}
# ***WARNING*** ***WARNING*** ***WARNING*** ***WARNING***
# Please see gitlab comment in setup_environment.sh
# ***WARNING*** ***WARNING*** ***WARNING*** ***WARNING***
function _run_gitlab() {
rootless_uid=$(id -u)
systemctl enable --now --user podman.socket
export DOCKER_HOST=unix:///run/user/${rootless_uid}/podman/podman.sock
export CONTAINER_HOST=$DOCKER_HOST
cd $GOPATH/src/gitlab.com/gitlab-org/gitlab-runner
set +e
go test -v ./executors/docker |& tee $GOSRC/gitlab-runner-podman.log
ret=$?
set -e
# This file is collected and parsed by Cirrus-CI so must be in $GOSRC
cat $GOSRC/gitlab-runner-podman.log | \
go-junit-report > $GOSRC/gitlab-runner-podman.xml
return $ret
}
# Name pattern for logformatter output file, derived from environment
function output_name() {
# .cirrus.yml defines this as a short readable string for web UI
std_name_fmt=$(sed -ne 's/^.*std_name_fmt \"\(.*\)\"/\1/p' <.cirrus.yml)
test -n "$std_name_fmt" || die "Could not grep 'std_name_fmt' from .cirrus.yml"
# Interpolate envariables. 'set -u' throws fatal if any are undefined
(
set -u
eval echo "$std_name_fmt" | tr ' ' '-'
)
}
function logformatter() {
if [[ "$CI" == "true" ]]; then
# Requires stdin and stderr combined!
cat - \
|& awk --file "${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk" \
|& "${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/logformatter" "$(output_name)"
else
# Assume script is run by a human, they want output immediately
cat -
fi
}
# Handle local|remote integration|system testing in a uniform way
dotest() {
local testsuite="$1"
req_env_vars testsuite CONTAINER TEST_ENVIRON PRIV_NAME
# shellcheck disable=SC2154
if ((CONTAINER==0)) && [[ "$TEST_ENVIRON" == "container" ]]; then
exec_container # does not return
fi;
# containers/automation sets this to 0 for its dbg() function
# but the e2e integration tests are also sensitive to it.
unset DEBUG
# shellcheck disable=SC2154
local localremote="$PODBIN_NAME"
case "$PODBIN_NAME" in
podman) localremote="local" ;;
esac
# We've had some oopsies where tests invoke 'podman' instead of
# /path/to/built/podman. Let's catch those.
sudo rm -f /usr/bin/podman /usr/bin/podman-remote
fallback_podman=$(type -p podman || true)
if [[ -n "$fallback_podman" ]]; then
die "Found fallback podman '$fallback_podman' in \$PATH; tests require none, as a guarantee that we're testing the right binary."
fi
# Catch invalid "TMPDIR == /tmp" assumptions; PR #19281
TMPDIR=$(mktemp --tmpdir -d CI_XXXX)
# tmp dir is commonly 1777 to allow all user to read/write
chmod 1777 $TMPDIR
export TMPDIR
fstype=$(findmnt -n -o FSTYPE --target $TMPDIR)
if [[ "$fstype" != "tmpfs" ]]; then
die "The CI test TMPDIR is not on a tmpfs mount, we need tmpfs to make the tests faster"
fi
showrun make ${localremote}${testsuite} PODMAN_SERVER_LOG=$PODMAN_SERVER_LOG \
|& logformatter
# FIXME: https://github.com/containers/podman/issues/22642
# Cannot delete this due cleanup errors, as the VM is basically
# done after this anyway let's not block on this for now.
# rm -rf $TMPDIR
# unset TMPDIR
}
_run_machine-linux() {
showrun make localmachine |& logformatter
}
# Nearly every task in .cirrus.yml makes use of this shell script
# wrapped by /usr/bin/time to collect runtime statistics. Because the
# --output option is used to log stats to a file, every child-process
# inherits an open FD3 pointing at the log. However, some testing
# operations depend on making use of FD3, and so it must be explicitly
# closed here (and for all further child-processes).
# STATS_LOGFILE assumed empty/undefined outside of Cirrus-CI (.cirrus.yml)
# shellcheck disable=SC2154
exec 3<&-
msg "************************************************************"
# Required to be defined by caller
# shellcheck disable=SC2154
msg "Runner executing $TEST_FLAVOR $PODBIN_NAME-tests as $PRIV_NAME on $DISTRO_NV($OS_REL_VER)"
if ((CONTAINER)); then
# shellcheck disable=SC2154
msg "Current environment container image: $CTR_FQIN"
else
# shellcheck disable=SC2154
msg "Current environment VM image: $VM_IMAGE_NAME"
fi
msg "************************************************************"
((${SETUP_ENVIRONMENT:-0})) || \
die "Expecting setup_environment.sh to have completed successfully"
if [[ "$UID" -eq 0 ]] && ((CONTAINER==0)); then
# start ebpf cleanup tracer (#23487)
msg "start ebpf cleanup tracer"
# replace zero bytes to make the log more readable
bpftrace $GOSRC/hack/podman_cleanup_tracer.bt |& \
tr '\0' ' ' >$GOSRC/podman-cleanup-tracer.log &
TRACER_PID=$!
fi
# shellcheck disable=SC2154
if [[ "$PRIV_NAME" == "rootless" ]] && [[ "$UID" -eq 0 ]]; then
# Remove /var/lib/cni, it is not required for rootless cni.
# We have to test that it works without this directory.
# https://github.com/containers/podman/issues/10857
rm -rf /var/lib/cni
# This must be done at the last second, otherwise `make` calls
# in setup_environment (as root) will balk about ownership.
msg "Recursively chowning \$GOPATH and \$GOSRC to $ROOTLESS_USER"
if [[ $PRIV_NAME = "rootless" ]]; then
chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
fi
req_env_vars ROOTLESS_USER
msg "Re-executing runner through ssh as user '$ROOTLESS_USER'"
msg "************************************************************"
set -x
exec ssh $ROOTLESS_USER@localhost \
-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
-o CheckHostIP=no $GOSRC/$SCRIPT_BASE/runner.sh
# Does not return!
fi
# else: not running rootless, do nothing special
# Dump important package versions. Before 2022-11-16 this took place as
# a separate .cirrus.yml step, but it really belongs here.
$(dirname $0)/logcollector.sh packages
msg "************************************************************"
cd "${GOSRC}/"
handler="_run_${TEST_FLAVOR}"
if [ "$(type -t $handler)" != "function" ]; then
die "Unknown/Unsupported \$TEST_FLAVOR=$TEST_FLAVOR"
fi
showrun $handler
if [[ -n "$TRACER_PID" ]]; then
# ignore any error here
kill "$TRACER_PID" || true
fi
showrun echo "finished"