restic rclone backup template
This commit is contained in:
parent
fdd9a34011
commit
ef0bd6556e
1 changed files with 141 additions and 0 deletions
141
shell/restic_backup.sh
Executable file
141
shell/restic_backup.sh
Executable file
|
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# restic backup using rclone as the transport
|
||||
# - designed to be cron/timer driven, uses repo key on disk (security warning)
|
||||
#
|
||||
# (a) set up and test the rclone remote
|
||||
# (b) run the restic init first-time repo prep
|
||||
# (c) prepare the encryption key and excludes files, chmod 0600
|
||||
# (d) uses ~/.mailrc to send backup log/report via `mail` cmd
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
##
|
||||
## TEMPLATE - NEEDS ALL SYSTEM SPECIFIC VARIABLES CONFIGURED
|
||||
##
|
||||
|
||||
# restic exit codes:
|
||||
# Exit status is 0 if the command was successful
|
||||
# Exit status is 1 if there was a fatal error
|
||||
# (no snapshot created).
|
||||
# Exit status is 3 if some source data could not be read
|
||||
# (incomplete snapshot created).
|
||||
|
||||
# restic init:
|
||||
# restic -r rclone:remote: init
|
||||
|
||||
# restic excludes format examples:
|
||||
# Downloads/
|
||||
# VirtualBox**
|
||||
# .config/**Cache*
|
||||
# .config/*/sessions
|
||||
# .config/restic/xyzzy.txt
|
||||
# .thunderbird/**/*.msf
|
||||
# .xsession-errors*
|
||||
|
||||
# cloud provider expired SSL cert hack
|
||||
RCLONE_NO_CHECK_CERTIFICATE=true
|
||||
export RCLONE_NO_CHECK_CERTIFICATE
|
||||
|
||||
# email and log settings
|
||||
MAILTO="user@example.com"
|
||||
LOGDIR="/home/user/.logs"
|
||||
TIMESTAMP=$(date +%Y-%m-%d_%H%M)
|
||||
MAILSUB="restic backup: ${TIMESTAMP}"
|
||||
LOGFILE="${LOGDIR}/restic_${TIMESTAMP}.log"
|
||||
|
||||
# restic settings
|
||||
REPO="rclone:remote:"
|
||||
RSRC="/home/user"
|
||||
# encryption key, plaintext, chmod 0600
|
||||
RKEY="/home/user/.config/restic/xyzzy.txt"
|
||||
# excludes, chmod 0600
|
||||
EXCL="/home/user/.config/restic/excludes.txt"
|
||||
# snapshots to keep
|
||||
KEEP=10
|
||||
|
||||
# trap our signals
|
||||
function error_exit {
|
||||
echo "Trapped a kill signal, exiting."
|
||||
exit 99
|
||||
}
|
||||
trap error_exit SIGHUP SIGINT SIGTERM
|
||||
|
||||
# this may be needed for non-packaged binaries
|
||||
# (e.g. using newer restic on older LTS distro)
|
||||
function check_restic() {
|
||||
echo "Checking restic..."
|
||||
# get installed version
|
||||
_LOCAL=$(restic version 2>/dev/null | awk '{print $2}'; exit ${PIPESTATUS[0]})
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Unable to get installed restic version" >> "${LOGFILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get latest version, strip leading "v" (v1.55.1 -> 1.55.1)
|
||||
_REMOTE=$(curl -s "https://api.github.com/repos/restic/restic/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")')
|
||||
_REMOTE=${_REMOTE#v}
|
||||
|
||||
# bash doesn't see versions as numbers, but as strings
|
||||
if [[ "${_LOCAL}" != "${_REMOTE}" ]]; then
|
||||
echo "Upgrade restic - installed ${_LOCAL}, latest ${_REMOTE}" >> "${LOGFILE}"
|
||||
else
|
||||
echo "Installed restic is the latest - ${_LOCAL}" >> "${LOGFILE}"
|
||||
fi
|
||||
}
|
||||
# uncomment as needed
|
||||
#check_restic
|
||||
|
||||
# begin timestamp
|
||||
echo "== ${TIMESTAMP} ==" >> "${LOGFILE}"
|
||||
|
||||
# create a new snapshot
|
||||
restic --quiet -r "${REPO}" \
|
||||
backup --no-scan \
|
||||
--password-file="${RKEY}" \
|
||||
--exclude-file="${EXCL}" \
|
||||
"${RSRC}" >> "${LOGFILE}"
|
||||
_EC=$?
|
||||
|
||||
# prune older snapshots
|
||||
if [[ $_EC -eq 0 ]]; then
|
||||
restic --quiet -r "${REPO}" \
|
||||
forget --prune --keep-last ${KEEP} \
|
||||
--password-file="${RKEY}" >> "${LOGFILE}"
|
||||
_EC=$?
|
||||
if [[ $_EC -ne 0 ]]; then
|
||||
echo "Non-zero exit from restic forget: $_EC" >> "${LOGFILE}"
|
||||
fi
|
||||
else
|
||||
echo "Non-zero exit from restic backup: $_EC" >> "${LOGFILE}"
|
||||
fi
|
||||
|
||||
# check reposotory health
|
||||
restic --cleanup-cache -r "${REPO}" \
|
||||
check --password-file="${RKEY}" >> "${LOGFILE}"
|
||||
_EC=$?
|
||||
if [[ $_EC -ne 0 ]]; then
|
||||
echo "Non-zero exit from restic check: $_EC" >> "${LOGFILE}"
|
||||
else
|
||||
# list available snapshots
|
||||
restic -r "${REPO}" \
|
||||
snapshots -c --password-file="${RKEY}" >> "${LOGFILE}"
|
||||
# generate stats about repo
|
||||
restic -r "${REPO}" \
|
||||
stats --mode=files-by-contents --password-file="${RKEY}" >> "${LOGFILE}"
|
||||
restic -r "${REPO}" \
|
||||
stats --mode=raw-data --password-file="${RKEY}" >> "${LOGFILE}"
|
||||
fi
|
||||
|
||||
# end timestamp
|
||||
_NOW=$(date +%Y-%m-%d_%H%M)
|
||||
echo "== ${_NOW} ==" >> "${LOGFILE}"
|
||||
|
||||
# ~/.mailrc needs to be configured
|
||||
cat "${LOGFILE}" | mail -A mailprovider -s "${MAILSUB}" "${MAILTO}"
|
||||
|
||||
# remove older logfiles
|
||||
find "${LOGDIR}" -type f -name restic\* -mtime +30 -delete
|
||||
|
||||
exit 0
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue