Skip to content

Instantly share code, notes, and snippets.

@eusonlito
Last active July 1, 2022 01:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eusonlito/79615ff145d9f3e0bbb1 to your computer and use it in GitHub Desktop.
Save eusonlito/79615ff145d9f3e0bbb1 to your computer and use it in GitHub Desktop.
#!/bin/bash
# -------------------------------------
# Script to do incremental rsync backups
# from a central backup server
#
# This script is freely distributed under the GPL
# -------------------------------------
# -------------------------------------
# Configuration
#
# You only should touch this section
# -------------------------------------
# This hostname
HOSTNAME="your-host-name"
# Email address to send the error mails
MAILADDR="logs@email.com"
# Root directory to for backup stuff. Must exists
BASEBACKUP="/backup"
EXCLUDE="--exclude /dev/ \
--exclude /media/ \
--exclude /mnt/ \
--exclude /proc/
--exclude /sys/ \
--exclude /tmp/ \
--exclude /usr/var/log/ \
--exclude /var/log/ \
--exclude /var/tmp/ \
--exclude /Volumes/ \
--exclude $BASEBACKUP"
# Folder name to full copy
FULLNAME="full"
# Folder name to incremental changes
INCREMENTALNAME="incremental"
# Days to store the incremental changes
INCREMENTALTIME=10
# Hosts list to backup (with port if different to 22 and base path)
# Add a space between servers
HOSTS="root@server.com:/ 8822|root@other-server.com:/"
# Log directory. Must exists
LOGS="/root/logs"
# Size max in bytes to log files
# After that size, log will be rotated and compressed
LOGSIZE=10000
# Search commands in...
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11"
# -------------------------------------
# Functions definition
# -------------------------------------
if [ -f "$HOME/.keychain/$HOSTNAME-sh" ]; then
source "$HOME/.keychain/$HOSTNAME-sh"
fi
echo_log () {
if [ "$CMD_ECHO" != '' ]; then
$CMD_ECHO "$1" >> $LOG
fi
}
echo_start () {
echo_log ''
echo_log '----------------------------------------------------'
echo_log "[$1] Start at: $($CMD_DATE "+%Y-%m-%d %H:%M:%S")"
echo_log '----------------------------------------------------'
}
echo_end () {
echo_log ''
echo_log '----------------------------------------------------'
echo_log "[$1] End at: $($CMD_DATE "+%Y-%m-%d %H:%M:%S")"
echo_log '----------------------------------------------------'
}
do_rsync () {
$CMD_KILLALL $CMD_RSYNC > /dev/null 2> /dev/null
OPTIONS="--force --ignore-errors --delete --backup --backup-dir=$INCREMENTDIR/ $EXCLUDE"
echo_log ''
echo_log '----------------------------------------------------'
echo_log "$CMD_RSYNC $OPTIONS -e $CMD_SSH -p $PORT -ap $HOST:$BASEDIR $BASECOPY"
echo_log '----------------------------------------------------'
echo_log ''
$CMD_RSYNC $OPTIONS -e "$CMD_SSH -p $PORT" -apz $HOST:$BASEDIR $BASECOPY >> $LOG 2>&1
echo_log ''
echo_log '----------------------------------------------------'
echo_log "ls -t "$BASEINCREMENT" | tail -n +$INCREMENTALTIME | xargs -0 $CMD_RM"
echo_log '----------------------------------------------------'
echo_log ''
for OLD in $(ls -t "$BASEINCREMENT" | tail -n +$INCREMENTALTIME); do
echo_log "Deleted history backup $BASEINCREMENT/$OLD"
$CMD_RM -rf "$BASEINCREMENT/$OLD"
done
}
do_mail_error () {
echo_log ''
echo_log "[ERROR] Backup problem for $HOST"
echo_log ''
echo_log $1
{ $CMD_ECHO 'Subject: [ERROR] Backup problem for '.$HOST; $CMD_ECHO $1; } | $CMD_SENDMAIL $MAILADDR
}
# -------------------------------------
# Script execution
# -------------------------------------
LOG="$LOGS/error.log"
COMMANDS="echo date sendmail awk bzip2 du find install killall mv rm rsync ssh"
for i in $COMMANDS; do
exists=$(which $i)
if [ "$exists" = "" ]; then
echo_log ''
echo_log "Command $i does not exists in $PATH. Backup will be cancelled."
if [ "$CMD_SENDMAIL" != "" ]; then
do_mail_error "Command $i does not exists. Backup will be cancelled"
fi
echo_end
exit 1
fi
eval "CMD_"$(echo $i | tr "[:lower:]" "[:upper:]")"='$exists'"
done
if [ ! -d $BASEBACKUP ]; then
echo_log ''
echo_log "Backup folder ($BASEBACKUP) does not exists"
do_mail_error "Backup folder ($BASEBACKUP) does not exists"
echo_end
exit 1
fi
if [ ! -d $LOGS ]; then
echo_log ''
echo_log "Logs folder ($LOGS) does not exists"
do_mail_error "Logs folder ($LOGS) does not exists"
echo_end
exit 1
fi
for HOST in $HOSTS; do
if [ "$(echo $HOST | grep '|')" == "" ]; then
PORT=22
else
PORT=$(echo $HOST | $CMD_AWK -F'|' '{print $1}')
HOST=$(echo $HOST | $CMD_AWK -F'|' '{print $2}')
fi
BASEDIR=$(echo $HOST | $CMD_AWK -F':' '{print $2}')
HOST=$(echo $HOST | $CMD_AWK -F':' '{print $1}')
LOG="$LOGS/$HOST.log"
if [ -f "$LOG" ]; then
if [ $LOGSIZE -lt "$($CMD_DU -s $LOG | $CMD_AWK -F' ' '{print $1}')" ]; then
OLD_LOG=$LOG.$($CMD_DATE "+%Y%m%d-%H%M%S")
$CMD_MV $LOG $OLD_LOG
$CMD_BZIP2 -9 $OLD_LOG
fi
fi
echo_start $HOST
if [ "$HOST" = '' ]; then
echo_log ''
echo_log "No HOST is defined at first parameter"
do_mail_error "No HOST is defined at first parameter"
echo_end $HOST
exit 1
fi
test=$($CMD_SSH -p $PORT -o "PasswordAuthentication no" -q -q $HOST $CMD_ECHO 1 || $CMD_ECHO 2)
if [ "$test" = '2' ]; then
echo_log ''
echo_log "Can not connect to $HOST server"
continue
do_mail_error "Can not connect to $HOST server"
echo_end $HOST
exit 1
fi
ARCHIVEROOT="$BASEBACKUP/$HOST"
BASECOPY="$ARCHIVEROOT/$FULLNAME"
BASEINCREMENT="$ARCHIVEROOT/$INCREMENTALNAME"
INCREMENTDIR="$BASEINCREMENT/"$($CMD_DATE "+%Y-%m-%d")
if [ ! -d $BASECOPY ]; then
$CMD_INSTALL -d "$BASECOPY"
fi
if [ ! -d $BASEINCREMENT ]; then
$CMD_INSTALL -d "$BASEINCREMENT"
fi
do_rsync
echo_end $HOST
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment