Sandbox Lifecycle
What create, exec, and delete actually do — the real code paths in the Firecracker-backed Manager.
A sandbox is one Firecracker microVM. The sandbox.Manager interface has exactly
three methods, and the HTTP API maps one endpoint to each:
type Manager interface {
Create(ctx context.Context, languagePack string) (*Sandbox, error)
Exec(ctx context.Context, id string, req proto.ExecRequest) (proto.ExecResult, error)
Delete(ctx context.Context, id string) error
}The Firecracker-backed implementation lives in pkg/sandbox/firecracker.
Create — boot a microVM
POST /sandboxes → Manager.Create:
-
Resolve the language pack. Look up
languagePackin the registry. An unknown name returnsErrUnknownPack→ HTTP 400. This happens before any VM work, so it's cheap. -
Allocate identity and workspace. Generate
sb_<hex>, create${TMPDIR}/emberd/<id>/, openvm.log. -
Set up the control channel. Allocate a guest context ID (CID, counting up from 3) and pick the host vsock socket path
<dir>/vsock.sock. -
Build the Firecracker config:
- kernel =
vmlinux-6.1.155, initrd =emberd-initramfs.cpio - rootfs drive = the pack's squashfs, read-only, root device (
/dev/vda) - a hybrid-vsock device pointing at
vsock.sock+ the guest CID - 1 vCPU, 256 MiB (configurable)
- kernel args = base args plus
emberd.interpreter=<pack interpreter>
- kernel =
-
Launch the VMM. Build the
firecrackercommand (custom binary path, per-VM API socket, console wired to a log file) andStartit under a background context that lives for the VM's whole lifetime — not the HTTP request context, which would cancel the VM when the request returns. -
Record the handle in the manager's map and return
{ "id": "sb_..." }with HTTP 201. -
Wait for readiness. Before returning,
Createblocks onwaitReady, which polls the guest vsock control plane (50ms interval,BootTimeoutdefault 15s). A successful hybrid-vsockCONNECT/OKhandshake only happens onceemberd-initis past bootstrap and listening, so it's a precise readiness signal — not a fixed sleep. If the guest never comes up, the half-booted VM is torn down and an error returned.
Because Create waits for the guest to actually accept on vsock (~400ms on the
reference host), a returned sandbox is immediately usable — an exec issued
with zero delay succeeds on the first try, no client-side retry needed.
Exec — run code in the guest
POST /sandboxes/{id}/exec → Manager.Exec:
- Look up the live VM by ID (unknown →
ErrNotFound→ 404). proto.DialGuest(vsockUDS, GuestPort)— connect to the host vsock socket and perform the Firecracker hybrid-vsockCONNECT/OKhandshake.- Set a deadline on the connection:
timeout_ms + 10s, or 60s if no timeout was given, so a wedged guest can't hang the request. WriteMessage(conn, ExecRequest)thenReadMessage(conn, &ExecResult).- Map the result to the HTTP response.
Inside the guest, emberd-init writes the code to a temp file, runs it under the
pack's interpreter with the request's stdin piped in, and captures
stdout/stderr/exit. A non-zero exit from your program is a normal result
(exit_code set, error empty); only a failure to launch the interpreter
populates error. See the control plane for the
wire details and the guest rootfs for how the
interpreter runs.
Delete — tear it down
DELETE /sandboxes/{id} → Manager.Delete:
- Remove the handle from the map (unknown →
ErrNotFound→ 404). StopVMM()sendsSIGTERMto the firecracker process — a clean VMM shutdown.Waitwith a 5-second bound; cancel the VM's context (which kills the process if the graceful stop stalled).RemoveAllthe work directory.
The per-VM tmpfs overlay dies with the VM, so there's nothing to garbage-collect inside the guest — the writable layer simply ceases to exist.
State machine
There is no "paused" or "stopped-but-kept" state in v0.1 — a sandbox is either running or gone. Snapshotting changes that in v0.2.