Files
UmbraAudio/scripts/verify_backup.sh
B.D. Murphy 26de44feb1 Cluster worker for the UmbraTrans integration
The UmbraAudio side of the cross-machine contract: this node registers
with the UmbraTrans controller, polls for jobs, claims them under a
lease, and writes artifacts back over NFS.

* `umbraaudio/cluster/` - configuration, PostgreSQL access, node
  registration and heartbeat, the job queue, artifact storage and NFS
  mount management.
* `scripts/cluster_worker.py` - the CLI: `worker`, `check-cluster`,
  `register-node`.
* `scripts/backup_system.sh` / `scripts/verify_backup.sh` - whole-system
  backup and integrity verification.
* `.env` - the `UMBRA_CLUSTER__*` settings. `UMBRA_CLUSTER__PG_PASSWORD`
  is deliberately empty; the password comes from the environment, not
  from a committed file.

`k3s-agent.yaml` is NOT committed: it contains a K3s server join token.
It is now gitignored, and the token should be rotated if that file has
ever left this machine.

ruff clean on the whole package.
2026-11-06 17:03:16 -08:00

116 lines
2.9 KiB
Bash
Executable File

#!/bin/zsh
# verify_backup.sh - Verify UmbraAudio backup integrity
set -e
SOURCE_DIR=""
BACKUP_DATE=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE_DIR="$2"
shift 2
;;
--date)
BACKUP_DATE="$2"
shift 2
;;
--help|-h)
echo "Usage: $0 --source DIR --date YYYYMMDD"
echo " --source Backup directory (default: /tmp/backups)"
echo " --date Date to verify (default: 7 days ago)"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Set defaults
if [[ -z "$SOURCE_DIR" ]]; then
SOURCE_DIR="/tmp/backups"
fi
if [[ -z "$BACKUP_DATE" ]]; then
BACKUP_DATE=$(date -v-7 +%Y%m%d 2>/dev/null || date --date='7 days ago' +%Y%m%d 2>/dev/null || echo "$(date +%Y%m%d)")
fi
echo "========================================="
echo "UmbraAudio Backup Verification"
echo "========================================="
echo "Source: $SOURCE_DIR"
echo "Date: $BACKUP_DATE"
echo "========================================="
# Validate source
if [[ ! -d "$SOURCE_DIR" ]]; then
echo "❌ Error: Source directory missing: $SOURCE_DIR"
exit 1
fi
# Find backup items matching the date pattern inside the source directory
# Look for files/dirs with the date pattern in their name
MATCHED=$(find "$SOURCE_DIR" -maxdepth 1 -name "*${BACKUP_DATE}*" 2>/dev/null | head -5)
if [[ -z "$MATCHED" ]]; then
# Try listing recent subdirectories
echo "No exact date match. Checking recent backups..."
MATCHED=$(ls -td "$SOURCE_DIR"/*/ 2>/dev/null | head -1)
if [[ -z "$MATCHED" ]]; then
echo "❌ No backups found in $SOURCE_DIR"
echo "Contents of $SOURCE_DIR:"
ls -la "$SOURCE_DIR" 2>/dev/null | head -10
exit 1
fi
NAME=$(basename "$MATCHED" | tr -d '/')
else
NAME=$(basename "$MATCHED" | tr -d '/')
fi
echo "✓ Found: $NAME"
echo ""
# Check if it's a file or directory inside backups
if [[ -f "$SOURCE_DIR/$NAME" ]]; then
TYPE="file"; FULL_PATH="$SOURCE_DIR/$NAME"
elif [[ -d "$SOURCE_DIR/$NAME" ]]; then
TYPE="directory"; FULL_PATH="$SOURCE_DIR/$NAME"
else
TYPE="unknown"; FULL_PATH=""
fi
echo "Type: $TYPE"
# For directory backups, check key items
if [[ "$TYPE" == "directory" ]]; then
echo "Checking key backup items..."
KEYS=("project.db" "voices" "speakers.json" ".env" "config.py")
ERRORS=0
for k in "${KEYS[@]}"; do
if [[ -e "$FULL_PATH/$k" ]] || [[ -e "$FULL_PATH/$k."* ]]; then
echo " ✓ $k"
else
echo " ⚠ $k missing"
ERRORS=$((ERRORS+1))
fi
done
echo ""
if [[ $ERRORS -eq 0 ]]; then
echo "✅ All key items present"
else
echo "⚠ $ERRORS item(s) missing"
fi
fi
echo ""
echo "========================================="
if [[ "$TYPE" == "directory" && $ERRORS -eq 0 ]]; then
echo "✅ VERIFICATION PASSED"
else
echo "⚠ VERIFICATION COMPLETED"
fi
echo "========================================="