docs(beefcake): relocation runbook (ZFS-native mounts, done imperatively) #619

Merged
lytedev merged 2 commits from beefcake-relocate-state into main 2026-06-29 10:39:00 -05:00
Owner

DRAFT — do not deploy until (1) the runbook's data migration is done and (2) beefcake's live dirty dns-primary.nix/router.nix edits are committed.

What

Moves the last two big stateful trees off beefcake's single non-redundant boot disk onto the pool:

  • zstorage/containers/var/lib/containers (podman overlay store, ~42G)
  • zstorage/varlib-private/var/lib/private (systemd DynamicUser state, ~29G)

Both as legacy mountpoints declared in hardware.nix (like /nix), so NixOS owns the mount and boot ordering.

Why

Root sits at 224G/86% on a single 10K SAS spinner with no redundancy. Everything else already lives on zstorage/storage; these never moved. Relocating gets them triple-parity + auto-snapshots and shrinks root enough for the planned 240GB SSD boot mirror.

/home (73G) is not in this PR — the audit found it's ~99% disposable (60G rootless podman images, caches, toolchains, ISOs, game tarballs). It's handled as cleanup in the runbook (rescue ~tens of MB — incl. 8 unpushed code/nix commits — then wipe).

Runbook

issues/open/beefcake-relocate-state-to-pool.md — full copy→verify→swap procedure (originals kept as *.old), ordered: resilver-done → /home cleanup → containers → /var/lib/private → deploy this PR → verify → delete .old.

⚠️ Ordering / coordination

  1. Datasets + data must exist before this deploys, or empty datasets mount over live state.
  2. The deploy reverts uncommitted work; beefcake's live DNS edits must be committed first.

🤖 Generated with Claude Code

> **DRAFT — do not deploy until (1) the runbook's data migration is done and (2) beefcake's live dirty `dns-primary.nix`/`router.nix` edits are committed.** ## What Moves the last two big stateful trees off beefcake's single non-redundant boot disk onto the pool: - `zstorage/containers` → `/var/lib/containers` (podman overlay store, ~42G) - `zstorage/varlib-private` → `/var/lib/private` (systemd DynamicUser state, ~29G) Both as `legacy` mountpoints declared in `hardware.nix` (like `/nix`), so NixOS owns the mount and boot ordering. ## Why Root sits at 224G/86% on a single 10K SAS spinner with no redundancy. Everything else already lives on `zstorage/storage`; these never moved. Relocating gets them triple-parity + auto-snapshots and shrinks root enough for the planned 240GB SSD boot mirror. `/home` (73G) is **not** in this PR — the audit found it's ~99% disposable (60G rootless podman images, caches, toolchains, ISOs, game tarballs). It's handled as cleanup in the runbook (rescue ~tens of MB — incl. **8 unpushed `code/nix` commits** — then wipe). ## Runbook `issues/open/beefcake-relocate-state-to-pool.md` — full copy→verify→swap procedure (originals kept as `*.old`), ordered: resilver-done → /home cleanup → containers → /var/lib/private → deploy this PR → verify → delete `.old`. ## ⚠️ Ordering / coordination 1. Datasets + data must exist **before** this deploys, or empty datasets mount over live state. 2. The deploy reverts uncommitted work; beefcake's live DNS edits must be committed first. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(beefcake): relocate containers + DynamicUser state onto zstorage
All checks were successful
/ check-format (push) Successful in 8s
/ build (push) Successful in 6m58s
9ab50d8587
Add fileSystems entries mounting zstorage/containers -> /var/lib/containers
and zstorage/varlib-private -> /var/lib/private (legacy mountpoints, like
/nix) so podman's overlay store and systemd DynamicUser state land on the
redundant pool instead of the single non-redundant boot disk.

Paired with a runbook (issues/open/beefcake-relocate-state-to-pool.md): the
datasets + data must be created/rsynced BEFORE this deploys, else empty
datasets mount over live state. /home is handled as cleanup (it is ~99%
disposable cruft), not relocation.

Do not deploy until the runbook's data-migration steps are done AND the live
dirty dns-primary/router edits on beefcake are committed (else the deploy
reverts them).
lytedev changed title from feat(beefcake): relocate containers + DynamicUser state onto zstorage to wip: feat(beefcake): relocate containers + DynamicUser state onto zstorage 2026-06-26 20:55:09 -05:00
lytedev changed title from wip: feat(beefcake): relocate containers + DynamicUser state onto zstorage to WIP: feat(beefcake): relocate containers + DynamicUser state onto zstorage 2026-06-29 09:37:41 -05:00
Author
Owner

Marked WIP/draft — do not merge as-is.

The migration was ultimately done with ZFS-native mountpoints (mountpoint=/var/lib/containers and /var/lib/private, same pattern as /storage), executed imperatively on 2026-06-29. The hardware.nix fileSystems entries in this PR assume legacy mountpoints and would conflict with the live ZFS-native mounts if deployed — a backward / duplicate-mount hazard.

To make ready, pick one:

  1. Runbook-only: drop the hardware.nix change; keep issues/open/beefcake-relocate-state-to-pool.md as documentation (safe to merge).
  2. Proper declarative: switch the live datasets to mountpoint=legacy (zfs set mountpoint=legacy zstorage/containers zstorage/varlib-private — needs the services stopped to remount) then deploy these fileSystems entries, for ironclad reboot ordering on /var/lib/private.

Until one of those is done + verified, this stays draft.

Marked WIP/draft — do **not** merge as-is. The migration was ultimately done with **ZFS-native mountpoints** (`mountpoint=/var/lib/containers` and `/var/lib/private`, same pattern as `/storage`), executed imperatively on 2026-06-29. The `hardware.nix` `fileSystems` entries in this PR assume **legacy** mountpoints and would **conflict** with the live ZFS-native mounts if deployed — a backward / duplicate-mount hazard. To make ready, pick one: 1. **Runbook-only:** drop the `hardware.nix` change; keep `issues/open/beefcake-relocate-state-to-pool.md` as documentation (safe to merge). 2. **Proper declarative:** switch the live datasets to `mountpoint=legacy` (`zfs set mountpoint=legacy zstorage/containers zstorage/varlib-private` — needs the services stopped to remount) **then** deploy these `fileSystems` entries, for ironclad reboot ordering on `/var/lib/private`. Until one of those is done + verified, this stays draft.
make runbook-only: drop conflicting hardware.nix fileSystems entries
All checks were successful
/ check-format (push) Successful in 23s
/ build (push) Successful in 21m25s
97b589fa3c
The relocation was done imperatively with ZFS-native mountpoints (like
/storage), so declaring legacy-mountpoint fileSystems here would conflict
with the live mounts. Keep only the runbook (moved to issues/closed/ as the
work is complete 2026-06-29). Mounts intentionally stay ZFS-native and are
deploy-safe (verified: survived a full switch-to-configuration).
lytedev changed title from WIP: feat(beefcake): relocate containers + DynamicUser state onto zstorage to docs(beefcake): relocation runbook (ZFS-native mounts, done imperatively) 2026-06-29 10:14:19 -05:00
lytedev deleted branch beefcake-relocate-state 2026-06-29 10:39:01 -05:00
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
lytedev/nix!619
No description provided.