Skip to content

Instantly share code, notes, and snippets.

@sammy8806
Last active February 21, 2018 03:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sammy8806/b87021bbca83c9aff56c1c22941dcbc0 to your computer and use it in GitHub Desktop.
Save sammy8806/b87021bbca83c9aff56c1c22941dcbc0 to your computer and use it in GitHub Desktop.
"Simple" script for zfs snapshot replication over ssh
#/usr/bin/env bash
share_volume="<zfs base-dataset>" # ex. /trunk
target_host="<user>@<target_host>" # ex. root@fileserver
keep_snaps=$((24*4))
for path in $(zfs list -o name -t filesystem -r "$share_volume" | tail -n +2)
do
echo "=> Volume: $path";
snapname=$(zfs list -t snapshot -o name,creation -s creation -d 1 "$path" | tail -n +2 | grep 'frequent' | tail -n 1 | awk '{print $1}' 2>&1)
dataset=$(echo $snapname | cut -d "@" -f 1)
echo "Snapshot: $snapname"
last_snapshot=$(ssh "$target_host" "(zfs list -o name -t filesystem -d 1 \"$path\" | tail -n +2) 2>&1")
echo "Remote Filesystem: $last_snapshot"
echo
if [[ "$last_snapshot" =~ "dataset does not exist" ]]; then
echo "- Dataset $dataset not found ... creating"
zfs send $snapname | gzip | ssh "$target_host" "gzip -d | zfs recv \"$dataset\""
else
lastremote=$(ssh "$target_host" "(zfs list -t snapshot -o name,creation -s creation -d 1 $path | tail -n +2 | grep 'frequent' | tail -n 1 | awk '{print \$1}' | cut -d '@' -f 2) 2>&1")
echo "Last Remote: $lastremote"
localref=$(zfs list "$dataset@$lastremote" | tail -n +2 | awk '{print $1}')
if [ "$dataset@$lastremote" == "$snapname" ]; then
echo "Replication already up-to-date ... skipping"
echo
continue
fi
if [[ "$lastremote" =~ "no datasets available" ]]; then
echo "No Snapshot for reference found ... doing full replication"
zfs send "$snapname" | gzip | ssh "$target_host" "gzip -d | zfs recv -F \"$dataset\""
else
echo "Doing incremental replication ..."
if zfs send -i "$lastremote" "$snapname" | gzip | ssh "$target_host" "gzip -d | zfs recv -F \"$dataset\""
then
echo "Replicated successfully"
else
echo "!! Failed! ... continuing"
continue
fi
fi
fi
echo "Cleanup remote snapshots (keep last $keep_snaps) ..."
ssh "$target_host" "zfs list -t snapshot -d 1 \"$path\" | grep frequent | sort -r | tail -n \"+$keep_snaps\" | sort -r | awk '{print \$1}'| xargs -I {} bash -c 'echo \"Destroying \$1\"; zfs destroy \"\$1\";' _ {}"
echo
done
echo "DONE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment