Support multiple simultaneous offsite mirrors, not just one
Requested: mirror to Backblaze B2 AND directly to the IONOS spare box over Tailscale, at the same time, not one or the other. REMOTE_TYPE/ REMOTE_ARGS was hardcoded to a single mirror target — extending it to a list would have meant redesigning the one thing that already works and was already verified against real B2 credentials, so this adds a separate, additive mechanism instead: EXTRA_MIRROR_NAMES, a space- separated list, with per-entry MIRROR_<name>_TYPE/_ARGS (same argument shape as REMOTE_ARGS). An existing B2-only backup.conf keeps working completely unchanged if this new section is skipped. install_backup() gets a new "ADDITIONAL MIRROR" prompt after the existing B2 section: offers a direct SFTP mirror (Kopia's sync-to sftp, not the deprecated b2 provider — same reasoning as the S3/B2 choice already made), defaults the destination to whatever was typed at the DR-spare prompt above (same box, same purpose, no reason to ask twice), checks passwordless SSH and an SSH key exist first, then verifies with a --dry-run against the just-created 'default' repo before saving it — same "don't save something broken" discipline as the B2 flow. Verified against a mock backup.conf that install-side writes and worker-side reads agree on the exact format, and that reusing an existing mirror name reconfigures it instead of duplicating it in the name list. One correction while researching sync-to sftp's flags: unlike plain ssh, Kopia doesn't shell out to the system SSH client, so it needs an explicit --keyfile and --known-hosts path rather than picking up whatever `ssh` already trusts automatically — checked Kopia's own docs for the exact flags before writing this, same as the earlier S3 case. extras/backup_kopia.sh's worker loops through EXTRA_MIRROR_NAMES after the existing REMOTE_TYPE mirror step, running sync-to for each destination against each additional mirror and folding failures into the same FAILED_SVCS/notification reporting the primary mirror already uses. Verified end-to-end against a mock backup.conf and a stubbed kp_for: both the B2 and the new SFTP mirror get called in sequence with the correct arguments. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn
This commit is contained in:
@@ -170,6 +170,27 @@ if [ "${REMOTE_TYPE:-none}" != "none" ] && [ -n "${REMOTE_TYPE:-}" ]; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Additional mirrors (EXTRA_MIRROR_NAMES) — run alongside REMOTE_TYPE above,
|
||||
# not instead of it, so a box can mirror to e.g. Backblaze B2 AND directly
|
||||
# to a spare over SSH/SFTP at the same time.
|
||||
for mirror_name in ${EXTRA_MIRROR_NAMES:-}; do
|
||||
_mtype_var="MIRROR_${mirror_name}_TYPE"
|
||||
_margs_var="MIRROR_${mirror_name}_ARGS"
|
||||
_mtype="${!_mtype_var:-}"
|
||||
_margs="${!_margs_var:-}"
|
||||
[ -n "$_mtype" ] || continue
|
||||
for dest in ${DEST_NAMES:-default}; do
|
||||
log "Mirroring '$dest' to '$mirror_name' ($_mtype)..."
|
||||
# shellcheck disable=SC2086
|
||||
if ! kp_for "$dest" repository sync-to "$_mtype" $_margs 2>"$_ERR"; then
|
||||
_reason="$(categorize_error "$(cat "$_ERR")")"
|
||||
log "WARNING: mirror '$mirror_name' failed for '$dest' — $_reason"
|
||||
FAILED_SVCS+=("mirror[$mirror_name/$dest]: $_reason")
|
||||
rc=1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# ── Keep a spare box's copy of backup.conf + README current ─────────────────
|
||||
# Runs after the data itself is backed up (and mirrored, if configured) so a
|
||||
# sync never ships config pointing at a repo state that isn't actually there
|
||||
|
||||
Reference in New Issue
Block a user