Last active
May 15, 2020 13:25
-
-
Save chris-roerig/5b6418a30749021714eb017420b2fc43 to your computer and use it in GitHub Desktop.
rsync backup with 6 day rotation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# copied from http://www.noah.org/engineering/src/shell/rsync_backup | |
# minor modifications made to support --exclude-from file | |
#!/bin/sh | |
# | |
# This maintains a one week rotating backup. This will normalize permissions on | |
# all files and directories on backups. It has happened that someone removed | |
# owner write permissions on some files, thus breaking the backup process. This | |
# prevents that from happening. All this permission changing it tedious, but it | |
# eliminates any doubts. I could have done this with "chmod -R +X", but I | |
# wanted to explicitly set the permission bits. | |
# | |
# Pass two arguments: rsync_backup SOURCE_PATH BACKUP_PATH | |
# | |
# $Id: rsync_backup 222 2008-02-21 22:05:30Z noah $ | |
usage() { | |
echo "usage: rsync_backup [-v] [-n] SOURCE_PATH BACKUP_PATH" | |
echo " SOURCE_PATH and BACKUP_PATH may be ssh-style remote paths; although," | |
echo " BACKUP_PATH is usually a local directory where you want the" | |
echo " backup set stored." | |
echo " -v : set verbose mode" | |
echo " -n : normalize directory and file permissions to 755 for dirs and 644 for files." | |
} | |
VERBOSE=0 | |
NORMALIZE_PERMS=0 | |
while getopts ":vnh" options; do | |
case $options in | |
v ) VERBOSE=1;; | |
n ) NORMALIZE_PERMS=1;; | |
h ) usage | |
exit 1;; | |
\? ) usage | |
exit 1;; | |
* ) usage | |
exit 1;; | |
esac | |
done | |
shift $(($OPTIND - 1)) | |
SOURCE_PATH=$1 | |
BACKUP_PATH=$2 | |
EXCLUDE_LIST_PATH=$3 | |
if [ -z $SOURCE_PATH ] ; then | |
echo "Missing argument. Give source path and backup path." | |
usage | |
exit 1 | |
fi | |
if [ -z $BACKUP_PATH ] ; then | |
echo "Missing argument. Give source path and backup path." | |
usage | |
exit 1 | |
fi | |
SOURCE_BASE=`basename $SOURCE_PATH` | |
PERMS_DIR=755 | |
PERMS_FILE=644 | |
if [ $VERBOSE ]; then | |
RSYNC_OPTS="-a --delete -v" | |
date | |
else | |
RSYNC_OPTS="-a --delete -q" | |
fi | |
# Create the rotation directories if they don't exist. | |
if [ ! -d $BACKUP_PATH ] ; then | |
mkdir $BACKUP_PATH | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.0 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.0 | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.1 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.1 | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.2 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.2 | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.3 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.3 | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.4 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.4 | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.5 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.5 | |
fi | |
if [ ! -d $BACKUP_PATH/$SOURCE_BASE.6 ] ; then | |
mkdir $BACKUP_PATH/$SOURCE_BASE.6 | |
fi | |
# TODO All these find operations to clean up permissions is going to add a lot | |
# of overhead as the backup set gets bigger. At 100 GB it's not a big deal. The | |
# correct thing would be to have an exception based system where I correct | |
# permissions when/if they cause a problem. | |
# Rotate backups. | |
if [ $NORMALIZE_PERMS ]; then | |
if [ $VERBOSE ]; then | |
echo "Normalizing file permissions." | |
fi | |
find $BACKUP_PATH/$SOURCE_BASE.6 -type d -exec chmod $PERMS_DIR {} \; | |
find $BACKUP_PATH/$SOURCE_BASE.6 -type f -exec chmod $PERMS_FILE {} \; | |
fi | |
rm -rf $BACKUP_PATH/$SOURCE_BASE.6 | |
mv $BACKUP_PATH/$SOURCE_BASE.5 $BACKUP_PATH/$SOURCE_BASE.6 | |
mv $BACKUP_PATH/$SOURCE_BASE.4 $BACKUP_PATH/$SOURCE_BASE.5 | |
mv $BACKUP_PATH/$SOURCE_BASE.3 $BACKUP_PATH/$SOURCE_BASE.4 | |
mv $BACKUP_PATH/$SOURCE_BASE.2 $BACKUP_PATH/$SOURCE_BASE.3 | |
mv $BACKUP_PATH/$SOURCE_BASE.1 $BACKUP_PATH/$SOURCE_BASE.2 | |
cp -al $BACKUP_PATH/$SOURCE_BASE.0 $BACKUP_PATH/$SOURCE_BASE.1 | |
# Backup. | |
if [ $NORMALIZE_PERMS ]; then | |
if [ $VERBOSE ]; then | |
echo "Normalizing file permissions." | |
fi | |
find $BACKUP_PATH/$SOURCE_BASE.0 -type d -exec chmod $PERMS_DIR {} \; | |
find $BACKUP_PATH/$SOURCE_BASE.0 -type f -exec chmod $PERMS_FILE {} \; | |
fi | |
rsync $RSYNC_OPTS --exclude-from $EXCLUDE_LIST_PATH $SOURCE_PATH/. $BACKUP_PATH/$SOURCE_BASE.0/. | |
RSYNC_EXIT_STATUS=$? | |
if [ $NORMALIZE_PERMS ]; then | |
if [ $VERBOSE ]; then | |
echo "Normalizing file permissions." | |
fi | |
find $BACKUP_PATH/$SOURCE_BASE.0 -type d -exec chmod $PERMS_DIR {} \; | |
find $BACKUP_PATH/$SOURCE_BASE.0 -type f -exec chmod $PERMS_FILE {} \; | |
fi | |
# Ignore error code 24, "rsync warning: some files vanished before they could be transferred". | |
if [ $RSYNC_EXIT_STATUS = 24 ] ; then | |
RSYNC_EXIT_STATUS=0 | |
fi | |
# Create a timestamp file to show when backup process completed successfully. | |
if [ $RSYNC_EXIT_STATUS = 0 ] ; then | |
rm -f $BACKUP_PATH/$SOURCE_BASE.0/BACKUP_ERROR | |
date > $BACKUP_PATH/$SOURCE_BASE.0/BACKUP_TIMESTAMP | |
else # Create a timestamp if there was an error. | |
rm -f $BACKUP_PATH/$SOURCE_BASE.0/BACKUP_TIMESTAMP | |
echo "rsync failed" > $BACKUP_PATH/$SOURCE_BASE.0/BACKUP_ERROR | |
date >> $BACKUP_PATH/$SOURCE_BASE.0/BACKUP_ERROR | |
echo $RSYNC_EXIT_STATUS >> $BACKUP_PATH/$SOURCE_BASE.0/BACKUP_ERROR | |
fi | |
if [ $VERBOSE ]; then | |
date | |
fi | |
exit $RSYNC_EXIT_STATUS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment