aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTharre <tharre3@gmail.com>2018-03-27 07:02:36 +0200
committerTharre <tharre3@gmail.com>2018-03-27 07:17:08 +0200
commitb8a806dfc701118ce1f10d5332093ac1f710d808 (patch)
tree264129ebbf2db959ffbd4dfa97c6034222b1434c
parent3cf436534fc2c3886184d7bbf441f45791bdc4a0 (diff)
downloadpkgbuilds-b8a806dfc701118ce1f10d5332093ac1f710d808.tar.gz
pkgbuilds-b8a806dfc701118ce1f10d5332093ac1f710d808.tar.xz
pkgbuilds-b8a806dfc701118ce1f10d5332093ac1f710d808.zip
arch-system: add backup-system package
This implements fully automated, hourly backups of my /home via borgbackup, btrfs and systemd timers. Note that `setup_borgbackup`, a related function that is part of my dotfiles, is needed to setup backups for the first time, as well as a call to `borg init` with the proper environment variables.
-rw-r--r--arch-system/PKGBUILD20
-rwxr-xr-xarch-system/backup-sudo34
-rw-r--r--arch-system/borg-backup.service11
-rw-r--r--arch-system/borg-backup.timer11
-rwxr-xr-xarch-system/borgbackup65
-rw-r--r--arch-system/sudoers-borgbackup4
6 files changed, 144 insertions, 1 deletions
diff --git a/arch-system/PKGBUILD b/arch-system/PKGBUILD
index e1208fd..d1adbd0 100644
--- a/arch-system/PKGBUILD
+++ b/arch-system/PKGBUILD
@@ -1,7 +1,7 @@
# Maintainer: Tharre <tharre3@gmail.com>
pkgbase=arch-system
-pkgname=('base-system' 'xps13')
+pkgname=('base-system' 'backup-system' 'xps13')
pkgver=1
pkgrel=1
pkgdesc="Arch Linux system configuration"
@@ -12,6 +12,9 @@ source=('base-system.install' 'etc-pacman.conf' 'etc-locale.conf'
'etc-locale.gen' 'etc-vconsole.conf' 'mirrorupgrade.hook'
'sudoers-wheel' 'etc-nsswitch.conf' 'etc-sysctl.conf'
+ 'sudoers-borgbackup' 'backup-sudo' 'borg-backup.service'
+ 'borg-backup.timer' 'borgbackup'
+
'xps13-i915.conf')
sha256sums=('bb00c42f2802c12536c46700b948d41a43153d97a6986827b7c61203880e1ad1'
'b3b540ac0dd68831d813e34dd8465cd00e8ba6a56fa6e5a162dc5ef469ec584c'
@@ -22,6 +25,11 @@ sha256sums=('bb00c42f2802c12536c46700b948d41a43153d97a6986827b7c61203880e1ad1'
'62c1a085f7a9d1c5d57b40516fea5d7e8dfb3593d5c0a713cd571c8e5bae2584'
'9c1648e1e9219efbe1e4098952f7595f1ebb0eca629d2c8957079186c56d1822'
'67b6ebe8a8e52cd60266f418b7af77c2ef0b2b6596de494ec5c37824f355a3ae'
+ '483a7d9350653c2cf22f36f67f1a83cc5c95232dfc10642a20d76e3c32c9e2e3'
+ '99cd268de0e9b847d65f802e7bcbbf7318398a04db61523545d4002ebdfb4d9c'
+ '27a22dfc1904c8c35e3855b4e1a52b96239d390de1c497ea9ab994ef8bd2b52b'
+ 'e1bf3dc5978a7641f86975b7ee770a6914b30a8e4b7e3be2f1b07eaa7098591d'
+ 'ad3e8af09bfa1084e6ea70cab11088219d609398c61f162cabbf5a524b54783b'
'4e30b6dc062849a8217f419ca4752f062a8dafbbfb1f6f24ba894eb8dc78c736')
package_base-system() {
@@ -41,6 +49,16 @@ package_base-system() {
ln -s /usr/share/zoneinfo/Europe/Berlin "$pkgdir"/etc/localtime
}
+package_backup-system() {
+ depends=('libnotify')
+
+ install -dm0750 "$pkgdir"/etc/sudoers.d/
+ install -Dm0644 sudoers-borgbackup "$pkgdir"/etc/sudoers.d/70_borgbackup
+ install -Dm0644 borg-backup.service -t "$pkgdir"/usr/lib/systemd/user/
+ install -Dm0644 borg-backup.timer -t "$pkgdir"/usr/lib/systemd/user/
+ install -Dm0755 borgbackup backup-sudo -t "$pkgdir"/usr/bin/
+}
+
package_xps13() {
depends=('mesa' 'lib32-mesa' 'vulkan-intel' 'libva-intel-driver'
'lib32-libva-intel-driver' 'libvdpau-va-gl')
diff --git a/arch-system/backup-sudo b/arch-system/backup-sudo
new file mode 100755
index 0000000..b2694b6
--- /dev/null
+++ b/arch-system/backup-sudo
@@ -0,0 +1,34 @@
+#!/bin/bash -e
+
+validate_path() {
+ # validate path
+ targetpath=$(realpath -m -- "$1")
+ if [[ "$targetpath" != /.snapshots/* ]]; then
+ echo "Invalid path given." >&2
+ exit 2
+ fi
+}
+
+case "$1" in
+ snapshot)
+ validate_path "$2"
+ btrfs subvolume snapshot -r -- /home "$2"
+ ;;
+ delete_snapshot)
+ validate_path "$2"
+ btrfs subvolume delete -- "$2"
+ ;;
+ mount)
+ validate_path "$2"
+ mkdir -p /backup
+ mount --bind -- "$2" /backup
+ ;;
+ cleanup)
+ umount /backup 2> /dev/null || true
+ rm -rf /backup
+ ;;
+ *)
+ echo "No command specified." >&2
+ exit 1
+ ;;
+esac
diff --git a/arch-system/borg-backup.service b/arch-system/borg-backup.service
new file mode 100644
index 0000000..196b87f
--- /dev/null
+++ b/arch-system/borg-backup.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Borg backup service for /home (BTRFS)
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+ExecStart=/usr/bin/borgbackup
+Type=simple
+
+[Install]
+WantedBy=multi-user.target
diff --git a/arch-system/borg-backup.timer b/arch-system/borg-backup.timer
new file mode 100644
index 0000000..0ac9096
--- /dev/null
+++ b/arch-system/borg-backup.timer
@@ -0,0 +1,11 @@
+[Unit]
+Description=Runs backups every hour
+
+[Timer]
+OnCalendar=hourly
+OnBootSec=5min
+RandomizedDelaySec=5min
+Unit=borg-backup.service
+
+[Install]
+WantedBy=timers.target
diff --git a/arch-system/borgbackup b/arch-system/borgbackup
new file mode 100755
index 0000000..5cc635d
--- /dev/null
+++ b/arch-system/borgbackup
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+set -o errexit -o errtrace
+
+export SNAPSHOT_TARGET="/.snapshots/home-$(date "+%Y-%m-%dT%H:%M:%S")"
+export BORG_REPO="borg@borg1.th73.ovh:."
+export BORG_PASSPHRASE="$(< ~/.borg_secret)"
+export BORG_RSH="ssh -o IdentitiesOnly=yes -i ~/.ssh/borg_key"
+export LC_COLLATE=C
+
+cleanup() {
+ cd /
+ sudo -n /usr/bin/backup-sudo cleanup
+}
+
+handle_failure() {
+ notify-send -u critical "Backup failed!"
+ echo "Backup failed!" >&2
+ cleanup
+ exit 2
+}
+
+trap cleanup EXIT
+trap handle_failure INT TERM ERR
+
+notify-send "Backup started."
+
+cleanup
+
+backup() {
+ # borg's caching of 'known' files is really dumb - it takes the full
+ # canonical path to check if it has already seen a file. This means that the
+ # path of files must never change if you want fast backups.
+ # As symlinks won't work, we use mount(8) to ensure the paths stay the same.
+ sudo -n backup-sudo mount "$1"
+
+ cd /backup
+ # TODO: break lock when necessary?
+ borg create --stats \
+ --exclude-from ~/.borg_exclude \
+ --show-rc \
+ ::"$(basename "$1")" .
+
+ cleanup
+ sudo -n backup-sudo delete_snapshot "$1"
+}
+
+if [ ! -d "$SNAPSHOT_TARGET" ]; then
+ sudo -n backup-sudo snapshot "$SNAPSHOT_TARGET"
+fi
+
+for d in /.snapshots/*/ ; do
+ echo "Now working on: $d"
+ backup "$d"
+done
+
+echo "Pruning repository."
+
+borg prune --show-rc --list \
+ --keep-hourly 24 \
+ --keep-daily 7 \
+ --keep-weekly 4 \
+ --keep-monthly 6
+
+echo "Backup finished."
diff --git a/arch-system/sudoers-borgbackup b/arch-system/sudoers-borgbackup
new file mode 100644
index 0000000..a6f40b0
--- /dev/null
+++ b/arch-system/sudoers-borgbackup
@@ -0,0 +1,4 @@
+# /etc/sudoers.d/borgbackup
+
+# allow systemd service files to call backup-sudo
+%wheel ALL=(root) NOPASSWD: /usr/bin/backup-sudo