123 lines
3.1 KiB
Nix
123 lines
3.1 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
inherit (builtins) map;
|
|
inherit (lib)
|
|
concatStringsSep
|
|
mkIf
|
|
mkEnableOption
|
|
mkOption
|
|
mkBefore
|
|
;
|
|
inherit (lib.types)
|
|
bool
|
|
str
|
|
listOf
|
|
submodule
|
|
;
|
|
cfg = config.ataraxia.filesystems.btrfs;
|
|
|
|
eraseVolumesOpts =
|
|
{ ... }:
|
|
{
|
|
options = {
|
|
vol = mkOption {
|
|
type = str;
|
|
example = "rootfs";
|
|
description = "Name of submodule to erase";
|
|
};
|
|
blank = mkOption {
|
|
type = str;
|
|
example = "rootfs-blank";
|
|
description = "Name of submodule to clone into `vol`";
|
|
};
|
|
};
|
|
};
|
|
in
|
|
{
|
|
options.ataraxia.filesystems.btrfs = {
|
|
enable = mkEnableOption "Root on btrfs";
|
|
# Btrfs clean root
|
|
eraseOnBoot = {
|
|
enable = mkOption {
|
|
type = bool;
|
|
default = config.persist.enable;
|
|
description = "Clean btrfs subvolumes on boot";
|
|
};
|
|
device = mkOption {
|
|
type = str;
|
|
description = "Device on which is btrfs partititon";
|
|
};
|
|
systemdDevice = mkOption {
|
|
type = str;
|
|
description = "Escaped string with name of .device service";
|
|
example = "dev-disk-by\\x2did-ata\\x2dPhison_SATA_SSD_2165.device";
|
|
};
|
|
eraseVolumes = mkOption {
|
|
type = listOf (submodule eraseVolumesOpts);
|
|
default = [ ];
|
|
example = [
|
|
{
|
|
vol = "rootfs";
|
|
blank = "rootfs-blank";
|
|
}
|
|
];
|
|
description = ''
|
|
A list of subvolumes to erase on boot.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
config =
|
|
let
|
|
script = ''
|
|
mkdir -p /mnt
|
|
mount -t btrfs -o subvol=/ ${cfg.eraseOnBoot.device} /mnt
|
|
|
|
${concatStringsSep "\n" (
|
|
map (x: ''
|
|
btrfs subvolume list -o /mnt/${x.vol} |
|
|
cut -f9 -d' ' |
|
|
while read subvolume; do
|
|
echo "deleting /$subvolume subvolume..."
|
|
btrfs subvolume delete "/mnt/$subvolume"
|
|
done &&
|
|
|
|
echo "deleting /${x.vol} subvolume..."
|
|
btrfs subvolume delete /mnt/${x.vol}
|
|
echo "restoring blank ${x.blank} subvolume..."
|
|
btrfs subvolume snapshot /mnt/snapshots/${x.blank} /mnt/${x.vol}
|
|
'') cfg.eraseOnBoot.eraseVolumes
|
|
)}
|
|
|
|
umount /mnt
|
|
'';
|
|
in
|
|
mkIf cfg.enable {
|
|
boot.initrd = mkIf cfg.eraseOnBoot.enable {
|
|
postDeviceCommands = mkIf (!config.boot.initrd.systemd.enable) (mkBefore script);
|
|
|
|
systemd.services.rollback = mkIf config.boot.initrd.systemd.enable {
|
|
description = "Rollback btrfs root subvolume to a pristine state on boot";
|
|
wantedBy = [ "initrd.target" ];
|
|
requires = [ cfg.eraseOnBoot.systemdDevice ];
|
|
after = [ cfg.eraseOnBoot.systemdDevice ];
|
|
before = [ "sysroot.mount" ];
|
|
path = [
|
|
pkgs.btrfs-progs
|
|
pkgs.coreutils
|
|
pkgs.util-linuxMinimal.mount
|
|
];
|
|
unitConfig.DefaultDependencies = "no";
|
|
serviceConfig.Type = "oneshot";
|
|
script = script;
|
|
};
|
|
};
|
|
};
|
|
}
|