diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c650df6a0ec2a..5f135cd1fdd2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,26 @@ jobs: uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be if: matrix.free_disk + - name: free up more disk space + if: matrix.free_disk + run: | + sudo apt purge -y --autoremove \ + '^java-*' \ + 'groff' \ + 'groff-base' \ + '^libllvm.*' \ + '^llvm.*' \ + 'gcc' \ + 'gcc-11' \ + 'libicu-dev' \ + '^vim.*' \ + 'python3-breezy' \ + && sudo rm -rf /var/lib/apt/lists/* + df -h / + + - name: Show installed packages ordered by size + run: dpkg-query -W --showformat='${Installed-Size} ${Package}\n' | sort -nr + # Rust Log Analyzer can't currently detect the PR number of a GitHub # Actions build on its own, so a hint in the log message is needed to # point it in the right direction. @@ -174,6 +194,8 @@ jobs: - name: enable ipv6 on Docker run: src/ci/scripts/enable-docker-ipv6.sh + # Don't run on codebuild because systemctl is not available + if: ${{ !contains(matrix.os, 'codebuild-ubuntu') }} # Disable automatic line ending conversion (again). On Windows, when we're # installing dependencies, something switches the git configuration directory or diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 76ee40c6f45fe..4cdd91acdc67c 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1002,10 +1002,14 @@ def build_bootstrap(self): env = os.environ.copy() if "GITHUB_ACTIONS" in env: print("::group::Building bootstrap") + print("Current home directory:", os.path.expanduser("~")) + print("Current working directory:", os.getcwd()) + print("Current HOME:", env["HOME"]) else: eprint("Building bootstrap") args = self.build_bootstrap_cmd(env) + print("Running", args, "in", self.rust_root) # Run this from the source directory so cargo finds .cargo/config run(args, env=env, verbose=self.verbose, cwd=self.rust_root) @@ -1015,6 +1019,7 @@ def build_bootstrap(self): def build_bootstrap_cmd(self, env): """For tests.""" build_dir = os.path.join(self.build_dir, "bootstrap") + print("Building bootstrap in", build_dir) if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) # `CARGO_BUILD_TARGET` breaks bootstrap build. diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile index 0cae83a85b3a4..ed1e7358f6b3f 100644 --- a/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile @@ -2,7 +2,7 @@ # Fuchsia as an integration test of the toolchain. See the build-fuchsia.sh # script in this directory for more details. -FROM ubuntu:22.04 +FROM ghcr.io/marcoieni/ubuntu:22.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -75,5 +75,7 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-fuchsia.linker=/usr/local/bin/ld.lld ENV SCRIPT \ + echo "x install" && df -h / && \ python3 ../x.py install --target $TARGETS compiler/rustc library/std clippy && \ + echo "build fuchsia" && df -h / && \ bash ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index d1bc0519bc1eb..2d0a048742172 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -39,6 +39,7 @@ root_dir="`dirname $src_dir`" source "$ci_dir/shared.sh" if isCI; then + echo "CI detected" objdir=$root_dir/obj else objdir=$root_dir/obj/$image @@ -53,6 +54,7 @@ fi CACHE_DOMAIN="${CACHE_DOMAIN:-ci-caches.rust-lang.org}" if [ -f "$docker_dir/$image/Dockerfile" ]; then + echo "Dockerfile found for $image" hash_key=/tmp/.docker-hash-key.txt rm -f "${hash_key}" echo $image >> $hash_key @@ -140,7 +142,8 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then elif [[ "$PR_CI_JOB" == "1" ]]; then # Enable a new Docker driver so that --cache-from works with a registry backend - docker buildx create --use --driver docker-container + docker buildx create --use --driver docker-container \ + --driver-opt image=ghcr.io/marcoieni/buildkit:buildx-stable-1 # Build the image using registry caching backend retry docker \ @@ -150,14 +153,17 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then --output=type=docker # On auto/try builds, we can also write to the cache. else + echo "Logging into the Docker registry" # Log into the Docker registry, so that we can read/write cache and the final image echo ${DOCKER_TOKEN} | docker login ${REGISTRY} \ --username ${REGISTRY_USERNAME} \ --password-stdin # Enable a new Docker driver so that --cache-from/to works with a registry backend - docker buildx create --use --driver docker-container + docker buildx create --use --driver docker-container \ + --driver-opt image=ghcr.io/marcoieni/buildkit:master + echo "Building Docker image with cache" # Build the image using registry caching backend retry docker \ buildx \ @@ -166,11 +172,13 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then --cache-to type=registry,ref=${CACHE_IMAGE_TAG},compression=zstd \ --output=type=docker + echo "Docker image built" # Print images for debugging purposes docker images # Tag the built image and push it to the registry docker tag rust-ci "${IMAGE_TAG}" + echo "Pushing Docker image to the registry" docker push "${IMAGE_TAG}" # Record the container registry tag/url for reuse, e.g. by rustup.rs builds @@ -222,6 +230,7 @@ else exit 1 fi +echo "Creating directories" mkdir -p $HOME/.cargo mkdir -p $objdir/tmp mkdir -p $objdir/cores @@ -277,7 +286,8 @@ args="$args --privileged" # `LOCAL_USER_ID` (recognized in `src/ci/run.sh`) to ensure that files are all # read/written as the same user as the bare-metal user. if [ -f /.dockerenv ]; then - docker create -v /checkout --name checkout alpine:3.4 /bin/true + echo "Dockerenv detected. We are in docker-in-docker scenario." + docker create -v /checkout --name checkout ghcr.io/marcoieni/alpine:3.4 /bin/true docker cp . checkout:/checkout args="$args --volumes-from checkout" else @@ -285,16 +295,23 @@ else args="$args --volume $objdir:/checkout/obj" args="$args --volume $HOME/.cargo:/cargo" args="$args --volume /tmp/toolstate:/tmp/toolstate" +fi - id=$(id -u) - if [[ "$id" != 0 && "$(docker version)" =~ Podman ]]; then - # Rootless podman creates a separate user namespace, where an inner - # LOCAL_USER_ID will map to a different subuid range on the host. - # The "keep-id" mode maps the current UID directly into the container. - args="$args --env NO_CHANGE_USER=1 --userns=keep-id" - else - args="$args --env LOCAL_USER_ID=$id" - fi +id=$(id -u) +if [[ "$id" != 0 && "$(docker version)" =~ Podman ]]; then + # Rootless podman creates a separate user namespace, where an inner + # LOCAL_USER_ID will map to a different subuid range on the host. + # The "keep-id" mode maps the current UID directly into the container. + echo "Running in rootless podman" + args="$args --env NO_CHANGE_USER=1 --userns=keep-id" +elif [[ "$id" != 0 ]]; then + echo "Running in docker as non-root" + args="$args --env LOCAL_USER_ID=$id" +else + echo "Running in docker as root. Using id 1001." + # If we're running as root, we don't want to run the container as root, + # so we set id `1001` instead of `0`. + args="$args --env LOCAL_USER_ID=1001" fi if [ "$dev" = "1" ] diff --git a/src/ci/github-actions/ci.py b/src/ci/github-actions/ci.py index b7dac412dbecf..fa0c04e2b80be 100755 --- a/src/ci/github-actions/ci.py +++ b/src/ci/github-actions/ci.py @@ -195,6 +195,19 @@ def format_run_type(run_type: WorkflowRunType) -> str: raise AssertionError() +# Add new function before main: +def substitute_github_vars(jobs: list) -> list: + """Replace GitHub context variables with environment variables in job configs.""" + for job in jobs: + if "os" in job: + job["os"] = ( + job["os"] + .replace("${{ github.run_id }}", os.environ["GITHUB_RUN_ID"]) + .replace("${{ github.run_attempt }}", os.environ["GITHUB_RUN_ATTEMPT"]) + ) + return jobs + + def get_job_image(job: Job) -> str: """ By default, the Docker image of a job is based on its name. @@ -265,6 +278,7 @@ def calculate_job_matrix(job_data: Dict[str, Any]): if run_type is not None: jobs = calculate_jobs(run_type, job_data) jobs = skip_jobs(jobs, channel) + jobs = substitute_github_vars(jobs) if not jobs: raise Exception("Scheduled job list is empty, this is an error") diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 6bf4a75d080cc..483c3877d0edc 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -46,6 +46,16 @@ runners: - &job-aarch64-linux os: ubuntu-22.04-arm64-8core-32gb + - &job-linux-8c-codebuild + free_disk: true + os: codebuild-ubuntu-22-8c-${{ github.run_id }}-${{ github.run_attempt }} + <<: *base-job + + - &job-linux-36c-codebuild + free_disk: true + os: codebuild-ubuntu-22-36c-${{ github.run_id }}-${{ github.run_attempt }} + <<: *base-job + envs: env-x86_64-apple-tests: &env-x86_64-apple-tests SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact @@ -256,7 +266,7 @@ auto: # nightly features to compile, and this job would fail if # executed on beta and stable. only_on_channel: nightly - <<: *job-linux-8c + <<: *job-linux-8c-codebuild # Tests integration with Rust for Linux. # Builds stage 1 compiler and tries to compile a few RfL examples with it. @@ -264,7 +274,7 @@ auto: <<: *job-linux-4c - name: x86_64-gnu - <<: *job-linux-4c + <<: *job-linux-8c-codebuild # This job ensures commits landing on nightly still pass the full # test suite on the stable channel. There are some UI tests that diff --git a/src/ci/run.sh b/src/ci/run.sh index b874f71832d73..792c7454a14ce 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -2,16 +2,49 @@ set -e +change_ownership_if_needed() { + local path=$1 + local owner="user:user" + local current_owner=$(stat -f "%Su:%Sg" "$path" 2>/dev/null) + local test_file="$path/.write_test" + + # Test if filesystem is writable by attempting to touch a temporary file + if touch "$test_file" 2>/dev/null; then + rm "$test_file" + if [ "$current_owner" != "$owner" ]; then + chown -R $owner "$path" + fi + else + echo "$path is read-only, skipping ownership change" + fi +} + +echo "Running inside src/ci/run.sh script" + if [ -n "$CI_JOB_NAME" ]; then echo "[CI_JOB_NAME=$CI_JOB_NAME]" fi +echo "whoami: $(whoami). id: $(id -u) Home: $HOME" +echo "--- current directory ---" +pwd +ls -l +echo "-------------------------" +echo "NO_CHANGE_USER=$NO_CHANGE_USER. LOCAL_USER_ID=$LOCAL_USER_ID" if [ "$NO_CHANGE_USER" = "" ]; then + echo "can change user" if [ "$LOCAL_USER_ID" != "" ]; then + echo "Starting with UID: $LOCAL_USER_ID" id -u user &>/dev/null || useradd --shell /bin/bash -u $LOCAL_USER_ID -o -c "" -m user export HOME=/home/user unset LOCAL_USER_ID + # Give ownership of necessary directories to the user + change_ownership_if_needed . + mkdir -p /cargo + change_ownership_if_needed /cargo + change_ownership_if_needed /checkout + # Ensure that runners are able to execute git commands in the worktree, # overriding the typical git protections. In our docker container we're running # as root, while the user owning the checkout is not root. @@ -21,6 +54,7 @@ if [ "$NO_CHANGE_USER" = "" ]; then # For NO_CHANGE_USER done in the small number of Dockerfiles affected. echo -e '[safe]\n\tdirectory = *' > /home/user/.gitconfig + echo "Switching to user" exec su --preserve-environment -c "env PATH=$PATH \"$0\"" user fi fi diff --git a/src/ci/scripts/run-build-from-ci.sh b/src/ci/scripts/run-build-from-ci.sh index 55e75800d91c4..90d6894c7c234 100755 --- a/src/ci/scripts/run-build-from-ci.sh +++ b/src/ci/scripts/run-build-from-ci.sh @@ -17,7 +17,9 @@ echo "::add-matcher::src/ci/github-actions/problem_matchers.json" # the environment rustup self uninstall -y || true if [ -z "${IMAGE+x}" ]; then + echo "Running ci/run.sh" src/ci/run.sh else + echo "Running docker/run.sh with image ${IMAGE}" src/ci/docker/run.sh "${IMAGE}" fi