218 lines
8.3 KiB
Nix
218 lines
8.3 KiB
Nix
# Legacy storage configuration for defiant
|
|
# This file manually defines ZFS datasets matching the existing on-disk layout
|
|
# to allow incremental migration to the new storage module (generateBase = true).
|
|
#
|
|
# ============================================================================
|
|
# INCREMENTAL MIGRATION PLAN
|
|
# ============================================================================
|
|
#
|
|
# Current disk usage (for reference):
|
|
# rpool/local/system/nix ~26G (renamed in place, no copy)
|
|
# rpool/local/system/sops ~328K (renamed in place, no copy)
|
|
# rpool/persist/system/jellyfin ~32T (renamed in place, no copy)
|
|
# rpool/persist/system/qbittorrent ~6.5T (copied into media dataset, ~6.5T temp)
|
|
# rpool free space ~30T
|
|
#
|
|
# Phase 1: Migrate base datasets on disk (boot from live USB or rescue)
|
|
# All operations in this phase are instant renames -- no data is copied.
|
|
#
|
|
# Unlock the pool:
|
|
# zfs load-key -a
|
|
#
|
|
# Step 1a: Move nix and sops out of local/ (they go to persist/local/)
|
|
# The -p flag auto-creates the parent datasets.
|
|
#
|
|
# zfs rename -p rpool/local/system/nix rpool/persist/local/nix
|
|
# zfs rename -p rpool/local/system/sops rpool/persist/local/system/sops
|
|
#
|
|
# Step 1b: Rename local/ -> ephemeral/ (takes remaining children with it)
|
|
# zfs rename rpool/local rpool/ephemeral
|
|
# # This moves: local/system/root -> ephemeral/system/root
|
|
# # local/home/leyla -> ephemeral/home/leyla
|
|
#
|
|
# Step 1c: Recreate blank snapshots on ephemeral datasets
|
|
# zfs destroy rpool/ephemeral/system/root@blank
|
|
# zfs snapshot rpool/ephemeral/system/root@blank
|
|
# zfs destroy rpool/ephemeral/home/leyla@blank
|
|
# zfs snapshot rpool/ephemeral/home/leyla@blank
|
|
#
|
|
# Step 1d: Move persist/ children under persist/replicate/
|
|
# zfs create -o canmount=off rpool/persist/replicate
|
|
# zfs create -o canmount=off rpool/persist/replicate/system
|
|
# zfs rename rpool/persist/system/root rpool/persist/replicate/system/root
|
|
# zfs rename rpool/persist/system/var rpool/persist/replicate/system/var
|
|
# zfs rename rpool/persist/home/leyla rpool/persist/replicate/home
|
|
# # Clean up the now-empty home parent
|
|
# zfs destroy rpool/persist/home
|
|
# # NOTE: Do NOT destroy rpool/persist/system -- it still contains
|
|
# # persist/system/jellyfin and persist/system/qbittorrent which are
|
|
# # migrated in Phase 2.
|
|
#
|
|
# Verify the new layout:
|
|
# zfs list -r rpool -o name,used,mountpoint
|
|
#
|
|
# Phase 2: Merge media into a single dataset (do this last)
|
|
# Strategy: Rename the jellyfin dataset to become the shared media dataset
|
|
# (zero copy, instant), then copy qbittorrent data into it (~6.5T copy).
|
|
# This avoids duplicating the 32T jellyfin dataset.
|
|
#
|
|
# Step 2a: Rename jellyfin dataset to the shared media name
|
|
# zfs rename rpool/persist/system/jellyfin rpool/persist/replicate/system/media
|
|
#
|
|
# Step 2b: Copy qbittorrent data into the media dataset
|
|
# This copies ~6.5T and may take several hours/days depending on disk speed.
|
|
# The qbittorrent data is not critical to back up so no snapshot needed.
|
|
#
|
|
# systemctl stop qbittorrent
|
|
# rsync -avPHAX /persist/system/qbittorrent/ /persist/replicate/system/media/
|
|
#
|
|
# Step 2c: Verify the data and clean up
|
|
# ls -la /persist/replicate/system/media/
|
|
# zfs destroy rpool/persist/system/qbittorrent
|
|
# # persist/system should now be empty, clean it up:
|
|
# zfs destroy rpool/persist/system
|
|
#
|
|
# Phase 3: Enable generateBase
|
|
# In the nix config:
|
|
# - Delete this file (legacy-storage.nix) and remove its import from default.nix
|
|
# - Remove [PHASE 3] entries from legacy-impermanence.nix:
|
|
# - var-lib-private-permissions activation script
|
|
# - /etc/machine-id, SSH host keys (files block)
|
|
# - /var/lib/nixos, /var/lib/systemd/coredump (directories)
|
|
# - /persist/system/var/log persistence block
|
|
# These are now handled automatically by storage.nix and ssh.nix.
|
|
# Rebuild and verify:
|
|
# sudo nixos-rebuild switch --flake .#defiant
|
|
# # Verify mounts: findmnt -t fuse.bindfs,fuse
|
|
# # Verify persist: ls /persist/replicate/system/root/var/lib/nixos
|
|
# # Verify boot: reboot and confirm system comes up cleanly
|
|
#
|
|
# Phase 4: Migrate services (one at a time, any order)
|
|
# For each service (except jellyfin/qbittorrent):
|
|
# 1. Remove the service's [PHASE 4] section from legacy-impermanence.nix
|
|
# 2. Remove `impermanence.enable = false` for that service in configuration.nix
|
|
# 3. Rebuild: sudo nixos-rebuild switch --flake .#defiant
|
|
# 4. Verify: systemctl status <service>, check the service's data is intact
|
|
# No data migration is needed -- the data already lives on the renamed
|
|
# dataset at the new path.
|
|
#
|
|
# Migrate jellyfin and qbittorrent LAST (after Phase 2 media merge):
|
|
# 1. Remove [PHASE 4 - LAST] jellyfin entries from legacy-impermanence.nix
|
|
# 2. Remove [PHASE 4 - LAST] qbittorrent entries from legacy-impermanence.nix
|
|
# 3. Remove `impermanence.enable = false` for both in configuration.nix
|
|
# 4. Rebuild: sudo nixos-rebuild switch --flake .#defiant
|
|
# 5. Verify: systemctl status jellyfin qbittorrent
|
|
#
|
|
# Phase 5: Cleanup
|
|
# Once all services are migrated and legacy-impermanence.nix is empty:
|
|
# - Delete legacy-impermanence.nix and remove its import from default.nix
|
|
# - Rebuild: sudo nixos-rebuild switch --flake .#defiant
|
|
#
|
|
# ============================================================================
|
|
#
|
|
# Current on-disk dataset layout:
|
|
# rpool/local/ - ephemeral parent
|
|
# rpool/local/home/leyla - ephemeral user home (rolled back on boot)
|
|
# rpool/local/system/nix - nix store
|
|
# rpool/local/system/root - root filesystem (rolled back on boot)
|
|
# rpool/local/system/sops - sops age key
|
|
# rpool/persist/ - persistent parent
|
|
# rpool/persist/home/leyla - persistent user home
|
|
# rpool/persist/system/jellyfin - jellyfin media
|
|
# rpool/persist/system/qbittorrent - qbittorrent media
|
|
# rpool/persist/system/root - persistent root data
|
|
# rpool/persist/system/var/log - log persistence
|
|
{lib, ...}: {
|
|
# Disable automatic base dataset generation so we can define them manually
|
|
storage.generateBase = false;
|
|
|
|
# Manually define ZFS datasets matching main's structure
|
|
storage.zfs.datasets = {
|
|
# Ephemeral datasets (local/)
|
|
"local" = {
|
|
type = "zfs_fs";
|
|
mount = null;
|
|
};
|
|
"local/home/leyla" = {
|
|
type = "zfs_fs";
|
|
mount = "/home/leyla";
|
|
snapshot = {
|
|
blankSnapshot = true;
|
|
};
|
|
};
|
|
"local/system/nix" = {
|
|
type = "zfs_fs";
|
|
mount = "/nix";
|
|
atime = "off";
|
|
relatime = "off";
|
|
snapshot = {
|
|
autoSnapshot = false;
|
|
};
|
|
};
|
|
"local/system/root" = {
|
|
type = "zfs_fs";
|
|
mount = "/";
|
|
snapshot = {
|
|
blankSnapshot = true;
|
|
};
|
|
};
|
|
"local/system/sops" = {
|
|
type = "zfs_fs";
|
|
mount = "/var/lib/sops-nix";
|
|
};
|
|
|
|
# Persistent datasets (persist/)
|
|
"persist" = {
|
|
type = "zfs_fs";
|
|
mount = null;
|
|
};
|
|
"persist/home/leyla" = {
|
|
type = "zfs_fs";
|
|
mount = "/persist/home/leyla";
|
|
snapshot = {
|
|
autoSnapshot = true;
|
|
};
|
|
};
|
|
"persist/system/jellyfin" = {
|
|
type = "zfs_fs";
|
|
mount = "/persist/system/jellyfin";
|
|
atime = "off";
|
|
relatime = "off";
|
|
};
|
|
"persist/system/qbittorrent" = {
|
|
type = "zfs_fs";
|
|
mount = "/persist/system/qbittorrent";
|
|
atime = "off";
|
|
relatime = "off";
|
|
};
|
|
"persist/system/root" = {
|
|
type = "zfs_fs";
|
|
mount = "/persist/system/root";
|
|
snapshot = {
|
|
autoSnapshot = true;
|
|
};
|
|
};
|
|
"persist/system/var/log" = {
|
|
type = "zfs_fs";
|
|
mount = "/persist/system/var/log";
|
|
};
|
|
};
|
|
|
|
# Boot commands to rollback ephemeral root and user homes on boot
|
|
boot.initrd.postResumeCommands = lib.mkAfter ''
|
|
zfs rollback -r rpool/local/system/root@blank
|
|
zfs rollback -r rpool/local/home/leyla@blank
|
|
'';
|
|
|
|
# FileSystems needed for boot
|
|
fileSystems = {
|
|
"/".neededForBoot = true;
|
|
"/persist/system/root".neededForBoot = true;
|
|
"/persist/system/var/log".neededForBoot = true;
|
|
"/persist/system/jellyfin".neededForBoot = true;
|
|
"/persist/system/qbittorrent".neededForBoot = true;
|
|
"/var/lib/sops-nix".neededForBoot = true;
|
|
"/persist/home/leyla".neededForBoot = true;
|
|
"/home/leyla".neededForBoot = true;
|
|
};
|
|
}
|