From 7ec35b21a8a5291553d96806a3fba0fdd9c08917 Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Sat, 4 Jun 2022 19:07:08 +0300
Subject: [PATCH] Simpler backup script.

Backups across the different services have been changed. There are now
snapshots for each services with copies saved for a few weeks. All of
them under /var/backups. The backup script doesn't need to work around
btrfs subvolumes. Instead just snapshotting /var/backups and rsync'ing
to a removable media. The old script is kept in source for reference.
---
 .../roles/debian_server/files/offsite-backup  | 62 +++++++++++++++++++
 Ansible/roles/debian_server/tasks/btrfs.yml   |  4 +-
 2 files changed, 64 insertions(+), 2 deletions(-)
 create mode 100755 Ansible/roles/debian_server/files/offsite-backup

diff --git a/Ansible/roles/debian_server/files/offsite-backup b/Ansible/roles/debian_server/files/offsite-backup
new file mode 100755
index 0000000..1534ed5
--- /dev/null
+++ b/Ansible/roles/debian_server/files/offsite-backup
@@ -0,0 +1,62 @@
+#!/bin/sh
+set -eu
+
+is_btrfs() {
+    [ "$(df --output=fstype "$1" | tail +2)" = 'btrfs' ]
+}
+
+is_subvolume() {
+    btrfs subvolume show "$1" >/dev/null 2>&1
+}
+
+root_subvolume() {
+    path="$1"
+    until is_subvolume "$path" || [ "$path" = '/' ]
+    do
+        path="$(dirname "$path")"
+    done
+    echo "$path"
+}
+
+cleanup() {
+    exit_code="$?"
+    if [ -n "${snapshot:-}" ]
+    then
+        btrfs subvolume delete "$snapshot"
+    fi
+    sync --file-system "$destination"
+    if [ "$exit_code" -eq 0 ]
+    then
+        curl -so /dev/null "https://notify.shore.co.il/send?message=Backup%20finished%20successfully%20on%20$(hostname -s)."
+    else
+        curl -so /dev/null  "https://notify.shore.co.il/send?message=Backup%20failed%20on%20$(hostname -s)."
+    fi
+}
+
+if [ "$#" -ne 1 ]
+then
+    echo "Usage: $0 destination" >&2
+    exit 1
+fi
+
+if ! is_btrfs /var/backups
+then
+    echo '/var/backups is not on btrfs filesystem. Exiting.' >&2
+    exit 1
+fi
+
+trap 'cleanup' INT QUIT EXIT TERM
+
+destination="$1"
+volume="$(root_subvolume /var/backups)"
+snapshot="$(mktemp --dry-run "--tmpdir=$volume")"
+btrfs subvolume snapshot -r "$volume" "$snapshot"
+source="/var/backups"
+source="${snapshot}${source#$volume}/"
+
+sync --file-system /var/backups
+rsync --archive \
+      --delete \
+      --info=progress2 \
+      "$source" \
+      "$destination"
diff --git a/Ansible/roles/debian_server/tasks/btrfs.yml b/Ansible/roles/debian_server/tasks/btrfs.yml
index 7091069..b0f37ac 100644
--- a/Ansible/roles/debian_server/tasks/btrfs.yml
+++ b/Ansible/roles/debian_server/tasks/btrfs.yml
@@ -9,11 +9,11 @@
 
 - name: Copy btrfs backup script
   ansible.builtin.copy:
-    dest: /usr/local/sbin/btrfs-backup
+    dest: /usr/local/sbin/offsite-backup
     group: root
     mode: preserve
     owner: root
-    src: btrfs-backup
+    src: offsite-backup
 
 - name: Install btrfs scrub services and timers
   loop: &loop
-- 
GitLab