Skip to content

Instantly share code, notes, and snippets.

@haarp
Created December 2, 2023 13:05
Show Gist options
  • Save haarp/6ab1667b92f9c42daa25447710b30dcc to your computer and use it in GitHub Desktop.
Save haarp/6ab1667b92f9c42daa25447710b30dcc to your computer and use it in GitHub Desktop.
zfs-snapshot
#!/bin/bash
# Keep a number of snapshots
# adapted from my `backup-zfs`
PREFIX="daily"
KEEP=31 # days
SOURCE="data3"
# non-recursive:
EXCLUDES=("$SOURCE/Temp" "$SOURCE/Temp/playground" "$SOURCE/tmp")
# Sanity check
if ! /sbin/zpool list -o name "$SOURCE" &>/dev/null; then
echo "$0: Source pool $SOURCE not found, aborting!"
exit 1
fi
# Generate fs list
fslist=()
while read fs; do
# Skip excluded fs
# NOTE: will also skip deletion of old snapshots for this fs
for e in ${EXCLUDES[@]}; do
if [[ "$fs" == "$e" ]]; then
continue 2
fi
done
fslist+=("$fs")
done <<< $(/sbin/zfs list -H -o name -t filesystem,volume -r "$SOURCE")
# Create snapshot
newsnap="${PREFIX}_$(date '+%Y-%m-%d')"
/sbin/zfs snapshot "${fslist[@]/%/@$newsnap}" || exit 1
destroy=()
for fs in "${fslist[@]}"; do
# Generate list of snapshots
snaps=()
while IFS='@' read junk snap; do
[[ "$snap" =~ "${PREFIX}"_[0-9-]+$ ]] && snaps+=("$snap")
done <<< "$(/sbin/zfs list -H -o name -t snapshot -s creation "$fs" 2>/dev/null)"
# Generate list of old snapshots to destroy, keeping $KEEP most recent (reverse order because faster)
destroy_snaps=""
for (( i=$(( ${#snaps[@]}-1 - $KEEP )); i>=0; i-- )); do
destroy_snaps+="${snaps[$i]}," # only snapshot names can be comma-separated
done
[[ "$destroy_snaps" ]] && destroy+=("$fs@$destroy_snaps")
done
# Execute destruction
if [[ "${destroy[@]}" ]]; then
for d in "${destroy[@]}"; do
/sbin/zfs destroy "$d" >/dev/null || exit 1
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment