diff options
author | Tharre <tharre3@gmail.com> | 2018-03-27 07:02:36 +0200 |
---|---|---|
committer | Tharre <tharre3@gmail.com> | 2018-03-27 07:17:08 +0200 |
commit | b8a806dfc701118ce1f10d5332093ac1f710d808 (patch) | |
tree | 264129ebbf2db959ffbd4dfa97c6034222b1434c | |
parent | 3cf436534fc2c3886184d7bbf441f45791bdc4a0 (diff) | |
download | pkgbuilds-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/PKGBUILD | 20 | ||||
-rwxr-xr-x | arch-system/backup-sudo | 34 | ||||
-rw-r--r-- | arch-system/borg-backup.service | 11 | ||||
-rw-r--r-- | arch-system/borg-backup.timer | 11 | ||||
-rwxr-xr-x | arch-system/borgbackup | 65 | ||||
-rw-r--r-- | arch-system/sudoers-borgbackup | 4 |
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 |