server-scripts/zsc.sh

109 lines
2.4 KiB
Bash
Executable File

#!/bin/bash
# ZSC - zfs snapshot cron
CONFIG_FILE="$HOME/.zsc"
FORMAT='+%Y-%m-%d'
DATE=$(date $FORMAT)
### LOCK ###
echo "Locking $0"
if ! lockfile-create -p -r 2 "$0"; then
echo "Another backup is running, aborting"
exit 49
fi
split_date() {
echo "$1" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\1\n\2\n\3/'
}
handle_dataset() {
DATASET=$1
AUTO_CREATE=$2
D=$3
W=$4
M=$5
Y=$6
PREFIX=$7
if test -z "$PREFIX"; then
PREFIX="zsc-"
fi
if test "!no_prefix!" = "$PREFIX"; then
PREFIX=""
fi
echo "--- $DATASET --- $D $W $M $Y $PREFIX"
# Create new snapshot
if [ $(zfs list -t snapshot -o name "$DATASET" | grep "$DATE" | head -n1 | wc -l) -eq 0 ]; then
echo -e
if [ $AUTO_CREATE == "true" ]; then
echo -e "Creating snapshot $DATASET@$PREFIX$DATE"
zfs snapshot "$DATASET@$PREFIX$DATE"
else
echo -e "Skip snapshot creation"
fi
echo -e
fi
# Delete old snapshots
SNAPSHOTS=($(zfs list -t snapshot -o name "$DATASET" | grep "@$PREFIX" | sort -r))
for s in "${SNAPSHOTS[@]}"; do
sdate=$(echo "$s" | awk 'match($0, /.+@'"$PREFIX"'(.+)/, a) {print a[1]}')
scomp=($(split_date "$sdate") $(date -d "$sdate" "+%u %W"))
echo -n "${scomp[3]} ${scomp[4]} | "
echo -n "${sdate}: "
if [ $D -gt 0 ]; then
D=$(( D-1 ))
echo "KEEP; D: $D"
elif [ $W -gt 0 ] && [ ${scomp[3]#0} -eq 1 ]; then
W=$(( W-1 ))
echo "KEEP; W: $W"
elif [ $M -gt 0 ] && [ ${scomp[3]#0} -eq 1 ] && [ $(( ${scomp[4]#0} % 4 )) -eq 0 ]; then
M=$(( M-1 ))
echo "KEEP; M: $M"
elif [ $Y -gt 0 ] && [ ${scomp[3]#0} -eq 1 ] && [ ${scomp[4]#0} -eq 4 ]; then
Y=$(( Y-1 ))
echo "KEEP; Y: $Y"
else
zfs destroy "$s"
echo "DISCARD"
fi
done
}
cat "$CONFIG_FILE" | while IFS=: read dataset recursive auto_create d w m y prefix; do
echo "| ##### Dataset: $dataset Recursive: $recursive Auto create: $auto_create Prefix: $prefix d: $d w: $w m: $m y: $y #####"
if [ $recursive = "true" ]; then
SUBDATASETS=($(zfs list -o name | grep "$dataset/"))
echo -e "| Subdatasets: ${SUBDATASETS[@]}"
echo -e '|'
for p in "${SUBDATASETS[@]}"; do
handle_dataset $p $auto_create $d $w $m $y $prefix | awk '{print "| " $0}'
echo -e '|'
done
fi
handle_dataset $dataset $auto_create $d $w $m $y $prefix | awk '{print "| " $0}'
echo -e "----------------------------------------------------------------------"
done
### UNLOCK ###
echo "Unlocking $0"
lockfile-remove "$0"