draupnir 0.1.2

Draupnir — the nordisk boot/provisioning library: fire up a runtime from one BootSpec across three backends (KVM via tunnr · OCI container · Redfish bare-metal virtual-media) and drive its power lifecycle. Odin's ring that drips eight identical copies → boot a fleet of identical machines from one ISO.
Documentation
# draupnir

The **boot / provisioning engine** of the **nordisk** constellation — named for
**Draupnir**, Odin's gold ring that drips eight identical copies of itself every
ninth night.

One lean **Rust** library, one `BootSpec`, **three boot backends**: it fires up a
runtime instance and drives its power lifecycle, whether that instance is a KVM
virtual machine, an OCI container (a redis service, say), or a **bare-metal
server** provisioned out-of-band. Draupnir's own code is the thin unifying seam —
each backend *delegates* to an existing engine (Brokkr's minimal-dependency law:
reuse, don't reinvent).

---

## The three backends

- **KVM** — an appliance VM, booted by driving
  **[tunnr]https://codeberg.org/mikronova/tunnr**'s QEMU + OVMF (UEFI) + KVM
  primitive (`BootSpec` / `boot_test` / `BootHandle`). Draupnir does **not**
  reimplement VM boot.
- **Container** — an OCI container over a container runtime (podman/Docker REST).
- **Redfish** — the capability Draupnir uniquely owns: boot **bare metal** through
  a server's BMC (iLO / iDRAC / OpenBMC) over the DMTF **Redfish** REST API —
  insert a virtual-media ISO, set the one-time boot override to it, power the node
  on. No OS on the box required.

```rust
use draupnir::{BootSpec, Boot, container::ContainerBoot};

let spec = BootSpec::container("cache", "docker.io/library/redis:7");
let redis = ContainerBoot::new().boot(&spec)?;   // a redis service, fired up
```

## The ring drips eight copies

Draupnir's namesake dripped eight identical rings every ninth night. Here that is a
*natural extension, not the core*: `plan_fleet(&spec, 8)` fans one `BootSpec` out
into eight identically-payloaded, distinctly-named specs — **a fleet of identical
machines booted from one ISO** (bare-metal fleet provisioning via Redfish). The
core stays simple: one library, three boot backends.

## Where it sits in the stack

Draupnir is the **shared low-level boot lib**. Two higher-level tools depend on it
**directly** and call *down* into it — neither reimplements boot code:

- **[Skidbladnir]https://codeberg.org/nordisk/Skidbladnir** — the service /
  systemd / airgap layer. It now **delegates instance-firing to Draupnir** and
  keeps only the high-level service & orchestration logic.
- **jera** (edda's job handler) — stays thin (a job is `process | VM | container`)
  and reaches booting straight through Draupnir.

```text
  jera ─────────┐
                ├──▶ draupnir ──▶ tunnr        (KVM VM)
  Skidbladnir ──┘             ├─▶ OCI runtime  (container / redis)
                              └─▶ Redfish BMC  (bare-metal ISO boot)
```

One home per capability: instance *booting* lives only in Draupnir; tunnr is the
sole KVM boot primitive, reached only through Draupnir's KVM backend.

## Honest by construction

The trait surface, the `BootSpec`/`Machine` types, spec validation and the fleet
fan-out are **real and unit-tested**. Every unimplemented backend internal is an
honest `todo!("draupnir: …")` — never a fake-green stub. The default build is
**pure std, zero dependencies**; each live backend sits behind a feature.

```console
$ cargo build          # pure-std, green
$ cargo test           # spec + fleet bookkeeping
$ cargo build --features backend-tunnr   # live KVM boot via tunnr
```

## Docs

`.nornir/` is the source of the docs: **[design](.nornir/design.md)** (the
ownership table + extraction plan) · **[guide](.nornir/guide.md)** (usage) ·
**[for-idiots](.nornir/for-idiots.md)** (the beginner walk-through).

---

Every crate in the constellation is held to
**[Brokkr's Software Criteria](brokkr-software-criteria.md)** — baremetal,
minimal-dependency, zero-copy / multi-core / SIMD.