docs(migration): guide for migrating an existing NixOS machine to Nomarchy
Some checks failed
Check / eval (push) Has been cancelled
Some checks failed
Check / eval (push) Has been cancelled
Bernardo asked whether TuringMachine (NixOS 25.11) could adopt Nomarchy without a reinstall, keeping all files. It can — it's a config switch that reuses the existing hardware-configuration.nix, not a reformat. Adds docs/MIGRATION.md: a generic "existing NixOS → Nomarchy" walkthrough with TuringMachine as the worked example — candidacy checklist, the two data-safety rules (never bump system.stateVersion; /home untouched), a reversible Phase 0→4 (btrfs snapshot → build-only gate → nixos-rebuild test → reconcile → cutover) and a triple rollback net. Bakes his decisions: Nomarchy PPD (drop all ryzenadj), no Secure Boot (drop lanzaboote), full cutover. Flake/system/home examples verified against lib.nix mkFlake + templates/downstream, not guessed. Also files a PROPOSED note: home.stateVersion should be mkDefault so migrating users don't need mkForce. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -275,6 +275,16 @@ actually float once seen (regex tolerance for the `.…-wrapped` form).
|
|||||||
*Agents: append here with a one-paragraph pitch (what/why/cost). Do not
|
*Agents: append here with a one-paragraph pitch (what/why/cost). Do not
|
||||||
implement. Bernardo moves accepted items into a tier.*
|
implement. Bernardo moves accepted items into a tier.*
|
||||||
|
|
||||||
|
- **`home.stateVersion` should be `mkDefault`** (surfaced writing
|
||||||
|
docs/MIGRATION.md, 2026-07-08). `modules/home/default.nix:51` sets
|
||||||
|
`home.stateVersion = "26.05"` as a *plain* assignment, so a downstream
|
||||||
|
home.nix that needs a different value (anyone migrating an existing NixOS
|
||||||
|
install — their original install's stateVersion) can only override it with
|
||||||
|
`lib.mkForce`, which reads as a hack. Cheap fix: make it
|
||||||
|
`lib.mkDefault "26.05"` so a plain downstream assignment wins cleanly,
|
||||||
|
matching the mkDefault discipline the rest of the distro follows. (The
|
||||||
|
system side is already fine — the downstream owns system.nix outright.)
|
||||||
|
|
||||||
- **Battery charge-limit — make the toggle instant** `[blocked:hw]`
|
- **Battery charge-limit — make the toggle instant** `[blocked:hw]`
|
||||||
(follow-up to the preset toggle shipped 2026-07-07, iteration #55).
|
(follow-up to the preset toggle shipped 2026-07-07, iteration #55).
|
||||||
The control-center now has a proper toggle (Off / 80% / 90% / 60% /
|
The control-center now has a proper toggle (Off / 80% / 90% / 60% /
|
||||||
|
|||||||
@@ -17,6 +17,33 @@ Template:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-07-08 — Migration guide: existing NixOS → Nomarchy (docs, direct request)
|
||||||
|
- **Task:** Bernardo asked whether THIS machine (TuringMachine, NixOS 25.11)
|
||||||
|
can migrate to Nomarchy without a reinstall, keeping all files — and to
|
||||||
|
write the walkthrough into a MIGRATION.md.
|
||||||
|
- **Investigated the live machine:** already NixOS, personal modular flake,
|
||||||
|
systemd-boot, LUKS2 + btrfs with the exact subvol layout Nomarchy wants
|
||||||
|
(incl. `@snapshots`/`@home-snapshots`), AMD 7840U. Verdict: migration is a
|
||||||
|
config switch (reuse hardware-configuration.nix), NOT a reinstall; `@home`
|
||||||
|
is never touched. Main deltas: 25.11→26.05, keep system.stateVersion=24.11,
|
||||||
|
power-mgmt collision (his ryzenadj/TLP vs Nomarchy PPD), HM-module→standalone.
|
||||||
|
- **Decisions (Bernardo):** adopt Nomarchy PPD + drop all ryzenadj; no Secure
|
||||||
|
Boot (drop lanzaboote); full cutover.
|
||||||
|
- **Did:** wrote `docs/MIGRATION.md` — generic "existing NixOS → Nomarchy"
|
||||||
|
guide with TuringMachine as the worked example: candidacy checklist, the
|
||||||
|
two data-safety rules (never bump system.stateVersion; /home untouched),
|
||||||
|
Phase 0 snapshots → Phase 1 build-only gate → Phase 2 reversible
|
||||||
|
`nixos-rebuild test` → Phase 3 reconcile → Phase 4 cutover, triple rollback
|
||||||
|
net. Verified the downstream API against lib.nix (mkFlake src/username/
|
||||||
|
hardwareProfile) + templates/downstream so the flake/system/home examples
|
||||||
|
are real, not guessed.
|
||||||
|
- **Verified:** V0 (docs) — referential accuracy against lib.nix + template;
|
||||||
|
did NOT run the migration commands (they'd alter the live machine).
|
||||||
|
- **Follow-ups:** PROPOSED — make `home.stateVersion` mkDefault (migrating
|
||||||
|
users currently need mkForce).
|
||||||
|
- **Next suggestion:** if Bernardo greenlights, scaffold Phase 1 from his real
|
||||||
|
hardware-configuration.nix.
|
||||||
|
|
||||||
## 2026-07-08 — Calendar on the clock click (iteration #68, item 42)
|
## 2026-07-08 — Calendar on the clock click (iteration #68, item 42)
|
||||||
- **Task:** item 42, de-scoped live by Bernardo — DON'T hook up calendar
|
- **Task:** item 42, de-scoped live by Bernardo — DON'T hook up calendar
|
||||||
accounts; just ship a lightweight calendar that opens instantly on the
|
accounts; just ship a lightweight calendar that opens instantly on the
|
||||||
|
|||||||
300
docs/MIGRATION.md
Normal file
300
docs/MIGRATION.md
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
# Migrating an existing NixOS machine to Nomarchy (no reinstall)
|
||||||
|
|
||||||
|
If your machine already runs NixOS, you do **not** need the installer or a
|
||||||
|
reformat to adopt Nomarchy. Nomarchy is a flake; "installing" it onto an
|
||||||
|
existing NixOS box means pointing `nixos-rebuild` at a Nomarchy‑based flake
|
||||||
|
that reuses your current `hardware-configuration.nix`. Nothing repartitions,
|
||||||
|
and your `/home` is never written to by an activation.
|
||||||
|
|
||||||
|
This guide is written generically, with **TuringMachine** — a Lenovo AMD
|
||||||
|
Ryzen 7840U / Radeon 780M laptop, LUKS + btrfs, systemd‑boot — as the
|
||||||
|
concrete worked example. Substitute your own values where called out.
|
||||||
|
|
||||||
|
> **The promise:** every step below is reversible. You keep three
|
||||||
|
> independent rollback nets (NixOS generations, a btrfs snapshot, and the
|
||||||
|
> fact that `nixos-rebuild test` never changes the boot default), and your
|
||||||
|
> files live on a separate subvolume that no config switch touches.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Is your machine a good candidate?
|
||||||
|
|
||||||
|
Migration is cleanest when your machine already matches Nomarchy's
|
||||||
|
assumptions. Check each:
|
||||||
|
|
||||||
|
| Nomarchy expects | Check it | If it differs |
|
||||||
|
|---|---|---|
|
||||||
|
| **systemd‑boot** | `bootctl status` → "Product: systemd‑boot" | GRUB works too; keep your loader config in `system.nix` |
|
||||||
|
| **btrfs** with `@`/`@home` subvolumes | `findmnt -t btrfs` | ext4/xfs boot fine — you just don't get snapshots |
|
||||||
|
| `@snapshots` + `@home-snapshots` subvols | in `findmnt` output | snapper features need them; create them or skip snapshots |
|
||||||
|
| **LUKS** (optional, themed prompt) | `lsblk -f` shows `crypto_LUKS` | none — LUKS is optional |
|
||||||
|
| Already a **flake** config | `test -f /etc/nixos/flake.nix` | fine either way; you'll write a fresh flake regardless |
|
||||||
|
|
||||||
|
TuringMachine matches all of these, including the `@snapshots` /
|
||||||
|
`@home-snapshots` subvolumes — so snapper works with zero disk work.
|
||||||
|
|
||||||
|
**Version note.** Nomarchy pins `nixos-26.05`. If you're on an older release
|
||||||
|
(TuringMachine is on **25.11**), the migration folds a one‑release upgrade
|
||||||
|
into the switch. That's normal and supported — read the
|
||||||
|
[NixOS 26.05 release notes](https://nixos.org/manual/nixos/stable/release-notes)
|
||||||
|
for option/package renames, and lean on generations if something regresses.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. The two rules that protect your data
|
||||||
|
|
||||||
|
1. **Never bump `system.stateVersion`.** It is an on‑disk/service
|
||||||
|
compatibility marker tied to when the machine was *first installed* — not
|
||||||
|
the nixpkgs version. Nomarchy's template ships `26.05`; you **must** change
|
||||||
|
it back to your machine's original value. Find yours:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nixos-option system.stateVersion # or: nix eval .#nixosConfigurations.<host>.config.system.stateVersion
|
||||||
|
"24.11"
|
||||||
|
```
|
||||||
|
|
||||||
|
*(TuringMachine: `24.11`.)*
|
||||||
|
|
||||||
|
2. **`/home` is never touched by an activation.** A `nixos-rebuild switch`
|
||||||
|
swaps the system generation; your data subvolume is untouched. The Phase 0
|
||||||
|
snapshot is belt‑and‑suspenders, not a necessity for file safety.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 0 — Safety net (nothing changes yet)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Read-only btrfs snapshots of root and home — instant rollback targets.
|
||||||
|
sudo btrfs subvolume snapshot -r / /.snapshots/pre-nomarchy-root
|
||||||
|
sudo btrfs subvolume snapshot -r /home /home/.snapshots/pre-nomarchy-home
|
||||||
|
|
||||||
|
# Freeze your current config as a clean git baseline.
|
||||||
|
cd /etc/nixos && git add -A && git commit -m "pre-nomarchy baseline" || true
|
||||||
|
```
|
||||||
|
|
||||||
|
You are currently booted in a known‑good generation; it remains in the
|
||||||
|
systemd‑boot menu throughout. Worst case at any later step: reboot and pick
|
||||||
|
it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1 — Build the Nomarchy flake alongside (no switch)
|
||||||
|
|
||||||
|
Stand the new config up in a working directory and **build** it without
|
||||||
|
activating. This is the real safety line: iterate here until it builds green
|
||||||
|
before anything touches the running system.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.bemagri.xyz/bernardo/nomarchy.git ~/nomarchy-migrate
|
||||||
|
cd ~/nomarchy-migrate
|
||||||
|
# Or start from the downstream template:
|
||||||
|
# nix flake init -t github:.../nomarchy (produces flake.nix/system.nix/home.nix/…)
|
||||||
|
```
|
||||||
|
|
||||||
|
A Nomarchy downstream flake owns exactly five files. Assemble them:
|
||||||
|
|
||||||
|
### `hardware-configuration.nix` — reuse yours unchanged
|
||||||
|
|
||||||
|
Copy your **existing** hardware config in verbatim. This is what preserves
|
||||||
|
your disks, LUKS, btrfs subvolumes and swap — the reason no reinstall is
|
||||||
|
needed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp /etc/nixos/hosts/TuringMachine/hardware-configuration.nix ./hardware-configuration.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
### `flake.nix` — one `mkFlake` call (from the template)
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
description = "TuringMachine — Nomarchy";
|
||||||
|
inputs.nomarchy.url = "git+https://git.bemagri.xyz/bernardo/nomarchy.git?ref=v1";
|
||||||
|
|
||||||
|
outputs = { nomarchy, ... }:
|
||||||
|
nomarchy.lib.mkFlake {
|
||||||
|
src = ./.;
|
||||||
|
username = "bernardo"; # <- your login name
|
||||||
|
# Optional nixos-hardware profile(s) for your model. For an AMD laptop:
|
||||||
|
# hardwareProfile = [ "common-cpu-amd-pstate" "common-gpu-amd" "common-pc-laptop-ssd" ];
|
||||||
|
# Names: https://github.com/NixOS/nixos-hardware (verify before use)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `system.nix` — machine specifics + your decisions
|
||||||
|
|
||||||
|
This is where your three migration decisions land: **PPD power (no
|
||||||
|
ryzenadj)**, **no Secure Boot**, and the **stateVersion override**.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ pkgs, username, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Plain systemd-boot — no lanzaboote / Secure Boot.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
networking.hostName = "TuringMachine";
|
||||||
|
time.timeZone = "Europe/London"; # your zone
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
users.users.${username} = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "networkmanager" "video" "input" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# ── Power: Nomarchy's PPD (drops all custom ryzenadj/TLP tuning) ──────
|
||||||
|
nomarchy.system.power = {
|
||||||
|
enable = true;
|
||||||
|
backend = "ppd"; # power-profiles-daemon
|
||||||
|
laptop = true;
|
||||||
|
batteryChargeLimit = 80; # optional longevity cap
|
||||||
|
};
|
||||||
|
|
||||||
|
# ── AMD 7840U / Radeon 780M ──────────────────────────────────────────
|
||||||
|
nomarchy.hardware.amd.enable = true; # amd-pstate + radeonsi VA-API
|
||||||
|
# nomarchy.hardware.amd.rocm.enable = true; # opt-in GPU compute (multi-GB)
|
||||||
|
|
||||||
|
# CRITICAL: keep your ORIGINAL install's value — never Nomarchy's 26.05.
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Dropped on purpose (decisions 1 & 2):** your old
|
||||||
|
> `modules/services/power-management.nix` ryzenadj stack, the `lanzaboote`
|
||||||
|
> input, and the `power-max`/`power-stealth` scripts. PPD's
|
||||||
|
> performance/balanced/power‑saver profiles (switchable from the Waybar
|
||||||
|
> battery/profile icons and `nomarchy-menu`) replace them.
|
||||||
|
|
||||||
|
### `home.nix` — your apps on top of Nomarchy's desktop
|
||||||
|
|
||||||
|
Start from the template's `home.nix` (it ships the default app set) and add
|
||||||
|
your personal packages/config. Carry over anything you still want (e.g. your
|
||||||
|
emacs setup).
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Nomarchy hardcodes home.stateVersion = "26.05". Moving home-manager's
|
||||||
|
# stateVersion is low-risk, but if you want to pin your original:
|
||||||
|
home.stateVersion = lib.mkForce "24.11";
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# your extras — e.g. emacs, language toolchains, …
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `theme-state.json`
|
||||||
|
|
||||||
|
Copy the template's `theme-state.json` (or let `nomarchy-menu theme` write
|
||||||
|
it after the switch). Your old `nomarchy-state.nix` prototype (schema
|
||||||
|
`nomarchy.theme = "nord"` …) is **retired** — the current distro uses this
|
||||||
|
JSON. `nord` is a shipped Nomarchy theme, so you lose nothing.
|
||||||
|
|
||||||
|
### The build gate
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-rebuild build --flake ~/nomarchy-migrate#default
|
||||||
|
```
|
||||||
|
|
||||||
|
Zero activation — this only evaluates and builds the system closure. Fix any
|
||||||
|
eval/build error here, in isolation, before touching the running machine.
|
||||||
|
Expect to resolve a few 25.11→26.05 option renames.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2 — Reversible activation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Activates now, but does NOT become the boot default. If the session
|
||||||
|
# breaks, REBOOT and you are back in your old generation, untouched.
|
||||||
|
sudo nixos-rebuild test --flake ~/nomarchy-migrate#default
|
||||||
|
|
||||||
|
# Bring the desktop (home-manager) up:
|
||||||
|
home-manager switch --flake ~/nomarchy-migrate#bernardo
|
||||||
|
```
|
||||||
|
|
||||||
|
Log into Hyprland and sanity‑check: Waybar renders, `SUPER+M` opens the
|
||||||
|
menu, theming is coherent, `SUPER+?` shows the cheatsheet. Confirm the
|
||||||
|
machine‑specific things you care about still work — suspend/hibernate, the
|
||||||
|
AMD GPU (`vainfo` → radeonsi), display brightness.
|
||||||
|
|
||||||
|
If anything is wrong: **reboot → old generation.** Nothing is committed as
|
||||||
|
default yet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3 — Reconcile
|
||||||
|
|
||||||
|
- **Power:** verify `powerprofilesctl get` works and the Waybar battery /
|
||||||
|
power‑profile icons open the power menu. Your ryzenadj scripts are gone;
|
||||||
|
if you miss a specific TDP behaviour, that's a follow‑up, not a blocker.
|
||||||
|
- **Theme:** `nomarchy-menu theme` → pick **nord** (writes
|
||||||
|
`theme-state.json`).
|
||||||
|
- **Snapshots:** `nomarchy-menu` → System → Snapshots should see your
|
||||||
|
existing `@snapshots` subvolume.
|
||||||
|
- **Secrets/services:** if you relied on agenix‑managed secrets for a
|
||||||
|
service, layer `agenix` back into `system.nix` as a machine‑specific
|
||||||
|
import (Nomarchy doesn't manage secrets). If you don't need them, leave
|
||||||
|
them out — this is a full cutover.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4 — Cutover
|
||||||
|
|
||||||
|
Once a test boot is solid:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Move the flake to its canonical home and make it the boot default.
|
||||||
|
mv ~/nomarchy-migrate ~/.nomarchy
|
||||||
|
sudo nixos-rebuild switch --flake ~/.nomarchy#default
|
||||||
|
home-manager switch --flake ~/.nomarchy#bernardo
|
||||||
|
|
||||||
|
# Point /etc/nixos at the flake (optional but conventional).
|
||||||
|
sudo mv /etc/nixos /etc/nixos.pre-nomarchy
|
||||||
|
sudo ln -s ~/.nomarchy /etc/nixos
|
||||||
|
```
|
||||||
|
|
||||||
|
From here you're on the standard Nomarchy update flow: `sys-update` (lock +
|
||||||
|
system) then `home-update` (desktop) — always in that order (a lock bump
|
||||||
|
before the home switch, or desktop changes are skipped against the old
|
||||||
|
lock).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rollback, at any point
|
||||||
|
|
||||||
|
| Net | How |
|
||||||
|
|---|---|
|
||||||
|
| **NixOS generation** | Reboot → pick the previous entry in the systemd‑boot menu. |
|
||||||
|
| **`nixos-rebuild test`** | Never sets the boot default; a reboot reverts it. |
|
||||||
|
| **btrfs snapshot** | Restore `/.snapshots/pre-nomarchy-root` (see `docs/RECOVERY.md`). |
|
||||||
|
| **git baseline** | `/etc/nixos.pre-nomarchy` (and the pre‑nomarchy commit) is your old config verbatim. |
|
||||||
|
|
||||||
|
`/home` is untouched by all of the above.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Post‑migration cleanup (once you're confident)
|
||||||
|
|
||||||
|
- Delete the safety snapshots: `sudo btrfs subvolume delete /.snapshots/pre-nomarchy-root` (and the home one).
|
||||||
|
- Remove `/etc/nixos.pre-nomarchy` and the old per‑host modules you cut
|
||||||
|
(ryzenadj power‑management, lanzaboote, the `nomarchy-state.nix`
|
||||||
|
prototype).
|
||||||
|
- Prune old generations: `sudo nix-collect-garbage -d`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TuringMachine — the decisions, at a glance
|
||||||
|
|
||||||
|
| Item | Choice |
|
||||||
|
|---|---|
|
||||||
|
| Power | Nomarchy **PPD** (`backend = "ppd"`); **all ryzenadj/TLP tuning dropped** |
|
||||||
|
| Secure Boot | **Off** — plain systemd‑boot, `lanzaboote` dropped |
|
||||||
|
| Scope | **Full cutover** to Nomarchy's structure |
|
||||||
|
| `system.stateVersion` | **`24.11`** (preserved from original install) |
|
||||||
|
| Hardware | `nomarchy.hardware.amd.enable = true` (7840U / Radeon 780M) |
|
||||||
|
| Bootloader | systemd‑boot (unchanged — already matched) |
|
||||||
|
| Filesystem | LUKS + btrfs, existing subvolumes reused (incl. snapshot subvols) |
|
||||||
Reference in New Issue
Block a user