1
1
Fork 0

more progress on the new version of btrfs-snapshots.sh, still untested though

This commit is contained in:
david 2023-10-29 22:54:21 +01:00
parent e72c4de394
commit c31fd02092
2 changed files with 121 additions and 38 deletions

View File

@ -35,15 +35,18 @@ LIBRARIES="lib.sh"
DEPENDENCIES="basename dirname readlink ln mkdir rm ls date btrfs"
REQUIRE_ROOT=1
SUBVOLUMES="/"
DESTINATION_ROOT=/srv/snapshots
SNAP_FOLDER=".snapshots"
SNAP_PREFIX="snapshot-"
SNAP_TIMESTAMP=$(date +%Y%m%d%H%M) #add %S if you want sub-minute snapshots
SNAP_NAME="$SNAP_PREFIX$SNAP_TIMESTAMP"
PREFIX="snapshot-"
TIMESTAMP=$(date +%Y%m%d%H%M) #add %S if you want sub-minute snapshots
NAME="$PREFIX$TIMESTAMP"
# Build the Btrfs command
BTRFS_BINARY="$(command -v btrfs)"
BTRFS_OPTIONS="-q"
BTRFS_COMMAND="$BTRFS_BINARY $BTRFS_OPTIONS"
# How many snapshots should be kept?
MAX_SNAPSHOTS=32
SNAPSHOTS=128
##
@ -52,14 +55,22 @@ MAX_SNAPSHOTS=32
# 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" \
printf "%s\n\n%s\n%b\n\n%s\n %-15s %s\n %-15s %s\n %-15s %s\n %-15s %s\n %-15s %s\n" \
"$DESCRIPTION" "Usage:" "$LIB_BOLD$EXECUTABLE <options> <subvolume>$LIB_CLEAR" "Options:" \
"-s, --snapshots <number>" "Override how many snapshots to keep (default: 128)" \
"-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)"
}
# Verify that input is a Btrfs subvolume
function is_subvolume() {
if ! $($BTRFS_COMMAND subvolume show $1 >/dev/null 2>&1); then
return 1
fi
}
##
## Preflight
@ -96,40 +107,88 @@ 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
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do
case $1 in
-s|--snapshots)
shift
if lib_is_int $1; then
SNAPSHOTS=$1
else
lib_print "!Input for --snapshots must be an intager"
exit 1
fi
;;
-h|--help)
H=1
;;
-i|--info)
I=1
;;
-v|--verbose)
V=1
;;
-q|--quiet)
Q=1
;;
*)
lib_print "!Unknown option [$1]"
lib_print "Try --help or -h for available options"
exit 1
;;
esac
shift
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
if [[ "$1" == '--' ]]; then
shift
fi
if [[ $I -eq 1 ]]; then
lib_print_info
exit 0
elif [[ $H -eq 1 ]]; then
print_help
exit 0
fi
if [[ -z "$1" ]]; then
print_help
exit 0
else
if is_subvolume "$1"; then
SNAP_FOLDER="${1%/}/$SNAP_FOLDER"
# Create $SNAP_FOLDER if it does not exist
if [[ ! -d "$SNAP_FOLDER" ]]; then
lib_print "?Creating snapshot folder because it does not yet exist [$SNAP_FOLDER]"
mkdir "$SNAP_FOLDER"
fi
i=$((i+1))
done
if [[ -d "$SNAP_FOLDER/$SNAP_NAME" ]]; then
lib_print "?Skipping snapshot because it already exists. [$SNAP_NAME]"
else
# Take the snapshot
$BTRFS_COMMAND subvolume snapshot -r "${1%/}" "$SNAP_FOLDER/$SNAP_NAME"
if [ -h "$SNAP_FOLDER/latest" ]; then
rm "$SNAP_FOLDER/latest"
fi
ln -sf "$SNAP_FOLDER/$SNAP_NAME" "$SNAP_FOLDER/latest"
# Delete old snapshots
SNAPS=$(ls -r $SNAP_FOLDER | grep $SNAP_PREFIX)
i=0
for SNAP in $SNAPS; do
if [[ $i -ge $SNAPSHOTS ]]; then
#TODO: handle failed snapshot deletions
$BTRFS_COMMAND subvolume delete "$SNAP_FOLDER/$SNAP"
lib_print "Deleted old snapshot [$SNAP_FOLDER/$SNAP]"
fi
i=$((i+1))
done
fi
else
lib_print "!Given path does not appear to be a Btrfs subvolume [$1]"
exit 1
fi
fi
##

24
lib.sh
View File

@ -142,3 +142,27 @@ function lib_healthchecks() {
curl -fsS -m 10 --retry 5 -o /dev/null "$1"
fi
}
# Verify if input is an intager
function lib_is_int {
local INT_EXPR='^[0-9]+$'
if ! [[ $1 =~ $INT_EXPR ]]; then
return 1
fi
}
# Verify if input is alphanumeric
function lib_is_alnum {
local ALNUM_EXPR='^[a-zA-Z0-9]+$'
if ! [[ $1 =~ $ALNUM_EXPR ]]; then
return 1
fi
}
# Verify if input looks like an URL
function lib_is_url {
local URL_EXPR='^https?://.+$'
if ! [[ $1 =~ $URL_EXPR ]]; then
return 1
fi
}