fix(build): hermetic netprobe eBPF object build for RBE/publish (#3425) #3511

Merged
mfreeman451 merged 1 commit from fix/netprobe-ebpf-cargo-hermetic into staging 2026-06-01 23:20:52 +00:00
Owner

Why

The netprobe native add-on bundle ships netprobe_ebpf.o, but the eBPF genrule
(//rust/netprobe/ebpf:netprobe_ebpf_object) shelled out to a host
cargo +nightly -Z build-std=core --target bpfel-unknown-none + host bpf-linker.
With no local/no-remote tag, under --remote_executor (the publish lane) it
dispatched to an RBE worker with no Rust toolchain and died at
cargo is required to build the netprobe eBPF object — blocking the
Publish Native Add-ons run and the netprobe capture e2e.

What

Build the eBPF object hermetically from Bazel-declared inputs only:

  • MODULE.bazel: pinned nightly rustc/cargo/rust-std/rust-src (2026-05-31)
    • a static bpf-linker v0.10.3 (@netprobe_ebpf_* http_archives, sha256-pinned).
      The default stable 1.93.0 rules_rust toolchain is untouched.
  • build-ebpf-object.sh: rewritten — assembles a scratch sysroot from the pinned
    components and builds offline against the committed vendor/ tree with
    -Z build-std=core --target bpfel-unknown-none. No host PATH tooling, no network.
  • vendor/: committed cargo-vendor of the eBPF crate's deps plus the
    -Z build-std std deps (cargo vendor --sync <rust-src>/library/Cargo.toml).
  • assemble_addon_bundle.py: harden the dependency-free YAML fallback parser to
    strip inline # comments (it was stricter than the authoritative Go validator,
    which masked-then-surfaced a rejection of addons/netprobe/addon.yaml).

Validation (carverauto RBE — the environment that was failing)

  • bazel build --config=ci //rust/netprobe/ebpf:netprobe_ebpf_object → builds
    remotely (1 remote), produces a valid 79952-byte eBPF ELF.
  • bazel build --config=ci //build/native_addons:netprobe_addon_bundle.linux.amd64.tar.gz
    → assembles with netprobe_ebpf.o + serviceradar-netprobe +
    serviceradar-netprobe.service + manifests.

Notes

  • Spec/design/tasks: openspec/changes/add-hermetic-netprobe-ebpf-build/.
  • Out of scope (follow-up): multi-arch eBPF — --cfg bpf_target_arch is x86_64;
    amd64 (the e2e target) is correct, arm64 is a separate change.

🤖 Generated with Claude Code

## Why The netprobe native add-on bundle ships `netprobe_ebpf.o`, but the eBPF genrule (`//rust/netprobe/ebpf:netprobe_ebpf_object`) shelled out to a **host** `cargo +nightly -Z build-std=core --target bpfel-unknown-none` + host `bpf-linker`. With no `local`/`no-remote` tag, under `--remote_executor` (the publish lane) it dispatched to an RBE worker with no Rust toolchain and died at `cargo is required to build the netprobe eBPF object` — blocking the `Publish Native Add-ons` run and the netprobe capture e2e. ## What Build the eBPF object **hermetically** from Bazel-declared inputs only: - `MODULE.bazel`: pinned nightly `rustc`/`cargo`/`rust-std`/`rust-src` (2026-05-31) + a static `bpf-linker` v0.10.3 (`@netprobe_ebpf_*` `http_archive`s, sha256-pinned). The default stable `1.93.0` rules_rust toolchain is untouched. - `build-ebpf-object.sh`: rewritten — assembles a scratch sysroot from the pinned components and builds **offline** against the committed `vendor/` tree with `-Z build-std=core --target bpfel-unknown-none`. No host `PATH` tooling, no network. - `vendor/`: committed cargo-vendor of the eBPF crate's deps **plus** the `-Z build-std` std deps (`cargo vendor --sync <rust-src>/library/Cargo.toml`). - `assemble_addon_bundle.py`: harden the dependency-free YAML fallback parser to strip inline `#` comments (it was stricter than the authoritative Go validator, which masked-then-surfaced a rejection of `addons/netprobe/addon.yaml`). ## Validation (carverauto RBE — the environment that was failing) - `bazel build --config=ci //rust/netprobe/ebpf:netprobe_ebpf_object` → builds remotely (`1 remote`), produces a valid **79952-byte eBPF ELF**. - `bazel build --config=ci //build/native_addons:netprobe_addon_bundle.linux.amd64.tar.gz` → assembles with `netprobe_ebpf.o` + `serviceradar-netprobe` + `serviceradar-netprobe.service` + manifests. ## Notes - Spec/design/tasks: `openspec/changes/add-hermetic-netprobe-ebpf-build/`. - Out of scope (follow-up): multi-arch eBPF — `--cfg bpf_target_arch` is `x86_64`; amd64 (the e2e target) is correct, arm64 is a separate change. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(build): hermetic netprobe eBPF object build for RBE/publish (#3425)
Some checks failed
Secret Scan / gitleaks (pull_request) Failing after 38s
Fingerprint Licensing / netprobe-fingerprint-licenses (push) Failing after 1m31s
Fingerprint Licensing / netprobe-fingerprint-licenses (pull_request) Failing after 1m0s
lint / lint (push) Successful in 1m44s
lint / lint (pull_request) Successful in 1m27s
Rust Tests / test-rust (rust/rdp-adapter, cargo) (push) Successful in 2m0s
Rust Tests / test-rust (//rust/netprobe:netprobe, //build/platforms:linux_x86_64_musl, rust/netprobe, bazel-static) (push) Successful in 2m2s
Golang Tests / test-go (push) Successful in 2m4s
Rust Tests / test-rust (//rust/netprobe:netprobe_test, rust/netprobe, bazel-test) (push) Successful in 2m21s
Rust Tests / test-rust (//rust/netprobe:netprobe, //build/platforms:linux_aarch64_musl, rust/netprobe, bazel-static) (push) Successful in 2m21s
Rust Tests / test-rust (rust/rperf-client, cargo) (push) Successful in 2m30s
Rust Tests / test-rust (rust/trapd, cargo) (push) Successful in 2m8s
Rust Tests / test-rust (//rust/rperf-server:rperf, rust/rperf-server, bazel) (push) Successful in 2m59s
Rust Tests / test-rust (rust/consumers/zen, cargo) (push) Successful in 3m14s
Rust Tests / test-rust (rust/log-collector, cargo) (push) Successful in 3m43s
CI / build (pull_request) Failing after 3m50s
Rust Tests / test-rust (rust/rdp-connector-probe, cargo) (push) Successful in 4m25s
Rust Tests / test-rust (rust/srql, cargo) (push) Successful in 5m21s
Elixir Quality / Elixir Quality (pull_request) Failing after 28m24s
Netprobe eBPF Verifier / Verify eBPF programs on Linux 5.15 (push) Has been cancelled
Netprobe eBPF Verifier / Verify eBPF programs on Linux 5.8 (push) Has been cancelled
Netprobe eBPF Verifier / Verify eBPF programs on Linux 6.x (push) Has been cancelled
Netprobe eBPF Verifier / Verify eBPF refusal on Linux 5.4 (push) Has been cancelled
d8133a2a82
The netprobe native add-on bundle ships netprobe_ebpf.o, but the eBPF
genrule shelled out to a host `cargo +nightly -Z build-std` + bpf-linker,
so it failed on remote execution (no toolchain) and blocked the publish
(`cargo is required to build the netprobe eBPF object`).

Build it hermetically instead: pinned nightly rustc/cargo/rust-std/rust-src
plus a static bpf-linker (MODULE.bazel @netprobe_ebpf_*) are assembled into
a scratch sysroot, and the crate is built offline against a committed cargo
vendor tree (including the -Z build-std std deps). No host toolchain and no
network, so it builds identically locally, in CI, and on RBE.

Also harden the bundle assembler's dependency-free YAML fallback parser to
strip inline `#` comments (it was stricter than the authoritative Go
validator), which otherwise rejected addons/netprobe/addon.yaml during
bundle assembly.

Validated on carverauto RBE: the eBPF genrule and the full
netprobe_addon_bundle.linux.amd64.tar.gz build remotely; the produced
object is a valid 79952-byte eBPF ELF.

Spec: openspec/changes/add-hermetic-netprobe-ebpf-build/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mfreeman451 left a comment

lgtm

lgtm
mfreeman451 deleted branch fix/netprobe-ebpf-cargo-hermetic 2026-06-01 23:21:03 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
carverauto/serviceradar!3511
No description provided.