258 lines
8.0 KiB
Bash
Executable File
258 lines
8.0 KiB
Bash
Executable File
#!/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 from standard location
|
|
CONFIG_DIR="$HOME/.config/citadel"
|
|
CONFIG_FILE="$CONFIG_DIR/backup.env"
|
|
|
|
if [ -f "$CONFIG_FILE" ]; then
|
|
source "$CONFIG_FILE"
|
|
else
|
|
echo "ERROR: Configuration not found at $CONFIG_FILE"
|
|
echo "Please run './install setup' to initialize configuration"
|
|
exit 1
|
|
fi
|
|
|
|
BACKUP_DIR="$BACKUP_BASE_DIR"
|
|
SERVICES_DIR="$SERVICES_BASE_DIR"
|
|
|
|
show_help() {
|
|
echo "Usage: $0 <command> [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 <service> Start backup timer for service"
|
|
echo " stop <service> Stop backup timer for service"
|
|
echo " restart <service> Restart backup timer for service"
|
|
echo " enable <service> Enable backup timer for service"
|
|
echo " disable <service> Disable backup timer for service"
|
|
echo " run <service> Run backup manually for service"
|
|
echo " logs <service> Show logs for service backup"
|
|
echo " install <service> Install timer for service"
|
|
echo " remove <service> Remove timer for service"
|
|
echo " available List services with backup.sh available"
|
|
echo ""
|
|
echo "Restore Commands:"
|
|
echo " snapshots [service] List available snapshots"
|
|
echo " restore <service> Restore service (test mode)"
|
|
echo " restore-prod <service> 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
|