feat(build): Gate the Linux port with full CI and document its runtime contract - #737
Merged
Merged
Conversation
Several helpers in shared files are reachable only from Windows code, so a Linux build sees them as dead. Move containsEventTypes and containsFieldMatch next to their only caller in compiler_windows.go, and isNumber next to the field definitions that validate with it. Drop the Linux framePID and threadpool accessor stubs, which nothing calls now that callstack and threadpool fields are Windows-only. event.PID is an alias for the same integer the params accessor already returns on both platforms, so the conversions around MustGetPid never converted anything. This makes the packages the Linux port owns lint clean, which the next commit turns into a CI gate.
mostafa
force-pushed
the
feat/linux-build-ci
branch
from
September 23, 2026 09:26
b00baa1 to
e01e683
Compare
mostafa
marked this pull request as draft
September 23, 2026 09:30
mostafa
force-pushed
the
feat/linux-build-ci
branch
from
September 23, 2026 09:33
e01e683 to
85026ab
Compare
mostafa
marked this pull request as ready for review
September 23, 2026 09:36
rabbitstack
requested changes
Sep 23, 2026
check-clang refuses to generate with the wrong clang major. The committed objects are byte-compared in CI and clang records its version in BTF, so generating with a different major rewrites every object and fails the drift check with a diff that looks like a source change. ebpf-drift turns that comparison into something runnable locally rather than a pair of CI steps, and build-linux cross-compiles from the committed objects to prove a checkout needs no clang. lint covers a narrower set than the tests. Packages outside it hold helpers only Windows reaches, so `unused` flags them on every Linux run with nothing to fix on this side.
Build before clang is installed, so the step fails if anything starts depending on generation tools at build time rather than on the committed objects. Probe the runtime contract as its own step. Without it a runner that lost runtime BTF or fell below the kernel floor produces a green suite that never loaded a program, because every test would fail the same way for a reason buried in a wrapped error. Pin clang to the major the objects were generated with, otherwise the drift check reports a diff on every unrelated change.
Covers what the backend refuses to start without, which capabilities replace running as root, and how to read the probe output. Calls out the two cases capabilities cannot fix, kernel lockdown and the pre-5.11 memlock accounting, because both surface as permission errors that look like a missing capability. Documents which attachment warnings are expected, since the optional legacy tracepoints log a permission denial on kernels that refuse a perf link on them and that is not a fault.
mostafa
force-pushed
the
feat/linux-build-ci
branch
from
September 23, 2026 12:02
85026ab to
c7e06f3
Compare
rabbitstack
approved these changes
Sep 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rounds out the Linux build and CI so the backend is gated the way the Windows one is, and documents what a host has to provide to run it.
Build targets
buildGOOS/GOARCHand builds from the committed objects, so a checkout needs no clangebpf-driftcheck-clangtest-race,test-integration,lintcheck-clangexists because clang records its version in BTF. Generating with a different major rewrites every object and fails the drift check with a diff that reads like a source change rather than a toolchain mismatch, which is a confusing half hour the first time it happens.CI
The Linux workflow now runs build, generation drift, lint, unit tests, race tests, rule validation, a prerequisite probe, and the privileged integration suite.
Two steps are ordered deliberately. The build runs before clang is installed, so it fails the moment something starts depending on generation tools at build time instead of the committed objects. And the prerequisite probe is its own step rather than being implied by the integration tests: without it, a runner that silently loses runtime BTF or drops below the 5.9 floor produces a suite where every test fails identically, for a reason buried in a wrapped error several frames down.
TestPrerequisitesAreMetruns the same gateOpendoes, so the architecture check is covered too, and it fails rather than skipping.clang is pinned to the major the committed objects were generated with, for the reason above.
Lint scope
Lint is blocking, but covers
internal/ebpf,internal/bootstrap,pkg/filter, andpkg/rulesrather than everything that builds on Linux. Widening it brings back 41 findings in shared code, nearly allunusedreports for helpers that only Windows reaches, and there is nothing to fix from this side without moving Windows code around.Getting that scope to zero did turn up real dead code, which is the first commit.
containsEventTypesandcontainsFieldMatchare only ever called fromcompiler_windows.go, andisNumberonly validates Windows field arguments, so all three moved next to their callers. The LinuxframePIDand threadpool accessor stubs had no callers at all and are gone. Theevent.PID(...)conversions aroundMustGetPidwere no-ops on both platforms, sincePIDis a type alias for exactly what the accessor returns.go vetis not a separate target:govetalready runs inside golangci-lint on the same scope, and running it wider trips pre-existingMarshalJSON() []bytesignature findings in shared marshalling code that are out of scope here.Docs
docs/setup/linux.mdcovers the hard prerequisites and why there is no BTF fallback, the capability set, how to read the startup probe, which attachment warnings are expected, best-effort procfs enrichment, and theebpf.*metrics.Two additions worth flagging.
CAP_KILLis listed because thekillaction needs it against processes Fibratus does not own. And the page calls out the two situations capabilities cannot fix, kernel lockdown inconfidentialitymode and pre-5.11RLIMIT_MEMLOCKaccounting, because both surface as permission errors that look exactly like a missing capability.Verification
build-linuxfrom committed objects with no clang present,make testacross 8 packages,make test-race,make ebpf-driftclean, lint clean on the gated scope, andGOOS=windows go build ./...unaffected. The prerequisite probe was exercised in both directions: failing loudly withlinux eBPF capture requires amd64on arm64, and passing with the full probe line on a capable host.