<!-- nornir:class: guide -->
# build-thing launch axis — guide
> **Class:** `guide` · The *what/why* is in
> [`build-thing-launch-design.md`](build-thing-launch-design.md). This is the
> hands-on path: from a built artifact to a running, asserted machine.
## The mental model in one line
**Build produces an artifact; launch runs it.** Same cell, two buttons. The launch
button is chosen by the artifact's kind — a container gets *deploy + logs*, a VM/ISO
gets *boot console + serial*, an exe gets *run*.
## From Rust — boot a VM artifact through the spine
```rust
use draupnir::{BootSpec, ImageSource, kvm::KvmBoot, Boot};
// direct-kernel (tunnr's thin appliance)
let spec = BootSpec::kvm("demo", ImageSource::KernelRootfs {
kernel: "/…/bzImage".into(),
rootfs: "/…/rootfs.cpio.gz".into(),
});
// bootloader-in-disk (the fat-dist / airgap end — new)
let fat = BootSpec::kvm("ubuntu", ImageSource::BootloaderDisk {
disk: "/…/disk.img".into(),
});
let handle = KvmBoot::new().boot(&spec)?; // → tunnr_vm::boot_test under the hood
```
`KvmBoot` maps the spec to a `tunnr_vm::BootSpec` and hands off to `boot_test`; a
`BootloaderDisk` becomes an **empty-kernel** tunnr spec so tunnr firmware-boots the
disk. Cloud-init, when present, is authored by `draupnir::seed` and attached via
tunnr's native `with_seed`.
## Deploy a container artifact (no shell — bollard)
The container launch is `podman run` through the bollard Rust API (build-thing's
`image-build` feature / `BollardImageBuilder`), never a shell string. The UI's
**DEPLOY** button dispatches that job and streams the container stdout into the logs
pane.
## In the build-thing UI
1. Pick a cell in the matrix. Its **kind** decides the launch control.
2. **Build** it (cargo / bollard / boot artifact) — sealed, content-addressed.
3. **Launch** it:
- container → **DEPLOY** → watch the **logs pane**;
- vm / iso → **BOOT CONSOLE** → watch the **serial pane** for the contract
markers and the `BOOT-OK` verdict;
- exe → **RUN**.
4. Prior builds come from **holger** (the artifact cache) so a launch need not
rebuild.
## In dwarves (the forge)
A `VmBoot` step no longer hits a stub — it routes through `jera → draupnir → boot_test`
when dwarves is built with the `vm-boot` feature. Without the feature it fails
honestly ("vm-boot not enabled"), never fake-green. The forge orchestrates the launch;
it never builds the qemu argv itself.
## Prerequisites for a real KVM launch
`qemu-system-x86_64`, OVMF, a readable kernel (`TUNNR_KERNEL`), and `/dev/kvm`
(falls back to TCG). Same contract as tunnr's `boot-smoke-guide`.
## The one caveat
The outer Buildroot build is still shell (`variants/buildroot/build.sh`) — a separate
Rust-migration project. Everything in the launch axis itself is pure Rust.