108 lines
3.5 KiB
Bash
108 lines
3.5 KiB
Bash
#!/bin/bash
|
|
|
|
# === Load environment ===
|
|
ENV_FILE="./AdGuardBackup.env"
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo "Environment file not found: $ENV_FILE"
|
|
exit 1
|
|
fi
|
|
source "$ENV_FILE"
|
|
|
|
# === Sanity Check ===
|
|
sanity_check() {
|
|
if [ -z "$HA_SSH_KEY" ]; then
|
|
echo "Error: HA_SSH_KEY is not set."; exit 1
|
|
fi
|
|
if [ -z "$HA_SSH_USER" ]; then
|
|
echo "Error: HA_SSH_USER is not set."; exit 1
|
|
fi
|
|
if [ -z "$BACKUP_DEST" ]; then
|
|
echo "Error: BACKUP_DEST is not set."; exit 1
|
|
fi
|
|
if [ -z "$SERVER_LIST" ]; then
|
|
echo "Error: SERVER_LIST is not set."; exit 1
|
|
fi
|
|
if [ "$NTFY_ENABLED" == "true" ]; then
|
|
if [ -z "$NTFY_SERVER" ] || [ -z "$NTFY_TOPIC" ]; then
|
|
echo "Error: NTFY settings are incomplete."; exit 1
|
|
fi
|
|
fi
|
|
if [ "$DISCORD_ENABLED" == "true" ]; then
|
|
if [ -z "$DISCORD_WEBHOOK_URL" ]; then
|
|
echo "Error: DISCORD_WEBHOOK_URL is not set."; exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# === Notification Functions ===
|
|
send_ntfy_notification() {
|
|
local message="$1"
|
|
if [ "$NTFY_ENABLED" = true ]; then
|
|
curl -s -X POST -d "$message" "$NTFY_SERVER/$NTFY_TOPIC" >/dev/null
|
|
fi
|
|
}
|
|
|
|
send_discord_notification() {
|
|
local message="$1"
|
|
if [ "$DISCORD_ENABLED" = true ]; then
|
|
curl -s -X POST -H "Content-Type: application/json" \
|
|
-d "{\"content\": \"$message\"}" "$DISCORD_WEBHOOK_URL" >/dev/null
|
|
fi
|
|
}
|
|
|
|
# === Run Sanity Check ===
|
|
sanity_check
|
|
|
|
# === Setup Variables ===
|
|
TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S')
|
|
START_TIME=$(date +%s)
|
|
LOG_FILE="$BACKUP_DEST/backup-$TIMESTAMP.log"
|
|
REMOTE_FILE=${REMOTE_FILE:-"/opt/AdGuardHome/AdGuardHome.yaml"}
|
|
|
|
mkdir -p "$BACKUP_DEST"
|
|
touch "$LOG_FILE"
|
|
|
|
# Parse server list
|
|
IFS=' ' read -r -a SERVERS <<< "$SERVER_LIST"
|
|
|
|
# === Start Logging and Notify ===
|
|
echo "[$(date)] Starting AdGuardHome backup..." | tee -a "$LOG_FILE"
|
|
send_ntfy_notification "🛡️ AdGuardHome backup started at $TIMESTAMP"
|
|
send_discord_notification "🛡️ AdGuardHome backup started at $TIMESTAMP"
|
|
|
|
# === Main Backup Loop ===
|
|
for HOST in "${SERVERS[@]}"; do
|
|
SERVER="$HA_SSH_USER@$HOST"
|
|
echo "[$(date)] Connecting to $SERVER..." | tee -a "$LOG_FILE"
|
|
|
|
REMOTE_HOSTNAME=$(ssh -i "$HA_SSH_KEY" -o StrictHostKeyChecking=no "$SERVER" 'hostname' 2>/dev/null)
|
|
if [[ -z "$REMOTE_HOSTNAME" ]]; then
|
|
echo "[$(date)] ❌ Failed to retrieve hostname from $HOST" | tee -a "$LOG_FILE"
|
|
send_ntfy_notification "❌ Backup failed: could not retrieve hostname from $HOST"
|
|
send_discord_notification "❌ Backup failed: could not retrieve hostname from $HOST"
|
|
continue
|
|
fi
|
|
|
|
DEST_FILE="$BACKUP_DEST/AdGuardHome.yaml-$REMOTE_HOSTNAME-$TIMESTAMP"
|
|
|
|
scp -i "$HA_SSH_KEY" -o StrictHostKeyChecking=no "$SERVER:$REMOTE_FILE" "$DEST_FILE" 2>>"$LOG_FILE"
|
|
if [[ $? -eq 0 ]]; then
|
|
echo "[$(date)] ✅ Backup successful: $DEST_FILE" | tee -a "$LOG_FILE"
|
|
send_ntfy_notification "✅ Backup complete for $REMOTE_HOSTNAME"
|
|
send_discord_notification "✅ Backup complete for $REMOTE_HOSTNAME"
|
|
else
|
|
echo "[$(date)] ❌ Failed to copy from $HOST" | tee -a "$LOG_FILE"
|
|
send_ntfy_notification "❌ Backup failed for $REMOTE_HOSTNAME"
|
|
send_discord_notification "❌ Backup failed for $REMOTE_HOSTNAME"
|
|
fi
|
|
done
|
|
|
|
# === Finalize ===
|
|
END_TIME=$(date +%s)
|
|
DURATION=$((END_TIME - START_TIME))
|
|
|
|
echo "[$(date)] Backup script completed in ${DURATION}s." | tee -a "$LOG_FILE"
|
|
send_ntfy_notification "📦 Backup completed in ${DURATION}s"
|
|
send_discord_notification "📦 Backup completed in ${DURATION}s"
|
|
|