123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- #!/bin/sh
- ##### This is my (demuredemeanor) borgbackup wrapper script.
- # Blog Post: https://demu.red/blog/2017/02/backups-revisited/
- # Source Code: https://notabug.org/demure/scripts/src/master/borg_wrap.sh
- # Uses tabstop=4; shiftwidth=4 tabs; foldmarker={{{,}}};
- #
- # This is a script to run my borg backups.
- # It has basic config error checking, and verifies I am on my home network.
- # Usage: borg_wrap.sh [-q|--quiet]
- #
- # Note: I run this as root, and have a /etc/sudoers.d/ file granting permissions.
- #
- # Note: I run this via crontab
- # 0 */1 * * * sudo /usr/local/sbin/borg_wrap.sh -q
- #
- # Note: pruning:
- # borg prune -v --list --dry-run -d=7 -w=4 -m=12 -y=-1 --keep-within=1d /media/store/backups/doom/
- ### Conf ### {{{
- ## Set Repo location
- #export BORG_REPO='/media/store/backups/doom/'
- export BORG_REPO='ssh://demure@10.0.0.10:500/mnt/borg/doom'
- ## Set the right ssh key
- ## Note, use with the following in the destination ssh authorized_keys
- ## command="borg serve --restrict-to-path /path/to/repo",no-pty,no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-user-rc ssh-rsa AAAAB3[...]
- export BORG_RSH="ssh -i $HOME/.ssh/borg_id_ed25519"
- ## Pull Repo passwd
- export BORG_PASSPHRASE="$(pass cli/borg 2>/dev/null)"
- ## Path to log file
- Log_Path="$HOME/.config/borg/log"
- ## Temp file for log pruning
- Log_tmp="/tmp/borg_log.tmp"
- ## Define home routers MAC addr.
- MAC_addr="10:FE:ED:E9:63:04"
- ## Define remote address, for testing.
- Host="10.0.0.10"
- ### End Conf ### }}}
- ### Conf Check ### {{{
- ## Exit if BORG_REPO not specified.
- if [ "${BORG_REPO}" = "" ]; then
- echo 'No repo specified.'
- exit 78
- fi
- ## Exit if no log file specified.
- if [ "${Log_Path}" = "" ]; then
- echo 'No log file specified.'
- exit 78
- fi
- ## Exit if no router MAC specified.
- if [ "${MAC_addr}" = "" ]; then
- echo 'No router MAC specified.'
- exit 78
- fi
- ## Exit if storage address specified.
- if [ "${Host}" = "" ]; then
- echo 'No storage address specified.'
- exit 78
- fi
- ### End Conf Check ### }}}
- ### Startup Check ### {{{
- ### Augment Check ### {{{
- if [ $# -gt 1 ]; then
- echo 'Too many augments.'
- exit 1
- fi
- if [ ! -z "$1" ]; then
- if [ "$1" = '-q' ] || [ "$1" = '--Quiet' ]; then
- VERBOSE=""
- Quiet=1
- else
- echo 'Bad augments.'
- exit 1
- fi
- else
- VERBOSE='-v --stats -p'
- Quiet=0
- fi
- ### End Augment Check ### }}}
- ### Network Check ### {{{
- check_mac="$(/bin/ip neigh | awk '/router/ {} END {print $5}')"
- if [ ! "$MAC_addr" = "$check_mac" ]; then
- if [ $Quiet -eq 0 ]; then
- echo "Not on home network."
- fi
- Error='BadNet'
- else
- ping -c 3 $Host 1>/dev/null
- if [ ! $? = 0 ]; then
- if [ $Quiet -eq 0 ]; then
- echo "Can't reach host."
- fi
- Error='NoPing'
- fi
- fi
- ### End Network Check ### }}}
- ### Passwd Load Check ### {{{
- if [ -z "$BORG_PASSPHRASE" ]; then
- if [ $Quiet -eq 0 ]; then
- echo "Password failed to load."
- fi
- Error='NoPass'
- fi
- ### End Passed Load Check ### }}}
- ### End Startup Check ### }}}
- ## If no errors, run.
- if [ -z $Error ]; then
- borg create ${VERBOSE} -C lz4 \
- ::'{hostname}_{now:%Y-%m-%d_%H%M}' \
- / \
- --exclude-caches \
- -e /dev \
- -e /media/ \
- -e /mnt/ \
- -e /proc \
- -e /run \
- -e /sys \
- -e /tmp \
- -e /var/cache \
- -e '/var/tmp/*' \
- -e '/home/*/Downloads/' \
- -e '/home/*/temp/' \
- -e '/home/*/vault' \
- -e '/home/*/.config/chromium' \
- -e '/home/*/.local/share/mana/updates' \
- -e '*.cache' \
- -e '*.mail' \
- -e '*.thumbnails'
- ## Catch exit code
- Error=$?
- fi
- ## Log pass/fail state
- if [ ! $Error = "0" ]; then
- echo "$(date '+%F %T')\tfailed\t${Error}" | cat >> ${Log_Path}
- else
- echo "$(date '+%F %T')\tpassed" | cat >> ${Log_Path}
- fi
- ## This prunes the log, leaving last 30 days.
- ## If no passed backups in 30 days, also leaves lasted passed entry.
- ## You can comment out to disable
- awk -v cutoff="$(date -d"-30 days" +%F)" 'BEGIN{pchk=0} {a[i++]=$0} END{for(j=i-1;j>=0;j--) if(a[j] >= cutoff || pchk==0 && a[j] ~ /passed/){if(a[j] ~ /passed/){pchk=1}; b[k++]=a[j]};{for(l=k-1;l>=0;l--) print b[l]}}' ${Log_Path} > ${Log_tmp} && mv ${Log_tmp} ${Log_Path}
- ## Fix borg permissions so that things like `borg list` work without sudo
- ## This assumes that sudo preserves envars.
- chown -R ${USER}:${USER} ${HOME}/.config/borg ${HOME}/.cache/borg
|