Documentation
¶
Overview ¶
Package firecracker is a thin Go wrapper around the Firecracker VMM's HTTP-over-Unix-socket REST API. It is intentionally small: a *Client owns a single VMM's API socket and exposes one Go method per Firecracker resource (machine-config, boot-source, drives, net-ifaces, vsock, actions, vm state, snapshot/{create,load}).
The package has no daemon-side state of its own. Lifecycle ownership — spawning the `firecracker` (or `jailer`-wrapped) process, knowing where its socket lives, supervising its exit — lives in internal/runtime/firecracker/, which uses this client to talk to the VMM it manages. Mirrors pkg/caddy/client.go in spirit: thin per-resource methods, idempotent where the upstream API is idempotent, errors returned verbatim with HTTP status context attached.
Firecracker's HTTP API is documented at https://github.com/firecracker-microvm/firecracker/blob/main/src/firecracker/swagger/firecracker.yaml. Stay close to that wire shape — every type in types.go corresponds to exactly one schema there.
Index ¶
- Constants
- type APIError
- type Action
- type BootSource
- type Client
- func (c *Client) Action(ctx context.Context, a Action) error
- func (c *Client) CreateSnapshot(ctx context.Context, req SnapshotCreate) error
- func (c *Client) InstanceInfo(ctx context.Context) (*InstanceInfo, error)
- func (c *Client) LoadSnapshot(ctx context.Context, req SnapshotLoad) error
- func (c *Client) PatchDrive(ctx context.Context, driveID string, patch DrivePatch) error
- func (c *Client) PatchNetworkInterface(ctx context.Context, ifaceID string, patch NetworkInterfacePatch) error
- func (c *Client) PatchVM(ctx context.Context, vm VM) error
- func (c *Client) Ping(ctx context.Context) error
- func (c *Client) PutBootSource(ctx context.Context, src BootSource) error
- func (c *Client) PutDrive(ctx context.Context, driveID string, drv Drive) error
- func (c *Client) PutLogger(ctx context.Context, lg Logger) error
- func (c *Client) PutMachineConfig(ctx context.Context, cfg MachineConfig) error
- func (c *Client) PutNetworkInterface(ctx context.Context, ifaceID string, iface NetworkInterface) error
- func (c *Client) PutVsock(ctx context.Context, v Vsock) error
- func (c *Client) SocketPath() string
- type Drive
- type DrivePatch
- type InstanceInfo
- type Logger
- type MachineConfig
- type MemoryBackend
- type NetworkInterface
- type NetworkInterfacePatch
- type NetworkOverride
- type SnapshotCreate
- type SnapshotLoad
- type VM
- type Vsock
Constants ¶
const ( VMStatePaused = "Paused" VMStateResumed = "Resumed" )
VM states accepted by PATCH /vm. Firecracker uses this endpoint for Paused/Resumed transitions, especially around snapshot create/load.
const (
ActionInstanceStart = "InstanceStart"
)
Action types Firecracker accepts on PUT /actions. Pause and Resume are intentionally not here: Firecracker v1.15 exposes those through PATCH /vm, not the action endpoint.
const DefaultRequestTimeout = 30 * time.Second
DefaultRequestTimeout caps a single REST call against the VMM. Firecracker itself responds in single-digit milliseconds for normal operations; we keep a generous ceiling so snapshot-load on a large memory file (mmap is fast but the API call still blocks on the kernel side) doesn't trip on a tight deadline. Callers that need their own ctx deadline should pass it to the methods — this is only the fallback.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
APIError carries a non-2xx response from the Firecracker API. Body is the raw response payload (typically a {"fault_message": "..."} JSON object); callers can switch on Status for retry decisions.
type Action ¶
type Action struct {
ActionType string `json:"action_type"`
}
Action is the PUT /actions body. ActionType is one of the constants above.
type BootSource ¶
type BootSource struct {
KernelImagePath string `json:"kernel_image_path"`
BootArgs string `json:"boot_args,omitempty"`
InitrdPath string `json:"initrd_path,omitempty"`
}
BootSource is the PUT /boot-source request for cold-boot VMMs. The kernel_image_path must be readable by the (possibly jailer-chrooted) firecracker process; the daemon resolves it ahead of time.
BootArgs is the kernel command line. Our template VMs use:
console=ttyS0 reboot=k panic=1 pci=off nomodules \ init=/usr/local/bin/toolboxd-init quiet
The init binary is the toolbox agent's pre-snapshot wrapper that brings the vsock listener up before the snapshot is taken; see cmd/toolboxd/.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a single-VMM Firecracker API client. One Client per Firecracker process; callers must not share a Client across processes because each VMM has its own socket. Methods are safe for concurrent use — the Firecracker API serializes mutations server-side and our http.Client is goroutine-safe.
func New ¶
New returns a Client that talks to the Firecracker API socket at socketPath. The socket need not exist at construction time; method calls will fail with a connect error until the VMM is spawned and binds it.
The returned client uses HTTP/1.1 over a Unix-domain stream — Firecracker's only transport. The fake "http://localhost" host in request URLs is a convention of net/http when the transport ignores it; the real address is socketPath.
func (*Client) Action ¶
Action issues a single action against the VMM. Firecracker v1.15 keeps InstanceStart on /actions; Paused/Resumed transitions use PatchVM instead.
func (*Client) CreateSnapshot ¶
func (c *Client) CreateSnapshot(ctx context.Context, req SnapshotCreate) error
CreateSnapshot writes a memory file + state file to the paths in req. Callers should put the VM in the Paused state first. SnapshotType=Full is the only option supported at template-build time; Diff is taken automatically by enable_diff_snapshots on load and does not flow through this call.
func (*Client) InstanceInfo ¶
func (c *Client) InstanceInfo(ctx context.Context) (*InstanceInfo, error)
InstanceInfo returns the VMM's self-reported state. Useful for confirming the guest is "Running" after InstanceStart or "Paused" after a snapshot load with resume_vm=false.
func (*Client) LoadSnapshot ¶
func (c *Client) LoadSnapshot(ctx context.Context, req SnapshotLoad) error
LoadSnapshot resumes a VMM from a memory file + state file pair. With EnableDiffSnapshots=true, the loaded memory file is mmap'd as the CoW base for the clone; per-clone writes land in a dirty bitmap and do not disturb the base — the property the whole plan rests on. With ResumeVM=true, the action implicitly resumes execution; otherwise the caller must PATCH /vm state=Resumed after attaching per-clone drives. TAP rebinding for restored snapshots is supplied in network_overrides.
func (*Client) PatchDrive ¶
PatchDrive updates a subset of drive fields on a running or paused VMM. Today the only mutable field is path_on_host — used by the clone path to rebind a per-sandbox overlay before Resume.
func (*Client) PatchNetworkInterface ¶
func (c *Client) PatchNetworkInterface(ctx context.Context, ifaceID string, patch NetworkInterfacePatch) error
PatchNetworkInterface updates a subset of network-interface fields on a VMM after snapshot/load. Firecracker v1.15 does not accept host_dev_name here; snapshot restore TAP rebinding must be sent in SnapshotLoad.
func (*Client) PatchVM ¶
PatchVM updates the microVM running state. Firecracker accepts Paused and Resumed here; sending those values to /actions is rejected by v1.15.
func (*Client) Ping ¶
Ping checks the VMM is reachable by issuing GET / (returns InstanceInfo). A nil error means the socket accepted a request and the VMM replied — it does NOT imply the guest has booted; for that, callers handshake with the in-VM agent over vsock.
func (*Client) PutBootSource ¶
func (c *Client) PutBootSource(ctx context.Context, src BootSource) error
PutBootSource declares the kernel image and command line for a cold-boot VMM. Not used on snapshot-load — the kernel is in the memory file there.
func (*Client) PutDrive ¶
PutDrive attaches (or replaces) a block device by drive_id. The first drive with IsRootDevice=true is the rootfs; additional drives are per-sandbox overlays / data disks.
On a snapshot-loaded VMM, this method is used between snapshot/load and Resume to swap the per-sandbox overlay onto the clone — the host_dev_path is the only piece that differs between clones of the same template.
func (*Client) PutLogger ¶
PutLogger attaches a file-backed logger to the VMM. Optional but useful for capturing Firecracker's own diagnostic output during early bring-up.
func (*Client) PutMachineConfig ¶
func (c *Client) PutMachineConfig(ctx context.Context, cfg MachineConfig) error
PutMachineConfig sets the VMM-wide CPU/memory shape. Must precede InstanceStart on a fresh VMM; ignored on a VMM that loads a snapshot (the snapshot already encodes the shape).
func (*Client) PutNetworkInterface ¶
func (c *Client) PutNetworkInterface(ctx context.Context, ifaceID string, iface NetworkInterface) error
PutNetworkInterface attaches a TAP device by iface_id during cold boot.
func (*Client) PutVsock ¶
PutVsock attaches a virtio-vsock device. The UDS path on the host is where in-guest connections to (CID 2, port N) appear; the toolbox agent listens on (CID 3, port N) inside the guest. Vsock is the snapshot-safe host↔guest channel; TCP over the TAP would tear on resume.
func (*Client) SocketPath ¶
SocketPath returns the API socket path this client targets. Useful for log lines that want to identify which VMM a call landed against without reaching into the runtime driver's bookkeeping.
type Drive ¶
type Drive struct {
DriveID string `json:"drive_id"`
PathOnHost string `json:"path_on_host"`
IsRootDevice bool `json:"is_root_device"`
IsReadOnly bool `json:"is_read_only"`
// CacheType: "Unsafe" or "Writeback". Default Unsafe matches the
// Firecracker default. Writeback is required for snapshot-safe
// overlays — the daemon sets it explicitly on per-sandbox overlays.
CacheType string `json:"cache_type,omitempty"`
}
Drive attaches a block device. PathOnHost is the file or block-device path; IsRootDevice and IsReadOnly carry the usual semantics. RateLimiter is omitted from the type — we don't throttle template I/O today and surfacing the nested rate-limiter shape would bloat this type for no gain. Add it when an actual driver path needs it.
type DrivePatch ¶
type DrivePatch struct {
DriveID string `json:"drive_id"`
PathOnHost string `json:"path_on_host,omitempty"`
}
DrivePatch is the PATCH /drives/{id} body. host_dev_path is the only mutable field today (the snapshot-clone overlay rebind path). Wire name is path_on_host — keep the JSON tag honest.
type InstanceInfo ¶
type InstanceInfo struct {
ID string `json:"id"`
State string `json:"state"`
// VmmVersion lets the driver fail-fast when a snapshot was taken on a
// different Firecracker build than the one trying to load it; mismatch
// is one of the top causes of mysterious snapshot-load failures
// (see plans/snapshot-clone-fast-boot.md §Operational concerns #6).
VmmVersion string `json:"vmm_version,omitempty"`
AppName string `json:"app_name,omitempty"`
}
InstanceInfo is the GET / response. The runtime driver uses State to distinguish "Not started" / "Running" / "Paused" without re-deriving from process signals -- useful as a sanity check before issuing VMStateResumed.
type Logger ¶
Logger attaches a file-backed logger. Optional; useful for capturing Firecracker's own diagnostic output (boot errors, snapshot fault messages) alongside the VMM process group's stderr.
type MachineConfig ¶
type MachineConfig struct {
VcpuCount int `json:"vcpu_count"`
MemSizeMib int `json:"mem_size_mib"`
SMT bool `json:"smt,omitempty"`
TrackDirtyPages bool `json:"track_dirty_pages,omitempty"`
HugePages string `json:"huge_pages,omitempty"`
}
MachineConfig is the PUT /machine-config request. Memory is in MiB, matching Firecracker's wire shape (do not multiply by 1024×1024 here). SMT defaults false; hugepages are off by default but flipped on for template VMs so clones can share huge pages with the page cache.
type MemoryBackend ¶
type MemoryBackend struct {
BackendType string `json:"backend_type"`
BackendPath string `json:"backend_path"`
}
MemoryBackend selects how Firecracker loads the snapshot memory file. BackendType "File" plus a file path is what we use; "Uffd" (userfaultfd) is a future axis for lazy fault-handler-driven page-in.
type NetworkInterface ¶
type NetworkInterface struct {
IfaceID string `json:"iface_id"`
HostDevName string `json:"host_dev_name"`
GuestMAC string `json:"guest_mac,omitempty"`
}
NetworkInterface attaches a TAP device. HostDevName is the host-visible TAP name (e.g. "fc-tap-<sandbox-id-prefix>"); GuestMAC is what the guest sees on eth0 — fixing it per-sandbox lets the host-side DHCP/static-IP machinery key off MAC. RX/TX rate limiters are intentionally omitted for the same reason as Drive's: add when needed.
type NetworkInterfacePatch ¶
type NetworkInterfacePatch struct {
IfaceID string `json:"iface_id"`
HostDevName string `json:"host_dev_name,omitempty"`
}
NetworkInterfacePatch is the PATCH /network-interfaces/{id} body. Firecracker v1.15 rejects host_dev_name on this endpoint, so current snapshot restore rebinding must use SnapshotLoad.NetworkOverrides. HostDevName remains here only for older API compatibility and tests that exercise the raw client.
type NetworkOverride ¶
type NetworkOverride struct {
IfaceID string `json:"iface_id"`
HostDevName string `json:"host_dev_name"`
}
NetworkOverride is one entry in SnapshotLoad.network_overrides. Firecracker applies these while restoring device state from the snapshot, before the VM is resumed.
type SnapshotCreate ¶
type SnapshotCreate struct {
SnapshotType string `json:"snapshot_type,omitempty"`
SnapshotPath string `json:"snapshot_path"`
MemFilePath string `json:"mem_file_path"`
Version string `json:"version,omitempty"`
}
SnapshotCreate is the PUT /snapshot/create body. SnapshotType=Full is what template builds use; diff snapshots are an internal property of LoadSnapshot via EnableDiffSnapshots and do not flow through this type. Paths are host-side absolute paths (jailer chroot already resolved by the runtime driver).
type SnapshotLoad ¶
type SnapshotLoad struct {
SnapshotPath string `json:"snapshot_path"`
MemBackend *MemoryBackend `json:"mem_backend,omitempty"`
EnableDiffSnapshots bool `json:"enable_diff_snapshots,omitempty"`
ResumeVM bool `json:"resume_vm,omitempty"`
NetworkOverrides []NetworkOverride `json:"network_overrides,omitempty"`
}
SnapshotLoad is the PUT /snapshot/load body. EnableDiffSnapshots=true is the load-time flag that gives us per-clone CoW: the memory file stays mmap'd read-only and per-VMM writes go to a dirty bitmap. ResumeVM=false keeps the clone paused so the daemon can rebind the per-sandbox overlay before issuing PATCH /vm state=Resumed. Per-sandbox TAP rebinding is part of the load request itself via NetworkOverrides.
type Vsock ¶
Vsock attaches a virtio-vsock device. UDSPath is the listen-side UDS on the host: in-guest connect(CID=2, port=N) becomes a connection accepted at <UDSPath>_<N>. GuestCID is the guest's own context ID (must be >= 3 per the virtio spec; CIDs 0–2 are reserved). The daemon allocates GuestCID from a SQLite pool — see internal/store/vsock_cids.