diff --git a/machines/lebesgue/config/hardware-configuration.nix b/machines/lebesgue/config/hardware-configuration.nix index 03724ba..ccaa0e2 100644 --- a/machines/lebesgue/config/hardware-configuration.nix +++ b/machines/lebesgue/config/hardware-configuration.nix @@ -17,6 +17,31 @@ boot.extraModulePackages = []; boot.supportedFilesystems = ["btrfs"]; + boot.initrd.postDeviceCommands = lib.mkAfter '' + mkdir /btrfs_tmp + mount /dev/disk/by-label/NIXROOT /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 + ''; + fileSystems."/" = { device = "/dev/disk/by-label/NIXROOT"; fsType = "btrfs"; diff --git a/machines/lebesgue/config/state.nix b/machines/lebesgue/config/state.nix new file mode 100644 index 0000000..8ea2adf --- /dev/null +++ b/machines/lebesgue/config/state.nix @@ -0,0 +1,24 @@ +{config, ...}: { + sops.age.sshKeyPaths = ["/persist/etc/ssh/ssh_host_ed25519_key"]; + + environment.persistence."/persist" = { + directories = + [ + "/var/lib/tailscale" + "/var/log" + "/var/lib/nixos" + "/var/lib/docker" + ] + ++ config.foehammer.backups.paths; + + files = [ + "/etc/machine-id" + "/etc/ssh/ssh_host_rsa_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/var/lib/systemd/random-seed" + "/var/lib/logrotate.status" + ]; + }; +} diff --git a/machines/lebesgue/flake.lock b/machines/lebesgue/flake.lock index c96f0de..210cf86 100644 --- a/machines/lebesgue/flake.lock +++ b/machines/lebesgue/flake.lock @@ -34,6 +34,21 @@ "type": "github" } }, + "impermanence": { + "locked": { + "lastModified": 1737831083, + "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1737672001, @@ -97,6 +112,7 @@ "root": { "inputs": { "common": "common", + "impermanence": "impermanence", "nixpkgs": "nixpkgs_2", "sops-nix": "sops-nix" } diff --git a/machines/lebesgue/flake.nix b/machines/lebesgue/flake.nix index 1586c78..dac8a7d 100644 --- a/machines/lebesgue/flake.nix +++ b/machines/lebesgue/flake.nix @@ -7,6 +7,10 @@ sops-nix = { url = "github:Mic92/sops-nix"; }; + + impermanence = { + url = "github:nix-community/impermanence"; + }; }; outputs = inputs @ {common, ...}: let supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"]; @@ -19,7 +23,11 @@ in { nixosConfigurations.default = let config = common.lib.utils.findNixFiles ./config; - modules = [inputs.sops-nix.nixosModules.sops inputs.common.nixosModules.default]; + modules = [ + inputs.sops-nix.nixosModules.sops + inputs.common.nixosModules.default + inputs.impermanence.nixosModules.impermanence + ]; in common.lib.mkSystem "lebesgue" "x86_64-linux" (config ++ modules); diff --git a/machines/lebesgue/tools/server/fs-diff b/machines/lebesgue/tools/server/fs-diff new file mode 100755 index 0000000..94a039d --- /dev/null +++ b/machines/lebesgue/tools/server/fs-diff @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# fs-diff.sh +# run on server. +set -euo pipefail + +if [[ -f /mnt ]]; then + mkdir /mnt +fi + +if ! mountpoint /mnt > /dev/null; then + mount -t btrfs /dev/disk/by-label/NIXROOT /mnt +fi + +OLD_TRANSID=$(sudo btrfs subvolume find-new /mnt/root-blank 9999999) +OLD_TRANSID=${OLD_TRANSID#transid marker was } + +sudo btrfs subvolume find-new "/mnt/root" "$OLD_TRANSID" | +sed '$d' | +cut -f17- -d' ' | +sort | +uniq | +while read path; do + path="/$path" + if [ -L "$path" ]; then + : # The path is a symbolic link, so is probably handled by NixOS already + elif [ -d "$path" ]; then + : # The path is a directory, ignore + else + echo "$path" + fi +done