Repository navigation
test: gate-refusal e2e + fix BTF mount to not block startup (ADR 0011, slice 7) - #35
Merged
Merged
Conversation
…, slice 7) The first live run of the ebpf node variant, and a manifest fix the e2e forced. - deploy/node-daemonset-ebpf.yaml: mount the always-present parent /sys/kernel (read-only) instead of /sys/kernel/btf directly. On a kernel without BTF the btf/ directory does not exist, and a hostPath of a missing directory blocks the pod from starting — which would defeat the graceful refusal whose whole point is that the node still runs as the scanner. The gate still checks /sys/kernel/btf/vmlinux under the mount. - test/e2e/profile_gate_test.go: TestEBPFGateRefusesGracefully deploys the ebpf variant into kind and asserts the graceful path — the pod reaches Running (so the manifest does not hard-require BTF), the profiler refuses with a distinct reason (btf_absent or kernel_too_old), and the Go-binary scanner keeps running (a coverage line appears). It runs anywhere, including kind on Docker Desktop / linuxkit where there is no BTF; gated on E2E_AGENT_IMAGE. - Makefile: a profile-gate-e2e target. This is the gate-refusal half of the two-mode slice-7 e2e. The full capture path needs a Linux+BTF host and lands as a separate target. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ERFMON Running it revealed a stronger constraint than BTF: on Docker Desktop / linuxkit the kind node cannot grant CAP_BPF/CAP_PERFMON, so the ebpf-variant pod fails at container init (runc "unable to apply caps") before the binary runs — the in-binary gate never gets a chance to refuse. The scanner variant (only SYS_PTRACE) starts fine, so it is those two caps specifically. The test now classifies the pod outcome and asserts only the case it can: - cap-apply failure -> Skip (the pod never starts; nothing to assert) - gate reported ready -> Skip (node supports eBPF; that is the capture e2e) - gate refused + scanner coverage -> assert the reason (btf_absent/kernel_too_old) So `make profile-gate-e2e` green-skips on Docker Desktop with a clear reason, and becomes a real assertion on a node that grants the caps but lacks BTF (the RHEL- style case). The live refusal/capture proof still needs a Linux+BTF host. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Slice 7 (part 1 — the local half) (plan, ADR 0011). The first live run of the ebpf node variant, plus a manifest fix the e2e forced.
Manifest fix: BTF mount must not block startup
The ebpf manifest mounted hostPath
/sys/kernel/btfwithtype: Directory. On a kernel without BTF that directory doesn't exist, so a hostPath of a missing directory blocks the pod from starting — which defeats the whole graceful-refusal design (the node is supposed to keep running as the scanner when BTF is absent) and makes the gate e2e impossible. Fix: mount the always-present parent/sys/kernelread-only; the gate still checks/sys/kernel/btf/vmlinuxunder it.Gate-refusal e2e (runs anywhere, incl. kind on macOS/linuxkit)
TestEBPFGateRefusesGracefullydeploys theebpfvariant into kind and asserts the graceful path (ADR 0011 §2):btf_absentorkernel_too_old),scan coverageline appears).Gated on
E2E_AGENT_IMAGE;make profile-gate-e2e. This is a real e2e (graceful degradation under a no-BTF kernel), not a stub.Checks
Compiles under
-tags e2eand skips cleanly without a cluster; defaultgo build ./...+golangci-lint ./...clean; manifest YAML validated (mount/volume names consistent, still[SYS_PTRACE, BPF, PERFMON], noprivileged).Not here
The full capture path (CPU-load pod → profile captured/filtered/spooled/valid) needs a Linux+BTF host and lands as a separate
profile-capture-e2etarget — the session where we spin a GCP VM (like the PGO spike) for the first real capture.🤖 Generated with Claude Code