Skip to content

Work on Metal ​

Local setup is a work in progress

The host setup and integration steps are not fully verified. Use a disposable host and ask the team if a step fails.

Metal is the Go daemon on each physical host. Atlas decides where a VM belongs and sends the requested state. Metal saves that request, applies it with Firecracker, systemd, ZFS, and Linux networking, then reports what happened. Start with how a VM request works if this boundary is new.

Trace one VM request ​

Flow diagram
Loading diagram...

The HTTP handler checks and passes the request to the VM manager. The manager writes the desired record before Metal returns success. The reconciler then applies host work and updates the observed record. A reply can arrive before the VM is ready. Reconciliation explains generations, retries, and failures.

For a VM change, start in internal/api, then follow internal/vm into the package that owns the host resource. cmd/metald connects those packages at startup. It should not contain VM policy.

Find the package that owns your change ​

If you change...Start hereRead
A route or request fieldinternal/apiAtlas to Metal rules, API reference
VM records, generations, or cleanupinternal/vm, internal/reconcilerReconciliation
Boot, stop, console, or Firecrackerinternal/firecracker, internal/console, internal/platformRuntime, console
Disks, images, or snapshotsinternal/storageHost storage, host layout
Namespaces, routes, firewall, or meshinternal/networkHost networking
Host inventory or capacityinternal/hostHost sync
Moving a running VMinternal/vm/migrationHost migration steps
Listeners, config, or worker lifetimecmd/metaldDaemon and API

Each package has a nearby SPEC.md with its code contract. The Metal specification has the import map. The code map links to entry files and tests.

Keep the ownership boundary clear

The API handles transport, the VM manager owns requested and observed state, and host packages own their resources. Put a rule where its owner can enforce it on every retry.

Build and check a change ​

Run Go commands from metal/. The eBPF object must exist before a direct Go test because the traffic package embeds it.

sh
cd metal
make bpf
make test
make vet
go test -race ./...
make build

Use gofmt -w <changed-go-files> after editing Go files. make build regenerates Swagger and builds Linux binaries. make openapi generates only Swagger, which Git ignores. eBPF needs Clang 12 or newer and Linux/libbpf headers. TCX traffic monitoring needs Linux 6.6 or newer.

Unit tests can run without a VM host. Boot, network, and firewall checks need host features. The Metal host test guide has the setup and commands. It is still a work in progress.

Check host behavior when it matters ​

Test both first boot from a fresh clone and later boot from an existing disk. Shared warm memory is valid only for the first case. If your change touches lifecycle or console handling, also test explicit stop, daemon restart with console adoption, and idle save and restore.

Use a disposable host for integration work. The development script changes networking and creates a ZFS pool, systemd unit, guest image, and TLS credentials. Its file-backed pool is a development aid, not a host provisioning design.

Source code and tests

AGPL-3.0