1
1
Fork 0
scripts/btrfs-snapshots.sh

140 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ##
## btrfs-snapshots.sh ##
## ##
## Take read-only snapshots of BTRFS ##
## subvolumes ##
## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ##
##
## Information
## (don't touch unless you are me)
##
NAME="btrfs-snapshots.sh"
VERSION="0.2.0"
AUTHOR="david@socialnerds.org"
LICENSE="MIT"
DESCRIPTION="Take read-only snapshots of BTRFS subvolumes."
WEBSITE="https://git.socialnerds.org/david/scripts"
CHANGELOG=("[2023-10-26][v0.2.0] Complete rewrite"
"[2021-01-01][v0.1.0] Initial version")
##
## Configuration
##
EXECUTABLE="$(basename $0)"
LIBRARIES="lib.sh"
DEPENDENCIES="basename dirname readlink ln mkdir rm ls date btrfs"
REQUIRE_ROOT=1
SUBVOLUMES="/"
DESTINATION_ROOT=/srv/snapshots
PREFIX="snapshot-"
TIMESTAMP=$(date +%Y%m%d%H%M) #add %S if you want sub-minute snapshots
NAME="$PREFIX$TIMESTAMP"
# How many snapshots should be kept?
MAX_SNAPSHOTS=32
##
## Functions
##
# Print help information
function print_help() {
printf "%s\n\n%s\n%b\n\n%s\n %-15s %s\n %-15s %s\n %-15s %s\n %-15s %s\n" \
"$DESCRIPTION" "Usage:" "$LIB_BOLD$EXECUTABLE <options> <subvolume>$LIB_CLEAR" "Options:" \
"-h, --help" "Print help screen and exit" \
"-i, --info" "Print script information and exit" \
"-v, --verbose" "More verbose output" \
"-q, --quiet" "No output except errors (overrides -v)"
}
##
## Preflight
##
# Load BASH libraries
SCRIPT_PATH=$(readlink -f "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
for LIBRARY in $LIBRARIES; do
if [[ -r "$SCRIPT_DIR/$LIBRARY" ]]; then
#echo "Loading library file [$SCRIPT_DIR/$LIBRARY]"
source "$SCRIPT_DIR/$LIBRARY"
else
echo "Error: Cannot load library file [$SCRIPT_DIR/$LIBRARY]"
exit 1
fi
done
# Check for root privileges
if ! lib_amiroot && [[ $REQUIRE_ROOT -eq 1 ]]; then
lib_print "!You need to have root privileges"
exit 1
fi
# Check for dependencies
MISSING_COMMANDS=$(lib_missing_commands $DEPENDENCIES)
if [[ -n "$MISSING_COMMANDS" ]]; then
lib_print "!One or more commands missing [$MISSING_COMMANDS]"
lib_print "Try installing them with your package manager"
exit 1
fi
##
## Liftoff
##
exit 0
# 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
# Delete 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
##
## Here be dragons
##
exit 0