1
0

impermanence.nix 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. {
  2. config,
  3. inputs,
  4. lib,
  5. ...
  6. }:
  7. {
  8. imports = [
  9. inputs.impermanence.nixosModules.impermanence
  10. ];
  11. boot.initrd.postDeviceCommands = lib.mkAfter ''
  12. #!/bin/sh
  13. DEVICE=${config.disko.devices.disk.main.device}-part2
  14. # Mount Btrfs root
  15. mkdir -p /mnt
  16. if ! mount -o subvol=/ $DEVICE /mnt; then
  17. echo "Failed to mount $DEVICE at /mnt"
  18. exit 1
  19. fi
  20. # Create directory for old roots
  21. mkdir -p /mnt/old-roots
  22. # Move current root to old-roots with current timestamp
  23. if [[ -e /mnt/@root && ! -e /mnt/@root-blank ]]; then
  24. timestamp=$(date +%Y-%m-%d_%H:%M:%S)
  25. if ! mv /mnt/@root "/mnt/old-roots/@root-$timestamp"; then
  26. echo "Failed to move /mnt/@root to old-roots"
  27. umount /mnt
  28. exit 1
  29. fi
  30. fi
  31. # Function to recursively delete subvolumes
  32. delete_subvolume_recursively() {
  33. for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
  34. delete_subvolume_recursively "/mnt/$i"
  35. done
  36. if ! btrfs subvolume delete "$1"; then
  37. echo "Failed to delete subvolume $1"
  38. fi
  39. }
  40. # Delete old roots older than 30 days
  41. for i in $(btrfs subvolume list /mnt | grep 'old-roots/@root-' | cut -f 9- -d ' '); do
  42. subvol_time=$(echo "$i" | grep -o '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}_[0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}')
  43. if [[ -n "$subvol_time" ]]; then
  44. subvol_secs=$(date -d "$subvol_time" +%s 2>/dev/null || continue)
  45. thirty_days_ago=$(date -d "30 days ago" +%s)
  46. if [[ $subvol_secs -lt $thirty_days_ago ]]; then
  47. delete_subvolume_recursively "/mnt/$i"
  48. fi
  49. fi
  50. done
  51. # Create or restore fresh root
  52. if [[ -e /mnt/@root-blank ]]; then
  53. btrfs subvolume delete /mnt/@root || true
  54. if ! btrfs subvolume snapshot /mnt/@root-blank /mnt/@root; then
  55. echo "Failed to snapshot @root-blank to @root"
  56. umount /mnt
  57. exit 1
  58. fi
  59. else
  60. if ! btrfs subvolume create /mnt/@root-blank; then
  61. echo "Failed to create @root-blank"
  62. umount /mnt
  63. exit 1
  64. fi
  65. if ! btrfs subvolume create /mnt/@root; then
  66. echo "Failed to create @root"
  67. umount /mnt
  68. exit 1
  69. fi
  70. fi
  71. # Unmount
  72. if ! umount /mnt; then
  73. echo "Failed to unmount /mnt"
  74. exit 1
  75. fi
  76. '';
  77. # Persistent directories for impermanence
  78. fileSystems."/persist".neededForBoot = true;
  79. fileSystems."/var/lib".neededForBoot = true;
  80. environment.persistence."/persist" = {
  81. hideMounts = true;
  82. directories = [
  83. "/etc/ssh"
  84. "/var/cache"
  85. ];
  86. files = [
  87. "/etc/machine-id"
  88. ];
  89. users.thomas.directories = [
  90. ".ssh"
  91. ".local/share"
  92. ];
  93. };
  94. }