diff --git a/.buildkite/steps/common.sh b/.buildkite/steps/common.sh index 6ee3499c8..7f60f2f8d 100644 --- a/.buildkite/steps/common.sh +++ b/.buildkite/steps/common.sh @@ -17,19 +17,35 @@ if [ "$(uname -s)" = "Linux" ]; then ca-certificates curl pkg-config libdbus-1-dev build-essential fi +# The Linux job runs as root, and test.sh re-execs the suite as an +# unprivileged user (root ignores permission bits, which silently defeats every +# read-only assertion). A toolchain under /root is unreadable after that swap -- +# build 1445 got `cargo: command not found` at uid 1000 -- so install it +# somewhere both users can reach. +if [ "$(id -u)" = "0" ] && [ "$(uname -s)" = "Linux" ]; then + export CARGO_HOME=/opt/cargo + export RUSTUP_HOME=/opt/rustup +else + export CARGO_HOME="${CARGO_HOME:-$HOME/.cargo}" + export RUSTUP_HOME="${RUSTUP_HOME:-$HOME/.rustup}" +fi +export PATH="$CARGO_HOME/bin:$PATH" + # rust-toolchain.toml pins `stable`; rustup honours it on first cargo call. if ! command -v cargo >/dev/null 2>&1; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ - | sh -s -- -y --profile minimal --default-toolchain stable + | sh -s -- -y --profile minimal --default-toolchain stable --no-modify-path fi # shellcheck disable=SC1091 -[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" - -# Export toolchain homes explicitly so the unprivileged re-exec in test.sh can -# inherit them; rustup's default HOME-relative paths do not survive a user swap. -export CARGO_HOME="${CARGO_HOME:-$HOME/.cargo}" -export RUSTUP_HOME="${RUSTUP_HOME:-$HOME/.rustup}" +[ -f "$CARGO_HOME/env" ] && . "$CARGO_HOME/env" export PATH="$CARGO_HOME/bin:$PATH" +# Readable+traversable by the unprivileged user; cargo still needs to write +# into CARGO_HOME for `cargo install`, so that stays root-owned until test.sh +# hands it over. +if [ "$(id -u)" = "0" ] && [ "$(uname -s)" = "Linux" ]; then + chmod -R a+rX "$CARGO_HOME" "$RUSTUP_HOME" 2>/dev/null || true +fi + cargo --version rustc --version diff --git a/.buildkite/steps/test.sh b/.buildkite/steps/test.sh index f00bf1176..8a15c2952 100755 --- a/.buildkite/steps/test.sh +++ b/.buildkite/steps/test.sh @@ -31,9 +31,12 @@ run_suite() { if [ "$(id -u)" = "0" ] && [ "$(uname -s)" = "Linux" ]; then id -u builder >/dev/null 2>&1 || useradd -m -s /bin/bash builder + # cargo writes into CARGO_HOME (registry, git checkouts) and ./target, so + # both must belong to the user that will actually run the suite. chown -R builder:builder . "$CARGO_HOME" "$RUSTUP_HOME" 2>/dev/null || true echo "--- re-exec as unprivileged user (root ignores permission bits)" exec runuser -u builder -- env \ + HOME=/home/builder \ PATH="$PATH" CARGO_HOME="$CARGO_HOME" RUSTUP_HOME="$RUSTUP_HOME" \ CARGO_TERM_COLOR="${CARGO_TERM_COLOR:-always}" \ CARGO_INCREMENTAL="${CARGO_INCREMENTAL:-0}" \