Vetrix Docs

Firecracker runner executor

Vetrix's Firecracker executor runs untrusted workloads — fork-PR refs and workflows that declare slsa: L3 — in an ephemeral microVM. The executor lives in cmd/worker/firecracker_executor.go and is selected per runner group via the isolation_kind='firecracker' column on the runner groups table.

When a job is forced onto a Firecracker runner

The engine evaluates the job's IsolationSpec at dispatch time (internal/cicd/isolation.go). Any job that meets one of these conditions is required to run on a Firecracker runner:

Trigger Additional requirement
Fork-PR ref Runner isolation_kind='firecracker'
slsa: L3 workflow Firecracker and a dedicated signing daemon

If no reachable runner group satisfies the tier the engine leaves the run queued and surfaces the stable reason string isolation_requirement_unsatisfied. The reason is recorded verbatim on the run row and exposed through the dashboard.

VM lifecycle

Per job:

  1. Allocate a private vsock pair and a copy-on-write overlay of the base rootfs image.
  2. Boot the microVM with the per-job CPU millis and memory MiB caps from the runner group (runner_groups.cpu_millis, runner_groups.mem_mib). Boot must land under MaxBootBudget (default 500 ms, p99) or the job fails fast with reason boot_budget_exceeded.
  3. Execute the job's commands through the in-guest init; stream stdout and stderr line-by-line to the log sink.
  4. Teardown: power off, wipe the COW overlay, release vsock ports.

Image management

runs-on: [linux, self-hosted, firecracker] tag matching resolves to one of the rootfs images staged on the host under FirecrackerExecutorConfig.RootfsDir. The default mapping translates alpine:3.19 to <dir>/alpine_3.19.ext4; operators override this with RootfsLookup when they maintain custom naming.

Image references are admitted only if at least one regex in FirecrackerExecutorConfig.ImageAllowlist matches the full reference string. An empty allowlist blocks every image — fork-PR refs must never run under an unrestricted allowlist. Trusted refs may use .* to accept any seeded rootfs.

Network posture

Ref class Allowlist applied
Trusted (non-fork) NetworkAllowlist + ControlPlaneEndpoints
Fork-PR ControlPlaneEndpoints only (user allowlist is suppressed)

DNS lookups are forwarded through the runner host resolver; the VM never sees cluster DNS directly. The cloud-metadata endpoint (169.254.169.254) is never reachable.

Resource caps

FirecrackerExecutorConfig.DefaultCPUMillis / DefaultMemMiB are the per-VM caps when the job does not supply its own. OOM kills surface as a job failure with reason oom_killed and the masked stdout convention (exit 137).

Metrics

Exposed through FirecrackerExecutor.Metrics() and read by the admin dashboard:

Name Shape Meaning
vetrix_firecracker_boot_ms histogram Rolling ring of the last 128 boots.
vetrix_firecracker_vm_alive_count gauge Live VMs managed by this executor.
vetrix_firecracker_teardown_ms histogram Rolling ring of the last 128 tears.

Testing the executor without a kernel

The executor delegates VM lifecycle to a vmBackend interface. Tests inject a fake backend that records the job's behaviour (boot latency, per-VM file writes, exec hooks) and verify every acceptance criterion without a live kernel. See cmd/worker/firecracker_executor_test.go.