#!/usr/bin/env bash

set -e

src="/"
snapshotdir="backup-snapshot"
backup_mountdir="/backup"

declare -a list_of_btrfs_submounts

##
#  usage : is_btrfs( $path )
# return : whether $path is on a btrfs
# source: makechrootpkg from devtools
##
is_btrfs() {
    [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs ]]
}

##
#  usage : delete_snapshot( $path )
##
delete_snapshot() {
    btrfs subvolume delete --commit-after "$1"
}

##
# exit cleanup handler
##
cleanup() {
  if is_btrfs "$src"; then
      umount -R "$backup_mountdir"
      for vol in $list_of_btrfs_submounts; do
          delete_snapshot "$vol/$snapshotdir"
      done
      rmdir "$backup_mountdir"
  fi
}

trap cleanup EXIT

# Dump databases to /root/backup-{postgres,mysql} before taking a btrfs snapshot
systemctl is-active postgresql && /usr/local/bin/backup-postgres.sh || true
if systemctl is-active mysqld || systemctl is-active mariadb; then
    /usr/local/bin/backup-mysql.sh || true
fi

{# When backing up to offsite, reuse the existing tarballs from the previous backup #}
{% if inventory_hostname == "gitlab.archlinux.org" and item['suffix'] != '-offsite' %}
# Create tarball backups of various GitLab directories using the official backup tool
systemctl is-active docker && /usr/local/bin/backup-gitlab.sh
{% endif %}

if is_btrfs "$src"; then
    # List all btrfs submounts we want to backup, e.g. homedir.archlinux.org with "/ /home"
    list_of_btrfs_submounts=$(findmnt -Rl -o target,fstype,options / | grep btrfs | grep -v docker | grep -v "subvol=\/[[:alnum:]]" | cut -d ' ' -f1)

    if [[ -d "$backup_mountdir" ]]; then
        if [[ $(findmnt -M "$backup_mountdir") ]]; then
            umount -R "$backup_mountdir"
        fi
        rmdir "$backup_mountdir"
    fi
    mkdir "$backup_mountdir"
    for vol in $list_of_btrfs_submounts; do
        if [[ -d "$vol/$snapshotdir" ]]; then
            delete_snapshot "$vol/$snapshotdir"
        fi

        btrfs subvolume snapshot -r "$vol" "$vol/$snapshotdir"
        mount -o bind "$vol/$snapshotdir" "$backup_mountdir/$vol"
    done
else
    backup_mountdir="$src"
fi

borg create -v --stats -C zstd \
    -e /proc \
    -e /sys \
    -e /dev \
    -e /run \
    -e /tmp \
    -e /var/cache \
    -e /var/lib/archbuild \
    -e /var/lib/archbuilddest \
    -e /var/lib/docker \
    -e "$backup_mountdir/proc" \
    -e "$backup_mountdir/sys" \
    -e "$backup_mountdir/dev" \
    -e "$backup_mountdir/run" \
    -e "$backup_mountdir/tmp" \
    -e "$backup_mountdir/var/cache" \
    -e "$backup_mountdir/var/lib/archbuild" \
    -e "$backup_mountdir/var/lib/archbuilddest" \
    -e "$backup_mountdir/var/lib/docker" \
    {{ item['host'] }}/{{ item['dir'] }}::$(date "+%Y%m%d-%H%M%S") "$backup_mountdir"
borg prune -v {{ item['host'] }}/{{ item['dir'] }} --keep-daily=7 --keep-weekly=4 --keep-monthly=6
