Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple backup script utilizing rsync and ZFS snapshots
#!/usr/bin/env bash
#
# zfs-backup.sh
#
# Simple backup script utilizing rsync and ZFS snapshots.
#
# rsync must be installed both on the server and the client.
# ssh must be installed on the client.
# bash must be installed on the server.
# The server must use zfs and provide a dataset for each client.
#
# David Prandzioch <kontakt@davidprandzioch.de>
#
# Pass the following environment variables to the script:
#
# * BACKUP_DATASET : ZFS dataset to use
# * BACKUP_SSH_PATH : Original data SSH path (user@host:path)
# * BACKUP_SSH_PORT : SSH source port (22)
#
DAY_OF_WEEKLY_BACKUP=1 # monday
DAY_OF_MONTHLY_BACKUP="01" # first day in month
######### DO NOT CHANGE ANYTHING DOWN HERE #########
if [ -z $BACKUP_DATASET ]
then
echo "Environment variable BACKUP_DATASET not set, exiting"
exit 1
fi
if [ -z $BACKUP_SSH_PATH ]
then
echo "Environment variable BACKUP_SSH_PATH not set, exiting"
exit 1
fi
if [ -z $BACKUP_SSH_PORT ]
then
echo "Environment variable BACKUP_SSH_PORT not set, exiting"
exit 1
fi
function delete_snapshots() {
DATASET=$1
TYPE=$2
SNAPSHOTS=$(zfs list -t snapshot -o name | grep "${DATASET}@${TYPE}-")
for SNAPSHOT in $SNAPSHOTS
do
zfs destroy $SNAPSHOT
done
}
function sync_data() {
DATASET=$1
BACKUP_SSH_PATH=$2
BACKUP_SSH_PORT=$3
MOUNTPOINT=$(zfs list -o mountpoint $DATASET | grep -v MOUNTPOINT)
cd $MOUNTPOINT
rsync -av --progress --delete --inplace -e "ssh -p ${BACKUP_SSH_PORT}" ${BACKUP_SSH_PATH}* .
}
function create_snapshot() {
DATASET=$1
TYPE=$2
zfs snapshot ${DATASET}@${TYPE}-$(date +%Y-%m-%d)
}
sync_data $BACKUP_DATASET $BACKUP_SSH_PATH $BACKUP_SSH_PORT
if [ "$(date +%d)" == "$DAY_OF_MONTHLY_BACKUP" ]
then
create_snapshot $BACKUP_DATASET "monthly"
delete_snapshots $BACKUP_DATASET "weekly"
delete_snapshots $BACKUP_DATASET "daily"
elif [ "$(date +%u)" == "$DAY_OF_WEEKLY_BACKUP" ]
then
create_snapshot $BACKUP_DATASET "weekly"
delete_snapshots $BACKUP_DATASET "daily"
else
create_snapshot $BACKUP_DATASET "daily"
fi
echo "Available snapshots for "$BACKUP_DATASET": "
zfs list -t snapshot -o name | grep "${BACKUP_DATASET}@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment