#!/bin/sh
SRC_POOL="rpool"
DST_POOL="rpoolbak"
TASMOTA_HOST="http://192.168.1.193"
DATE="$(date +%F)"
BACKUP_PREFIX="backup-"
NEW_SNAP_NAME="$BACKUP_PREFIX$DATE"
NEW_POOL_SNAP="$SRC_POOL@$NEW_SNAP_NAME"
# destroy all backups and start with a fresh full backup
# zpool destroy rpoolbak
# zpool create rpoolbak /dev/sdb
# list all snapshots
# zfs list -H -o name -t snapshot -r rpoolbak
# zfs list -H -o name -t snapshot -r rpoolbak | xargs -n1 zfs destroy
# destroy datasets recursively
# zfs destroy -R -f rpoolbak/ROOT
# control tasmota power switch
# curl http://192.168.1.193/cm?cmnd=POWER+TOGGLE
echo "starting backup $NEW_POOL_SNAP"
echo "switching on tasmota: $TASMOTA_HOST"
curl "$TASMOTA_HOST/cm?cmnd=POWER+ON"
echo ""
# import destination pool, but do not mount
LAST_IMPORT_POOL="$(zpool list -o name | tail -1)"
if ! [ "$LAST_IMPORT_POOL" = "$DST_POOL" ]; then
echo "importing $DST_POOL in 30 seconds..."
sleep 30
zpool import -N "$DST_POOL"
fi
LAST_IMPORT_POOL="$(zpool list -o name | tail -1)"
if ! [ "$LAST_IMPORT_POOL" = "$DST_POOL" ]; then
echo "ERROR: failed to import $DST_POOL"
exit 1
fi
# disable auto-snapshot for destination pool, if not done
DST_POOL_AUTO_STATE="$(zfs get com.sun:auto-snapshot $DST_POOL -o value | tail -1)"
# echo "zfs-auto-snapshot state for $DST_POOL: $DST_POOL_AUTO_STATE"
if ! [ "$DST_POOL_AUTO_STATE" = "false" ]; then
echo "disabling zfs-auto-snapshot for $DST_POOL"
zfs set com.sun:auto-snapshot=false "$DST_POOL"
fi
# create daily snapshot, if not exists
DAILY_SRC_SNAP="$(zfs list -H -o name -t snapshot "$SRC_POOL" | grep "@$NEW_SNAP_NAME")"
if [ "$DAILY_SRC_SNAP" = "" ]; then
echo "creating backup snapshot: $NEW_POOLSNAP"
zfs snapshot -r "$NEW_POOL_SNAP"
fi
# check last snapshot, that has been synced
LAST_DST_SNAP="$(zfs list -H -o name -t snapshot "$DST_POOL" | grep "@$BACKUP_PREFIX" | tail -1 | cut -d '@' -f 2)"
if [ "$LAST_DST_SNAP" = "" ]; then
echo "no existing snapshot found, full backup required"
# no existing snapshot, full send
# zfs send -R --raw "$SRC_POOL@$NEW_SNAP_NAME" | pv | zfs recv -Fdu "$DST_POOL"
zfs send --raw -R "$SRC_POOL@$NEW_SNAP_NAME" | pv | zfs recv -Fdu "$DST_POOL"
else
BACKUP_FROM_SNAPSHOT="$SRC_POOL@$LAST_DST_SNAP"
BACKUP_UNTIL_SNAPSHOT="$SRC_POOL@$NEW_SNAP_NAME"
if [ "$LAST_DST_SNAP" = "$NEW_SNAP_NAME" ]; then
echo "backup snapshot already exists on target, skipping"
else
echo "newest existing snapshot found: $SRC_POOL@$LAST_DST_SNAP"
echo "incremental backup $BACKUP_FROM_SNAPSHOT -> $BACKUP_UNTIL_SNAPSHOT"
# zfs send -RI --raw "$SRC_POOL@$LAST_DST_SNAP" "$SRC_POOL@$NEW_SNAP_NAME" | pv | zfs recv -Fdu "$DST_POOL"
zfs send --raw -RI "$BACKUP_FROM_SNAPSHOT" "$BACKUP_UNTIL_SNAPSHOT" | pv | zfs recv -Fdu "$DST_POOL"
fi
fi
echo "exporting pool and power off tasmota in 5 seconds..."
sleep 5
zpool export "$DST_POOL" && sleep 5 && curl "$TASMOTA_HOST/cm?cmnd=POWER+OFF"
echo ""
echo "done"