diff --git a/take_snapshot.sh b/take_snapshot.sh new file mode 100755 index 0000000..04a5509 --- /dev/null +++ b/take_snapshot.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# this will take read-only btrfs snapshots and make it available in /srv/snapshots + +# variables +SUBVOLUMES="/" +DESTINATION_ROOT=/srv/snapshots +TIMESTAMP=$(date +%Y%m%d%H%M) #add %S if you want sub-minute snapshots +PREFIX="snapshot-" +NAME="$PREFIX$TIMESTAMP" +MAX_SNAPSHOTS=28 #how many snapshots should be kept? + +# preflight checks +if [ $(whoami) != "root" ]; then + echo "error: you need to be root" + exit 1 +fi + +# take the snapshots +for SUBVOLUME in $SUBVOLUMES; do + if [ -z ${SUBVOLUME#/} ]; then + SNAPSHOT_PATH="$DESTINATION_ROOT" + else + PATH="$DESTINATION_ROOT/${SUBVOLUME#/}" + fi + if [ ! -d $SNAPSHOT_PATH ]; then + echo "warning: snapshot path ($SNAPSHOT_PATH) does not yet exist. creating." + mkdir -p $SNAPSHOT_PATH + fi + if [ -d $SNAPSHOT_PATH/$NAME ]; then + echo "warning: snapshots with same name already exists. skipping." + else + #TODO: handle failed snapshots and failed link creations + btrfs -q subvolume snapshot -r $SUBVOLUME $SNAPSHOT_PATH/$NAME + if [ -h $SNAPSHOT_PATH/latest ]; then + rm $SNAPSHOT_PATH/latest + fi + ln -sf $SNAPSHOT_PATH/$NAME $SNAPSHOT_PATH/latest + fi +done + +# prune old snapshots +SNAPSHOTS=$(ls -r $SNAPSHOT_PATH | grep $PREFIX) +i=0 +for SNAPSHOT in $SNAPSHOTS; do + if [ $i -ge $MAX_SNAPSHOTS ]; then + #TODO: handle failed snapshot deletions + btrfs -q subvolume delete $SNAPSHOT_PATH/$SNAPSHOT + fi + i=$((i+1)) +done + +# end script successfully +exit 0