From 78eb350962f6a8af41282836e2b884ef0bc4607a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charlotte=20=F0=9F=A6=9D=20Delenk?= Date: Tue, 29 Oct 2024 09:21:03 +0100 Subject: [PATCH] add impermanence --- flake.lock | 16 +++++++ flake.nix | 3 ++ modules/default.nix | 1 + modules/impermanence.nix | 91 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 modules/impermanence.nix diff --git a/flake.lock b/flake.lock index 7f090538..9ee08d2d 100644 --- a/flake.lock +++ b/flake.lock @@ -71,6 +71,21 @@ "type": "github" } }, + "impermanence": { + "locked": { + "lastModified": 1729068498, + "narHash": "sha256-C2sGRJl1EmBq0nO98TNd4cbUy20ABSgnHWXLIJQWRFA=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "e337457502571b23e449bf42153d7faa10c0a562", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "lix": { "inputs": { "flake-compat": [ @@ -239,6 +254,7 @@ "flake-utils": "flake-utils", "flakey-profile": "flakey-profile", "gitignore": "gitignore", + "impermanence": "impermanence", "lix": "lix", "lix-module": "lix-module", "nix2container": "nix2container", diff --git a/flake.nix b/flake.nix index ae3c098f..c3b911a8 100644 --- a/flake.nix +++ b/flake.nix @@ -17,6 +17,9 @@ url = "github:hercules-ci/gitignore.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + impermanence = { + url = "github:nix-community/impermanence"; + }; lix = { url = "git+https://git.lix.systems/lix-project/lix"; inputs.flake-compat.follows = "flake-compat"; diff --git a/modules/default.nix b/modules/default.nix index 333bd6b3..7fdb4403 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -3,5 +3,6 @@ ./riscv.nix ./containers/autoconfig.nix ./lix.nix + ./impermanence.nix ]; } diff --git a/modules/impermanence.nix b/modules/impermanence.nix new file mode 100644 index 00000000..8199ec3f --- /dev/null +++ b/modules/impermanence.nix @@ -0,0 +1,91 @@ +{ + impermanence, + config, + lib, + pkgs, + inTester, + ... +}: +with lib; { + imports = ["${impermanence}/nixos.nix"]; + options = { + environment.impermanence = mkEnableOption "Enables impermanence"; + }; + + config = mkMerge [ + { + environment.impermanence = mkDefault (!config.boot.isContainer && !inTester); + } + (mkIf config.environment.impermanence { + boot.initrd.postDeviceCommands = mkAfter '' + mkdir /btrfs_tmp + mount ${config.fileSystems."/".device} -t btrfs /btrfs_tmp + if [[ -e /btrfs_tmp/root ]]; then + mkdir -p /btrfs_tmp/old_roots + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } + + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do + delete_subvolume_recursively "$i" + done + + btrfs subvolume create /btrfs_tmp/root + umount /btrfs_tmp + ''; + assertions = [ + { + assertion = hasAttr "/" config.fileSystems; + message = "To use impermanence, you need to define a root volume"; + } + { + assertion = + if hasAttr "/" config.fileSystems + then config.fileSystems."/".fsType == "btrfs" + else false; + message = "rootfs must be btrfs"; + } + { + assertion = + if hasAttr "/" config.fileSystems + then any (t: t == "subvol=root") config.fileSystems."/".options + else false; + message = "rootfs must mount subvolume root"; + } + ]; + fileSystems."/persistent" = { + device = + if hasAttr "/" config.fileSystems + then mkDefault config.fileSystems."/".device + else "/dev/null"; + fsType = "btrfs"; + options = ["subvol=persistent"]; + neededForBoot = true; + }; + environment.persistence."/persistent" = { + enable = true; + hideMounts = true; + directories = [ + "/var/log" + "/var/lib/nixos" + ]; + files = [ + "/etc/ssh/ssh_host_ecdsa_key" + "/etc/ssh/ssh_host_ecdsa_key.pub" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + }; + }) + ]; +}