50 lines
1.5 KiB
Nix
50 lines
1.5 KiB
Nix
{
|
|
lib,
|
|
config,
|
|
...
|
|
}: let
|
|
root = config.fileSystems."/";
|
|
|
|
wipeScript = ''
|
|
mkdir /tmp -p
|
|
MNTPOINT=$(mktemp -d)
|
|
(
|
|
mount -t btrfs -o subvol=/ ${root.device} "$MNTPOINT"
|
|
trap 'umount "$MNTPOINT"' EXIT
|
|
|
|
echo "Creating needed directories"
|
|
mkdir -p "$MNTPOINT"/persist/var/{log,lib/{nixos,systemd}}
|
|
if [ -e "$MNTPOINT/dont-wipe" ]; then
|
|
echo "Skipping wipe"
|
|
else
|
|
echo "Cleaning root subvolume"
|
|
btrfs subvolume delete -R "$MNTPOINT/root"
|
|
echo "Restoring blank subvolume"
|
|
btrfs subvolume snapshot "$MNTPOINT/root-blank" "$MNTPOINT/root"
|
|
fi
|
|
)
|
|
'';
|
|
|
|
# Convert a device path to a systemd .device
|
|
toSystemdDevice = device: lib.concatStringsSep "-" (lib.tail (map (lib.replaceString "-" "\\x2d" ) (lib.splitString "/" device))) + ".device";
|
|
|
|
phase1Systemd = config.boot.initrd.systemd.enable;
|
|
in {
|
|
boot.initrd = {
|
|
supportedFilesystems = ["btrfs"];
|
|
postDeviceCommands = lib.mkIf (!phase1Systemd) (lib.mkBefore wipeScript);
|
|
systemd.services.restore-root = lib.mkIf phase1Systemd {
|
|
description = "Rollback btrfs rootfs";
|
|
wantedBy = ["initrd.target"];
|
|
requires = [(toSystemdDevice root.device)];
|
|
after = [(toSystemdDevice root.device)];
|
|
before = ["sysroot.mount"];
|
|
unitConfig.DefaultDependencies = "no";
|
|
serviceConfig.Type = "oneshot";
|
|
script = wipeScript;
|
|
};
|
|
};
|
|
|
|
fileSystems."/persist".neededForBoot = lib.mkDefault true;
|
|
}
|