Skip to content

Instantly share code, notes, and snippets.

@cnrd
Last active January 15, 2022 14:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cnrd/434ce7990e5f68fa9521473a90103ccc to your computer and use it in GitHub Desktop.
Save cnrd/434ce7990e5f68fa9521473a90103ccc to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
## Configs ##
ZFSSNAPSHOTNAME="rclone"
RCLONECONFIGPATH="/root/.config/rclone/rclone.conf"
BWLIMIT=10M
TRANSFERS=10
ZFSPATH="/sbin/zfs"
mountSnapshots () {
mkdir -p "/mnt/$RUNNAME"
mount -t zfs "$ZFSSNAPSHOTBASE@$ZFSSNAPSHOTNAME" "/mnt/$RUNNAME"
while read -r line
do
MOUNTPATH=$(echo "$line" | sed "s/$ESCAPEDZFSSNAPSHOTBASE\///" | sed "s/@$ZFSSNAPSHOTNAME//")
if [ -d "/mnt/$RUNNAME/$MOUNTPATH" ]; then
mount -t zfs "$line" "/mnt/$RUNNAME/$MOUNTPATH"
fi
done < <("$ZFSPATH" list -t snapshot | grep "$ZFSSNAPSHOTNAME" | grep "$ZFSSNAPSHOTBASE" | grep -v "$ZFSSNAPSHOTBASE/\." | grep -o "$ZFSSNAPSHOTBASE/[0-9,a-z,A-Z,/,[:space:]]*@$ZFSSNAPSHOTNAME" | sed 's/[[:space:]]*$//')
}
unmountSnapshots () {
while read -r line
do
MOUNTPATH=$(echo "$line" | sed "s/$ESCAPEDZFSSNAPSHOTBASE\///" | sed "s/@$ZFSSNAPSHOTNAME//")
if [ -d "/mnt/$RUNNAME/$MOUNTPATH" ]; then
umount "/mnt/$RUNNAME/$MOUNTPATH"
fi
done < <("$ZFSPATH" list -t snapshot | grep "$ZFSSNAPSHOTNAME" | grep "$ZFSSNAPSHOTBASE" | grep -v "$ZFSSNAPSHOTBASE/\." | grep -o "$ZFSSNAPSHOTBASE/[0-9,a-z,A-Z,/,[:space:]]*@$ZFSSNAPSHOTNAME" | sed 's/[[:space:]]*$//' | tac)
umount "/mnt/$RUNNAME"
rmdir "/mnt/$RUNNAME"
}
cleanup () {
cd "/"
unmountSnapshots
"$ZFSPATH" destroy -r "$ZFSSNAPSHOTBASE@$ZFSSNAPSHOTNAME"
if [ -f "/var/log/$RUNNAME.log" ]; then
bzip2 "/var/log/$RUNNAME.log"
fi
rm $PIDFILE
}
trapCleanup () {
trap SIGINT
cleanup
exit
}
createPIDFile () {
if [ -f $PIDFILE ]
then
PID=$(cat $PIDFILE)
ps -p $PID > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "Process already running"
exit 1
else
## Process not found assume not running
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
else
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
}
if [ $# -eq 3 ]
then
BASENAME=$(basename $1)
RUNNAME="$ZFSSNAPSHOTNAME-$BASENAME"
ZFSSNAPSHOTBASE=$("$ZFSPATH" list | grep "$BASENAME" | grep -v "$BASENAME/" | awk '{print $1}')
ESCAPEDZFSSNAPSHOTBASE=$(echo "$ZFSSNAPSHOTBASE" | sed 's/\//\\\//')
PIDFILE=/var/lock/$RUNNAME.pid
ISOTIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
YEAR=$(date -u +"%Y")
createPIDFile
"$ZFSPATH" snapshot -r "$ZFSSNAPSHOTBASE@$ZFSSNAPSHOTNAME"
trap "trapCleanup" INT
if [ -f "/var/log/$RUNNAME.log.bz2" ]; then
bunzip2 "/var/log/$RUNNAME.log.bz2"
fi
mountSnapshots
# Do tha backup dance!
if [[ $BWLIMIT ]]; then
rclone --config "$RCLONECONFIGPATH" sync "/mnt/$RUNNAME" "$2:$BASENAME/current" --backup-dir "$2:$BASENAME/$YEAR/$ISOTIME" --transfers $TRANSFERS --log-file /var/log/$RUNNAME.log --log-level INFO --bwlimit $BWLIMIT
else
rclone --config "$RCLONECONFIGPATH" sync "/mnt/$RUNNAME" "$2:$BASENAME/current" --backup-dir "$2:$BASENAME/$YEAR/$ISOTIME" --transfers $TRANSFERS --log-file /var/log/$RUNNAME.log --log-level INFO
fi
# Create filelist
# | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g' | sed 's/\?/\\\?/g' | sed 's/\*/\\\*/g' | sed 's/{/\\{/g' | sed 's/}/\\}/g'
if [ $3 = "true" ]; then
cd "/mnt/$RUNNAME"
find . | sed 's/^.\/*\(.*\)/\1/' | sed '/^[[:space:]]*$/d' | bzip2 > "/tmp/filelist-$RUNNAME.bz2"
rclone --config "$RCLONECONFIGPATH" copyto "/tmp/filelist-$RUNNAME.bz2" "$2:$BASENAME/$YEAR/$ISOTIME/filelist.bz2"
rm "/tmp/filelist-$RUNNAME.bz2"
fi
cleanup
else
echo "Argument should be: path remote filelist ( Either true or false)"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment