diff --git a/hosts/nixos/calypso/filesystems/default.nix b/hosts/nixos/calypso/filesystems/default.nix index 154d7ec..dd8cac2 100644 --- a/hosts/nixos/calypso/filesystems/default.nix +++ b/hosts/nixos/calypso/filesystems/default.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: +{ lib, ... }: { imports = [ (import ./partitions.nix { }) ]; @@ -22,18 +22,49 @@ # }}} # {{{ Rollback boot.initrd.systemd.services.rollback = { - path = [ pkgs.btrfs-progs ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - unitConfig.DefaultDependencies = "no"; + description = "Rollback BTRFS root subvolume to a pristine state"; wantedBy = [ "initrd.target" ]; after = [ "systemd-cryptsetup@enc.service" ]; before = [ "sysroot.mount" ]; + unitConfig.DefaultDependencies = "no"; + serviceConfig.Type = "oneshot"; script = '' - btrfs subvolume delete / - btrfs subvolume create / + mkdir -p /mnt + + # We first mount the btrfs root to /mnt + # so we can manipulate btrfs subvolumes. + mount -o subvol=/ /dev/mapper/enc /mnt + + # While we're tempted to just delete /root and create + # a new snapshot from /root-blank, /root is already + # populated at this point with a number of subvolumes, + # which makes `btrfs subvolume delete` fail. + # So, we remove them first. + # + # /root contains subvolumes: + # - /root/var/lib/portables + # - /root/var/lib/machines + # + # I suspect these are related to systemd-nspawn, but + # since I don't use it I'm not 100% sure. + # Anyhow, deleting these subvolumes hasn't resulted + # in any issues so far, except for fairly + # benign-looking errors from systemd-tmpfiles. + btrfs subvolume list -o /mnt/root | + cut -f9 -d' ' | + while read subvolume; do + echo "deleting /$subvolume subvolume..." + btrfs subvolume delete "/mnt/$subvolume" + done && + echo "deleting /root subvolume..." && + btrfs subvolume delete /mnt/root + + echo "restoring blank /root subvolume..." + btrfs subvolume snapshot /mnt/root-blank /mnt/root + + # Once we're done rolling back to a blank snapshot, + # we can unmount /mnt and continue on the boot process. + umount /mnt ''; }; # }}} diff --git a/hosts/nixos/common/optional/services/restic/default.nix b/hosts/nixos/common/optional/services/restic/default.nix index 0cefef0..d25d6fb 100644 --- a/hosts/nixos/common/optional/services/restic/default.nix +++ b/hosts/nixos/common/optional/services/restic/default.nix @@ -3,24 +3,32 @@ let backupUrl = lib.removeSuffix "\n" (builtins.readFile ./url.txt); # {{{ Backup helper - createBackup = { name, paths, exclude, pruneOpts }: { - inherit pruneOpts paths; + createBackup = + { + name, + paths, + exclude, + pruneOpts, + }: + { + inherit pruneOpts paths; - initialize = true; - repository = "sftp:${backupUrl}:backups/${name}"; - passwordFile = config.sops.secrets.backup_password.path; - extraOptions = [ "sftp.args='-i ${config.users.users.pilot.home}/.ssh/id_ed25519'" ]; + initialize = true; + repository = "sftp:${backupUrl}:backups/${name}"; + passwordFile = config.sops.secrets.backup_password.path; + extraOptions = [ "sftp.args='-i ${config.users.users.pilot.home}/.ssh/id_ed25519'" ]; - exclude = [ - # Syncthing / direnv / git stuff - ".direnv" - ".git" - ".stfolder" - ".stversions" - ] ++ exclude; - }; - # }}} + exclude = [ + # Syncthing / direnv / git / snapper stuff + ".direnv" + ".git" + ".stfolder" + ".stversions" + ".snapshots" + ] ++ exclude; + }; in +# }}} { sops.secrets.backup_password.sopsFile = ../../../secrets.yaml; @@ -54,7 +62,8 @@ in paths = [ "/persist/state" ]; exclude = - let home = "/persist/state/${config.users.users.pilot.home}"; + let + home = "/persist/state/${config.users.users.pilot.home}"; in [ "${home}/discord" # There's lots of cache stored in here @@ -64,4 +73,3 @@ in # }}} }; } -