60 lines
1.7 KiB
Nix
60 lines
1.7 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let cfg = config.sydnix.impermanence.rollback;
|
|
in {
|
|
options = {
|
|
sydnix.impermanence.rollback = {
|
|
enable = mkEnableOption "rollback of the root filesystem";
|
|
|
|
device = mkOption {
|
|
description = "Device to be wiped";
|
|
type = types.str;
|
|
};
|
|
|
|
subvolume = mkOption {
|
|
description = ''
|
|
The subvolume to be rolled back. Usually, this should be where your
|
|
root filesystem resides.
|
|
'';
|
|
type = types.str;
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
boot.initrd.postDeviceCommands = ''
|
|
# Mount the btrfs filesystem.
|
|
mkdir -p /btrfs-tmp
|
|
mount -t btrfs "${cfg.device}" /btrfs-tmp
|
|
|
|
# If the moribound subvolume exists, send it do 'death row' (old-roots),
|
|
# where live for about three days before its eventual deletion.
|
|
if [[ -e "/btrfs-tmp/${cfg.subvolume}" ]]; then
|
|
mkdir -p /btrfs-tmp/old-roots
|
|
timestamp=$(date --date="@$(stat -c %Y "/btrfs-tmp/${cfg.subvolume}")" "+%Y-%m-%-d_%H:%M:%S")
|
|
mv "/btrfs-tmp/${cfg.subvolume}" "/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"
|
|
}
|
|
|
|
# Delete previous roots older than three days.
|
|
# TODO: I would prefer archiving the last N previous roots, rather than
|
|
# time.
|
|
for i in $(find /btrfs-tmp/old-roots/ -maxdepth 1 -mtime +3); do
|
|
delete_subvolume_recursively "$i"
|
|
done
|
|
|
|
btrfs subvolume create "/btrfs-tmp/${cfg.subvolume}"
|
|
umount /btrfs-tmp
|
|
'';
|
|
};
|
|
}
|