#!/usr/bin/env bash # This script is intended to be run by a systemd timer # Exit on failure or pipefail set -e -o pipefail #Set this to any location you like BACKUP_PATHS="/" BACKUP_EXCLUDES="/etc/restic/exclude" BACKUP_TAG=$(hostname -s) FEAT_NOTIFY=false # How many backups to keep. RETENTION_DAYS=7 RETENTION_WEEKS=4 RETENTION_MONTHS=3 RETENTION_YEARS=1 # Paths to binaries CURL="/usr/bin/curl" RESTIC="/usr/bin/restic" ECHO="/usr/bin/echo" HOST=$(hostname -s) source /etc/restic/env # define functions timestamp () { date "+%Y-%m-%d %H:%M:%S" } run_checklock () { OUTPUT=$(${RESTIC} list locks|wc -l) if (( OUTPUT != 0 ));then return 1 else return 0 fi } run_backup () { #Do the backup ${ECHO} "Starting backup on $HOST at $(timestamp)" ${RESTIC} backup \ --tag "$BACKUP_TAG" \ --exclude-file $BACKUP_EXCLUDES \ $BACKUP_PATHS & wait $! return $? } run_forget (){ # Remove old Backups ${ECHO} "Removing old backups per retention settings" ${RESTIC} forget \ --tag "$BACKUP_TAG" \ --prune \ --keep-daily $RETENTION_DAYS \ --keep-weekly $RETENTION_WEEKS \ --keep-monthly $RETENTION_MONTHS \ --keep-yearly $RETENTION_YEARS & wait $! return $? } run_check () { # Check if everything is fine ${ECHO} "Running check" ${RESTIC} check & wait $! return $? } cleanup () { # Remove locks in case other stale processes kept them in ${ECHO} "Removing lockfile" ${RESTIC} unlock } send_matrix () { ${CURL} -skd "{\"body\": \"$1\"}" $MATRIX_HOOK_URL/\?key\=$MATRIX_HOOK_KEY\&room_id\=$MATRIX_HOOK_ROOMID > /dev/null } notify () { #notify works either from stdin or from $1, so you can call it as # notify "text to send" # or # echo "text to send" | notify local message=$1 if [ -z "$message" ]; then read -r message fi # call whatever notification script/function you wish with "$message" as the part you want to show if $FEAT_NOTIFY; then send_matrix "$message" fi } # Do the actual work ERRORS="" STATUS_TOTAL=0 if run_checklock; then ${ECHO} "Restic backup on $HOST starting at $(timestamp)"|notify else ${ECHO} "Backup on $HOST aborted at $(timestamp) due to locks" |notify exit 1 fi if ! run_backup; then STATUS_TOTAL=$((STATUS_TOTAL+1)) ERRORS="$ERRORS [backup step failed]" fi if ! run_forget; then STATUS_TOTAL=$((STATUS_TOTAL+1)) ERRORS="$ERRORS [forget step failed]" fi if ! run_check ; then STATUS_TOTAL=$((STATUS_TOTAL+1)) ERRORS="$ERRORS [check step failed]" fi cleanup if (( STATUS_TOTAL == 0 ));then ${ECHO} "Backup on $HOST completed successfully at $(timestamp)" |notify else ${ECHO} "Backup on $HOST completed at $(timestamp) with issues: $ERRORS " |notify fi