ops: add adguard restore test
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
restoretest-adguard:
|
||||
image: adguard/adguardhome:v0.107.76@sha256:7157eb1dc3b26c7af1d6898759a7b3f7d0fa09891fbd2d3caa6abc1057a9179b
|
||||
container_name: restoretest-adguard
|
||||
restart: "no"
|
||||
ports:
|
||||
- "127.0.0.1:15353:53/tcp"
|
||||
- "127.0.0.1:15353:53/udp"
|
||||
- "127.0.0.1:13001:80/tcp"
|
||||
volumes:
|
||||
- /mnt/user/backups/restore-lab/adguard/work:/opt/adguardhome/work
|
||||
- /mnt/user/backups/restore-lab/adguard/conf:/opt/adguardhome/conf
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
Executable
+181
@@ -0,0 +1,181 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# AdGuard Home Restore Smoke Test
|
||||
#
|
||||
# Scope:
|
||||
# - Borg-Extract von /local/appdata/adguard/conf
|
||||
# - YAML-/Strukturcheck fuer AdGuardHome.yaml
|
||||
# - Start einer isolierten Testinstanz auf localhost-Ports
|
||||
# - HTTP-Smoke gegen Admin-UI/API
|
||||
# - DNS-Smoke gegen localhost:15353, falls ein passender Resolver-Client vorhanden ist
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
. "$SCRIPT_DIR/common.sh"
|
||||
|
||||
WHATIF=0
|
||||
KEEP_DATA=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--what-if) WHATIF=1 ;;
|
||||
--keep-data) KEEP_DATA=1 ;;
|
||||
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
RESTORE_ROOT="/mnt/user/backups/restore-lab/adguard"
|
||||
REPORT_ROOT="/mnt/user/backups/restore-reports"
|
||||
EXTRACT_DIR="$BORG_RESTORE_HOST_ROOT/adguard-extract"
|
||||
COMPOSE_FILE="$SCRIPT_DIR/adguard-compose.test.yml"
|
||||
REPORT_FILE="$REPORT_ROOT/adguard-$(date +%F).md"
|
||||
TEST_HTTP="http://127.0.0.1:13001"
|
||||
TEST_DNS_PORT="15353"
|
||||
|
||||
if [ "$WHATIF" -eq 1 ]; then
|
||||
cat <<EOF
|
||||
AdGuard Home restore test
|
||||
Mode: WhatIf
|
||||
RestoreRoot: $RESTORE_ROOT
|
||||
Borg source: local/appdata/adguard/conf
|
||||
Test HTTP endpoint: $TEST_HTTP
|
||||
Test DNS endpoint: 127.0.0.1:$TEST_DNS_PORT
|
||||
Scope: Config-Restore + isolated AdGuard boot + HTTP/DNS smoke
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
require_cmd docker
|
||||
require_cmd curl
|
||||
require_path "$BORG_PASSPHRASE_FILE_DEFAULT"
|
||||
require_path "$COMPOSE_FILE"
|
||||
|
||||
RESTORE_SUCCESS=0
|
||||
cleanup() {
|
||||
cleanup_compose "$COMPOSE_FILE"
|
||||
if [ "$RESTORE_SUCCESS" -ne 1 ]; then
|
||||
preserve_on_failure "adguard" "$RESTORE_ROOT"
|
||||
rm -rf "$EXTRACT_DIR"
|
||||
return
|
||||
fi
|
||||
if [ "$KEEP_DATA" -ne 1 ]; then
|
||||
rm -rf "$RESTORE_ROOT"
|
||||
fi
|
||||
rm -rf "$EXTRACT_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
rm -rf "$EXTRACT_DIR" "$RESTORE_ROOT"
|
||||
mkdir -p "$RESTORE_ROOT/conf" "$RESTORE_ROOT/work"
|
||||
|
||||
archive="$(latest_archive_name)"
|
||||
repo="$(borg_repo_url)"
|
||||
|
||||
if [ -z "$archive" ] || [ -z "$repo" ]; then
|
||||
echo "Could not resolve Borg repo/archive from borg-ui database" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
borg_extract "/restore/adguard-extract" "local/appdata/adguard/conf"
|
||||
|
||||
if [ ! -d "$EXTRACT_DIR/local/appdata/adguard/conf" ]; then
|
||||
echo "AdGuard conf path missing in Borg archive" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -a "$EXTRACT_DIR/local/appdata/adguard/conf/." "$RESTORE_ROOT/conf/"
|
||||
chmod -R a+rX "$RESTORE_ROOT/conf"
|
||||
chmod -R a+rwX "$RESTORE_ROOT/work"
|
||||
|
||||
config_file="$RESTORE_ROOT/conf/AdGuardHome.yaml"
|
||||
if [ ! -s "$config_file" ]; then
|
||||
echo "Missing restored AdGuardHome.yaml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if command -v ruby >/dev/null 2>&1; then
|
||||
ruby -e 'require "yaml"; YAML.load_file(ARGV.fetch(0))' "$config_file"
|
||||
yaml_check="ruby-yaml-ok"
|
||||
else
|
||||
grep -q '^dns:' "$config_file"
|
||||
grep -q '^http:' "$config_file"
|
||||
yaml_check="basic-structure-ok"
|
||||
fi
|
||||
|
||||
filter_count="$(grep -c '^[[:space:]]*-[[:space:]]*enabled:' "$config_file" 2>/dev/null || true)"
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" up -d restoretest-adguard >/dev/null
|
||||
|
||||
http_status=""
|
||||
for _ in $(seq 1 60); do
|
||||
http_status="$(curl -s -o /tmp/adguard-body.html -w '%{http_code}' \
|
||||
"$TEST_HTTP/control/status" || true)"
|
||||
if [ "$http_status" = "200" ] || [ "$http_status" = "401" ] || [ "$http_status" = "403" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$http_status" != "200" ] && [ "$http_status" != "401" ] && [ "$http_status" != "403" ]; then
|
||||
echo "AdGuard HTTP smoke failed: status=$http_status" >&2
|
||||
docker logs --tail 80 restoretest-adguard >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dns_status="not-run"
|
||||
dns_detail="no dig/drill command available"
|
||||
if command -v dig >/dev/null 2>&1; then
|
||||
if dig @127.0.0.1 -p "$TEST_DNS_PORT" git.kaleschke.info A +time=3 +tries=1 >/tmp/adguard-dig.out 2>&1; then
|
||||
dns_status="ok"
|
||||
dns_detail="$(grep -E '^[[:alnum:].-]+[[:space:]]+[0-9]+[[:space:]]+IN[[:space:]]+A[[:space:]]+' /tmp/adguard-dig.out | head -1 || true)"
|
||||
else
|
||||
dns_status="failed"
|
||||
dns_detail="$(tail -20 /tmp/adguard-dig.out | tr '\n' ' ')"
|
||||
fi
|
||||
elif command -v drill >/dev/null 2>&1; then
|
||||
if drill -p "$TEST_DNS_PORT" git.kaleschke.info @127.0.0.1 >/tmp/adguard-drill.out 2>&1; then
|
||||
dns_status="ok"
|
||||
dns_detail="$(grep -E '^[[:alnum:].-]+\\.[[:space:]]+[0-9]+[[:space:]]+IN[[:space:]]+A[[:space:]]+' /tmp/adguard-drill.out | head -1 || true)"
|
||||
else
|
||||
dns_status="failed"
|
||||
dns_detail="$(tail -20 /tmp/adguard-drill.out | tr '\n' ' ')"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$dns_status" = "failed" ]; then
|
||||
echo "AdGuard DNS smoke failed: $dns_detail" >&2
|
||||
docker logs --tail 80 restoretest-adguard >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
write_report "$REPORT_FILE" <<EOF
|
||||
# AdGuard Home Restore Test Report - $(date +%F)
|
||||
|
||||
- Service: \`adguard\`
|
||||
- Source repo: \`$repo\`
|
||||
- Archive: \`$archive\`
|
||||
- Restore root: \`$RESTORE_ROOT\`
|
||||
- Test container: \`restoretest-adguard\`
|
||||
- Test HTTP endpoint: \`$TEST_HTTP/control/status\`
|
||||
- Test DNS endpoint: \`127.0.0.1:$TEST_DNS_PORT\`
|
||||
- Result: \`SUCCESS\`
|
||||
|
||||
## Checks
|
||||
|
||||
- Borg extract of conf: \`ok\`
|
||||
- Restored config file: \`AdGuardHome.yaml\`
|
||||
- Config check: \`$yaml_check\`
|
||||
- Filter-list-like entries counted: \`$filter_count\`
|
||||
- HTTP status from /control/status: \`$http_status\`
|
||||
- DNS smoke: \`$dns_status\`
|
||||
- DNS detail: \`$dns_detail\`
|
||||
|
||||
## Notes
|
||||
|
||||
- Productive AdGuard DNS port 53 and admin port 8082 were NOT used.
|
||||
- Test ports were bound to localhost only: \`127.0.0.1:15353\` and \`127.0.0.1:13001\`.
|
||||
- Login credentials are part of the restored AdGuardHome.yaml and were not printed.
|
||||
- Test data was cleaned after success: \`$([ "$KEEP_DATA" -eq 1 ] && echo no || echo yes)\`
|
||||
EOF
|
||||
|
||||
RESTORE_SUCCESS=1
|
||||
echo "AdGuard restore test ok -> $REPORT_FILE"
|
||||
@@ -40,6 +40,12 @@ case "$MODE" in
|
||||
fi
|
||||
exec "$SCRIPT_DIR/authelia-restore-test.sh"
|
||||
;;
|
||||
adguard)
|
||||
if [ "$WHATIF" = "--what-if" ]; then
|
||||
exec "$SCRIPT_DIR/adguard-restore-test.sh" --what-if
|
||||
fi
|
||||
exec "$SCRIPT_DIR/adguard-restore-test.sh"
|
||||
;;
|
||||
nextcloud)
|
||||
if [ "$WHATIF" = "--what-if" ]; then
|
||||
exec "$SCRIPT_DIR/nextcloud-restore-test.sh" --what-if
|
||||
@@ -83,7 +89,7 @@ case "$MODE" in
|
||||
exec "$SCRIPT_DIR/shared-pg-cluster-restore-test.sh"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {freshness|vaultwarden|gitea|paperless|immich|authelia|nextcloud|komodo-bootstrap|komodo-mongo-restore|shared-pg-cluster} [--what-if]" >&2
|
||||
echo "Usage: $0 {freshness|vaultwarden|gitea|paperless|immich|authelia|adguard|nextcloud|komodo-bootstrap|komodo-mongo-restore|traefik|mailarchiver|mealie|shared-pg-cluster} [--what-if]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user