]> code.delx.au - monosys/commitdiff
zfs: snapshot backup with borg
authorJames Bunton <jbunton@atlassian.com>
Sat, 2 Sep 2017 04:49:08 +0000 (14:49 +1000)
committerJames Bunton <jamesbunton@delx.net.au>
Sat, 2 Sep 2017 05:18:17 +0000 (15:18 +1000)
borg/backup
borg/do-install
borg/do-update [deleted file]
lvm/bsnap [moved from borg/bsnap with 100% similarity]
lvm/do-install [new file with mode: 0755]
zfs/bsnap [new file with mode: 0755]
zfs/do-install [new file with mode: 0755]
zfs/znap-list [new file with mode: 0755]
zfs/znap-mount [new file with mode: 0755]
zfs/znap-umount-all [new file with mode: 0755]

index a5793837d25ee3e0daaa5ec1db390c4196fab3e0..c92cc96e57d6dfb54cd63a603f50c3ac70a01b57 100755 (executable)
@@ -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 \
index dd0eeb9dbfcd3cc20581facb40526f8d207e266a..bbdf7a4ab90262b57554ce48c8f0d56a38acb24d 100755 (executable)
@@ -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 (executable)
index d9665fc..0000000
+++ /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
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 (executable)
index 0000000..1052cbc
--- /dev/null
@@ -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 (executable)
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 (executable)
index 0000000..5959326
--- /dev/null
@@ -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 (executable)
index 0000000..5dbf381
--- /dev/null
@@ -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 (executable)
index 0000000..7522eb8
--- /dev/null
@@ -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 (executable)
index 0000000..30a88ba
--- /dev/null
@@ -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