137 lines
2.6 KiB
Bash
Executable file
137 lines
2.6 KiB
Bash
Executable file
#!/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
|