system/roles/backup/files/snapstic
Marty Oehme 19162e2af3
feat(backup): Add restic backup
Restic backup creates a snapper snapshot of the root system which it
then chroots into and starts a restic backup to a (wasabi) S3 bucket to.

Intended to roughly follow this
<https://codeberg.org/silmaril/my-restic-solution> solution to achieve
restic backup of the _newest_ snapshot of my live root system.
2025-03-13 11:24:13 +01:00

53 lines
2.3 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
shopt -s expand_aliases
# Restic snapshot backup script
msg() { # $1=message string $2=unit
printf "[%s] %s\n" "${2:-snapstic}" "$1"
}
config="${SNAPSTIC_RESTIC_CONFIG:-root}"
restic_conf="/etc/restic/${config}/restic.conf"
snapper_snapshot_dir="${SNAPSTIC_SNAPSHOT_DIR:-/.snapshots}"
# snapper_config="${SNAPSTIC_SNAPPER_CONFIG}" # TODO: call snapper with associated conf if exists?
source "$restic_conf"
trap cleanup 1 2 3 6
cleanup() {
msg "unmount restic configuration"
umount "${snap_dir}/.snapshots"
umount "${snap_dir}/tmp"
exit
}
msg "create snapper snapshot"
snap_num=$(snapper create --cleanup-algorithm number --description 'restic' --print-number)
snap_dir="${snapper_snapshot_dir}/${snap_num}/snapshot"
if [[ "$#" -eq 0 ]]; then
msg "no backup options selected"
fi
msg "mount restic configuration to ephemeral dir"
mount --bind "/etc/restic/${config}" "${snap_dir}/.snapshots"
msg "mount restic cache dir"
mount --bind "/tmp" "${snap_dir}/tmp"
if [[ $* == *"backup"* ]]; then
msg "backup in chrooted $snap_dir"
chroot "$snap_dir" /bin/bash -c '. /.snapshots/restic.conf && AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" RESTIC_REPOSITORY=$RESTIC_REPOSITORY RESTIC_PASSWORD="$RESTIC_PASSWORD" /usr/bin/restic backup --tag "snapstic" --files-from="/.snapshots/include" --exclude-file="/.snapshots/exclude" --exclude "/.snapshots" --exclude-caches --no-cache'
fi
if [[ $* == *"forget"* ]]; then
msg "forget snapshots in $snap_dir"
chroot "$snap_dir" /bin/bash -c '. /.snapshots/restic.conf && DAILY=$DAILY WEEKLY=$WEEKLY MONTHLY=$MONTHLY YEARLY=$YEARLY AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" RESTIC_REPOSITORY=$RESTIC_REPOSITORY RESTIC_PASSWORD="$RESTIC_PASSWORD" /usr/bin/restic forget --tag "snapstic" --group-by "paths,tags" --keep-daily="${DAILY:-0}" --keep-weekly="${WEEKLY:-0}" --keep-monthly="${MONTHLY:-0}" --keep-yearly="${YEARLY:-0}" --no-cache'
fi
if [[ $* == *"stats"* ]]; then
msg "display repo stats"
chroot "$snap_dir" /bin/bash -c '. /.snapshots/restic.conf && AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" RESTIC_REPOSITORY=$RESTIC_REPOSITORY RESTIC_PASSWORD="$RESTIC_PASSWORD" /usr/bin/restic stats --no-cache'
fi
msg "done"