From: James Bunton Date: Sat, 2 Sep 2017 04:49:08 +0000 (+1000) Subject: zfs: snapshot backup with borg X-Git-Url: https://code.delx.au/monosys/commitdiff_plain/be606986daa7b7b9668a8fbeafd9391f4a983332?hp=cc151db98fa750e312c7f4e2b4abb0c59d71ec4b zfs: snapshot backup with borg --- diff --git a/borg/backup b/borg/backup index a579383..c92cc96 100755 --- a/borg/backup +++ b/borg/backup @@ -16,12 +16,14 @@ renice -n 19 -p $$ > /dev/null [ "$BACKUP_SNAP" -eq 1 ] && bsnap on +cd "$BACKUP_PATH" + borg create \ $([ -t 0 ] && echo --progress) \ --info --stats \ --compression lz4 \ --exclude-from "$BACKUP_EXCLUDE_FILE" \ - "${BACKUP_REPO}::{hostname}-{now}" "$BACKUP_PATH" + "${BACKUP_REPO}::{hostname}-{now}" . borg prune \ --info --stats \ diff --git a/borg/do-install b/borg/do-install index dd0eeb9..bbdf7a4 100755 --- a/borg/do-install +++ b/borg/do-install @@ -4,9 +4,13 @@ set -eux cd "$(dirname "$0")" -BORG_PASSPHRASE="$(dd if=/dev/urandom of=/dev/stdout bs=1 count=15 2>/dev/null | base64)" +install -m 0755 backup /usr/local/bin/ + +if [ "${1:-}" != "full" ]; then + exit 0 +fi -install -m 0755 bsnap backup /usr/local/bin/ +BORG_PASSPHRASE="$(dd if=/dev/urandom of=/dev/stdout bs=1 count=15 2>/dev/null | base64)" install -m 0644 -T etc-borg-exclude /etc/borg-exclude install -m 0600 -T etc-borg-env /etc/borg-env sed -i "s|SECRET|$BORG_PASSPHRASE|" /etc/borg-env diff --git a/borg/do-update b/borg/do-update deleted file mode 100755 index d9665fc..0000000 --- a/borg/do-update +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -eux - -cd "$(dirname "$0")" - -install -m 0755 bsnap backup /usr/local/bin/ - -grep -q BACKUP_PATH /etc/borg-env || sed -i '1s|^|BACKUP_PATH=/a\n|' /etc/borg-env -grep -q BACKUP_SNAP /etc/borg-env || sed -i '1s|^|BACKUP_SNAP=1\n|' /etc/borg-env -grep -q BACKUP_EXCLUDE_FILE /etc/borg-env || sed -i '1s|^|BACKUP_EXCLUDE_FILE=/etc/borg-exclude\n|' /etc/borg-env - -sed -i 's|backup$|backup /etc/borg-env|' /etc/cron.d/backup diff --git a/borg/bsnap b/lvm/bsnap similarity index 100% rename from borg/bsnap rename to lvm/bsnap diff --git a/lvm/do-install b/lvm/do-install new file mode 100755 index 0000000..1052cbc --- /dev/null +++ b/lvm/do-install @@ -0,0 +1,7 @@ +#!/bin/bash + +set -eux + +cd "$(dirname "$0")" + +install -m 0755 bsnap /usr/local/bin/ diff --git a/zfs/bsnap b/zfs/bsnap new file mode 100755 index 0000000..6c9194d --- /dev/null +++ b/zfs/bsnap @@ -0,0 +1,29 @@ +#!/bin/bash + +set -eu + +function snap { + unsnap + + znap-list | xargs -n1 znap-mount /a +} + +function unsnap { + znap-umount-all /a +} + +if [ "$(id -u)" -ne 0 ]; then + echo "Must be root" + exit 1 +fi + +mkdir -p /a + +if [ "${1:-}" = "off" ]; then + unsnap +elif [ "${1:-}" = "on" ]; then + snap +else + echo "Usage: $0 on|off" + exit 1 +fi diff --git a/zfs/do-install b/zfs/do-install new file mode 100755 index 0000000..5959326 --- /dev/null +++ b/zfs/do-install @@ -0,0 +1,7 @@ +#!/bin/bash + +set -eux + +cd "$(dirname "$0")" + +install -m 0755 bsnap znap-list znap-mount znap-umount-all /usr/local/bin/ diff --git a/zfs/znap-list b/zfs/znap-list new file mode 100755 index 0000000..5dbf381 --- /dev/null +++ b/zfs/znap-list @@ -0,0 +1,19 @@ +#!/bin/bash + +set -eu + +function root_dataset { + mount | grep 'on / ' | cut -d' ' -f1 +} + +function find_latest_snapshot_timestamp { + zfs list -H -t snapshot -r "$(root_dataset)" -o name -S creation \ + | grep @znap | head -n1 | cut -d'@' -f2 +} + +function list_snapshots { + local timestamp="$1" + zfs list -H -t snapshot -o name | grep "$timestamp" +} + +list_snapshots "$(find_latest_snapshot_timestamp)" diff --git a/zfs/znap-mount b/zfs/znap-mount new file mode 100755 index 0000000..7522eb8 --- /dev/null +++ b/zfs/znap-mount @@ -0,0 +1,21 @@ +#!/bin/bash + +if [ -z "$1" ] || [ -z "$2" ]; then + echo "Usage: $0 prefix snapshot" + exit 1 +fi + +set -eu + +PREFIX="$1" +SNAPSHOT="$2" +DATASET="${SNAPSHOT%@*}" +MOUNTPOINT="${PREFIX}/$(echo "$DATASET" | cut -d@ -f1 | cut -d/ -f2- | tr '/' '_')" + +if [ "$(zfs get -H -o value backup:skip "$DATASET")" = "true" ]; then + exit 0 +fi + +set -x +mkdir -p "$MOUNTPOINT" +mount -t zfs "$SNAPSHOT" "$MOUNTPOINT" diff --git a/zfs/znap-umount-all b/zfs/znap-umount-all new file mode 100755 index 0000000..30a88ba --- /dev/null +++ b/zfs/znap-umount-all @@ -0,0 +1,18 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Usage: $0 prefix" + exit 1 +fi + +set -eu + +PREFIX="$1" + +set -x + +if ls &> /dev/null "$PREFIX"/*; then + umount "$PREFIX"/* || true + rmdir "$PREFIX"/* || true +fi +rmdir "$PREFIX" || true