New rollback script
This commit is contained in:
parent
c217465409
commit
19d2ef374c
|
@ -1,4 +1,4 @@
|
||||||
{ lib, pkgs, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
imports = [ (import ./partitions.nix { }) ];
|
imports = [ (import ./partitions.nix { }) ];
|
||||||
|
|
||||||
|
@ -22,18 +22,49 @@
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ Rollback
|
# {{{ Rollback
|
||||||
boot.initrd.systemd.services.rollback = {
|
boot.initrd.systemd.services.rollback = {
|
||||||
path = [ pkgs.btrfs-progs ];
|
description = "Rollback BTRFS root subvolume to a pristine state";
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
};
|
|
||||||
unitConfig.DefaultDependencies = "no";
|
|
||||||
wantedBy = [ "initrd.target" ];
|
wantedBy = [ "initrd.target" ];
|
||||||
after = [ "systemd-cryptsetup@enc.service" ];
|
after = [ "systemd-cryptsetup@enc.service" ];
|
||||||
before = [ "sysroot.mount" ];
|
before = [ "sysroot.mount" ];
|
||||||
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
script = ''
|
script = ''
|
||||||
btrfs subvolume delete /
|
mkdir -p /mnt
|
||||||
btrfs subvolume create /
|
|
||||||
|
# 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
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
# }}}
|
# }}}
|
||||||
|
|
|
@ -3,24 +3,32 @@ let
|
||||||
backupUrl = lib.removeSuffix "\n" (builtins.readFile ./url.txt);
|
backupUrl = lib.removeSuffix "\n" (builtins.readFile ./url.txt);
|
||||||
|
|
||||||
# {{{ Backup helper
|
# {{{ Backup helper
|
||||||
createBackup = { name, paths, exclude, pruneOpts }: {
|
createBackup =
|
||||||
inherit pruneOpts paths;
|
{
|
||||||
|
name,
|
||||||
|
paths,
|
||||||
|
exclude,
|
||||||
|
pruneOpts,
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
inherit pruneOpts paths;
|
||||||
|
|
||||||
initialize = true;
|
initialize = true;
|
||||||
repository = "sftp:${backupUrl}:backups/${name}";
|
repository = "sftp:${backupUrl}:backups/${name}";
|
||||||
passwordFile = config.sops.secrets.backup_password.path;
|
passwordFile = config.sops.secrets.backup_password.path;
|
||||||
extraOptions = [ "sftp.args='-i ${config.users.users.pilot.home}/.ssh/id_ed25519'" ];
|
extraOptions = [ "sftp.args='-i ${config.users.users.pilot.home}/.ssh/id_ed25519'" ];
|
||||||
|
|
||||||
exclude = [
|
exclude = [
|
||||||
# Syncthing / direnv / git stuff
|
# Syncthing / direnv / git / snapper stuff
|
||||||
".direnv"
|
".direnv"
|
||||||
".git"
|
".git"
|
||||||
".stfolder"
|
".stfolder"
|
||||||
".stversions"
|
".stversions"
|
||||||
] ++ exclude;
|
".snapshots"
|
||||||
};
|
] ++ exclude;
|
||||||
# }}}
|
};
|
||||||
in
|
in
|
||||||
|
# }}}
|
||||||
{
|
{
|
||||||
sops.secrets.backup_password.sopsFile = ../../../secrets.yaml;
|
sops.secrets.backup_password.sopsFile = ../../../secrets.yaml;
|
||||||
|
|
||||||
|
@ -54,7 +62,8 @@ in
|
||||||
|
|
||||||
paths = [ "/persist/state" ];
|
paths = [ "/persist/state" ];
|
||||||
exclude =
|
exclude =
|
||||||
let home = "/persist/state/${config.users.users.pilot.home}";
|
let
|
||||||
|
home = "/persist/state/${config.users.users.pilot.home}";
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
"${home}/discord" # There's lots of cache stored in here
|
"${home}/discord" # There's lots of cache stored in here
|
||||||
|
@ -64,4 +73,3 @@ in
|
||||||
# }}}
|
# }}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue