From acf82c432d1e8b75ef163ddac6501dcfb245ca43 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 27 Oct 2020 15:15:22 +0100 Subject: [PATCH] Add zfs_backup.sh and zfs_backup_dataset.sh --- zfs_backup.sh | 60 +++++++++++++++++++++++++++++++++++++ zfs_backup_dataset.sh | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100755 zfs_backup.sh create mode 100755 zfs_backup_dataset.sh diff --git a/zfs_backup.sh b/zfs_backup.sh new file mode 100755 index 0000000..c97191d --- /dev/null +++ b/zfs_backup.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +if ! lockfile-create -p -r 2 $0; then + echo "Another backup is running, aborting" + exit 49 +fi + + +### Arguments ### +DATASET=$1 +if test -z "$DATASET"; then + echo "Missing dataset argument" + exit 1 +fi + +NAME=$2 +if test -z "$NAME"; then + echo "Missing snapshot name argument" + exit 1 +fi + +PREVIOUS_NAME=$3 +if test -z "$NAME"; then + echo "Missing previous snapshot name argument" + exit 1 +fi + +TARGET=$4 +if test -z "$TARGET"; then + echo "Missing target" + exit 1 +fi + +TARGET_PATH=$5 +if test -z "$TARGET_PATH"; then + echo "Missing target path" + exit 1 +fi + +SNAPSHOT="$DATASET@$NAME" +PREVIOUS_SNAPSHOT="$DATASET@$PREVIOUS_NAME" +REMOTE_NAME="$TARGET_PATH/"$(echo -e $DATASET | sed -r "s/\//_/g") + + +# Take snapshot +echo "Creating $SNAPSHOT snapshot..." +zfs snapshot $SNAPSHOT || exit 1 +echo "Snapshot created." + +# Send snapshot +echo "Sending snapshot ($PREVIOUS_SNAPSHOT --- $SNAPSHOT) to $REMOTE_NAME ..." +if test ! -z "$PREVIOUS_NAME"; then + incr="-I $PREVIOUS_SNAPSHOT" +fi +zfs send -v -p $incr $SNAPSHOT | ssh $TARGET zfs receive -F $REMOTE_NAME || exit 1 +echo "Snapshot sent." + +# Remove lock +echo "Backup finished. Removing lock..." +lockfile-remove $0 diff --git a/zfs_backup_dataset.sh b/zfs_backup_dataset.sh new file mode 100755 index 0000000..d538d26 --- /dev/null +++ b/zfs_backup_dataset.sh @@ -0,0 +1,70 @@ +#!/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 + +### New snapshot ### +NAME=$(date +%Y-%m-%d_%H-%M-%S) +SNAPSHOT="$DATASET@$NAME" + +echo "New snapshot name is: $NAME" +echo "New snapshot is: $SNAPSHOT" + + +### Default last snapshot ### +DEFAULT_LAST_SNAPSHOT=$(zfs list -t snapshot -o name -s creation -H $DATASET | tail -n 1) +DEFAULT_LAST_NAME=$(echo -e $DEFAULT_LAST_SNAPSHOT | rev | cut -d"@" -f1 | rev) +echo "Default last snapshot is: $DEFAULT_LAST_SNAPSHOT" +echo "Default last snapshot name is: $DEFAULT_LAST_NAME" + + +### Tracking folder ### +tracking_folder="$HOME/.local/share/zfs_backup" +if test ! -d $tracking_folder; then + echo "Creating backup tracking files directory" + mkdir -p $tracking_folder +fi + + +### Last snapshot ### +LAST_SNAPSHOT=$DEFAULT_LAST_SNAPSHOT + +last_snapshot_file="$tracking_folder/last_snapshot_"$(echo -e $DATASET | sed -r "s/\//_/g") +if test -f $last_snapshot_file; then + LAST_SNAPSHOT=$(cat $last_snapshot_file) + echo "Found $last_snapshot_file" +else + echo "No $last_snapshot_file, resolving to default" +fi + +LAST_SNAPSHOT_NAME=$(echo -e $LAST_SNAPSHOT | rev | cut -d"@" -f1 | rev) + +echo "Last snapshot is: $LAST_SNAPSHOT" +echo "Last snapshot name is: $LAST_SNAPSHOT_NAME" + +echo "Starting backup with args $DATASET $NAME $LAST_SNAPSHOT_NAME" +$HOME/scripts/zfs_backup.sh $DATASET $NAME $LAST_SNAPSHOT_NAME $TARGET $TARGET_PATH || exit 1 + +echo "Saving new snapshot in tracking folder..." +echo -e $SNAPSHOT > $last_snapshot_file + +echo "Destroying last snapshot..." +# zfs destroy $LAST_SNAPSHOT +echo "(dry)" + +echo "Backup finished."