feat(fw): add cloonar.vms QEMU launcher and migrate openclaw (ADR-0018) #163

Merged
dominik.polakovics merged 1 commit from afk/160 into main 2026-06-14 16:15:11 +02:00

First slice of the dev → self-managed QEMU VM migration (ADR-0018, PR1). Pure Nix, dry-build-gated, no runtime cutover — the running dev microVM (.97.15) is untouched.

What

  • utils/modules/qemu-vm.nix — new reusable launcher exposing cloonar.vms.<name>: a state-dir tmpfile, a <name>-vm-init oneshot (download Ubuntu cloud image → qcow2 + resize → regenerate the cloud-init seed ISO), and a <name>-vm service (tap up on the server bridge → qemu → tap down). Options: mac / ip / mem / vcpu / diskSizeG / autostart / cpuWeight / cloudInit (sshKeys / packages / runcmd / writeFiles). cloud-init user-data is rendered via pkgs.formats.yaml, so arbitrary writeFiles content is quoted/indented correctly instead of hand-spliced into a template. The gateway/nameserver is derived as .1 of the IP's /24.

  • Migrate openclaw onto cloonar.vms.openclaw — the two-consumer proof. Behaviour unchanged: same .97.61, MAC, 2 GiB / 2 vcpu, opt-in start, openclaw-vm unit and /var/lib/openclaw-vm state dir, and the setup-openclaw runcmd. The only delta is the internal tap name (vm-openclawvm-openclaw-vm), still matching vm-*.

  • Add cloonar.vms.dev — a temporary parallel VM on .97.16 + a temp MAC, autostart, 100 GiB, cpuWeight = 20. Its tap vm-dev-vm deliberately avoids the live microVM's vm-dev. The microVM keeps .97.15; mem/vcpu stay at module defaults until cutover.

Safety

No collision with the live microVM: distinct unit (dev-vm vs microvm@dev), tap (vm-dev-vm vs vm-dev), MAC (…04:01 vs …02:01), IP (.16 vs .15), and state dir. cpu-priorities.nix is left targeting microvm@dev (still present); it folds into the new unit at cutover (PR3).

Pre-commit dry-build green for all 6 hosts.

Closes #160

First slice of the dev → self-managed QEMU VM migration ([ADR-0018](https://git.cloonar.com/Cloonar/nixos/src/branch/main/docs/adr/0018-dev-self-managed-qemu-vm.md), PR1). Pure Nix, dry-build-gated, no runtime cutover — the running dev microVM (.97.15) is untouched. ## What - **`utils/modules/qemu-vm.nix`** — new reusable launcher exposing `cloonar.vms.<name>`: a state-dir tmpfile, a `<name>-vm-init` oneshot (download Ubuntu cloud image → qcow2 + resize → regenerate the cloud-init seed ISO), and a `<name>-vm` service (tap up on the `server` bridge → qemu → tap down). Options: `mac` / `ip` / `mem` / `vcpu` / `diskSizeG` / `autostart` / `cpuWeight` / `cloudInit` (`sshKeys` / `packages` / `runcmd` / `writeFiles`). cloud-init user-data is rendered via `pkgs.formats.yaml`, so arbitrary `writeFiles` content is quoted/indented correctly instead of hand-spliced into a template. The gateway/nameserver is derived as `.1` of the IP's /24. - **Migrate openclaw onto `cloonar.vms.openclaw`** — the two-consumer proof. Behaviour unchanged: same `.97.61`, MAC, 2 GiB / 2 vcpu, opt-in start, `openclaw-vm` unit and `/var/lib/openclaw-vm` state dir, and the `setup-openclaw` runcmd. The only delta is the internal tap name (`vm-openclaw` → `vm-openclaw-vm`), still matching `vm-*`. - **Add `cloonar.vms.dev`** — a temporary parallel VM on `.97.16` + a temp MAC, `autostart`, 100 GiB, `cpuWeight = 20`. Its tap `vm-dev-vm` deliberately avoids the live microVM's `vm-dev`. The microVM keeps `.97.15`; mem/vcpu stay at module defaults until cutover. ## Safety No collision with the live microVM: distinct unit (`dev-vm` vs `microvm@dev`), tap (`vm-dev-vm` vs `vm-dev`), MAC (`…04:01` vs `…02:01`), IP (`.16` vs `.15`), and state dir. `cpu-priorities.nix` is left targeting `microvm@dev` (still present); it folds into the new unit at cutover (PR3). Pre-commit dry-build green for all 6 hosts. Closes #160
First slice of the dev → self-managed QEMU VM migration (ADR-0018, PR1).
Pure Nix, dry-build-gated; no runtime cutover — the running dev microVM
(.97.15) is untouched.

- utils/modules/qemu-vm.nix: new reusable launcher exposing cloonar.vms.<name>
  — a state-dir tmpfile, a <name>-vm-init oneshot (Ubuntu cloud image → qcow2 +
  resize → regenerate cloud-init seed ISO), and a <name>-vm service (tap up on
  the server bridge → qemu → tap down). Options: mac / ip / mem / vcpu /
  diskSizeG / autostart / cpuWeight / cloudInit (sshKeys / packages / runcmd /
  writeFiles). cloud-init user-data is rendered via pkgs.formats.yaml so
  arbitrary writeFiles content is quoted/indented correctly.

- Migrate openclaw onto cloonar.vms.openclaw (two-consumer proof). Behaviour
  unchanged: same .97.61, MAC, 2 GiB / 2 vcpu, opt-in start, openclaw-vm unit
  and /var/lib/openclaw-vm state dir, and the setup-openclaw runcmd. The only
  delta is the internal tap name (vm-openclaw → vm-openclaw-vm), still vm-*.

- Add cloonar.vms.dev as a temporary parallel VM on .97.16 + a temp MAC,
  autostart, 100 GiB, cpuWeight 20. tap vm-dev-vm avoids the live microVM's
  vm-dev. The microVM keeps .97.15; mem/vcpu stay at defaults until cutover.

Closes #160
Author
Owner

This was generated by AI while landing a PR.

Validation: PASS — ready to merge pending maintainer go-ahead.

Signal relied on: this repo's gate is the commit-time pre-commit dry-build (eval). The body reports it green for all 6 hosts, and the diff adds no derivation src/*Hash (the Ubuntu image is a runtime curl, not a Nix fetch), so eval-only has no blind spot here — not re-run, per the repo's gate model.

Checked:

  • AFK contract: Closes #160 present (head afk/160).
  • Conventions: Conventional title; no secrets.yaml edit; no stateVersion change; module imported by explicit path.
  • Module (utils/modules/qemu-vm.nix): faithful generalisation of the openclaw lifecycle — pkgs.formats.yaml seed (safer than the old hand-spliced template), gateway derived as .1 of the /24, opt-in vs autostart, optional CPUWeight, tap on the server bridge with a -vm suffix to dodge the live vm-dev.
  • openclaw migration: behaviour-preserving — same .97.61 / MAC / 2 GiB / 2 vcpu / 20 G / opt-in / openclaw-vm unit + state dir + setup runcmd. Only delta: tap vm-openclaw → vm-openclaw-vm (cosmetic).
  • dev-temp: no collision with the live microVM — distinct unit (dev-vm vs microvm@dev), tap (vm-dev-vm vs vm-dev), MAC (…04:01 vs …02:01), IP (.16 vs .15), state dir.

Non-blocking notes for PR2 (#161):

  • -serial mon:stdio under systemd routes the console to the journal, not an interactive TTY — so the nixos-infect "serial console safety net" will in practice be SSH to .97.16; plan a real fallback (qemu monitor socket) in case infect drops the NIC.
  • cpu-priorities.nix still targets microvm@dev; it folds into dev-vm at cutover (PR3), as the body notes.
> *This was generated by AI while landing a PR.* **Validation: PASS** — ready to merge pending maintainer go-ahead. **Signal relied on:** this repo's gate is the commit-time pre-commit dry-build (eval). The body reports it green for all 6 hosts, and the diff adds no derivation `src`/`*Hash` (the Ubuntu image is a runtime `curl`, not a Nix fetch), so eval-only has no blind spot here — not re-run, per the repo's gate model. Checked: - **AFK contract:** `Closes #160` present (head `afk/160`). - **Conventions:** Conventional title; no `secrets.yaml` edit; no `stateVersion` change; module imported by explicit path. - **Module (`utils/modules/qemu-vm.nix`):** faithful generalisation of the openclaw lifecycle — `pkgs.formats.yaml` seed (safer than the old hand-spliced template), gateway derived as `.1` of the `/24`, opt-in vs `autostart`, optional `CPUWeight`, tap on the `server` bridge with a `-vm` suffix to dodge the live `vm-dev`. - **openclaw migration:** behaviour-preserving — same `.97.61` / MAC / 2 GiB / 2 vcpu / 20 G / opt-in / `openclaw-vm` unit + state dir + setup runcmd. Only delta: tap `vm-openclaw → vm-openclaw-vm` (cosmetic). - **dev-temp:** no collision with the live microVM — distinct unit (`dev-vm` vs `microvm@dev`), tap (`vm-dev-vm` vs `vm-dev`), MAC (…04:01 vs …02:01), IP (.16 vs .15), state dir. Non-blocking notes for PR2 (#161): - `-serial mon:stdio` under systemd routes the console to the journal, not an interactive TTY — so the `nixos-infect` "serial console safety net" will in practice be SSH to `.97.16`; plan a real fallback (qemu monitor socket) in case infect drops the NIC. - `cpu-priorities.nix` still targets `microvm@dev`; it folds into `dev-vm` at cutover (PR3), as the body notes.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/nixos!163
No description provided.