Add curacao backup stuff
This commit is contained in:
parent
740e103730
commit
a3552634b6
|
@ -17,7 +17,7 @@ function help {
|
|||
echo " -h: Display this help message."
|
||||
}
|
||||
|
||||
while getopts "hvb" OPTION
|
||||
while getopts "h" OPTION
|
||||
do
|
||||
case "$OPTION" in
|
||||
h)
|
||||
|
|
83
curacao/backup/backup.sh
Executable file
83
curacao/backup/backup.sh
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
# Parse arguments
|
||||
function help {
|
||||
echo "Usage: $0 [-h|-i] volume"
|
||||
echo "Backup BTRFS subvolume on rapido to razmo."
|
||||
echo
|
||||
echo "Arguments:"
|
||||
echo " volume: Name of the subvolume to backup"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -h: Display this help message."
|
||||
echo " -i: Don't fail if the receiving subvolume doesn't exist."
|
||||
}
|
||||
|
||||
init=false
|
||||
while getopts "hi" OPTION
|
||||
do
|
||||
case "$OPTION" in
|
||||
h)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
i)
|
||||
init=true
|
||||
;;
|
||||
?)
|
||||
help
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift "$((OPTIND - 1))"
|
||||
|
||||
if [ "$#" -ne 1 ]
|
||||
then
|
||||
help
|
||||
exit 2
|
||||
fi
|
||||
volume="$1"
|
||||
|
||||
# Assertions
|
||||
[ -d "/mnt/rapido/${volume}" ]
|
||||
[ -d "/mnt/rapido/${volume}.bkp" ] || "$init"
|
||||
[ ! -d "/mnt/rapido/${volume}.new" ]
|
||||
[ -d "/mnt/razmo/${volume}.bkp" ] || "$init"
|
||||
[ -d "/mnt/razmo/${volume}" ] || "$init"
|
||||
[ ! -d "/mnt/razmo/${volume}.new" ]
|
||||
[ ! -d "/mnt/razmo/${volume}.snapshots" ]
|
||||
|
||||
# Taking a snapshot of the running subvolume
|
||||
btrfs subvolume snapshot -r "/mnt/rapido/${volume}" "/mnt/rapido/${volume}.new"
|
||||
|
||||
# Sending (the difference with) the last backup to the backup disk
|
||||
function error_handler() {
|
||||
btrfs subvolume delete "/mnt/rapido/${volume}.new" || true
|
||||
btrfs subvolume delete "/mnt/razmo/${volume}.new" || true
|
||||
}
|
||||
trap error_handler ERR
|
||||
if [ -d "/mnt/rapido/${volume}.bkp" ]
|
||||
then
|
||||
btrfs send -p "/mnt/rapido/${volume}.bkp" "/mnt/rapido/${volume}.new" | btrfs receive /mnt/razmo
|
||||
else
|
||||
btrfs send "/mnt/rapido/${volume}.new" | btrfs receive /mnt/razmo
|
||||
fi
|
||||
trap - ERR
|
||||
|
||||
# Removing old backups and putting the new one in place
|
||||
[ ! -d "/mnt/rapido/${volume}.bkp" ] || btrfs subvolume delete "/mnt/rapido/${volume}.bkp"
|
||||
mv "/mnt/rapido/${volume}.new" "/mnt/rapido/${volume}.bkp"
|
||||
[ ! -d "/mnt/razmo/${volume}.bkp" ] || btrfs subvolume delete "/mnt/razmo/${volume}.bkp"
|
||||
mv "/mnt/razmo/${volume}.new" "/mnt/razmo/${volume}.bkp"
|
||||
|
||||
# Create a writeable clone in case we need to boot on the HDD
|
||||
# Needs to move away then back the .snapshots folder
|
||||
[ ! -d "/mnt/razmo/${volume}/.snapshots" ] || mv "/mnt/razmo/${volume}/.snapshots" "/mnt/razmo/${volume}.snapshots"
|
||||
[ ! -d "/mnt/razmo/${volume}" ] || btrfs subvolume delete "/mnt/razmo/${volume}"
|
||||
btrfs subvolume snapshot "/mnt/razmo/${volume}.bkp" "/mnt/razmo/${volume}"
|
||||
[ ! -d "/mnt/razmo/${volume}.snapshots" ] || mv "/mnt/razmo/${volume}.snapshots" "/mnt/razmo/${volume}/.snapshots"
|
||||
|
||||
sync
|
64
curacao/backup/default.nix
Normal file
64
curacao/backup/default.nix
Normal file
|
@ -0,0 +1,64 @@
|
|||
{ pkgs, lib, ... }:
|
||||
# MANU Snapper is not able to create the snapshot directory, so you'll need to do this after eventually running the backup script:
|
||||
# sudo btrfs subvol create /mnt/razmo/$subvolume/.snapshots
|
||||
let
|
||||
backup_subvolumes = [ "nixos" "home.rapido" ];
|
||||
backup_app = pkgs.writeShellApplication {
|
||||
name = "backup-subvolume";
|
||||
runtimeInputs = with pkgs; [ coreutils btrfs-progs ];
|
||||
text = builtins.readFile ./backup.sh;
|
||||
};
|
||||
snapper_subvolumes = [ "nixos" "home.rapido" "home.razmo" ];
|
||||
in
|
||||
{
|
||||
services =
|
||||
let
|
||||
default = {
|
||||
# filesystem type
|
||||
FSTYPE = "btrfs";
|
||||
|
||||
# run daily number cleanup
|
||||
NUMBER_CLEANUP = true;
|
||||
NUMBER_MIN_AGE = 1800;
|
||||
NUMBER_LIMIT = 25;
|
||||
|
||||
# create hourly snapshots
|
||||
TIMELINE_CREATE = true;
|
||||
|
||||
# cleanup hourly snapshots after some time
|
||||
TIMELINE_CLEANUP = true;
|
||||
TIMELINE_MIN_AGE = 1800;
|
||||
TIMELINE_LIMIT_HOURLY = 24;
|
||||
TIMELINE_LIMIT_DAILY = 31;
|
||||
TIMELINE_LIMIT_WEEKLY = 8;
|
||||
TIMELINE_LIMIT_MONTHLY = 0;
|
||||
TIMELINE_LIMIT_YEARLY = 0;
|
||||
|
||||
# cleanup empty pre-post-pairs
|
||||
EMPTY_PRE_POST_CLEANUP = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
snapper.configs = lib.attrsets.mergeAttrsList (map (s: { "${s}" = default // { SUBVOLUME = "/mnt/razmo/${s}"; }; }) snapper_subvolumes);
|
||||
};
|
||||
|
||||
|
||||
systemd = {
|
||||
services.bkp_rapido = {
|
||||
description = "Make a snapshot of the SSD to the HDD";
|
||||
before = [ "snapper-timeline.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = map (s: "${backup_app}/bin/backup-subvolume ${s}") backup_subvolumes;
|
||||
};
|
||||
# TODO Harden
|
||||
};
|
||||
timers.bkp_rapido = {
|
||||
description = "Regular snapshot of SSD to HDD";
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
};
|
||||
wantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
{ passwordFile ? "/should_not_be_needed_in_this_context", ... }:
|
||||
# FIXME Subvolumes for backup. If they're not created with the script. Add the script btw.
|
||||
# TODO Not relatime everywhere, thank you
|
||||
# TODO Default options
|
||||
let
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
./options.nix
|
||||
./hardware.nix
|
||||
./dk.nix
|
||||
./backup
|
||||
];
|
||||
|
||||
networking.hostName = "curacao";
|
||||
|
|
Loading…
Reference in a new issue