#!/bin/sh # {{ ansible_managed }} # Configure restic through environment variables. export RESTIC_PASSWORD_FILE="/root/.restic.pass" export RESTIC_REPOSITORY_FILE="/root/.restic.repo" export GOMAXPROCS=3 indent() { sed 's/^/ /' } # Ask the kernel for a list of all ZFS filesystems. FS_LIST="$(zfs list -H -t filesystem -o name)" # Back up all mounted ZFS file systems with restic one at a time. echo "Backing up ZFS filesystems:" for FS in $FS_LIST do echo # Seperate the file systems by empty lines (for human consumption) # Because scripts shouldn't meddle in the system configuration we # have to skip over unmounted file systems. MNT="$(zfs get -H -t filesystem -o value mountpoint "$FS")" case "$MNT" in /*) echo "* The file system \"$FS\" is mounted at \"$MNT\"." ;; *) echo "* Skipping \"$FS\" (no valid mountpoint)." continue ;; esac if [ "$(zfs get -H -o value mounted "$FS")" = "no" ] then echo "* Skipping \"$FS\" (not mounted)." continue fi # Clean up if the previous run failed if [ -e "$MNT/.zfs/snapshot/restic" ] then echo "* Deleting stale restic snapshot of \"$FS\"." zfs destroy -v "$FS@restic" 2>&1 | indent fi # It's important to backup from a snapshot to get a consistent backup. echo "* Taking ZFS snapshot of \"$FS\"." zfs snapshot "$FS@restic" 2>&1 | indent # Finally backup the filesystem to a (remote) restic repo. echo "* Backing up \"$FS\"." nice -n 15 restic backup "$MNT/.zfs/snapshot/restic" 2>&1 | indent # Clean up the ZFS snapshot. echo "* Deleting ZFS snapshot of \"$FS\"." zfs destroy -v "$FS@restic" 2>&1 | indent done echo echo # Ask the kernel for a list of all ZFS volumes. VOL_LIST="$(zfs list -H -t volume -o name)" echo "Backing up ZFS volumes:" for VOL in $VOL_LIST do echo if [ -e "/dev/zvol/$VOL@restic" ] then echo "* Deleting stale restic snapshot of \"$VOL\"." zfs destroy -v "$VOL@restic" 2>&1 | indent fi echo "* Taking ZFS snapshot of \"$VOL\"." zfs snapshot "$VOL@restic" 2>&1 | indent echo "* Backing up \"$VOL\"." buffer -s128k -m 128m -i "/dev/zvol/$VOL@restic" | nice -n 15 restic backup --stdin --stdin-filename "$VOL" 2>&1 | indent echo "$ Deleting ZFS snapshot of \"$VOL\"." zfs destroy -v "$VOL@restic" 2>&1 | indent done echo echo echo # Delete old backups echo "* Thin out older backups." restic forget --keep-yearly 3 --keep-monthly 12 --keep-weekly 13 --keep-daily 31 2>&1 | indent echo "* Prune unreferenced data from the repository." restic prune 2>&1 | indent