Skip to content

feat: zero-config gadget validation (OCI loading + --quick + auto-size runtime maps)#39

Merged
ErenAri merged 6 commits into
mainfrom
feat/oci-gadget-loading
Jun 22, 2026
Merged

feat: zero-config gadget validation (OCI loading + --quick + auto-size runtime maps)#39
ErenAri merged 6 commits into
mainfrom
feat/oci-gadget-loading

Conversation

@ErenAri

@ErenAri ErenAri commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

What

Make bpfcompat validate a published eBPF gadget across kernels locally, with zero config — the workflow an Inspektor Gadget maintainer asked for. Three pieces:

  1. OCI gadget loading--artifact accepts an OCI image, not just a local .bpf.o: a registry reference (ghcr.io/inspektor-gadget/gadget/trace_open:latest), an OCI layout dir, or an OCI/docker archive. Extracts the eBPF layer (IG's application/vnd.gadget.ebpf.program.v1+binary media type, ELF-magic fallback) via go-containerregistry.
  2. --quick — a built-in kernel set (old LTS → recent), no --matrix file needed.
  3. Auto-size runtime-sized maps — maps shipped with max_entries=0 (which the real loader sizes at runtime) get a default size so they load, but only for types where 0 is invalid; perf-event-array, ringbuf, and *_STORAGE local-storage maps (where 0 is meaningful) are never touched, and manifest fixups take precedence. Reported per map.

Together:

bpfcompat test --artifact ghcr.io/inspektor-gadget/gadget/trace_open:latest --quick

Why

Discovery thread with Alban Crequy (Inspektor Gadget / Microsoft): IG's official-gadget CI (vimto + ci-kernels) isn't exhaustive, and third-party gadget authors can't easily test their eBPF across kernels without standing up similar CI. His ask: let the bpfcompat CLI load a gadget straight from an OCI registry/tarball and test it locally.

Verification — real IG gadget, zero config

bpfcompat test --artifact ghcr.io/inspektor-gadget/gadget/trace_open:latest --quick (no manifest, no matrix file):

Kernel Load Attach Note
Ubuntu 20.04 (5.4) fail events ring buffer needs ≥5.8 — auto-size correctly left the ringbuf alone
Debian 12 (6.1) pass 4/4 ig_build_id auto-sized to 4096
Ubuntu 24.04 (6.8) pass 4/4 ig_build_id auto-sized to 4096

A true "kernel version ≠ feature support" result, produced with no configuration. (With the full 5-kernel matrix it also passes on AlmaLinux 8 / 4.18 — RHEL backported the ring buffer into 4.18.)

  • Unit tests: OCI source detection, media-type + ELF-magic selection, name derivation, zip-slip rejection (image synthesized in-test, no network); matrix.Quick validation.
  • Auto-size verified end-to-end on the live gadget across kernels.
  • go build, go vet, gofmt, go test ./... all clean. go-containerregistry added + vendored.

🤖 Generated with Claude Code

ErenAri and others added 2 commits June 22, 2026 01:13
--artifact now accepts an OCI image in addition to a local .bpf.o ELF: a
registry reference (e.g. ghcr.io/inspektor-gadget/gadget/trace_open:latest),
an OCI layout directory, or an OCI/docker image archive. bpfcompat extracts
the eBPF object layer — preferring Inspektor Gadget's
application/vnd.gadget.ebpf.program.v1+binary media type, with an ELF-magic
fallback for gadgets packaged by other tooling — and validates it through the
existing flow.

internal/artifact/oci.go adds IsOCISource + ExtractEBPFFromOCI (via
go-containerregistry: registry pull, OCI layout, tarball, with zip-slip-safe
extraction); runner resolves an OCI source to a temp ELF before Inspect.
Tests cover detection, media-type and ELF-magic selection, name derivation,
and path-escape rejection; verified end-to-end pulling a real IG gadget.

Requested by Inspektor Gadget maintainer Alban Crequy as a way for gadget
authors to validate published gadgets across kernels without standing up CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add --quick, which runs a small built-in kernel set (matrix.Quick: old LTS →
recent) instead of requiring a --matrix file. Aimed at the local dev loop a
gadget/eBPF author hits before any CI exists — pair with OCI loading for a
one-liner: `bpfcompat test --artifact ghcr.io/org/gadget:tag --quick`.

Config.Validate now accepts --quick in place of --matrix; runner uses
matrix.Quick() when no matrix path is given.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ErenAri ErenAri changed the title feat: load eBPF gadgets from OCI images (registry ref / layout / archive) feat: validate published OCI gadgets locally (OCI loading + --quick) Jun 21, 2026
Many real loaders (Inspektor Gadget, KubeArmor, Falco libpman) compile maps
with max_entries=0 and set the size at load time from a userspace param. A
generic load can't, so map creation fails with EINVAL on every kernel — a
loader contract, not a compatibility result.

The validator now gives such maps a default max_entries (4096), but only for
types where 0 is invalid AND the real loader supplies a size
(hash/array/percpu/LRU/stack-trace/LPM/prog-array). Types where 0 is
meaningful are never touched: perf-event-array (nr_cpus), ring/user ringbuf
(byte size), and the *_STORAGE local-storage maps (which require 0). Manifest
max_entries fixups run first and win; auto-sizing only fills remaining zeros.
Each auto-sized map is reported in the run notes for transparency.

This makes zero-config gadget validation work: e.g.
`bpfcompat test --artifact ghcr.io/inspektor-gadget/gadget/trace_open:latest --quick`
loads with no manifest (ig_build_id auto-sized) and correctly fails only on
Ubuntu 5.4, where the events ring buffer needs >= 5.8.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ErenAri ErenAri changed the title feat: validate published OCI gadgets locally (OCI loading + --quick) feat: zero-config gadget validation (OCI loading + --quick + auto-size runtime maps) Jun 22, 2026
ErenAri and others added 3 commits June 22, 2026 13:01
…al or CI)

Add docs/case-study-inspektor-gadget.md — zero-config validation of published
gadgets pulled from OCI (trace_open/trace_exec clean matrices; the trace_dns
socket1 program-type loader-contract finding), with the AlmaLinux 8 / 4.18
backported-ringbuf "kernel version != feature support" highlight.

Reposition the README and demo banner from "CI-first" to "test your eBPF across
real kernels — locally or in CI", lead with the one-command OCI gadget example,
and list the reference matrices in the docs map.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Range OCI index descriptors by index (they are ~136-byte structs), and
rename safeJoin's parameter so it no longer shadows the imported
go-containerregistry `name` package.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ErenAri ErenAri merged commit 757f051 into main Jun 22, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant