From d93b0bc8fdc13145c8be54c5404de83cac7e1ecf Mon Sep 17 00:00:00 2001 From: James Bunton Date: Mon, 12 Jun 2017 00:04:18 +1000 Subject: [PATCH] borg backups --- borg/backup | 33 ++++++++++++ borg/bsnap | 52 +++++++++++++++++++ borg/do-install | 21 ++++++++ borg/do-update | 8 +++ borg/etc-borg-env | 5 ++ borg/etc-borg-exclude | 6 +++ borg/etc-cron.d-backup | 6 +++ borg/root-ssh-config | 6 +++ backup-all => rdiff-backup/backup-all | 0 common => rdiff-backup/common | 0 .../etc-cron.d-backup | 0 .../template-rdiff-backup | 0 template-rsync => rdiff-backup/template-rsync | 0 13 files changed, 137 insertions(+) create mode 100755 borg/backup create mode 100755 borg/bsnap create mode 100755 borg/do-install create mode 100755 borg/do-update create mode 100644 borg/etc-borg-env create mode 100644 borg/etc-borg-exclude create mode 100644 borg/etc-cron.d-backup create mode 100644 borg/root-ssh-config rename backup-all => rdiff-backup/backup-all (100%) rename common => rdiff-backup/common (100%) rename etc-cron.d-backup => rdiff-backup/etc-cron.d-backup (100%) rename template-rdiff-backup => rdiff-backup/template-rdiff-backup (100%) rename template-rsync => rdiff-backup/template-rsync (100%) diff --git a/borg/backup b/borg/backup new file mode 100755 index 0000000..997d5ac --- /dev/null +++ b/borg/backup @@ -0,0 +1,33 @@ +#!/bin/bash + +set -eu + +if pgrep borg > /dev/null; then + echo "Borg is still running!" + exit 1 +fi + +source "$1" + +set -x + +ionice -c 3 -p $$ +renice -n 19 -p $$ > /dev/null + +[ "$BACKUP_SNAP" -eq 1 ] && bsnap on + +borg create \ + $([ -t 0 ] && echo --progress) \ + --info --stats \ + --compression lz4 \ + --exclude-from "$BACKUP_EXCLUDE_FILE" \ + "${BACKUP_REPO}::{hostname}-{now}" "$BACKUP_PATH" + +borg prune \ + --info --stats \ + --keep-daily=7 \ + --keep-weekly=4 \ + --keep-monthly=12 \ + "$BACKUP_REPO" + +[ "$BACKUP_SNAP" -eq 1 ] && bsnap off diff --git a/borg/bsnap b/borg/bsnap new file mode 100755 index 0000000..75d8f1b --- /dev/null +++ b/borg/bsnap @@ -0,0 +1,52 @@ +#!/bin/bash + +set -eu + +function snap { + unsnap + + cat /etc/fstab | awk '{print $5 " " $1 " " $2;}' | while read -r dump dev mnt; do + if [ "$dump" = 1 ]; then + echo "bind mount $mnt" + mount --bind "${mnt}" "/a${mnt}" + elif [ "$dump" = 2 ]; then + read -r lvname vgname _ < <(lvdisplay --noheadings -C "$dev") + echo "snapshot ${vgname}/${lvname}" + lvcreate -L1G --snapshot --name "${lvname}snap" "${vgname}/${lvname}" + mount -o ro "${dev}snap" "/a${mnt}" + fi + done +} + +function unsnap { + tac /etc/fstab | awk '{print $5 " " $1 " " $2;}' | while read -r dump dev mnt; do + snapmnt="/a${mnt}" + snapdev="${dev}snap" + if [ "$dump" = 1 ]; then + echo "umount $snapmnt" + mountpoint -q "$snapmnt" && umount "$snapmnt" + elif [ "$dump" = 2 ]; then + echo "umount $snapmnt" + mountpoint -q "$snapmnt" && umount "$snapmnt" + + echo "unsnapshot $snapdev" + [ -b "$(readlink -f "$snapdev")" ] && echo y | lvremove "${dev}snap" + fi + done +} + +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/borg/do-install b/borg/do-install new file mode 100755 index 0000000..dd0eeb9 --- /dev/null +++ b/borg/do-install @@ -0,0 +1,21 @@ +#!/bin/bash + +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 bsnap backup /usr/local/bin/ +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 + +install -m 0644 -T etc-cron.d-backup /etc/cron.d/backup +H=$((16#$(hostname|md5sum|head -c 1) % 7 + 14)) +M=$((16#$(hostname|md5sum|head -c 2) % 60)) +sed -i -e "s|\$H|$H|" -e "s|\$M|$M|" /etc/cron.d/backup + +[ -f /root/.ssh/id_rsa.pub ] || ssh-keygen +cat /root/.ssh/id_rsa.pub +install -m 0600 -T root-ssh-config /root/.ssh/config diff --git a/borg/do-update b/borg/do-update new file mode 100755 index 0000000..b9060f7 --- /dev/null +++ b/borg/do-update @@ -0,0 +1,8 @@ +#!/bin/bash + +set -eux + +cd "$(dirname "$0")" + +git pull --ff-only +install -m 0755 bsnap backup /usr/local/bin/ diff --git a/borg/etc-borg-env b/borg/etc-borg-env new file mode 100644 index 0000000..b7ed751 --- /dev/null +++ b/borg/etc-borg-env @@ -0,0 +1,5 @@ +BACKUP_SNAP=1 +BACKUP_EXCLUDE_FILE="/etc/borg-exclude" +BACKUP_PATH="/a" +BACKUP_REPO="backuphost:root" +export BORG_PASSPHRASE="SECRET" diff --git a/borg/etc-borg-exclude b/borg/etc-borg-exclude new file mode 100644 index 0000000..abb22d5 --- /dev/null +++ b/borg/etc-borg-exclude @@ -0,0 +1,6 @@ +/a/home/*/.cache +/a/home/*/.thumbnails +/a/home/*/tmp +/a/tmp +/a/var/cache +/a/var/tmp diff --git a/borg/etc-cron.d-backup b/borg/etc-cron.d-backup new file mode 100644 index 0000000..075aa6f --- /dev/null +++ b/borg/etc-cron.d-backup @@ -0,0 +1,6 @@ +SHELL=/bin/bash +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +MAILTO=root + +# m h dom mon dow user command + $M $H * * * root chronic backup diff --git a/borg/root-ssh-config b/borg/root-ssh-config new file mode 100644 index 0000000..70c030f --- /dev/null +++ b/borg/root-ssh-config @@ -0,0 +1,6 @@ +Host * + HashKnownHosts no + +Host backuphost + User borg + Hostname backup.example.com diff --git a/backup-all b/rdiff-backup/backup-all similarity index 100% rename from backup-all rename to rdiff-backup/backup-all diff --git a/common b/rdiff-backup/common similarity index 100% rename from common rename to rdiff-backup/common diff --git a/etc-cron.d-backup b/rdiff-backup/etc-cron.d-backup similarity index 100% rename from etc-cron.d-backup rename to rdiff-backup/etc-cron.d-backup diff --git a/template-rdiff-backup b/rdiff-backup/template-rdiff-backup similarity index 100% rename from template-rdiff-backup rename to rdiff-backup/template-rdiff-backup diff --git a/template-rsync b/rdiff-backup/template-rsync similarity index 100% rename from template-rsync rename to rdiff-backup/template-rsync -- 2.39.2