From 22f6a37ea89f7247008e9afccfcc8ecf277a8fc0 Mon Sep 17 00:00:00 2001
From: Leyla Becker <git@jan-leila.com>
Date: Mon, 11 Nov 2024 17:17:50 -0600
Subject: [PATCH] drafted out impermanence for defiant

---
 README.md                                |   2 +-
 flake.lock                               |  16 ++++
 flake.nix                                |   6 ++
 hosts/defiant/disko-config.nix           |  91 +++++++++---------
 hosts/defiant/hardware-configuration.nix | 113 ++++++++++++++++++++++-
 5 files changed, 182 insertions(+), 46 deletions(-)

diff --git a/README.md b/README.md
index 5f4848e..e94d8b3 100644
--- a/README.md
+++ b/README.md
@@ -60,4 +60,4 @@ to update passwords run: `nix shell nixpkgs#sops -c sops secrets/user-passwords.
 - mastodon server
 - tail scale clients
 - wake on LAN
-- ISO target that contains authorized keys for nixos-anywhere
\ No newline at end of file
+- ISO target that contains authorized keys for nixos-anywhere https://github.com/diegofariasm/yggdrasil/blob/4acc43ebc7bcbf2e41376d14268e382007e94d78/hosts/bootstrap/default.nix
\ No newline at end of file
diff --git a/flake.lock b/flake.lock
index 4d181fa..ed31d1e 100644
--- a/flake.lock
+++ b/flake.lock
@@ -74,6 +74,21 @@
         "type": "github"
       }
     },
+    "impermanence": {
+      "locked": {
+        "lastModified": 1730403150,
+        "narHash": "sha256-W1FH5aJ/GpRCOA7DXT/sJHFpa5r8sq2qAUncWwRZ3Gg=",
+        "owner": "nix-community",
+        "repo": "impermanence",
+        "rev": "0d09341beeaa2367bac5d718df1404bf2ce45e6f",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "impermanence",
+        "type": "github"
+      }
+    },
     "nix-vscode-extensions": {
       "inputs": {
         "flake-compat": "flake-compat",
@@ -146,6 +161,7 @@
       "inputs": {
         "disko": "disko",
         "home-manager": "home-manager",
+        "impermanence": "impermanence",
         "nix-vscode-extensions": "nix-vscode-extensions",
         "nixos-hardware": "nixos-hardware",
         "nixpkgs": "nixpkgs",
diff --git a/flake.nix b/flake.nix
index aaf2266..7e716ec 100644
--- a/flake.nix
+++ b/flake.nix
@@ -23,6 +23,10 @@
       inputs.nixpkgs.follows = "nixpkgs";
     };
 
+    impermanence = {
+      url = "github:nix-community/impermanence";
+    };
+
     # users home directories
     home-manager = {
       url = "github:nix-community/home-manager";
@@ -49,6 +53,7 @@
   outputs = {
     nixpkgs,
     disko,
+    impermanence,
     nixos-hardware,
     home-manager,
     ...
@@ -102,6 +107,7 @@
         specialArgs = {inherit inputs lib;};
         modules = [
           ./overlays
+          impermanence.nixosModules.impermanence
           disko.nixosModules.disko
           home-manager.nixosModules.home-manager
           home-manager-config
diff --git a/hosts/defiant/disko-config.nix b/hosts/defiant/disko-config.nix
index a913aeb..0be19c4 100644
--- a/hosts/defiant/disko-config.nix
+++ b/hosts/defiant/disko-config.nix
@@ -1,10 +1,9 @@
-{lib, ...}: let
+{...}: let
   bootDisk = devicePath: {
     type = "disk";
     device = devicePath;
     content = {
       type = "gpt";
-
       partitions = {
         boot = {
           size = "1M";
@@ -32,37 +31,37 @@
           size = "100%";
           content = {
             type = "zfs";
-            pool = "zroot";
-          };
-        };
-      };
-    };
-  };
-  cacheDisk = devicePath: swapSize: {
-    type = "disk";
-    device = devicePath;
-    content = {
-      type = "gpt";
-      partitions = {
-        encryptedSwap = {
-          size = swapSize;
-          content = {
-            type = "swap";
-            randomEncryption = true;
-            discardPolicy = "both";
-            resumeDevice = true;
-          };
-        };
-        zfs = {
-          size = "100%";
-          content = {
-            type = "zfs";
-            pool = "zroot";
+            pool = "rpool";
           };
         };
       };
     };
   };
+  # cacheDisk = devicePath: swapSize: {
+  #   type = "disk";
+  #   device = devicePath;
+  #   content = {
+  #     type = "gpt";
+  #     partitions = {
+  #       encryptedSwap = {
+  #         size = swapSize;
+  #         content = {
+  #           type = "swap";
+  #           randomEncryption = true;
+  #           discardPolicy = "both";
+  #           resumeDevice = true;
+  #         };
+  #       };
+  #       zfs = {
+  #         size = "100%";
+  #         content = {
+  #           type = "zfs";
+  #           pool = "rpool";
+  #         };
+  #       };
+  #     };
+  #   };
+  # };
 in {
   disko.devices = {
     disk = {
@@ -75,7 +74,7 @@ in {
       # ssd_2_tb_a = cacheDisk "64G" "/dev/disk/by-id/XXX";
     };
     zpool = {
-      zroot = {
+      rpool = {
         type = "zpool";
         mode = {
           topology = {
@@ -92,7 +91,7 @@ in {
               }
             ];
             cache = [];
-            # cache = [ "ssd_2_tb_a" ];
+            # cache = [ "ssd_2_tb_a" ];z
           };
         };
 
@@ -101,34 +100,40 @@ in {
         };
 
         rootFsOptions = {
-          encryption = "on";
-          keyformat = "hex";
-          keylocation = "prompt";
+          # encryption = "on";
+          # keyformat = "hex";
+          # keylocation = "prompt";
           compression = "lz4";
           xattr = "sa";
           acltype = "posixacl";
+          canmount = "off";
           "com.sun:auto-snapshot" = "false";
         };
 
-        mountpoint = "/";
-        postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot@blank$' || zfs snapshot zroot@blank";
-
         datasets = {
-          "nix" = {
+          root = {
+            type = "zfs_fs";
+            mountpoint = "/";
+            options.mountpoint = "legacy";
+            postCreateHook = "zfs snapshot rpool/root@blank";
+          };
+          home = {
+            type = "zfs_fs";
+            options.mountpoint = "legacy";
+            mountpoint = "/home";
+            postCreateHook = "zfs snapshot rpool/home@blank";
+          };
+          nix = {
             type = "zfs_fs";
             mountpoint = "/nix";
           };
-          "home" = {
+          persistent = {
             type = "zfs_fs";
-            mountpoint = "/mnt/home";
+            mountpoint = "/persistent";
             options = {
               "com.sun:auto-snapshot" = "true";
             };
           };
-          "var" = {
-            type = "zfs_fs";
-            mountpoint = "/var";
-          };
         };
       };
     };
diff --git a/hosts/defiant/hardware-configuration.nix b/hosts/defiant/hardware-configuration.nix
index edfaeee..0d345f2 100644
--- a/hosts/defiant/hardware-configuration.nix
+++ b/hosts/defiant/hardware-configuration.nix
@@ -2,9 +2,9 @@
 # and may be overwritten by future invocations.  Please make changes
 # to /etc/nixos/configuration.nix instead.
 {
+  pkgs,
   config,
   lib,
-  pkgs,
   modulesPath,
   ...
 }: {
@@ -13,27 +13,136 @@
     ../hardware-common.nix
   ];
 
+  security.sudo.extraConfig = "Defaults lecture=never";
+
   boot = {
     initrd = {
       availableKernelModules = ["xhci_pci" "aacraid" "ahci" "usbhid" "usb_storage" "sd_mod"];
       kernelModules = [];
+      # TODO: figure out some kind of snapshotting before rolebacks
+      # postDeviceCommands = lib.mkAfter ''
+      #   zfs rollback -r rpool/root@blank
+      #   zfs rollback -r rpool/home@blank
+      # '';
+      systemd = {
+        enable = lib.mkDefault true;
+        services.rollback = {
+          description = "Rollback root filesystem to a pristine state on boot";
+          wantedBy = [
+            "zfs.target"
+            "initrd.target"
+          ];
+          after = [
+            "zfs-import-rpool.service"
+          ];
+          before = [
+            "sysroot.mount"
+            "fs.target"
+          ];
+          path = with pkgs; [
+            zfs
+          ];
+          unitConfig.DefaultDependencies = "no";
+          # serviceConfig = {
+          #   Type = "oneshot";
+          #   ExecStart =
+          #     "${config.boot.zfs.package}/sbin/zfs rollback -r rpool/home@blank";
+          # };
+          serviceConfig.Type = "oneshot";
+          script = ''
+            zfs list -t snapshot || echo
+            zfs rollback -r rpool/root@blank
+            zfs rollback -r rpool/home@blank
+          '';
+        };
+      };
     };
     kernelModules = ["kvm-amd"];
+    kernelParams = ["quiet"];
     extraModulePackages = [];
 
     supportedFilesystems = ["zfs"];
 
-    zfs.extraPools = ["zroot"];
+    zfs.extraPools = ["rpool"];
   };
 
   swapDevices = [];
 
+  fileSystems = {
+    "/" = {
+      neededForBoot = true;
+    };
+
+    "/home" = {
+      neededForBoot = true;
+    };
+
+    "/persistent" = {
+      neededForBoot = true;
+    };
+  };
+
   networking = {
     hostId = "c51763d6";
     hostName = "defiant"; # Define your hostname.
     useNetworkd = true;
   };
 
+  environment.persistence."/persistent" = {
+    enable = true;
+    hideMounts = true;
+    directories = [
+      # "/run/secrets"
+
+      "/etc/ssh"
+
+      "/var/log"
+      "/var/lib/nixos"
+      "/var/lib/systemd/coredump"
+
+      # config.apps.pihole.directory.root
+
+      # config.apps.jellyfin.mediaDirectory
+      # config.services.jellyfin.configDir
+      # config.services.jellyfin.cacheDir
+      # config.services.jellyfin.dataDir
+
+      # "/var/hass" # config.users.users.hass.home
+      # "/var/postgresql" # config.users.users.postgresql.home
+      # "/var/forgejo" # config.users.users.forgejo.home
+      # "/var/nextcloud" # config.users.users.nextcloud.home
+      # "/var/headscale" # config.users.users.headscale.home
+    ];
+    files = [
+      "/etc/machine-id"
+      # config.environment.sessionVariables.SOPS_AGE_KEY_FILE
+    ];
+    users.leyla = {
+      directories = [
+        "documents"
+        ".ssh"
+      ];
+      files = [];
+    };
+  };
+
+  # systemd.services = {
+  #   # https://github.com/openzfs/zfs/issues/10891
+  #   systemd-udev-settle.enable = false;
+  #   # Snapshots are not accessable on boot for some reason this should fix it
+  #   # https://github.com/NixOS/nixpkgs/issues/257505
+  #   zfs-mount = {
+  #     serviceConfig = {
+  #       # ExecStart = [ "${lib.getExe' pkgs.util-linux "mount"} -a -t zfs -o remount" ];
+  #       ExecStart = [
+  #         "${lib.getExe' pkgs.util-linux "mount"} -t zfs rpool/root -o remount"
+  #         "${lib.getExe' pkgs.util-linux "mount"} -t zfs rpool/home -o remount"
+  #         "${lib.getExe' pkgs.util-linux "mount"} -t zfs rpool/persistent -o remount"
+  #       ];
+  #     };
+  #   };
+  # };
+
   systemd.network = {
     enable = true;