podman/contrib/cirrus/lib.sh
Chris Evich 5b7c64cc97
Cirrus: Fix obtaining a CI VM
Also removed automatic exection of setup_environment.sh since most
people using this script are podman developers (not automation/CI
folks).  If executing the automation scripts is necessary, manual
attendance to required variables like `$TEST_FLAVOR` is mandatory.

Signed-off-by: Chris Evich <cevich@redhat.com>
2020-10-07 15:29:43 -04:00

256 lines
10 KiB
Bash

# Library of common, shared utility functions. This file is intended
# to be sourced by other scripts, not called directly.
# BEGIN Global export of all variables
set -a
if [[ "$CI" == "true" ]]; then
# Due to differences across platforms and runtime execution environments,
# handling of the (otherwise) default shell setup is non-uniform. Rather
# than attempt to workaround differences, simply force-load/set required
# items every time this library is utilized.
source /etc/profile
source /etc/environment
USER="$(whoami)"
HOME="$(getent passwd $USER | cut -d : -f 6)"
# Some platforms set and make this read-only
[[ -n "$UID" ]] || \
UID=$(getent passwd $USER | cut -d : -f 3)
GID=$(getent passwd $USER | cut -d : -f 4)
fi
# During VM Image build, the 'containers/automation' installation
# was performed. The final step of that installation sets the
# installation location in $AUTOMATION_LIB_PATH in /etc/environment
# or in the default shell profile.
# shellcheck disable=SC2154
if [[ -n "$AUTOMATION_LIB_PATH" ]]; then
for libname in defaults anchors console_output utils; do
# There's no way shellcheck can process this location
# shellcheck disable=SC1090
source $AUTOMATION_LIB_PATH/${libname}.sh
done
else
(
echo "WARNING: It does not appear that containers/automation was installed."
echo " Functionality of most of this library will be negatively impacted"
echo " This ${BASH_SOURCE[0]} was loaded by ${BASH_SOURCE[1]}"
) > /dev/stderr
fi
OS_RELEASE_ID="$(source /etc/os-release; echo $ID)"
# GCE image-name compatible string representation of distribution _major_ version
OS_RELEASE_VER="$(source /etc/os-release; echo $VERSION_ID | cut -d '.' -f 1)"
# Combined to ease soe usage
OS_REL_VER="${OS_RELEASE_ID}-${OS_RELEASE_VER}"
# This is normally set from .cirrus.yml but default is necessary when
# running under hack/get_ci_vm.sh since it cannot infer the value.
DISTRO_NV="${DISTRO_NV:-$OS_REL_VER}"
# Essential default paths, many are overridden when executing under Cirrus-CI
GOPATH="${GOPATH:-/var/tmp/go}"
if type -P go &> /dev/null
then
# Cirrus-CI caches $GOPATH contents
export GOCACHE="${GOCACHE:-$GOPATH/cache/go-build}"
# called processes like `make` and other tools need these vars.
eval "export $(go env)"
# Ensure compiled tooling is reachable
PATH="$PATH:$GOPATH/bin:$HOME/.local/bin"
fi
CIRRUS_WORKING_DIR="${CIRRUS_WORKING_DIR:-$(realpath $(dirname ${BASH_SOURCE[0]})/../../)}"
GOSRC="${GOSRC:-$CIRRUS_WORKING_DIR}"
PATH="$HOME/bin:/usr/local/bin:$PATH"
LD_LIBRARY_PATH="/usr/local/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
# Saves typing / in case location ever moves
SCRIPT_BASE=${SCRIPT_BASE:-./contrib/cirrus}
# Downloaded, but not installed packages.
PACKAGE_DOWNLOAD_DIR=/var/cache/download
# Log remote-client system test varlink output here
PODMAN_SERVER_LOG=$CIRRUS_WORKING_DIR/varlink.log
# 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:-podman}
# N/B: CIRRUS_BASE_SHA is empty on branch and tag push.
CIRRUS_BASE_SHA=${CIRRUS_BASE_SHA:-${CIRRUS_LAST_GREEN_CHANGE:-YOU_FOUND_A_BUG}}
CIRRUS_BUILD_ID=${CIRRUS_BUILD_ID:-$RANDOM$(date +%s)} # must be short and unique
# The starting place for linting and code validation
EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA"
# Regex of env. vars. to explicitly pass when executing tests
# inside a container or as a rootless user
PASSTHROUGH_ENV_RE='(^CI.*)|(^CIRRUS)|(^DISTRO_NV)|(^GOPATH)|(^GOCACHE)|(^GOSRC)|(^SCRIPT_BASE)|(CGROUP_MANAGER)|(OCI_RUNTIME)|(^TEST.*)|(^PODBIN_NAME)|(^PRIV_NAME)|(^ALT_NAME)|(^ROOTLESS_USER)|(SKIP_USERNS)|(.*_NAME)|(.*_FQIN)'
# Unsafe env. vars for display
SECRET_ENV_RE='(ACCOUNT)|(GC[EP]..+)|(SSH)|(PASSWORD)|(TOKEN)'
# Type of filesystem used for cgroups
CG_FS_TYPE="$(stat -f -c %T /sys/fs/cgroup)"
# Set to 1 in all podman container images
CONTAINER="${CONTAINER:-0}"
# END Global export of all variables
set +a
lilto() { err_retry 8 1000 "" "$@"; } # just over 4 minutes max
bigto() { err_retry 7 5670 "" "$@"; } # 12 minutes max
# Print shell-escaped variable=value pairs, one per line, based on
# variable name matching a regex. This is intended to support
# passthrough of CI variables from host -> container or from root -> user.
# For all other vars. we rely on tooling to load this library from inside
# the container or as rootless user to pickup the remainder.
passthrough_envars(){
local xchars
local envname
local envval
# Avoid values containing entirely punctuation|control|whitespace
xchars='[:punct:][:cntrl:][:space:]'
warn "Will pass env. vars. matching the following regex:
$PASSTHROUGH_ENV_RE"
for envname in $(awk 'BEGIN{for(v in ENVIRON) print v}' | \
grep -Ev "SETUP_ENVIRONMENT" | \
grep -Ev "$SECRET_ENV_RE" | \
grep -E "$PASSTHROUGH_ENV_RE"); do
envval="${!envname}"
[[ -n $(tr -d "$xchars" <<<"$envval") ]] || continue
# Properly escape values to prevent injection
printf -- "$envname=%q\n" "$envval"
done
}
setup_rootless() {
req_env_vars ROOTLESS_USER GOPATH GOSRC SECRET_ENV_RE
local rootless_uid
local rootless_gid
local env_var_val
# Only do this once; established by setup_environment.sh
# shellcheck disable=SC2154
if passwd --status $ROOTLESS_USER
then
msg "Updating $ROOTLESS_USER user permissions on possibly changed libpod code"
chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
return 0
fi
msg "************************************************************"
msg "Setting up rootless user '$ROOTLESS_USER'"
msg "************************************************************"
cd $GOSRC || exit 1
# Guarantee independence from specific values
rootless_uid=$[RANDOM+1000]
rootless_gid=$[RANDOM+1000]
msg "creating $rootless_uid:$rootless_gid $ROOTLESS_USER user"
groupadd -g $rootless_gid $ROOTLESS_USER
useradd -g $rootless_gid -u $rootless_uid --no-user-group --create-home $ROOTLESS_USER
chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
msg "creating ssh key pair for $USER"
[[ -r "$HOME/.ssh/id_rsa" ]] || \
ssh-keygen -P "" -f "$HOME/.ssh/id_rsa"
msg "Allowing ssh key for $ROOTLESS_USER"
(umask 077 && mkdir "/home/$ROOTLESS_USER/.ssh")
chown -R $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.ssh"
install -o $ROOTLESS_USER -g $ROOTLESS_USER -m 0600 \
"$HOME/.ssh/id_rsa.pub" "/home/$ROOTLESS_USER/.ssh/authorized_keys"
# Makes debugging easier
cat /root/.ssh/authorized_keys >> "/home/$ROOTLESS_USER/.ssh/authorized_keys"
msg "Configuring subuid and subgid"
grep -q "${ROOTLESS_USER}" /etc/subuid || \
echo "${ROOTLESS_USER}:$[rootless_uid * 100]:65536" | \
tee -a /etc/subuid >> /etc/subgid
# Env. vars set by Cirrus and setup_environment.sh must be explicitly
# transferred to the test-user.
msg "Configuring rootless user's environment variables:"
(
echo "# Added by ${BASH_SOURCE[0]} ${FUNCNAME[0]}()"
echo "export SETUP_ENVIRONMENT=1"
) >> "/home/$ROOTLESS_USER/.bashrc"
while read -r env_var_val; do
echo "export $env_var_val" >> "/home/$ROOTLESS_USER/.bashrc"
done <<<"$(passthrough_envars)"
chown $ROOTLESS_USER:$ROOTLESS_USER "/home/$ROOTLESS_USER/.bashrc"
cat "/home/$ROOTLESS_USER/.bashrc" | indent 2
msg "Ensure the systems ssh process is up and running within 5 minutes"
systemctl start sshd
lilto ssh $ROOTLESS_USER@localhost \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-o CheckHostIP=no true
}
install_test_configs() {
echo "Installing cni config, policy and registry config"
req_env_vars GOSRC SCRIPT_BASE
cd $GOSRC || exit 1
install -v -D -m 644 ./cni/87-podman-bridge.conflist /etc/cni/net.d/
# This config must always sort last in the list of networks (podman picks first one
# as the default). This config prevents allocation of network address space used
# by default in google cloud. https://cloud.google.com/vpc/docs/vpc#ip-ranges
install -v -D -m 644 $SCRIPT_BASE/99-do-not-use-google-subnets.conflist /etc/cni/net.d/
install -v -D -m 644 ./test/registries.conf /etc/containers/
}
# Remove all files provided by the distro version of podman.
# 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_vars OS_RELEASE_ID
# If any binaries are resident they could cause unexpected pollution
for unit in io.podman.service io.podman.socket
do
for state in enabled active
do
if systemctl --quiet is-$state $unit
then
echo "Warning: $unit found $state prior to packaged-file removal"
systemctl --quiet disable $unit || true
systemctl --quiet stop $unit || true
fi
done
done
if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]]
then
LISTING_CMD="dpkg-query -L podman"
else
LISTING_CMD="rpm -ql podman"
fi
# yum/dnf/dpkg may list system directories, only remove files
$LISTING_CMD | while read fullpath
do
# Sub-directories may contain unrelated/valuable stuff
if [[ -d "$fullpath" ]]; then continue; fi
ooe.sh rm -vf "$fullpath"
done
# Be super extra sure and careful vs performant and completely safe
sync && echo 3 > /proc/sys/vm/drop_caches || true
}