84 lines
2.2 KiB
Bash
Executable File
84 lines
2.2 KiB
Bash
Executable File
#! /bin/sh
|
|
|
|
# change this to the name of your ZFS pool. Or set ZPOOL envvar at runtime
|
|
zpool=${ZPOOL:-"rpool"}
|
|
|
|
# names of the DATASETs to exclude (datasets, not mountpoints!)
|
|
# can override this list at runtime with EXCLUDES envvar.
|
|
# can extend this list at runtime with EXTRA_EXCLUDES envvar.
|
|
#excludes=${EXCLUDES:-"/usr/ports /usr/src"}
|
|
excludes=${EXCLUDES:-""}
|
|
|
|
|
|
# You do not want to edit anything below here
|
|
|
|
tstamp=`date +%Y%m%d-%H%M%S`
|
|
label_pfx="zbk-"
|
|
|
|
# expecting optional arguments: $1 -> usrlabel, $2 -> numsnaps
|
|
usrlabel=${1:-"default"}
|
|
maxnum=${2:-"10"}
|
|
|
|
usage () {
|
|
echo Usage:
|
|
echo "zfssnap [label [maxnum]]"
|
|
echo "* label: tag name of snapshot (alphanumeric, default 'default')"
|
|
echo "* maxnum: prune old snapshots when more than this snaps exist"
|
|
echo
|
|
echo "Optional envvars:"
|
|
echo "ZPOOL name of ZFS pool to manage (default 'zroot')"
|
|
echo "EXCLUDES list of dataset paths to exclude from snaps. Overrides default."
|
|
echo "EXTRA_EXCLUDES list of dataset paths to exclude from snaps. Extends default."
|
|
echo "default excluded DATASET paths:"
|
|
echo $excludes
|
|
}
|
|
|
|
failmsg () {
|
|
echo $*
|
|
echo
|
|
usage
|
|
exit 1
|
|
}
|
|
|
|
verify_zpool () {
|
|
zpool status $zpool >/dev/null 2>&1 || failmsg "ZFS pool '$zpool' not found. Fix your \$ZPOOL envvar."
|
|
}
|
|
|
|
verify_zpool
|
|
|
|
# build list of dataset paths to exclude
|
|
if [ "x$EXTRA_EXCLUDES" != x ]
|
|
then
|
|
excludes="$excludes $EXTRA_EXCLUDES"
|
|
fi
|
|
|
|
# label
|
|
echo "$usrlabel" | grep -qiE '^([a-z0-9]{1,10})$' || failmsg "Invalid label '$usrlabel'! Quitting."
|
|
label_pfx="$label_pfx$usrlabel"
|
|
|
|
# maxnum
|
|
echo "$maxnum" | grep -qE '^[0-9]+$' || failmsg "Invalid maxnum '$maxnum'! Terminating."
|
|
|
|
|
|
# add timestamp to label
|
|
label="${label_pfx}-$tstamp"
|
|
|
|
# take recursive snap
|
|
zfs snapshot -r $zpool@$label || exit $?
|
|
# exclude folders
|
|
for xm in $excludes
|
|
do
|
|
# let this fail, the ds might not exist
|
|
zfs destroy -r $zpool$xm@$label
|
|
done
|
|
|
|
# prune dbs if requested
|
|
if [ "x$maxnum" != x ]
|
|
then
|
|
ls /.zfs/snapshot/ | sort -rt- -k 3,4 | awk -v maxnum=$maxnum -v matchlabel=$label_pfx 'BEGIN {x=0} $0 ~ "^"matchlabel { x++; if (x>maxnum) print}' | while read snapname
|
|
do
|
|
zfs destroy -r $zpool@$snapname || exit $?
|
|
done
|
|
fi
|
|
|