blob: ac797a666fb4d938901d3de523db804838a7c7e0 [file] [log] [blame]
# SPDX-FileCopyrightText: 2024 Clicks Codes
# SPDX-FileCopyrightText: 2020 Nix Community Projects
#
# SPDX-License-Identifier: MIT
# postDeviceCommands based of code from https://github.com/nix-community/impermanence/tree/d5f1ed7141fa407880ff5956ded2c88a307ca940?tab=readme-ov-file#btrfs-subvolumes
{ lib, config, ... }:
let
cfg = config.clicks.storage.impermanence;
in
{
options.clicks.storage.impermanence = {
enable = lib.mkEnableOption "Enable impermanent rootfs with btrfs subvolumes";
device = lib.mkOption {
type = lib.types.str;
description = "Device Path";
};
volumes = {
mount = lib.mkOption {
type = lib.types.str;
description = "Path on device to the mounting subvolume, everything on here will be deleted";
default = "@";
};
old_roots = lib.mkOption {
type = lib.types.str;
description = "Path on device to store old roots on";
default = "old_roots";
};
};
delete_days = lib.mkOption {
type = lib.types.int;
description = "How many days to wait before deleting an old root from cfg.old_roots";
default = 7;
};
};
config = lib.mkIf cfg.enable {
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /impermanent_fs
mount ${cfg.device} /impermanent_fs
if [[ -e /impermanent_fs/${cfg.volumes.mount} ]]; then
mkdir -p /impermanent_fs/${cfg.volumes.old_roots}
timestamp=$(date --date="@$(stat -c %Y /impermanent_fs/${cfg.volumes.mount})" "+%Y-%m-%-d_%H:%M:%S")
mv /impermanent_fs/${cfg.volumes.mount} "/impermanent_fs/${cfg.volumes.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 "/impermanent_fs/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /impermanent_fs/${cfg.volumes.old_roots}/ -maxdepth 1 -mtime +${builtins.toString cfg.delete_days}); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /impermanent_fs/${cfg.volumes.mount}
umount /impermanent_fs
'';
fileSystems."/" = {
device = cfg.device;
fsType = "btrfs";
options = [ "subvol=${cfg.volumes.mount}" ];
};
};
}