dotfiles/curacao/backup/backup.sh

84 lines
2.4 KiB
Bash
Executable file

#!/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