server-scripts/zfs_backup_dataset.sh

92 lines
2.0 KiB
Bash
Executable File

#!/bin/sh
DATASET=$1
if test -z "$DATASET"; then
echo "Missing dataset argument"
exit 1
fi
TARGET=$2
if test -z "$TARGET"; then
echo "Missing target"
exit 1
fi
TARGET_PATH=$3
if test -z "$TARGET_PATH"; then
echo "Missing target path"
exit 1
fi
DATE=$4
if test -z "$DATE"; then
DATE=$(date +%Y-%m-%d_%H-%M)
fi
REMOTE_NAME="$TARGET_PATH/"$(echo -e $DATASET | sed -r "s/\//_/g")
### Resume existing transfer ###
RESUME_TOKEN=$(ssh $TARGET zfs get -H -p receive_resume_token -o value "$REMOTE_NAME")
if [ "$RESUME_TOKEN" != "" ] && [ "$RESUME_TOKEN" != "-" ]; then
echo "Resuming interrupted transfer..."
zfs send -v -t "$RESUME_TOKEN" | ssh $TARGET zfs receive -F -s "$REMOTE_NAME" || exit 1
echo "Resumed transfer finished."
exit 0
fi
### Sync existing snapshots ###
REMOTE_SNAPSHOTS=($(ssh $TARGET zfs list -H -t snapshot -o name -s creation $REMOTE_NAME | cut -d"@" -f 2))
LOCAL_SNAPSHOTS=($(zfs list -H -t snapshot -o name -s creation $DATASET | cut -d"@" -f 2))
echo "Remote snapshots: $REMOTE_SNAPSHOTS"
for local_snapshot in "${LOCAL_SNAPSHOTS[@]}"; do
echo "Syncing local snapshot $local_snapshot ..."
found=false
for remote_snapshot in "${REMOTE_SNAPSHOTS[@]}"; do
if [ "$remote_snapshot" = "$local_snapshot" ] ; then
found=true
break
fi
done
if [ $found = true ] ; then
echo "> Found remotely, setting as last snapshot"
LAST_SNAPSHOT=$local_snapshot
EXISTING_SNAPSHOT=""
else
echo "> Needs sync"
EXISTING_SNAPSHOT=$local_snapshot
fi
done
### New snapshot ###
if [ "$EXISTING_SNAPSHOT" = "" ]; then
NAME=$DATE
else
NAME=$EXISTING_SNAPSHOT
fi
SNAPSHOT="$DATASET@$NAME"
echo "New snapshot name is: $NAME"
echo "New snapshot is: $SNAPSHOT"
### Last snapshot ###
echo "Last snapshot is: $LAST_SNAPSHOT"
## Perform transfer
echo "Starting backup with args $DATASET $NAME $LAST_SNAPSHOT"
$HOME/scripts/zfs_backup.sh $DATASET $NAME "$LAST_SNAPSHOT" $TARGET $TARGET_PATH || exit 1
## Destroy last snapshot
echo "Destroying last snapshot..."
zfs destroy "$DATASET@$LAST_SNAPSHOT" || exit 1
echo "Backup finished."