mesa/.gitlab-ci/crosvm-runner.sh

114 lines
3.9 KiB
Bash
Raw Normal View History

#!/bin/sh
set -e
#
# Helper to generate CIDs for virtio-vsock based communication with processes
# running inside crosvm guests.
#
# A CID is a 32-bit Context Identifier to be assigned to a crosvm instance
# and must be unique across the host system. For this purpose, let's take
# the least significant 26 bits from CI_JOB_ID as a base and generate a 6-bit
# prefix number to handle up to 64 concurrent crosvm instances per job runner.
#
# As a result, the following variables are set:
# - VSOCK_CID: the crosvm unique CID to be passed as a run argument
#
# - VSOCK_STDOUT, VSOCK_STDERR: the port numbers the guest should accept
# vsock connections on in order to transfer output messages
#
# - VSOCK_TEMP_DIR: the temporary directory path used to pass additional
# context data towards the guest
#
set_vsock_context() {
[ -n "${CI_JOB_ID}" ] || {
echo "Missing or unset CI_JOB_ID env variable" >&2
exit 1
}
local dir_prefix="/tmp-vsock."
local cid_prefix=0
unset VSOCK_TEMP_DIR
while [ ${cid_prefix} -lt 64 ]; do
VSOCK_TEMP_DIR=${dir_prefix}${cid_prefix}
mkdir "${VSOCK_TEMP_DIR}" >/dev/null 2>&1 && break || unset VSOCK_TEMP_DIR
cid_prefix=$((cid_prefix + 1))
done
[ -n "${VSOCK_TEMP_DIR}" ] || return 1
VSOCK_CID=$(((CI_JOB_ID & 0x3ffffff) | ((cid_prefix & 0x3f) << 26)))
VSOCK_STDOUT=5001
VSOCK_STDERR=5002
return 0
}
# The dEQP binary needs to run from the directory it's in
if [ -n "${1##*.sh}" ] && [ -z "${1##*"deqp"*}" ]; then
DEQP_BIN_DIR=$(dirname "$1")
export DEQP_BIN_DIR
fi
set_vsock_context || { echo "Could not generate crosvm vsock CID" >&2; exit 1; }
# Ensure cleanup on script exit
trap 'exit ${exit_code}' INT TERM
trap 'exit_code=$?; [ -z "${SOCAT_PIDS}" ] || kill ${SOCAT_PIDS} >/dev/null 2>&1 || true; rm -rf ${VSOCK_TEMP_DIR}' EXIT
virgl/ci: make crosvm-runner pass variables in a secure way crosvm-runner.sh was using `export -p` to create an environment script for the virtualized system, but this command will dump every declared environment variable in the system, which includes Gitlab's CI variables with sensitive data, such as passwords and auth tokens. Replacing `export -p` to `generate-env.sh`, which only exports the necessary variables for Mesa CI jobs. Extra changes: * Stop changing ${PWD} variable programmatically in scripts. ${PWD} is a variable used by most prolific coreutils and bash commands, such as `cd` and `pwd`, besides it is set by subshells [1]; changing this variable may lead to complex situations. As drop-in replacement for ${PWD}, use ${DEQP_BIN_DIR} to flag that there is a special folder where dEQP should be run. * Double quote path and array variables. See: https://github.com/koalaman/shellcheck/wiki/SC2086 * Do not export variables directly from commands output. See: https://github.com/koalaman/shellcheck/wiki/SC2155 [1] ``` $ cd /tmp $ export PWD=test; bash -c 'echo $PWD' /tmp ``` v2: - Revert $DEQP_BIN_DIR quoting in crosvm-runner.sh and crosvm-init.sh - Log all the passed variables to stdout, to help with debugging when new variable are needed to be put in `generate-env.sh` v3: - Revert $DEQP_BIN_DIR quoting leftovers Signed-off-by: Guilherme Gallo <guilherme.gallo@collabora.com> Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14626>
2022-01-14 21:43:08 +00:00
# Securely pass the current variables to the crosvm environment
CI_COMMON="${CI_PROJECT_DIR}"/install/common
virgl/ci: make crosvm-runner pass variables in a secure way crosvm-runner.sh was using `export -p` to create an environment script for the virtualized system, but this command will dump every declared environment variable in the system, which includes Gitlab's CI variables with sensitive data, such as passwords and auth tokens. Replacing `export -p` to `generate-env.sh`, which only exports the necessary variables for Mesa CI jobs. Extra changes: * Stop changing ${PWD} variable programmatically in scripts. ${PWD} is a variable used by most prolific coreutils and bash commands, such as `cd` and `pwd`, besides it is set by subshells [1]; changing this variable may lead to complex situations. As drop-in replacement for ${PWD}, use ${DEQP_BIN_DIR} to flag that there is a special folder where dEQP should be run. * Double quote path and array variables. See: https://github.com/koalaman/shellcheck/wiki/SC2086 * Do not export variables directly from commands output. See: https://github.com/koalaman/shellcheck/wiki/SC2155 [1] ``` $ cd /tmp $ export PWD=test; bash -c 'echo $PWD' /tmp ``` v2: - Revert $DEQP_BIN_DIR quoting in crosvm-runner.sh and crosvm-init.sh - Log all the passed variables to stdout, to help with debugging when new variable are needed to be put in `generate-env.sh` v3: - Revert $DEQP_BIN_DIR quoting leftovers Signed-off-by: Guilherme Gallo <guilherme.gallo@collabora.com> Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14626>
2022-01-14 21:43:08 +00:00
echo "Variables passed through:"
"${CI_COMMON}"/generate-env.sh | tee ${VSOCK_TEMP_DIR}/crosvm-env.sh
# Set the crosvm-script as the arguments of the current script
echo "$@" > ${VSOCK_TEMP_DIR}/crosvm-script.sh
# Start background processes to receive output from guest
socat -u vsock-connect:${VSOCK_CID}:${VSOCK_STDERR},retry=200,interval=0.1 stderr &
SOCAT_PIDS=$!
socat -u vsock-connect:${VSOCK_CID}:${VSOCK_STDOUT},retry=200,interval=0.1 stdout &
SOCAT_PIDS="${SOCAT_PIDS} $!"
# Setup networking
/usr/sbin/iptables-legacy -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
# Prepare to start crosvm
unset DISPLAY
unset XDG_RUNTIME_DIR
CROSVM_KERN_ARGS="quiet console=null root=my_root rw rootfstype=virtiofs ip=192.168.30.2::192.168.30.1:255.255.255.0:crosvm:eth0"
CROSVM_KERN_ARGS="${CROSVM_KERN_ARGS} init=${CI_PROJECT_DIR}/install/crosvm-init.sh -- ${VSOCK_STDOUT} ${VSOCK_STDERR} ${VSOCK_TEMP_DIR}"
set +e -x
# We aren't testing LLVMPipe here, so we don't need to validate NIR on the host
NIR_DEBUG="novalidate" LIBGL_ALWAYS_SOFTWARE="true" GALLIUM_DRIVER=${CROSVM_GALLIUM_DRIVER} \
crosvm run \
--gpu "${CROSVM_GPU_ARGS}" -m 4096 -c 2 --disable-sandbox \
--shared-dir /:my_root:type=fs:writeback=true:timeout=60:cache=always \
--host_ip "192.168.30.1" --netmask "255.255.255.0" --mac "AA:BB:CC:00:00:12" \
--cid ${VSOCK_CID} -p "${CROSVM_KERN_ARGS}" \
/lava-files/bzImage > ${VSOCK_TEMP_DIR}/crosvm 2>&1
CROSVM_RET=$?
[ ${CROSVM_RET} -eq 0 ] && {
# socat bg processes should terminate as soon as the remote peers exit
wait
# The actual return code is the crosvm guest script's exit code
CROSVM_RET=$(cat ${VSOCK_TEMP_DIR}/exit_code 2>/dev/null)
# Force error when the guest script's exit code is not available
CROSVM_RET=${CROSVM_RET:-1}
}
# Show crosvm output on error to help with debugging
[ ${CROSVM_RET} -eq 0 ] || {
set +x
echo "Dumping crosvm output.." >&2
cat ${VSOCK_TEMP_DIR}/crosvm >&2
set -x
}
exit ${CROSVM_RET}