Skip to content

Instantly share code, notes, and snippets.

Forked from erikw/znp
Created Jul 7, 2020
What would you like to do?
znp: Wrap shell command in ZFS pre-post snapshots and log outputs.
#!/usr/bin/env bash
# Runs a command wrapped in ZFS pre-post snapshots. The whole data pool is recursively snapshotted.
# Analogous to my snp script for BTRFS:
# Usage: $ znp <commands>
# e.g.: $ znp pgk upgrade
# e.g.: $ znp portmaster -aG
# e.g.: $ znp freebsd-upgrade install
date=$(date "+%Y-%m-%d-%H%M%S")
! [ -d $log_path ] && mkdir -p $log_path
# Log stdout and stderr. Reference:
exec > >(tee -a "$log_file")
exec 2> >(tee -a "$log_file" >&2)
echo "> Logging to: ${log_file}"
# snapper create --type=pre --cleanup-algorithm=number --print-number --description="${cmd}"
zfs snapshot -r $snapshot_pre
echo "> New pre snapshot created: ${snapshot_pre}"
echo -e "> Running command \"${cmd}\".\n"
eval "$cmd"
echo -e "\n> Command exit code: ${ecode}"
zfs snapshot -r $snapshot_post
echo "> New post snapshot created: ${snapshot_post}"
echo "> See the diff between them using:"
# Tip: add -t to xargs to print every individual command.
echo "zfs list -t snapshot -o name | grep ${snapshot_prefix} | cut -d@ -f1 | uniq | xargs -I{} -n1 sh -c 'zfs diff -F {}@${snapshot_prefix}_pre {}@${snapshot_prefix}_post 2>/dev/null'"
echo "> Destroy these snapshots with:"
echo "zfs destroy -r ${snapshot_pre} && zfs destroy -r ${snapshot_post}"
echo "> Destroy all snapshots created with znp:"
echo "zfs list -H -o name -t snapshot | grep "${zfs_pool}@znp_" | xargs -n1 zfs destroy -r"
echo "> Destroy the 10 oldest snapshot pairs created with znp:"
echo "zfs list -H -o name -t snapshot | grep "${zfs_pool}@znp_" | head -20 | xargs -n1 zfs destroy -r"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment