#!/usr/bin/env bash # unms-backup-sync.sh -- Daily UISP/UNMS backup sync to Wasabi S3. # Pulls backups from old historical UNMS and live app2 to local staging, # then uploads to s3://hermes-vps-backups/unms-backups/. set -euo pipefail SSH_KEY="/root/.ssh/itpp-infra" S3_BUCKET="s3://hermes-vps-backups/unms-backups" ENDPOINT="https://s3.us-east-1.wasabisys.com" STAGE="/root/.hermes/.backups/unms-sync" TS="$(date -u +%Y%m%d-%H%M%S)" LOG="/tmp/unms-backup-sync-${TS}.log" # Cron-safe AWS CLI path if [ -f /opt/awscli-venv/bin/activate ]; then # shellcheck disable=SC1091 source /opt/awscli-venv/bin/activate fi log() { echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $*" | tee -a "$LOG"; } sync_remote_dir() { local label="$1" host="$2" remote="$3" dest="$4" required="$5" local local_dir="${STAGE}/${dest}" mkdir -p "$local_dir" log "Checking ${label} ${host}:${remote}" if ! ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o BatchMode=yes "root@${host}" "test -d '${remote}'" >/dev/null 2>&1; then if [ "$required" = "yes" ]; then log "ERROR: Required source missing/unreachable: ${label}" return 1 fi log "WARN: Optional source missing/unreachable: ${label}; skipping" return 0 fi rsync -az --delete \ -e "ssh -i ${SSH_KEY} -o BatchMode=yes" \ "root@${host}:${remote}/" \ "${local_dir}/" >>"$LOG" 2>&1 local count count=$(find "$local_dir" -type f | wc -l) log "OK: ${label} staged ${count} files -> ${local_dir}" } main() { mkdir -p "$STAGE" log "Starting UNMS backup sync" # Historical old UNMS -- optional because it may be decommissioned. sync_remote_dir "old-unms-backups" "5.161.225.131" "/home/unms/data/unms-backups/backups" "old-unms" "no" # Live app2 UNMS -- required. sync_remote_dir "live-unms-backups" "152.53.39.202" "/home/unms/data/unms-backups/backups" "live/backups" "yes" # UCRM backups -- optional; path exists only when UCRM backup job has generated files. sync_remote_dir "live-ucrm-backups" "152.53.39.202" "/home/unms/data/ucrm/ucrm/data/backup" "live/ucrm" "no" log "Uploading staged backups to ${S3_BUCKET}" aws s3 sync "$STAGE/" "$S3_BUCKET/" --endpoint-url "$ENDPOINT" --delete >>"$LOG" 2>&1 log "Verifying S3 contents" aws s3 ls "$S3_BUCKET/live/backups/" --endpoint-url "$ENDPOINT" >>"$LOG" 2>&1 local live_count live_count=$(aws s3 ls "$S3_BUCKET/live/backups/" --endpoint-url "$ENDPOINT" | wc -l) if [ "$live_count" -lt 1 ]; then log "ERROR: S3 verification found no live backup objects" return 1 fi log "DONE: UNMS backup sync complete; live backup objects=${live_count}" } main "$@"