more progress on the new version of btrfs-snapshots.sh, still untested though
This commit is contained in:
parent
e72c4de394
commit
c31fd02092
|
@ -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
24
lib.sh
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue