#!/bin/bash
# On-site second copy of cloud-primary B2 data (azkaban -> tmpool/cloud-copy). See backups/BACKUPS.md "On-site copy".
# usage: cloud-copy-backup [source ...]   (default: all)   -- mounts each source read-only with rclone, restic-backs it up, unmounts.
# Secrets: /etc/cloud-copy/{rclone.conf,restic.pw} (root 0600). Nothing is printed.
set -u
export RCLONE_CONFIG=/etc/cloud-copy/rclone.conf RESTIC_REPOSITORY=/tmpool/cloud-copy/restic RESTIC_PASSWORD_FILE=/etc/cloud-copy/restic.pw GOMEMLIMIT=2GiB XDG_CACHE_HOME=/var/cache/cloud-copy
# Home-link courtesy (owner 2026-11-01: bulk pulls stalled Plex in the evening). rclone timetable, host time (Pacific):
# 00:00-01:00 3 MB/s, 01:00-07:00 unlimited, 07:00-17:00 8 MB/s, 17:00-24:00 3 MB/s. Override: BWLIMIT=off cloud-copy-backup
BWLIMIT=${BWLIMIT:-"00:00,3M 01:00,off 07:00,8M 17:00,3M"}
MNT=/run/cloud-copy; STATE=/var/lib/ctg-backup-cloud; mkdir -p "$MNT" "$STATE"
declare -A SRC=(
  [nextcloud-canutethegreat]="nc-canutethegreat:"
  [forgejo]="b2-forgejo:ctg-forgejo"
  [storage]="b2-storage:ctg-storage"
  [files]="b2-files:ctg-files"
)
ORDER=(nextcloud-canutethegreat files storage forgejo)
[ $# -gt 0 ] && ORDER=("$@")
fail=0; skipped=0
for n in "${ORDER[@]}"; do
  m=$MNT/$n; mkdir -p "$m"
  if pgrep -f "restic backup $m " >/dev/null || mountpoint -q "$m"; then echo "$n: a run is already in progress, skipping"; skipped=1; continue; fi
  echo "== $n: mount"
  rclone mount "${SRC[$n]}" "$m" --read-only --daemon --daemon-wait 60s --vfs-cache-mode off --dir-cache-time 10m \
      --buffer-size 32M --transfers 4 --checkers 8 --bwlimit "$BWLIMIT" --allow-other --log-file /var/log/cloud-copy-rclone.log --log-level NOTICE || { echo "mount failed: $n"; fail=1; continue; }
  # guard: an empty mount must never become an "everything deleted" snapshot
  if [ -z "$(ls -A "$m" 2>/dev/null | head -1)" ]; then echo "mount of $n is empty, skipping"; fail=1; fusermount3 -uz "$m"; continue; fi
  restic backup "$m" --host cloud-copy --tag "$n" --ignore-inode --ignore-ctime --read-concurrency "${RC:-2}" --exclude-caches 2>&1 | tail -15
  rc=${PIPESTATUS[0]}; [ $rc -ne 0 ] && { echo "restic backup $n exit $rc"; fail=1; }
  fusermount3 -u "$m" 2>/dev/null || fusermount3 -uz "$m"
done
[ $fail -eq 0 ] && [ $skipped -eq 0 ] && date +%s > $STATE/last-backup-ok
exit $fail
