diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05778c2c2..7a0a16d07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ on: - cron: 00 4 * * * env: + ALPINE_VERSION: 3.20 CARGO_TERM_COLOR: always jobs: @@ -186,7 +187,49 @@ jobs: --package aya-log-ebpf \ --feature-powerset + # Build a container image based on Alpine which: + # - Has a regular user in the `wheel` group, so we don't have to run all + # commands as root. + # - Has git installed, so the `checkout` action works. + build-container-image: + strategy: + fail-fast: false + runs-on: ubuntu-latest + steps: + - name: Log in to GHCR + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Check if Docker image already exists + id: check_image + run: | + if docker pull $IMAGE_NAME; then + echo "exists=true" >> $GITHUB_ENV + else + echo "exists=false" >> $GITHUB_ENV + fi + + - name: Build Alpine container image (with a regular user) + if: env.exists == 'false' + run: | + IMAGE_NAME=ghcr.io/${{ github.repository_owner }}/alpine:${{ env.ALPINE_VERSION }} + + cat << 'EOF' > Dockerfile + FROM alpine:${{ env.ALPINE_VERSION }} + + RUN apk update && apk add --no-cache git sudo \ + && adduser -D aya \ + && echo "aya ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers + + USER aya + WORKDIR /home/aya + EOF + + docker build -t $IMAGE_NAME . + docker push $IMAGE_NAME + run-integration-test: + needs: + - build-container-image strategy: fail-fast: false matrix: @@ -202,14 +245,21 @@ jobs: - target: x86_64-unknown-linux-gnu # We don't use ubuntu-latest because we care about the apt packages available. os: ubuntu-22.04 + - target: x86_64-unknown-linux-musl + os: ubuntu-22.04 + container: ghcr.io/aya-rs/alpine:3.20 runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} steps: + - run: apk add git + if: runner.os == 'Linux' && contains(matrix.container, 'alpine') + - uses: actions/checkout@v4 with: submodules: recursive - name: Install prerequisites - if: runner.os == 'Linux' + if: runner.os == 'Linux' && matrix.container == '' # ubuntu-22.04 comes with clang 13-15[0]; support for signed and 64bit # enum values was added in clang 15[1] which isn't in `$PATH`. # @@ -224,6 +274,24 @@ jobs: sudo apt -y install gcc-multilib lynx qemu-system-{arm,x86} echo /usr/lib/llvm-15/bin >> $GITHUB_PATH + - name: Install prerequisites + if: runner.os == 'Linux' && contains(matrix.container, 'alpine') + # Use clang for building the C eBPF programs for integration tests. + # Use gcc with binutils as the linker and libgcc_s as the runtime + # library. + run: | + set -euxo pipefail + apk add \ + bash \ + clang \ + curl \ + dpkg \ + gcc \ + jq \ + qemu-system-arm \ + qemu-system-x86_64 \ + wget + - name: Install prerequisites if: runner.os == 'macOS' # The xargs shipped on macOS always exits 0 with -P0, so we need GNU findutils. @@ -307,6 +375,7 @@ jobs: - lint - build-test-aya - build-test-aya-ebpf + - build-container-image - run-integration-test runs-on: ubuntu-latest steps: diff --git a/xtask/src/run.rs b/xtask/src/run.rs index c92d08d59..e46cc9da5 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -54,12 +54,17 @@ pub fn build(target: Option<&str>, f: F) -> Result> where F: FnOnce(&mut Command) -> &mut Command, { - // Always use rust-lld and -Zbuild-std in case we're cross-compiling. let mut cmd = Command::new("cargo"); cmd.args(["build", "--message-format=json"]); if let Some(target) = target { - let config = format!("target.{target}.linker = \"rust-lld\""); - cmd.args(["--target", target, "--config", &config]); + cmd.args(["--target", target]); + // Always use rust-lld on macOS hosts. See + // https://github.com/aya-rs/aya/pull/908#issuecomment-2402813711 + #[cfg(target_os = "macos")] + { + let config = format!("target.{target}.linker = \"rust-lld\""); + cmd.args(["--config", &config]); + } } f(&mut cmd);