Skip to content

Commit

Permalink
ci: Use release LLVM versions from tarballs
Browse files Browse the repository at this point in the history
Instead of relying on Homebrew for macOS (which ships older LLVM
versions) and `apt.llvm.org` for Linux (which often has bugs at the
packaging level), we now use:

- The tarball from Rust CI to provide `libLLVM`. This ensures it always
  matches the version used by the latest Rust nightly.
- The tarball from https://github.com/llvm/llvm-project to provide
  `clang` and `llvm-objcopy`. In this case, an exact match with
  `libLLVM` in `rustc` is not necessary. Nevertheless, using the latest
  versions is preferred.

Fixing the build on macOS runners is the main motivation behind this
change.

Co-authored-by: tyrone-wu <wudevelops@gmail.com>
  • Loading branch information
vadorovsky and tyrone-wu committed Sep 23, 2024
1 parent 5b29008 commit 0b4e34a
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 27 deletions.
83 changes: 58 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ on:

env:
CARGO_TERM_COLOR: always
LLVM_VERSION: 18

jobs:
lint:
Expand Down Expand Up @@ -183,52 +182,44 @@ jobs:
strategy:
fail-fast: false
matrix:
runner:
include:
# macos-14 is arm64 per
# https://github.com/actions/runner-images#available-images which
# doesn't support nested virtualization per
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#limitations-for-arm64-macos-runners
- macos-13
- ubuntu-22.04
runs-on: ${{ matrix.runner }}
- target: x86_64-apple-darwin
os: macos-13
os-name: macOS
- target: x86_64-unknown-linux-gnu
os: ubuntu-22.04
os-name: Linux
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install prerequisites
if: runner.os == 'Linux'
# ubuntu-22.04 comes with clang 14[0] which doesn't include support for signed and 64bit
# enum values which was added in clang 15[1].
#
# gcc-multilib provides at least <asm/types.h> which is referenced by libbpf.
#
# llvm provides llvm-objcopy which is used to build the BTF relocation tests.
#
# [0] https://github.com/actions/runner-images/blob/ubuntu22/20230724.1/images/linux/Ubuntu2204-Readme.md
#
# [1] https://github.com/llvm/llvm-project/commit/dc1c43d
run: |
set -euxo pipefail
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
echo deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{ env.LLVM_VERSION }} main | sudo tee /etc/apt/sources.list.d/llvm.list
sudo apt update
sudo apt -y install clang-${{ env.LLVM_VERSION }} gcc-multilib llvm-${{ env.LLVM_VERSION }} locate qemu-system-{arm,x86}
echo /usr/lib/llvm-${{ env.LLVM_VERSION }}/bin >> $GITHUB_PATH
- name: bpf-linker
if: runner.os == 'Linux'
run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git
sudo apt -y install gcc-multilib locate qemu-system-{arm,x86}
- name: Install prerequisites
if: runner.os == 'macOS'
# The xargs shipped on macOS always exits 0 with -P0, so we need GNU findutils.
#
# The tar shipped on macOS doesn't support --wildcards, so we need GNU tar.
#
# The clang shipped on macOS doesn't support BPF, so we need LLVM from brew.
# TODO(vadorovsky): There are LLVM binary tarballs for macOS on GitHub,
# but unfortunately they don't work correctly[0]. Once the issue is
# fixed, we could run the next step ("Install LLVM") on all systems.
#
# We also need LLVM for bpf-linker, see comment below.
# For now, install LLVM from homebrew.
#
# [0] https://github.com/llvm/llvm-project/issues/92260
run: |
set -euxo pipefail
brew update
Expand All @@ -249,10 +240,52 @@ jobs:

- uses: Swatinem/rust-cache@v2

- name: Install LLVM
if: runner.os == 'Linux'
# Download the upstream LLVM release tarball to get the latest version
# of clang. Version parity with LLVM shipped with Rust nightly is not
# required for clang, as it is only used for compiling eBPF programs
# written in C for integration tests. But we still prefer using a
# recent version, instead of relying on Homebrew or Ubuntu.
run: |
set -euxo pipefail
llvm_tarball_url=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/llvm/llvm-project/releases | jq -r \
'first | .assets | map(select(.name |
endswith("${{ matrix.os-name }}-X64.tar.xz"))) | first |
.browser_download_url')
mkdir -p /tmp/llvm-upstream
wget -q -O - $llvm_tarball_url | tar -xJ --strip-components 1 \
-C /tmp/llvm-upstream
echo /tmp/llvm-upstream/bin >> $GITHUB_PATH
- name: Install libLLVM
# Download libLLVM from Rust CI to ensure that the libLLVM version
# matches exactly with the version used by the current Rust nightly. A
# mismatch between libLLVM (used by bpf-linker) and Rust's LLVM version
# can lead to linking issues.
run: |
set -euxo pipefail
# Get the partial SHA from Rust nightly.
rustc_sha=$(rustc +nightly --version | grep -oE '[a-f0-9]{7,40}')
# Get the full SHA from GitHub.
rustc_sha=$(curl -s https://api.github.com/repos/rust-lang/rust/commits/$rustc_sha \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
| jq -r '.sha')
mkdir -p /tmp/rustc-llvm
wget -q -O - https://ci-artifacts.rust-lang.org/rustc-builds/$rustc_sha/rust-dev-nightly-${{ matrix.target }}.tar.xz | \
tar -xJ --strip-components 2 -C /tmp/rustc-llvm
echo /tmp/rustc-llvm/bin >> $GITHUB_PATH
- name: bpf-linker
if: runner.os == 'Linux'
run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git

- name: bpf-linker
if: runner.os == 'macOS'
# NB: rustc doesn't ship libLLVM.so on macOS, so disable proxying (default feature). We also
# --force so that bpf-linker gets always relinked against the latest LLVM installed by brew.
# --force so that bpf-linker gets always relinked against the latest LLVM downloaded above.
run: cargo install --force bpf-linker --git https://github.com/aya-rs/bpf-linker.git --no-default-features

- name: Download debian kernels
Expand Down
22 changes: 20 additions & 2 deletions test/integration-ebpf/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

use aya_ebpf::{
bindings::xdp_action,
bpf_printk,
macros::{kprobe, kretprobe, tracepoint, uprobe, uretprobe, xdp},
programs::{ProbeContext, RetProbeContext, TracePointContext, XdpContext},
EbpfContext,
};

#[xdp]
Expand All @@ -30,8 +32,24 @@ pub fn test_kretprobe(_ctx: RetProbeContext) -> u32 {
}

#[tracepoint]
pub fn test_tracepoint(_ctx: TracePointContext) -> u32 {
0
pub fn test_tracepoint(ctx: TracePointContext) -> u32 {
// QEMU with HVF accelerator causes the run times in guest systems to be
// resolved in milliseconds instead of nanoseconds.
// Therefore, to make sure that we receive a non-zero `run_time` in
// `test_program_info` when running on macOS, make some arbitrary work
// which makes the program run for some time which is noticible with the
// millisecond resolution.
let mut res = ctx.uid().wrapping_add(ctx.pid());
for _ in 0..10_000 {
res = res.wrapping_mul(123);
res ^= (ctx.pid() << 3) ^ (ctx.uid() << 4);
res = res.rotate_left(2);
res = res.reverse_bits();
res = res.swap_bytes();
res = res.count_ones();
unsafe { bpf_printk!(b"number %u", res) };
}
res
}

#[uprobe]
Expand Down
6 changes: 6 additions & 0 deletions test/integration-test/src/tests/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ fn test_prog_stats() {
.unwrap();
prog.load().unwrap();
prog.attach("syscalls", "sys_enter_bpf").unwrap();

// // Executing bpf syscalls to trigger `sys_enter_bpf`
// for _ in 0..5 {
// let _ = loaded_programs().collect::<Vec<_>>();
// }

let test_prog = prog.info().unwrap();

kernel_assert!(
Expand Down

0 comments on commit 0b4e34a

Please sign in to comment.