#!/bin/bash # Citadel Backup Management Interface # Automatically sources configuration from project root set -e # Get the directory where this script is located (project root) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Auto-source configuration if [ -f "$SCRIPT_DIR/backup.env" ]; then source "$SCRIPT_DIR/backup.env" else echo "ERROR: Configuration file backup.env not found in $SCRIPT_DIR" echo "Please ensure backup.env exists in project root directory" exit 1 fi BACKUP_DIR="$BACKUP_BASE_DIR" SERVICES_DIR="$SERVICES_BASE_DIR" show_help() { echo "Usage: $0 [service_name]" echo "" echo "Backup Commands:" echo " list List all backup timers and their status" echo " status [service] Show detailed status for service (or all)" echo " start Start backup timer for service" echo " stop Stop backup timer for service" echo " restart Restart backup timer for service" echo " enable Enable backup timer for service" echo " disable Disable backup timer for service" echo " run Run backup manually for service" echo " logs Show logs for service backup" echo " install Install timer for service" echo " remove Remove timer for service" echo " available List services with backup.sh available" echo "" echo "Restore Commands:" echo " snapshots [service] List available snapshots" echo " restore Restore service (test mode)" echo " restore-prod Restore service (production mode)" echo " cleanup-test [service] Clean up test restore instances" echo "" echo "Examples:" echo " $0 list" echo " $0 status paperless" echo " $0 run paperless" echo " $0 logs paperless" echo " $0 snapshots paperless" echo " $0 restore paperless" echo " $0 cleanup-test" } list_timers() { echo "=== Backup Timers Status ===" echo "" # Get all service-backup timers local timer_output=$(systemctl list-timers "service-backup@*.timer" --all --no-legend 2>/dev/null || true) if [ -z "$timer_output" ]; then echo "No backup timers found." echo "" echo "Available services with backup.sh:" find "$SERVICES_DIR" -name "backup.sh" -printf " %h\n" | sed "s|$SERVICES_DIR/||" 2>/dev/null || echo " (none found)" return fi printf "%-20s %-10s %-15s %s\n" "SERVICE" "STATUS" "ENABLED" "NEXT RUN" printf "%-20s %-10s %-15s %s\n" "-------" "------" "-------" "--------" # Parse each line from systemctl list-timers # Format: NEXT(1-4) LEFT(5) LAST(6-9) PASSED(10) UNIT(11) ACTIVATES(12) echo "$timer_output" | while read -r line; do # Extract timer name (11th field) local timer=$(echo "$line" | awk '{print $11}') # Extract service name from timer name local service_name=$(echo "$timer" | sed 's/service-backup@\(.*\)\.timer/\1/') # Skip if service name is empty if [ -z "$service_name" ]; then continue fi # Get next run (first 4 fields for date/time) local next_run=$(echo "$line" | awk '{print $1, $2, $3, $4}') # Get status and enabled state local status=$(systemctl is-active "$timer" 2>/dev/null || echo "inactive") local enabled=$(systemctl is-enabled "$timer" 2>/dev/null || echo "disabled") printf "%-20s %-10s %-15s %s\n" "$service_name" "$status" "$enabled" "$next_run" done } show_status() { local service="$1" if [ -n "$service" ]; then echo "=== Status for $service ===" systemctl status "service-backup@$service.timer" --no-pager -l echo "" echo "Next scheduled runs:" systemctl list-timers "service-backup@$service.timer" --no-legend else echo "=== All Backup Timers Status ===" systemctl list-timers "service-backup@*.timer" --no-legend fi } manage_timer() { local action="$1" local service="$2" if [ -z "$service" ]; then echo "ERROR: Service name required for $action" exit 1 fi local timer="service-backup@$service.timer" local service_unit="service-backup@$service.service" case $action in start) systemctl start "$timer" echo "✅ Started timer for $service" ;; stop) systemctl stop "$timer" echo "✅ Stopped timer for $service" ;; restart) systemctl restart "$timer" echo "✅ Restarted timer for $service" ;; enable) systemctl enable "$timer" echo "✅ Enabled timer for $service" ;; disable) systemctl disable "$timer" echo "✅ Disabled timer for $service" ;; run) echo "Running backup for $service..." systemctl start "$service_unit" echo "✅ Backup started for $service" echo "Monitor with: journalctl -u $service_unit -f" ;; logs) journalctl -u "$service_unit" --no-pager -l ;; remove) if systemctl is-active --quiet "$timer" 2>/dev/null; then systemctl stop "$timer" fi if systemctl is-enabled --quiet "$timer" 2>/dev/null; then systemctl disable "$timer" fi echo "✅ Removed timer for $service" ;; esac } install_timer() { local service="$1" if [ -z "$service" ]; then echo "ERROR: Service name required for install" exit 1 fi if [ "$EUID" -ne 0 ]; then echo "ERROR: Install requires sudo privileges" echo "Usage: sudo $0 install $service" exit 1 fi CALLED_FROM_MANAGE=true "$SCRIPT_DIR/backup/install-service" "$service" } list_available() { echo "=== Services with backup.sh available ===" echo "" local found=false for service_dir in "$SERVICES_DIR"/*; do if [ -d "$service_dir" ] && [ -f "$service_dir/backup.sh" ]; then local service_name=$(basename "$service_dir") local timer_status="not installed" if systemctl is-enabled --quiet "service-backup@$service_name.timer" 2>/dev/null; then timer_status="installed" fi printf " %-20s (timer: %s)\n" "$service_name" "$timer_status" found=true fi done if [ "$found" = false ]; then echo "No services with backup.sh found in $SERVICES_DIR" fi } # Main script logic case "${1:-}" in list) list_timers ;; status) show_status "$2" ;; start|stop|restart|enable|disable|run|logs|remove) if [ "$1" = "remove" ] || [ "$1" = "enable" ] || [ "$1" = "disable" ] || [ "$1" = "start" ] || [ "$1" = "stop" ] || [ "$1" = "restart" ]; then if [ "$EUID" -ne 0 ]; then echo "ERROR: $1 requires sudo privileges" echo "Usage: sudo $0 $1 $2" exit 1 fi fi manage_timer "$1" "$2" ;; install) install_timer "$2" ;; available) list_available ;; snapshots) CALLED_FROM_MANAGE=true "$SCRIPT_DIR/backup/list-snapshots" "$2" ;; restore) CALLED_FROM_MANAGE=true "$SCRIPT_DIR/backup/restore" "$2" --test ;; restore-prod) CALLED_FROM_MANAGE=true "$SCRIPT_DIR/backup/restore" "$2" --production ;; cleanup-test) CALLED_FROM_MANAGE=true "$SCRIPT_DIR/backup/cleanup-test" "$2" ;; help|--help|-h) show_help ;; *) echo "ERROR: Unknown command '${1:-}'" echo "" show_help exit 1 ;; esac