153 lines
4.4 KiB
Bash
Executable File
153 lines
4.4 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Redis 8 Restore Smoke Test
|
|
#
|
|
# Scope:
|
|
# - Restore aus dem dokumentierten shared-redis-pre-redis8-Artefakt
|
|
# - Start einer isolierten Redis-8-Testinstanz auf localhost:16379
|
|
# - PING, INFO server und DBSIZE ohne Ausgabe des Passworts
|
|
|
|
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/redis"
|
|
REPORT_ROOT="/mnt/user/backups/restore-reports"
|
|
PRE_CUTOVER_ROOT="/mnt/user/backups/borg/dumps/latest"
|
|
SECRET_FILE="/mnt/user/appdata/secrets/redis_password.txt"
|
|
COMPOSE_FILE="$SCRIPT_DIR/redis-compose.test.yml"
|
|
REPORT_FILE="$REPORT_ROOT/redis-$(date +%F).md"
|
|
|
|
if [ "$WHATIF" -eq 1 ]; then
|
|
cat <<EOF
|
|
Redis 8 restore test
|
|
Mode: WhatIf
|
|
RestoreRoot: $RESTORE_ROOT
|
|
Restore source: newest $PRE_CUTOVER_ROOT/shared-redis-pre-redis8-*
|
|
Secret source: $SECRET_FILE
|
|
Test endpoint: 127.0.0.1:16379
|
|
Scope: Data restore + isolated Redis boot + PING/INFO/DBSIZE smoke
|
|
EOF
|
|
exit 0
|
|
fi
|
|
|
|
require_cmd docker
|
|
require_path "$PRE_CUTOVER_ROOT"
|
|
require_path "$SECRET_FILE"
|
|
require_path "$COMPOSE_FILE"
|
|
|
|
RESTORE_SUCCESS=0
|
|
cleanup() {
|
|
cleanup_compose "$COMPOSE_FILE"
|
|
if [ "$RESTORE_SUCCESS" -ne 1 ]; then
|
|
preserve_on_failure "redis" "$RESTORE_ROOT"
|
|
return
|
|
fi
|
|
if [ "$KEEP_DATA" -ne 1 ]; then
|
|
rm -rf "$RESTORE_ROOT"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
rm -rf "$RESTORE_ROOT"
|
|
mkdir -p "$RESTORE_ROOT/data" "$RESTORE_ROOT/secrets"
|
|
|
|
restore_source="$(find "$PRE_CUTOVER_ROOT" -maxdepth 1 -type d -name 'shared-redis-pre-redis8-*' | sort | tail -1)"
|
|
if [ -z "$restore_source" ]; then
|
|
echo "No shared-redis-pre-redis8-* restore source found under $PRE_CUTOVER_ROOT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$restore_source" ]; then
|
|
echo "Redis restore source is not a directory: $restore_source" >&2
|
|
exit 1
|
|
fi
|
|
|
|
cp -a "$restore_source/." "$RESTORE_ROOT/data/"
|
|
cp "$SECRET_FILE" "$RESTORE_ROOT/secrets/redis_password.txt"
|
|
chmod -R a+rwX "$RESTORE_ROOT/data"
|
|
chmod a+r "$RESTORE_ROOT/secrets/redis_password.txt"
|
|
|
|
data_files="$(find "$RESTORE_ROOT/data" -type f | wc -l | tr -d ' ')"
|
|
data_bytes="$(du -sb "$RESTORE_ROOT/data" | awk '{print $1}')"
|
|
|
|
docker compose -f "$COMPOSE_FILE" up -d restoretest-redis >/dev/null
|
|
|
|
ping_result=""
|
|
for _ in $(seq 1 60); do
|
|
ping_result="$(docker exec restoretest-redis sh -lc \
|
|
'p=$(cat /run/secrets/redis_password); redis-cli -a "$p" --no-auth-warning PING' 2>/dev/null || true)"
|
|
if [ "$ping_result" = "PONG" ]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [ "$ping_result" != "PONG" ]; then
|
|
echo "Redis PING smoke failed: $ping_result" >&2
|
|
docker logs --tail 80 restoretest-redis >&2 || true
|
|
exit 1
|
|
fi
|
|
|
|
redis_version="$(docker exec restoretest-redis sh -lc \
|
|
'p=$(cat /run/secrets/redis_password); redis-cli -a "$p" --no-auth-warning INFO server | awk -F: "/^redis_version:/ {gsub(/\r/, \"\", \$2); print \$2}"')"
|
|
dbsize="$(docker exec restoretest-redis sh -lc \
|
|
'p=$(cat /run/secrets/redis_password); redis-cli -a "$p" --no-auth-warning DBSIZE' | tr -d '\r')"
|
|
aof_enabled="$(docker exec restoretest-redis sh -lc \
|
|
'p=$(cat /run/secrets/redis_password); redis-cli -a "$p" --no-auth-warning INFO persistence | awk -F: "/^aof_enabled:/ {gsub(/\r/, \"\", \$2); print \$2}"')"
|
|
|
|
case "$redis_version" in
|
|
8.*) ;;
|
|
*)
|
|
echo "Unexpected Redis version: $redis_version" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [ "${dbsize:-0}" -lt 1 ]; then
|
|
echo "Unexpected Redis DBSIZE: $dbsize" >&2
|
|
exit 1
|
|
fi
|
|
|
|
write_report "$REPORT_FILE" <<EOF
|
|
# Redis 8 Restore Test Report - $(date +%F)
|
|
|
|
- Service: \`redis\`
|
|
- Restore source: \`$restore_source\`
|
|
- Restore root: \`$RESTORE_ROOT\`
|
|
- Test container: \`restoretest-redis\`
|
|
- Test endpoint: \`127.0.0.1:16379\`
|
|
- Result: \`SUCCESS\`
|
|
|
|
## Checks
|
|
|
|
- Data restore from pre-Redis8 artifact: \`ok\`
|
|
- Secret file mounted from host secret path: \`ok\`
|
|
- Restored data files: \`$data_files\`
|
|
- Restored data bytes: \`$data_bytes\`
|
|
- PING: \`$ping_result\`
|
|
- Redis version: \`$redis_version\`
|
|
- AOF enabled: \`$aof_enabled\`
|
|
- DBSIZE: \`$dbsize\`
|
|
|
|
## Notes
|
|
|
|
- Productive Redis port 6379 and productive data path were NOT used.
|
|
- Test port was bound to localhost only: \`127.0.0.1:16379\`.
|
|
- Redis password value was used from the restored secret file and was not printed.
|
|
- Test data was cleaned after success: \`$([ "$KEEP_DATA" -eq 1 ] && echo no || echo yes)\`
|
|
EOF
|
|
|
|
RESTORE_SUCCESS=1
|
|
echo "Redis restore test ok -> $REPORT_FILE"
|