Documentation
¶
Overview ¶
Package fleetbox provides Linux VMs as Go test fixtures.
On macOS (Apple Silicon) fleetbox boots stock Linux cloud images via Apple Virtualization.framework; on Linux it boots them via cloud-hypervisor. Either way it configures the guest once with cloud-init and provides SSH access for testing, through the same backend-neutral Go API.
On macOS all Virtualization.framework work runs in a separately distributed, ad-hoc-signed fleetbox-helper subprocess that the library downloads at first use and drives over a unix socket, so the importable package — and therefore the user's test binary — is pure Go and needs neither cgo nor codesign (ADR-0017). On Linux the orchestration runs in-process. The public API below is identical on both.
Basic usage:
vm, err := fleetbox.Start(ctx, "myvm")
if err != nil {
log.Fatal(err)
}
defer vm.Stop(ctx)
out, err := vm.SSH(ctx, "uname -a")
Index ¶
Constants ¶
const ( Debian12 = "debian-12" Ubuntu2404 = "ubuntu-24.04" )
Image aliases for common distributions.
Variables ¶
var ErrClustersUnsupported = errors.New("fleetbox: clusters require macOS 26+")
ErrClustersUnsupported is returned when a second cluster member is requested on a backend that cannot interconnect VMs — macOS older than 26, where VZ NAT isolates VMs from one another (ADR-0008, ADR-0012). A single VM still works.
Functions ¶
func NestedVirtSupported ¶
func NestedVirtSupported() bool
NestedVirtSupported returns true if nested virtualization is available — what consumers that run KVM inside guests need. On macOS it requires Apple Silicon M3+ and macOS 15+; on Linux it requires /dev/kvm and the KVM nested parameter enabled. On macOS it is a pure-Go host heuristic (so deciding to skip a test never downloads the helper); the helper performs the authoritative VZ check at boot (ADR-0017, R7).
func Prune ¶
func Prune() error
Prune reclaims the inert host resources a fleetbox holder leaves behind if it dies without running its teardown — on Linux, orphaned bridges, taps, and firewall rules, plus restoring ip_forward once nothing of ours remains. It runs automatically on the CLI's down, so cleanup is never the user's job; this exported form is for library callers that want to sweep explicitly. On macOS it is a no-op: vmnet owns its own state and the in-process VMs of a dead helper die with it (ADR-0013, ADR-0017).
Types ¶
type Cluster ¶
type Cluster struct {
// contains filtered or unexported fields
}
Cluster is a set of VMs sharing one network, so every member reaches the others by IP — a vmnet SharedMode network on macOS, a Linux bridge on Linux (ADR-0008, ADR-0011). The shared network is a runtime object tied to the Cluster's lifetime — never persisted, so a Cluster is a runtime handle, not on-disk state. Members can be added after creation, which is what lets a CLI holder process grow a live cluster without recreating its network.
func NewCluster ¶
NewCluster creates a cluster's shared network but boots no VMs. Use Cluster.Add to bring members up on it. Shared setup (store, SSH key, image, backend) runs once here and is reused for every Add.
func StartCluster ¶
StartCluster boots the named VMs on one shared network and returns the Cluster. On any member's failure it destroys the members already started and closes the cluster, then returns the error (all-or-nothing, like StartN).
func (*Cluster) Add ¶
Add boots an additional VM on the cluster's shared network and registers it as a member. The new VM reaches every existing member by IP. Adding a second member on a backend that cannot interconnect VMs (macOS < 26) is rejected with ErrClustersUnsupported before any boot work — the same guard StartCluster applies up front, here also covering a node re-joining a live cluster (ADR-0012). The first member is a lone VM and is always allowed.
type Fixture ¶
Fixture is a read-only host directory packed into the guest at boot. At first creation HostPath is snapshotted into an ext4 image, attached to the VM as a read-only block device, and mounted by the stock guest at GuestPath via cloud-init. Fixtures are a property the VM is born with: the set is frozen at first creation and persisted, but the content is rebuilt from HostPath on every boot (so the guest sees the directory as it is at that boot, never live within a boot). Files arrive world-readable (0444), directories traversable (0555), owned by root; host permission and executable bits are not preserved. It works identically on macOS and Linux (ADR-0015).
type Option ¶
Option is a functional option for configuring a VM.
func WithFixture ¶
WithFixture packs the host directory hostDir into the guest at guestPath as a read-only fixture: at boot the directory is snapshotted into an ext4 image, attached as a read-only block device, and mounted by the stock guest at guestPath. Call it more than once to add several fixtures. guestPath must be absolute; hostDir must exist and be a directory, and is resolved to an absolute path. The fixture set is frozen when the VM is first created and ignored when passed to an already-existing VM (exactly as cpu/memory/disk options are), but the content is rebuilt from hostDir on every boot. Files arrive world-readable, owned by root. In a StartN or StartCluster every member receives the same fixtures (ADR-0015).
type VM ¶
type VM struct {
// contains filtered or unexported fields
}
VM represents a running virtual machine.
func Start ¶
Start creates and boots a new VM with the given name. If the VM already exists, it boots the existing VM. On Linux the orchestration runs in-process (cloud-hypervisor, pure Go).
func StartN ¶
StartN creates and boots N VMs with the given prefix (prefix-1, prefix-2, ...). All N VMs share ONE network, so they reach each other by IP — the cluster is interconnected (ADR-0008 macOS, ADR-0011 Linux). It is a thin wrapper over StartCluster with generated names.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
fleetbox
command
|
|
|
fleetbox-helper
command
On every platform but darwin/arm64 the helper is not a real binary: Linux runs the holder in-process by re-execing the CLI itself (no separate signed VM host is needed), and other platforms are unsupported.
|
On every platform but darwin/arm64 the helper is not a real binary: Linux runs the holder in-process by re-execing the CLI itself (no separate signed VM host is needed), and other platforms are unsupported. |
|
Package fleetboxtest provides testing.T integration for fleetbox VMs.
|
Package fleetboxtest provides testing.T integration for fleetbox VMs. |
|
internal
|
|
|
backend
Package backend defines the interface for VM backends.
|
Package backend defines the interface for VM backends. |
|
backend/cloudhypervisor
Package cloudhypervisor implements the backend interface using cloud-hypervisor on Linux.
|
Package cloudhypervisor implements the backend interface using cloud-hypervisor on Linux. |
|
control
Package control is the client half of the holder protocol: it spawns a holder process, waits for its members to come up, and queries or stops them over the per-member unix sockets.
|
Package control is the client half of the holder protocol: it spawns a holder process, waits for its members to come up, and queries or stops them over the per-member unix sockets. |
|
dhcp
Package dhcp parses macOS dhcpd_leases file to discover VM IP addresses.
|
Package dhcp parses macOS dhcpd_leases file to discover VM IP addresses. |
|
fetch
Package fetch downloads and caches remote files (cloud images, VMM binaries, firmware), verifying an optional SHA256 and writing atomically so a cached file is always complete.
|
Package fetch downloads and caches remote files (cloud images, VMM binaries, firmware), verifying an optional SHA256 and writing atomically so a cached file is always complete. |
|
fixture
Package fixture packs a host directory into a read-only ext4 filesystem image for attaching to a VM as a block device (ADR-0015).
|
Package fixture packs a host directory into a read-only ext4 filesystem image for attaching to a VM as a block device (ADR-0015). |
|
helperdist
Package helperdist resolves the signed fleetbox-helper binary the darwin client drives: it returns a locally pre-staged helper named by the FLEETBOX_HELPER environment variable, or downloads the checksum-pinned helper for this platform into ~/.fleetbox/bin, strips its Gatekeeper quarantine, and makes it executable.
|
Package helperdist resolves the signed fleetbox-helper binary the darwin client drives: it returns a locally pre-staged helper named by the FLEETBOX_HELPER environment variable, or downloads the checksum-pinned helper for this platform into ~/.fleetbox/bin, strips its Gatekeeper quarantine, and makes it executable. |
|
holder
Package holder is the server half of the holder protocol: one process owns one orchestrator.Cluster — its shared network and every VM on it — so a cluster gets the same VM↔VM connectivity the library StartN gives (ADR-0008).
|
Package holder is the server half of the holder protocol: one process owns one orchestrator.Cluster — its shared network and every VM on it — so a cluster gets the same VM↔VM connectivity the library StartN gives (ADR-0008). |
|
image
Package image handles cloud image download, verification, and conversion.
|
Package image handles cloud image download, verification, and conversion. |
|
opts
Package opts holds the backend-neutral VM creation options and their serialization across the helper-process boundary.
|
Package opts holds the backend-neutral VM creation options and their serialization across the helper-process boundary. |
|
orchestrator
Package orchestrator owns the VM lifecycle: it resolves the per-call dependencies (store, SSH key, image, backend), creates the backend network, and boots, waits for, and tears down VMs.
|
Package orchestrator owns the VM lifecycle: it resolves the per-call dependencies (store, SSH key, image, backend), creates the backend network, and boots, waits for, and tears down VMs. |
|
seed
Package seed creates cloud-init NoCloud seed ISOs.
|
Package seed creates cloud-init NoCloud seed ISOs. |
|
sshkey
Package sshkey manages SSH key generation and provides an SSH client for VM access.
|
Package sshkey manages SSH key generation and provides an SSH client for VM access. |
|
store
Package store manages VM state directories under ~/.fleetbox/clusters/<cluster>/<member>/.
|
Package store manages VM state directories under ~/.fleetbox/clusters/<cluster>/<member>/. |
|
third_party
|
|