-
-
Save laurentdinclaux/4242d18b7f16cd78b789ad9794d8bbba to your computer and use it in GitHub Desktop.
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
#!/bin/bash | |
zfs="zfs" | |
zfsDest=${zfs} | |
keep=3 | |
prefix=zfs-auto-snap | |
recursive=false | |
usage() { echo "Usage: $0 -r [-k <int>] source destination" 1>&2; exit 1; } | |
filesystem_exists() { | |
if [ -z "$1" ] || [ -z "$2" ]; then | |
return 1 | |
fi | |
if [ `${2} list -H -t filesystem -o name ${1} 2> /dev/null` ]; then | |
return 0 | |
fi | |
return 1 | |
} | |
while getopts ":rp:k:" o; do | |
case "${o}" in | |
k) | |
if echo "${OPTARG}" | grep -qE -v ^[1-9]+[0-9]*$; then usage; fi | |
keep=${OPTARG} | |
;; | |
r) | |
recursive=true | |
;; | |
p) | |
prefix=${OPTARG} | |
;; | |
esac | |
done | |
shift $(expr $OPTIND - 1) | |
source="$1"; shift | |
dest="$1"; shift | |
if [ -z "$source" ] || [ -z "$dest" ]; then | |
usage | |
fi | |
# verify filesystems exists | |
if ! filesystem_exists ${source} ${zfs}; then | |
echo "The file system '${source}' doesn't exists." | |
exit 1 | |
fi | |
# verify filesystems exists | |
if ! filesystem_exists ${dest} ${zfsDest}; then | |
echo "The file system '${dest}' doesn't exists." | |
exit 1 | |
fi | |
filesystems=${source} | |
if ${recursive}; then | |
filesystems=`${zfs} list -H -r -o name -t filesystem ${source} 2> /dev/null` | |
fi | |
for filesystem in ${filesystems} | |
do | |
echo -e "\033[0;34mBacking up ${filesystem}\033[0m" | |
# incremental ? | |
incremental=true | |
base_snapshot= | |
# lookup for destination filesystem | |
if [ ! -z ${zfsDest} list -H -t filesystem -o name ${dest}/${filesystem} 2> /dev/null ]; then | |
echo "Destination filesystem doesn't exists, doing full backup." | |
incremental=false | |
else | |
# lookup for destination snapshot | |
dest_snapshots=`${zfsDest} list -H -t snapshot -o name -S creation | grep ^${dest}/${filesystem}@${prefix} 2> /dev/null` | |
if [ -z "${dest_snapshots}" ]; then | |
echo "Destination filesystem has no snapshot, doing full backup." | |
incremental=false | |
else | |
for snap in ${dest_snapshots} | |
do | |
_base_snapshot=`echo ${snap} | sed -n "s/^.*\@\s*\(\S*\).*$/\1/p"` | |
if ${zfs} list -H ${filesystem}@${_base_snapshot} &> /dev/null; then | |
base_snapshot=${_base_snapshot} | |
break | |
fi | |
done | |
if [ -z "$base_snapshot" ]; then | |
echo "No base snapshot can be used for the incremental backup of ${filesystem}. Destroy the destination filsesystem and relaunch to start over with a full backup." | |
echo | |
continue | |
incremental=false | |
fi | |
fi | |
fi | |
# full/initial backup | |
if ! $incremental; then | |
latest=`${zfs} list -H -t snapshot -o name -S creation 2> /dev/null | grep ^${filesystem}@${prefix} | head -n 1` | |
if [ -z ${latest} ]; then | |
echo "No snapshot to use" | |
echo | |
continue | |
fi | |
${zfs} send ${latest} | ${zfsDest} receive -Fv ${dest}/${filesystem} | |
echo | |
continue | |
fi | |
echo Doing incremental backup of ${filesystem}. | |
latest=`${zfs} list -H -r -t snapshot -o name -S creation ${filesystem} 2> /dev/null | grep ^${filesystem}@${prefix} | head -n 1` | |
#roll back destination | |
${zfsDest} rollback -r ${dest}/${filesystem}@${base_snapshot} | |
${zfs} send -i $base_snapshot $latest | ${zfsDest} receive -v ${dest}/${filesystem} | |
# if [ $? -eq 0 ]; then | |
# delete old backup snapshots | |
# adjust retention to work with tail i.e. increase by one | |
retention=$keep | |
let retention+=1 | |
old_snapshots=`${zfsDest} list -H -t snapshot -o name -S creation | grep ^${dest}/${filesystem}@${prefix} | tail -n +${retention}` | |
if [ ! -z "${old_snapshots}" ]; then | |
echo Deleting old snap shots | |
for snapshot in ${old_snapshots} | |
do | |
echo - destroying ${snapshot} | |
${zfsDest} destroy ${snapshot} | |
done | |
fi | |
# fi | |
echo | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment