add tool to make and upload backups from ZFS snaps
This commit is contained in:
116
zfsbk.sh
Executable file
116
zfsbk.sh
Executable file
@ -0,0 +1,116 @@
|
||||
#! /bin/sh
|
||||
|
||||
# make a backup collection having 1 full and N-1 incremental backups.
|
||||
# set to 1 to avoid incrementals and always take full dumps.
|
||||
max_incremental=4
|
||||
zpool="zroot"
|
||||
destination_store="u84693@u84693.your-backup.de:calaf/"
|
||||
|
||||
usage () {
|
||||
echo "Usage:"
|
||||
echo "zfsbk.sh <bkname> [numincr]"
|
||||
echo "Takes & sends backup with given name. If snapshots with"
|
||||
echo "this name exist, backup incrementally. Limit incremental"
|
||||
echo "backup sequences to 'numincr' steps (default 1 = alw. full)."
|
||||
echo
|
||||
echo "Optional envvars:"
|
||||
echo "UPLOAD_PATH upload generated backup to this path. scp:// or rsync://"
|
||||
}
|
||||
|
||||
# first argument: name of backup set
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bkname=$1
|
||||
if ! echo $bkname | grep -qiE '^[a-z0-9-]+$'
|
||||
then
|
||||
echo "Given bkname is invalid. Want alphanumeric and hyphens."
|
||||
exit 1
|
||||
fi
|
||||
if echo "$2" | grep -qE '^[1-9][0-9]*$'
|
||||
then
|
||||
max_incremental=$2
|
||||
fi
|
||||
|
||||
export PATH=$PATH:/usr/local/bin
|
||||
|
||||
# list snapshots by decreasing time. Arguments: [name] restrict listing to this tag
|
||||
list_named_snaps () {
|
||||
local bkname=$1
|
||||
snapdir="/.zfs/snapshot"
|
||||
for i in $snapdir/zbk-$bkname-*
|
||||
do
|
||||
test -e "$i" && (echo $i |sed "s@^$snapdir/@@")
|
||||
done | sort -r
|
||||
}
|
||||
|
||||
# remove all datasets for a given tag. Arguments: $1 -> bkname
|
||||
reset_sequence () {
|
||||
local bkname=$1
|
||||
list_named_snaps $bkname | while read snapname
|
||||
do
|
||||
zfs destroy -r $zpool@$snapname
|
||||
done
|
||||
}
|
||||
|
||||
# take snapshot
|
||||
#echo ./zfssnap.sh $bkname $max_incremental
|
||||
if ! ./zfssnap.sh $bkname $max_incremental
|
||||
then
|
||||
echo "Error creating snapshot! Code $?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get label
|
||||
num_snaps=`list_named_snaps $bkname | awk 'END {print NR}'`
|
||||
label_latest=`list_named_snaps $bkname | awk NR==1`
|
||||
|
||||
# decide what to do based on how many snapshots were found
|
||||
if [ $num_snaps -eq 0 ]
|
||||
then
|
||||
# no snapshots. Something's wrong
|
||||
echo "Error, no snapshots found for $bkname!"
|
||||
list_named_snaps $bkname
|
||||
exit 1
|
||||
elif [ $num_snaps -eq 1 ]
|
||||
then
|
||||
# first snapshot. Send full
|
||||
bkfile="/backups/${label_latest}.dump"
|
||||
#echo zfs send -R $zpool@$label_latest
|
||||
zfs send -R $zpool@$label_latest 2>/dev/null > $bkfile
|
||||
else
|
||||
# n-th snapshot. Send incrementally
|
||||
label_2ndlatest=`list_named_snaps $bkname | awk NR==2`
|
||||
bkfile="/backups/${label_latest}--${label_2ndlatest}.dump"
|
||||
#echo zfs send -i $label_2ndlatest -R $zpool@$label_latest
|
||||
zfs send -i $label_2ndlatest -R $zpool@$label_latest 2>/dev/null > $bkfile
|
||||
fi
|
||||
|
||||
if [ $num_snaps -eq $max_incremental ]
|
||||
then
|
||||
# finished the incremental sequence. Take full backup next time
|
||||
echo "Sequence of $max_incremental increm steps complete. Resetting."
|
||||
reset_sequence $bkname
|
||||
fi
|
||||
|
||||
|
||||
# upload backup to remote location
|
||||
if [ "x$UPLOAD_PATH" != x ]
|
||||
then
|
||||
#echo "Archiving $bkfile remotely..."
|
||||
if echo "$UPLOAD_PATH" | grep -qE '^rsync://'
|
||||
then
|
||||
rsync -qz $bkfile ${UPLOAD_PATH#rsync://}
|
||||
elif echo "$UPLOAD_PATH" | grep -qE '^scp://'
|
||||
then
|
||||
scp -BCq $bkfile ${UPLOAD_PATH#scp://}
|
||||
else
|
||||
echo "UPLOAD_PATH not understood! '$UPLOAD_PATH'"
|
||||
echo "Expecting rsync://.. or scp://.."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user