refactor: migrate idols-ai to new ssd (#247)

* refactor: migrate idols-ai to new ssd

* fix: github repo mi2ebi/tree-sitter-bovex 404
• Updated input 'helix':
    'github:mattwparas/helix/908d48c5dd9700ddff65bcfce8850eea74af0360?narHash=sha256-hXxc3JqZ%2BxF2VjTOczmYHVttRIWlxGh5RmYZ9OcMPD8%3D' (2026-02-15)
  → 'github:mattwparas/helix/bb5efb6ec09792a91dc6b4dec1a4d6534b7185dc?narHash=sha256-FfbsMeo8p0JUUCf4TnYu5G35vVkFSuqh%2BEHXHyV1/UI%3D' (2026-03-13)

* chore: disable helix

* fix: failed to mount swapfile
This commit is contained in:
Ryan Yin
2026-03-16 10:07:08 +08:00
committed by GitHub
parent 850a7b2c43
commit a5295500f1
9 changed files with 337 additions and 403 deletions
+101 -18
View File
@@ -1,8 +1,12 @@
# Host - AI
Desktop (NixOS + preservation, LUKS + btrfs on nvme). Disk layout is declarative via
[disko](./disko-fs.nix) (target device: **nvme1n1**).
Related:
- [/nixos-installer/README.md](/nixos-installer/README.md)
- [nixos-installer README](/nixos-installer/README.md) install from ISO using disko
- [disko-fs.nix](./disko-fs.nix) partition/layout definition (ESP + LUKS + btrfs)
## TODOs
@@ -10,7 +14,7 @@ Related:
## Info
disk status & mountpoints:
Current disk status and mountpoints (example; after migration layout is on nvme1n1):
```bash
df -Th
@@ -36,50 +40,129 @@ tmpfs tmpfs 100K 0 100K 0% /var/lib/lxd/devlxd
~
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
zram0 253:0 0 15.6G 0 disk [SWAP]
nvme0n1 259:0 0 1.8T 0 disk
├─nvme0n1p1 259:2 0 598M 0 part /boot
└─nvme0n1p2 259:3 0 1.8T 0 part
└─crypted-nixos 254:0 0 1.8T 0 crypt /tmp
/swap/swapfile
├─nvme0n1p1 259:1 0 598M 0 part /boot
└─nvme0n1p2 259:2 0 1.8T 0 part
└─crypted-nixos 254:0 0 1.8T 0 crypt /swap/swapfile
/gnu/store
/swap
/tmp
/snapshots
/home/ryan/tmp
/gnu
/btr_pool
/var/log
/var/lib/qemu
/var/lib/tailscale
/var/lib/systemd
/var/lib/private
/var/lib/nixos
/var/lib/lxd
/var/lib/netbird-homelab
/var/lib/lxc
/var/lib/libvirt
/var/lib/iwd
/var/lib/flatpak
/var/lib/containers
/var/lib/cni
/var/lib/NetworkManager
/var/lib/bluetooth
/home/ryan/work
/home/ryan/nix-config
/home/ryan/tmp
/home/ryan/go
/home/ryan/codes
/home/ryan/Videos
/home/ryan/Pictures
/home/ryan/Music
/home/ryan/Games
/home/ryan/Downloads
/home/ryan/.zoom
/home/ryan/Documents
/home/ryan/.wakatime
/home/ryan/.vscode
/home/ryan/.var
/home/ryan/.terraform.d/plugin-cache
/home/ryan/.steam
/home/ryan/.ssh
/home/ryan/.pulumi
/home/ryan/.pki
/home/ryan/.npm
/home/ryan/.mozilla
/home/ryan/.local/state
/home/ryan/.local/share
/home/ryan/.m2
/home/ryan/.local/state/wireplumber
/home/ryan/.local/state/nvim
/home/ryan/.local/state/home-manager
/home/ryan/.local/share/uv
/home/ryan/.local/state/Heroic
/home/ryan/.local/state/nix/profiles
/home/ryan/.local/share/zoxide
/home/ryan/.local/share/umu
/home/ryan/.local/share/tiled
/home/ryan/.local/share/steel
/home/ryan/.local/share/remmina
/home/ryan/.local/share/password-store
/home/ryan/.local/share/opencode
/home/ryan/.local/share/nvim
/home/ryan/.local/share/nix
/home/ryan/.local/share/krita
/home/ryan/.local/share/lutris
/home/ryan/.local/share/keyrings
/home/ryan/.local/share/k9s
/home/ryan/.local/share/jupyter
/home/ryan/.local/share/flatpak
/home/ryan/.local/share/io.github.clash-verge-rev.clash-verge-rev
/home/ryan/.local/share/feral-interactive
/home/ryan/.local/share/direnv
/home/ryan/.local/share/clash-verge
/home/ryan/.local/share/containers
/home/ryan/.local/share/atuin
/home/ryan/.local/share/Steam
/home/ryan/.local/share/StardewValley
/home/ryan/.local/share/GOG.com
/home/ryan/.local/bin
/home/ryan/.local/pipx
/home/ryan/.kube
/home/ryan/.gradle
/home/ryan/.gnupg
/home/ryan/.kimi
/home/ryan/.ipython
/home/ryan/.gemini
/home/ryan/.docker
/home/ryan/.config/sunshine
/home/ryan/.cursor
/home/ryan/.context7
/home/ryan/.config/remmina
/home/ryan/.config/pulse
/home/ryan/.config/opencode
/home/ryan/.config/obs-studio
/home/ryan/.config/mozc
/home/ryan/.config/nushell
/home/ryan/.config/lutris
/home/ryan/.config/joplin
/home/ryan/.config/heroic
/home/ryan/.config/google-chrome
/home/ryan/.config/github-copilot
/home/ryan/.config/gcloud
/home/ryan/.config/freerdp
/home/ryan/.config/blender
/home/ryan/.config/chromium
/home/ryan/.config/LDtk
/home/ryan/.config/Joplin
/home/ryan/.config/Cursor
/home/ryan/.config/Code
/home/ryan/.conda
/home/ryan/.cargo
/home/ryan/.codex
/home/ryan/.cache
/home/ryan/.aws
/home/ryan/.aliyun
/etc/ssh
/etc/secureboot
/etc/nix/inputs
/etc/agenix
/etc/NetworkManager/system-connections
/etc/machine-id
/home/ryan/.config/nushell/history.txt
/home/ryan/.wakatime.cfg
/etc/agenix
/etc/netbird-homelab
/nix/store
/var/log
/var/lib
/nix
/etc/machine-id
/persistent
/nix
```
+8 -1
View File
@@ -1,4 +1,9 @@
{ myvars, lib, ... }:
{
disko,
myvars,
lib,
...
}:
#############################################################
#
# Ai - my main computer, with NixOS + I5-13600KF + RTX 4090 GPU, for gaming & daily use.
@@ -14,6 +19,8 @@ let
in
{
imports = [
disko.nixosModules.default
./disko-fs.nix
./netdev-mount.nix
# Include the results of the hardware scan.
./hardware-configuration.nix
+128
View File
@@ -0,0 +1,128 @@
# Disko layout for idols-ai on nvme1n1 (target disk after migration).
# Same structure as current nvme0n1: ESP + LUKS + btrfs with ephemeral root (tmpfs).
#
# Format & mount (from installer or live system):
# nix run github:nix-community/disko -- --mode disko ./disko-fs.nix
# Mount only (after first format):
# nix run github:nix-community/disko -- --mode mount ./disko-fs.nix
#
# Use by-id for stability; override device when installing, e.g.:
# nixos-install --flake .#ai --option disko.devices.disk.nixos-ai.device /dev/nvme1n1
{
# Ephemeral root; preservation mounts /persistent for state.
fileSystems."/persistent".neededForBoot = true;
disko.devices = {
# Ephemeral root; relatime and mode=755 so systemd does not set 777.
nodev."/" = {
fsType = "tmpfs";
mountOptions = [
"relatime" # Update inode access times relative to modify/change time
"mode=755"
];
};
disk.nixos-ai = {
type = "disk";
# Override at install time if needed: --option disko.devices.disk.nixos-ai.device /dev/nvme1n1
device = "/dev/nvme1n1";
content = {
type = "gpt";
partitions = {
# EFI system partition; must stay unencrypted for UEFI to load the bootloader.
ESP = {
priority = 1;
name = "ESP";
start = "1M";
end = "600M";
type = "EF00"; # EF00 = ESP in GPT
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"fmask=0177" # File mask: 777-177=600 (owner rw-, group/others ---)
"dmask=0077" # Directory mask: 777-077=700 (owner rwx, group/others ---)
"noexec,nosuid,nodev" # Security: no execution, ignore setuid, no device nodes
];
};
};
# Root partition: LUKS encrypted, then btrfs with subvolumes.
root = {
size = "100%";
content = {
type = "luks";
name = "nixos-luks"; # Mapper name; match boot.initrd.luks
settings = {
allowDiscards = true; # TRIM for SSDs; slightly less secure, better performance
};
# Add boot.initrd.luks.devices so initrd prompts for passphrase at boot
initrdUnlock = true;
# cryptsetup luksFormat options
extraFormatArgs = [
"--type luks2"
"--cipher aes-xts-plain64"
"--hash sha512"
"--iter-time 5000"
"--key-size 256"
"--pbkdf argon2id"
"--use-random" # Block until enough entropy from /dev/random
];
extraOpenArgs = [
"--timeout 10"
];
content = {
type = "btrfs";
extraArgs = [ "-f" ]; # Force overwrite if filesystem already exists
subvolumes = {
# Top-level subvolume (id 5); used for btrfs send/receive and snapshots
"/" = {
mountpoint = "/btr_pool";
mountOptions = [ "subvolid=5" ];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress-force=zstd:1" # Save space and reduce I/O on SSD
"noatime"
];
};
"@guix" = {
mountpoint = "/gnu";
mountOptions = [
"compress-force=zstd:1"
"noatime"
];
};
"@persistent" = {
mountpoint = "/persistent";
mountOptions = [
"compress-force=zstd:1"
];
};
"@snapshots" = {
mountpoint = "/snapshots";
mountOptions = [
"compress-force=zstd:1"
];
};
"@tmp" = {
mountpoint = "/tmp";
mountOptions = [
"compress-force=zstd:1"
];
};
# Swap subvolume read-only; disko creates swapfile and adds swapDevices
"@swap" = {
mountpoint = "/swap";
swap.swapfile.size = "20G";
};
};
};
};
};
};
};
};
};
}
+2 -126
View File
@@ -58,132 +58,8 @@
"exfat"
];
boot.initrd = {
# unlocked luks devices via a keyfile or prompt a passphrase.
luks.devices."crypted-nixos" = {
# NOTE: DO NOT use device name here(like /dev/sda, /dev/nvme0n1p2, etc), use UUID instead.
# https://github.com/ryan4yin/nix-config/issues/43
device = "/dev/disk/by-uuid/a21ca82a-9ee6-4e5c-9d3f-a93e84e4e0f4";
# the keyfile(or device partition) that should be used as the decryption key for the encrypted device.
# if not specified, you will be prompted for a passphrase instead.
#keyFile = "/root-part.key";
# whether to allow TRIM requests to the underlying device.
# it's less secure, but faster.
allowDiscards = true;
# Whether to bypass dm-crypts internal read and write workqueues.
# Enabling this should improve performance on SSDs;
# https://wiki.archlinux.org/index.php/Dm-crypt/Specialties#Disable_workqueue_for_increased_solid_state_drive_(SSD)_performance
bypassWorkqueues = true;
};
};
fileSystems."/btr_pool" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
# btrfs's top-level subvolume, internally has an id 5
# we can access all other subvolumes from this subvolume.
options = [ "subvolid=5" ];
};
# equal to `mount -t tmpfs tmpfs /`
fileSystems."/" = {
device = "tmpfs";
fsType = "tmpfs";
# set mode to 755, otherwise systemd will set it to 777, which cause problems.
# relatime: Update inode access times relative to modify or change time.
options = [
"relatime"
"mode=755"
];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
options = [
"subvol=@nix"
"noatime"
"compress-force=zstd:1"
];
};
# for guix store, which use `/gnu/store` as its store directory.
fileSystems."/gnu" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
options = [
"subvol=@guix"
"noatime"
"compress-force=zstd:1"
];
};
fileSystems."/persistent" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
options = [
"subvol=@persistent"
"compress-force=zstd:1"
];
# preservation's data is required for booting.
neededForBoot = true;
};
fileSystems."/snapshots" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
options = [
"subvol=@snapshots"
"compress-force=zstd:1"
];
};
fileSystems."/tmp" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
options = [
"subvol=@tmp"
"compress-force=zstd:1"
];
};
# mount swap subvolume in readonly mode.
fileSystems."/swap" = {
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
fsType = "btrfs";
options = [
"subvol=@swap"
"ro"
];
};
# remount swapfile in read-write mode
fileSystems."/swap/swapfile" = {
# the swapfile is located in /swap subvolume, so we need to mount /swap first.
depends = [ "/swap" ];
device = "/swap/swapfile";
fsType = "none";
options = [
"bind"
"rw"
];
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/90FB-9F88";
fsType = "vfat";
options = [
"fmask=0177" # File mask: 777-177=600 (Owner: rw-, Group/Others: ---)
"dmask=0077" # Directory mask: 777-077=700 (Owner: rwx, Group/Others: ---)
"noexec,nosuid,nodev" # Security: Block execution, ignore setuid, and disable device nodes
];
};
swapDevices = [
{ device = "/swap/swapfile"; }
];
# LUKS initrd, all fileSystems (/, /boot, /btr_pool, /nix, /gnu, /persistent, /snapshots, /tmp, /swap)
# and swap (including /swap/swapfile bind and swapDevices) are managed by disko (disko-fs.nix).
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's