Skip to content

Instantly share code, notes, and snippets.

@EthraZa
Last active December 13, 2019 08:26
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EthraZa/6cd402c3f461b01b23ab3f4166ae829e to your computer and use it in GitHub Desktop.
Save EthraZa/6cd402c3f461b01b23ab3f4166ae829e to your computer and use it in GitHub Desktop.
A Borg Backup script for a centralized storage server to backup other servers
#!/bin/bash
##
# BORG Backup
#
# [1.0] 2014-10-30 :: Allan Brazute
# - Assimilation
#
# All hosts need to have ssh and borg
# Backup Repository host may also need a compress tool like pigz
# [SSH password less](https://www.cyberciti.biz/tips/ssh-public-key-based-authentication-how-to.html)
##
#### Config ####
export HOME=/root
BKP_LOG_EMAIL="admin@domain.net"
BKP_LOG_FILE="bkp.log"
# For each BKP_SRC_HOSTS ("user@srv1"), add a path list ("/path1 /path2/to/elsewhere") to backup in the BKP_SRC_PATHS array
BKP_SRC_HOSTS="root@srv1.domain.net root@srv2.domain.net"
BKP_SRC_PATHS[0]="/etc /var/spool/cron /var/vmail/mailfilters"
BKP_SRC_PATHS[1]="/etc /home /var/spool/cron /var/log/mysql"
# Excludes are one per line
#/home/user1
#*/trash
BKP_EXCLUDE="exclude.txt"
# Uncomment and set to run a command before or after the borg command
#BKP_SRC_RUN_BEFORE[1]="stop mysql"
#BKP_SRC_RUN_AFTER[1]="start mysql"
REPO_HOST="root@storage.domain.net:"
REPO_DEST="/mnt/backup/repo"
#BKP_DEST="/mnt/backup/tar" # Uncomment and set to get the backup exported once a day to a tarball
BKP_DEST_TIME="04"
BKP_DEST_EXT=".tgz"
BORG_CMD="borg"
BORG_INIT="init --encryption none"
BORG_CREATE="create --list --filter AME --stats --show-rc --compression auto,lz4 --exclude-caches"
BORG_PRUNE="prune --prefix '{hostname}-' --list --show-rc --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --keep-yearly 1" #--dry-run
BORG_EXPORT="export-tar --last 1"
COMPRESS_CMD="pigz -p8 -9"
RSH_CMD="ssh"
#### SCRIPT ####
CC=0
# Script dir
cd "$(dirname "$(readlink -f ${BASH_SOURCE[0]})")"
# Clean log
if [ `date +'%u'` == '1' ] && [ `date +'%H'` == '00' ]; then
mv -f $BKP_LOG_FILE $BKP_LOG_FILE".1"
fi
echo "*-----------------------------------------" >> $BKP_LOG_FILE
echo "Start backup. ['`date`']" >> $BKP_LOG_FILE
if [ -f 'bkp.run' ]; then
echo "bkp.run lock" >> $BKP_LOG_FILE
exit 0
fi
touch bkp.run
if [ -n "$BKP_EXCLUDE" ]; then
BKP_EXCLUDE_CREATE="echo \"`cat $BKP_EXCLUDE`\" > $BKP_EXCLUDE"
BORG_CREATE="$BORG_CREATE --exclude-from $BKP_EXCLUDE"
fi
# Create dirs if not there
if [ ! -d "$REPO_DEST" ]; then
mkdir -p "$REPO_DEST"
fi
if [ -n "$BKP_DEST" ] && [ ! -d "$BKP_DEST" ]; then
mkdir -p "$BKP_DEST"
fi
# For each host, backup the paths list
for H in $BKP_SRC_HOSTS
do
echo "Syncing $H. ["`date`"]" >> $BKP_LOG_FILE
if [ ! -d "$REPO_DEST/$H" ]; then
$RSH_CMD $H "$BORG_CMD $BORG_INIT $REPO_HOST$REPO_DEST/$H" 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
fi
if [ -n "${BKP_SRC_RUN_BEFORE[$CC]}" ]; then
echo "- Running ${BKP_SRC_RUN_BEFORE[$CC]}" 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
$RSH_CMD $H ${BKP_SRC_RUN_BEFORE[$CC]}
fi
if [ -n "$BKP_EXCLUDE" ]; then
$RSH_CMD $H "$BKP_EXCLUDE_CREATE"
fi
echo "Running $RSH_CMD $H \"$BORG_CMD $BORG_CREATE $REPO_HOST$REPO_DEST/$H::'{hostname}-{now}' ${BKP_SRC_PATHS[$CC]}\"" >> $BKP_LOG_FILE
$RSH_CMD $H "$BORG_CMD $BORG_CREATE $REPO_HOST$REPO_DEST/$H::'{hostname}-{now}' ${BKP_SRC_PATHS[$CC]}" 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
echo "Running $RSH_CMD $H \"$BORG_CMD $BORG_PRUNE $REPO_HOST$REPO_DEST/$H\"" >> $BKP_LOG_FILE
$RSH_CMD $H "$BORG_CMD $BORG_PRUNE $REPO_HOST$REPO_DEST/$H" 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
if [ -n "${BKP_SRC_RUN_AFTER[$CC]}" ]; then
echo "- Running ${BKP_SRC_RUN_AFTER[$CC]}" 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
$RSH_CMD $H ${BKP_SRC_RUN_AFTER[$CC]}
fi
CC=$((CC+1))
done
# On time, if it's set, export the backup
if [ -n "$BKP_DEST" ] && [ `date +'%H'` == $BKP_DEST_TIME ]; then
for H in $BKP_SRC_HOSTS
do
echo "Backuping $H. ["`date`"]" >> $BKP_LOG_FILE
LATEST=`${BORG_CMD} list --short --last 1 ${REPO_DEST}/${H}`
echo "Running $BORG_CMD $BORG_EXPORT $REPO_DEST/$H::$LATEST - | $COMPRESS_CMD > $BKP_DEST/$H$BKP_DEST_EXT" >> $BKP_LOG_FILE
$BORG_CMD $BORG_EXPORT $REPO_DEST/$H::$LATEST - | $COMPRESS_CMD > $BKP_DEST/$H$BKP_DEST_EXT 2>> $BKP_LOG_FILE
if [ `date +'%u'` == '1' ]; then
echo "- Weekly backup $H. ["`date`"]" >> $BKP_LOG_FILE
mv -f $BKP_DEST/$H.tgz $BKP_DEST/${H}_weekly.tgz 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
fi
if [ `date +'%d'` == '01' ]; then
echo "- Monthly backup $H. ["`date`"]" >> $BKP_LOG_FILE
mv -f $BKP_DEST/$H.tgz $BKP_DEST/${H}_monthly.tgz 1>> $BKP_LOG_FILE 2>> $BKP_LOG_FILE
fi
done
fi
echo "End backup. ['`date`']" >> $BKP_LOG_FILE
(uuencode $BKP_LOG_FILE backup_log.txt; echo "Backup log attached.") | mailx -s 'Borg Backup Script Message' $BKP_LOG_EMAIL
rm -f bkp.run
@rugk
Copy link

rugk commented Nov 4, 2017

Nice script. I also see some locking mechanism being implemented… I've done something very similar (initially to workaround an issue in borg's own locking mechanism). I've added much more features since then. See https://github.com/rugk/borg-cron-helper for a full list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment