dot

vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks

897cb7d

Install with nixos-anywhere from the MacBook

By Gustaf Granström

MIGRATION.md drops the USB installer and the saved system: nixos-anywhere
kexecs CachyOS into an installer, runs disko and builds the system on the
desktop. tools/restore-from-sata puts back what restore-filter lists, and
the backup script no longer saves a built system. The Mac's SSH key goes in
macKeys in hosts/desktop/default.nix, for root and vizie.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

5 files changed +96 −120

modifiedMIGRATION.md
@@ -1,127 +1,79 @@
11 # Moving from CachyOS to NixOS
22
3-The install wipes the whole NVMe drive (`nvme0n1`, the 980 PRO) and lays it out
4-again with disko, as `hosts/desktop/disko.nix` describes. CachyOS and everything
5-in it are gone afterwards, so your home folder goes to the Kingston SATA SSD
6-(`sda`) first and comes back after the install. Game installs aren't backed up
7-(see `backup-filter`): Steam games and WoW download again. WoW's settings and
8-addons are kept.
3+[nixos-anywhere]https://github.com/nix-community/nixos-anywhere installs
4+NixOS from the MacBook over SSH. It switches the running CachyOS into a NixOS
5+installer in RAM (kexec), wipes the NVMe drive and lays it out as
6+`hosts/desktop/disko.nix` says, builds the system on the desktop itself and
7+reboots into it. No USB stick, and nothing Linux gets built on the Mac.
98
10-The other SATA SSD (`sdb`) isn't touched at any point. disko only knows the
11-NVMe drive, by its serial number.
9+CachyOS and everything on the NVMe drive are gone afterwards. Your home folder
10+is backed up to the Kingston SATA SSD (`sda`) first, and only what
11+`restore-filter` lists comes back: it's a fresh start. The other SATA SSD
12+(`sdb`) is never touched.
1213
13-## 1. Before you start (on CachyOS)
14+## 1. On the desktop (CachyOS)
1415
15-- [ ] Push this repo and the latest `Eiziv/philly`.
16-- [ ] Get the NixOS installer (26.05, minimal is enough) on a USB stick, and
17- make sure Secure Boot is off in the firmware, as it is for Limine now.
18-- [ ] Optional, but this is the last chance: record WoW's performance on
19- CachyOS, to compare with NixOS later. In Faugus, edit Battle.net, turn
20- on MangoHud and add this line to the launch arguments:
16+- [ ] Optional, but the last chance: record WoW's performance to compare
17+ later. In Faugus, edit Battle.net, turn on MangoHud and add this line to
18+ the launch arguments:
2119 `MANGOHUD_CONFIG=read_cfg,output_folder=/home/vizie/benchmarks,log_duration=60,log_interval=0`.
2220 In game, stand somewhere you can return to (a busy city), keep the camera
23- still and press Left Shift+F2. Do it three times. The logs land in
24- `~/benchmarks`, which the backup includes. Do the same on NixOS later,
25- then compare the two with `~/git/dot/tools/bench-compare`.
21+ still and press Left Shift+F2. Do it three times. Do the same on NixOS
22+ later and compare with `~/git/dot/tools/bench-compare`.
23+- [ ] Quit Signal, Discord, Firefox, Claude and the games, then update the
24+ backup (only what changed since the last run is copied):
2625
27-The backup can be made ahead of time, days before the install if you like.
28-Right before the wipe you run the two rsync commands below again (and the
29-"save the built system" step, if the config changed since); they only copy
30-what changed, so that takes a minute or two.
26+ ```bash
27+ sudo ~/git/dot/tools/backup-to-sata
28+ ```
3129
32-`tools/backup-to-sata` does all of the steps below in one go (run it with
33-`sudo`; it only formats the Kingston if it is empty). They are spelled out here
34-too, in case you'd rather do them by hand.
30+- [ ] Let the Mac log in as root, which nixos-anywhere needs. Paste the Mac's
31+ public key (`cat ~/.ssh/id_ed25519.pub` on the Mac) into:
3532
36-**Prepare the backup drive** (once). This erases `sda`, the 112 GB Kingston, which
37-is empty now. Check that the name points at `sda` first:
33+ ```bash
34+ sudo install -d -m700 /root/.ssh && sudo nano /root/.ssh/authorized_keys
35+ ```
3836
39-```bash
40-ls -l /dev/disk/by-id/ata-KINGSTON_SA400S37120G_50026B76820FD3CE
41-sudo mkfs.btrfs -L backup /dev/disk/by-id/ata-KINGSTON_SA400S37120G_50026B76820FD3CE
42-sudo mkdir -p /mnt/backup
43-sudo mount -o compress=zstd /dev/disk/by-label/backup /mnt/backup
44-sudo install -d -o vizie /mnt/backup/nix-cache /mnt/backup/wow
45-```
37+## 2. On the Mac
4638
47-**Save the built system.** The finished system and the disko script go onto
48-the backup drive, so the installer doesn't have to build anything (or compile
49-the CachyOS kernel, if its binary cache is still down):
39+Needs Nix (with flakes) and the GitHub CLI signed in to your account: `dot`
40+and `philly` are private, and `gh auth setup-git` lets Nix fetch them. The
41+Mac's public key must also be in `macKeys` in `hosts/desktop/default.nix`
42+(committed and pushed), so it can still log in after the install.
5043
5144 ```bash
52-cd ~/git/dot
53-sys=$(nix build --no-link --print-out-paths .#nixosConfigurations.desktop.config.system.build.toplevel)
54-disko=$(nix build --no-link --print-out-paths .#nixosConfigurations.desktop.config.system.build.diskoScript)
55-nix copy --to 'file:///mnt/backup/nix-cache?compression=zstd' "$sys" "$disko"
56-echo "$sys" > /mnt/backup/nix-cache/system
57-echo "$disko" > /mnt/backup/nix-cache/disko
45+gh auth setup-git
46+gh repo clone Eiziv/dot ~/dot
5847 ```
5948
60-**Back up WoW's settings and addons** (`WTF` is keybinds, macros and addon
61-settings, `Interface` is the addons):
49+Check from the Mac that `ssh root@10.0.0.40` logs in. Then install. **This wipes
50+the desktop's NVMe drive** without asking again:
6251
6352 ```bash
64-rsync -a --delete ~/Games/battlenet/drive_c/'Program Files (x86)'/'World of Warcraft'/_retail_/{WTF,Interface} /mnt/backup/wow/
53+nix run github:nix-community/nixos-anywhere -- --flake ~/dot#desktop --build-on remote --copy-host-keys --no-use-machine-substituters root@10.0.0.40
6554 ```
6655
67-**Back up your home folder.** Quit Signal, Discord, Firefox, Claude and the
68-games first, so their databases aren't copied halfway through a write. About
69-83 GB before compression, and the saved system adds roughly 10 GB, so it fits
70-the 112 GB drive with some room. If it runs out of space, leave out repos that
71-are pushed to GitHub (the biggest are `git/skate3`, 23 GB, and `git/philly`,
72-16 GB) with an extra `--exclude=/git/skate3/`:
56+It takes a while: the CachyOS kernel's binary cache has been down, so the
57+kernel compiles on the desktop. `--no-use-machine-substituters` skips that
58+cache; if it's back up (`curl -sI https://attic.xuyh0120.win/lantian/nix-cache-info`
59+gives 200), leave the flag out and the kernel downloads instead. The desktop
60+reboots into NixOS at the end.
7361
74-```bash
75-sudo rsync -aHAXx --delete --info=progress2 --filter='merge /home/vizie/git/dot/backup-filter' /home/vizie/ /mnt/backup/vizie/
76-```
77-
78-Check that it looks complete (`ls -a /mnt/backup/vizie`, `du -sh /mnt/backup/*`),
79-then `sudo umount /mnt/backup`. To update the backup later, mount it again
80-(`sudo mount -o compress=zstd /dev/disk/by-label/backup /mnt/backup`) and rerun
81-the commands above.
82-
83-## 2. Install
62+## 3. After the reboot
8463
85-Boot the installer. Wired network works out of the box; the install itself
86-doesn't need it.
64+From the Mac (its key is in the config, for root and for you):
8765
8866 ```bash
89-sudo -i
90-
91-# The backup drive, read-only. Not under /mnt: disko unmounts everything there.
92-mkdir /backup
93-mount -o ro /dev/disk/by-label/backup /backup
94-sys=$(cat /backup/nix-cache/system)
95-disko=$(cat /backup/nix-cache/disko)
96-
97-# The disko script. It doesn't ask before it wipes, so check that the drive it
98-# names is the 980 PRO (nvme0n1) one last time.
99-ls -l /dev/disk/by-id/nvme-Samsung_SSD_980_PRO_1TB_S5GXNF1R877751D
100-nix --extra-experimental-features nix-command copy --no-check-sigs --from file:///backup/nix-cache "$disko"
101-
102-# Wipe, partition, format and mount the NVMe drive at /mnt.
103-"$disko"
104-
105-# Copy the system onto it and install it, with the boot loader.
106-nix --extra-experimental-features nix-command copy --no-check-sigs \
107- --from file:///backup/nix-cache --to 'local?root=/mnt' "$sys"
108-nixos-install --system "$sys" --no-channel-copy
109-# It asks for a root password at the end.
110-
111-# What you chose to keep of your home folder (restore-filter), owned by you
112-# (uid 1000, group users). The rest stays on the backup drive.
113-rsync -aHAX --info=progress2 --chown=1000:100 \
114- --filter='merge /backup/vizie/git/dot/restore-filter' /backup/vizie/ /mnt/home/vizie/
115-nixos-enter --root /mnt -c 'passwd vizie'
116-reboot
67+ssh root@10.0.0.40
68+passwd vizie
69+mount -o ro /dev/disk/by-label/backup /mnt
70+/mnt/vizie/git/dot/tools/restore-from-sata
71+umount /mnt
11772 ```
11873
119-If something in `/backup/nix-cache` is missing, install from the flake instead
120-(this needs the network, and compiles the kernel if its cache is down):
121-`nixos-install --flake /backup/vizie/git/dot#desktop` after
122-`nix run github:nix-community/disko/latest -- --mode destroy,format,mount /backup/vizie/git/dot/hosts/desktop/disko.nix`.
74+Then log in on the desktop.
12375
124-## 3. First boot
76+## 4. On the new system
12577
12678 - The login screen is the same gtkgreet over the blurred wallpaper.
12779 - Only what `restore-filter` lists came back: app data and logins, SSH keys,
@@ -133,7 +85,7 @@
13385 `nix-index` (takes a few minutes).
13486 - Check the background programs: `systemctl --user list-units --type=service`.
13587
136-## 4. What changed
88+## 5. What changed
13789
13890 What is different from CachyOS, all on purpose:
13991
@@ -169,7 +121,7 @@
169121 - **sched-ext** schedulers stay off, as before. See the comment in
170122 `modules/nixos/cachyos.nix` to try one.
171123
172-## 5. Games
124+## 6. Games
173125
174126 - **Steam**: your settings, Proton versions and game saves (`compatdata`) are
175127 back. The games in `~/Games/SteamLibrary` and Steam's own library show as
@@ -191,7 +143,7 @@
191143 - **OSRS**: install the official Old School RuneScape launcher. Bolt is gone,
192144 and so is its data.
193145
194-## 6. Once you're happy
146+## 7. Once you're happy
195147
196148 The backup on `sda` stays until you need the drive for something else. It is
197149 the only copy of what wasn't restored, including the repos that exist only
@@ -1,5 +1,10 @@
11 # The desktop: ASUS TUF B850-PLUS, Ryzen 7 9850X3D, RTX 3080 Ti.
22 { inputs, ... }:
3+let
4+ # The MacBook's public SSH key (its ~/.ssh/id_ed25519.pub), see below.
5+ macKeys = [
6+ ];
7+in
38 {
49 imports = [
510 ./hardware-configuration.nix
@@ -11,6 +16,12 @@
1116
1217 networking.hostName = "desktop";
1318
19+ # The MacBook, which installs this machine with nixos-anywhere and can log in
20+ # before the home folder (and its ~/.ssh/authorized_keys) is restored. Root
21+ # too: a fresh install has no passwords, so that is how yours gets set.
22+ users.users.vizie.openssh.authorizedKeys.keys = macKeys;
23+ users.users.root.openssh.authorizedKeys.keys = macKeys;
24+
1425 home-manager = {
1526 useGlobalPkgs = true;
1627 useUserPackages = true;
@@ -1,5 +1,5 @@
11 # rsync filter for restoring the home folder from the backup drive after the
2-# install (MIGRATION.md, section 2). Only what is listed here comes back: the
2+# install (tools/restore-from-sata). Only what is listed here comes back: the
33 # move to NixOS is a fresh start. Everything else stays on the backup drive,
44 # to copy back by hand if you miss it. The first matching line wins.
55
@@ -1,8 +1,8 @@
11 #!/usr/bin/env bash
2-# Backs up what MIGRATION.md section 1 lists to the Kingston SATA SSD (sda):
3-# the built system and disko script, WoW's settings and addons, and the home
4-# folder. Safe to run again: the first run formats the drive (only if it is
5-# empty), later runs only copy what changed.
2+# Backs up the home folder and WoW's settings and addons to the Kingston SATA
3+# SSD (sda), before the install wipes the NVMe drive (MIGRATION.md). Safe to
4+# run again: the first run formats the drive (only if it is empty), later runs
5+# only copy what changed.
66 #
77 # sudo ~/git/dot/tools/backup-to-sata
88 set -euo pipefail
@@ -11,11 +11,8 @@
1111 mnt=/mnt/backup
1212 user=vizie
1313 home=/home/$user
14-repo=$home/git/dot
14+repo=$(dirname "$(dirname "$(readlink -f "$0")")")
1515 wow="$home/Games/battlenet/drive_c/Program Files (x86)/World of Warcraft/_retail_"
16-
17-# sudo's PATH leaves out Nix (installed with the official installer here).
18-export PATH="$PATH:/nix/var/nix/profiles/default/bin"
1916
2017 if [ "$EUID" -ne 0 ]; then
2118 echo "Run it with sudo: sudo $0" >&2
@@ -46,17 +43,7 @@
4643 if ! mountpoint -q "$mnt"; then
4744 mount -o compress=zstd /dev/disk/by-label/backup "$mnt"
4845 fi
49-install -d -o "$user" "$mnt/nix-cache" "$mnt/wow"
50-
51-echo "== Saving the built system and the disko script"
52-sudo -u "$user" env PATH="$PATH" bash -euo pipefail -c '
53- cd "$1"
54- sys=$(nix build --no-link --print-out-paths .#nixosConfigurations.desktop.config.system.build.toplevel)
55- disko=$(nix build --no-link --print-out-paths .#nixosConfigurations.desktop.config.system.build.diskoScript)
56- nix copy --to "file://$2/nix-cache?compression=zstd" "$sys" "$disko"
57- echo "$sys" > "$2/nix-cache/system"
58- echo "$disko" > "$2/nix-cache/disko"
59-' _ "$repo" "$mnt"
46+install -d -o "$user" "$mnt/wow"
6047
6148 echo "== WoW settings and addons"
6249 rsync -a --delete "$wow/WTF" "$wow/Interface" "$mnt/wow/"
@@ -1,0 +1,26 @@
1+#!/usr/bin/env bash
2+# Puts back what restore-filter lists from the backup drive into the new
3+# system's home folder (MIGRATION.md, step 3). Run it as root from the backup
4+# drive itself, mounted at /mnt:
5+#
6+# mount -o ro /dev/disk/by-label/backup /mnt
7+# /mnt/vizie/git/dot/tools/restore-from-sata
8+set -euo pipefail
9+
10+user=vizie
11+repo=$(dirname "$(dirname "$(readlink -f "$0")")")
12+backup=$(dirname "$(dirname "$repo")")
13+
14+if [ "$EUID" -ne 0 ]; then
15+ echo "Run it as root." >&2
16+ exit 1
17+fi
18+if [ ! -d "$backup/.ssh" ] || [ ! -f "$repo/restore-filter" ]; then
19+ echo "$backup doesn't look like the home folder backup." >&2
20+ exit 1
21+fi
22+
23+# Owned by you (uid 1000) and the users group (100), as NixOS sets them up.
24+rsync -aHAX --info=progress2 --chown=1000:100 \
25+ --filter="merge $repo/restore-filter" "$backup/" "/home/$user/"
26+echo "== Done. Log in on the desktop."