didi-lot1-ai/ai_platform/modules/web/deploy/metasearch/searxng-reset.sh

162 lines
4.6 KiB
Bash

#!/usr/bin/env bash
#
# SearXNG Reset Script (3-instance cluster)
# ==========================================
# Clears CAPTCHA/rate-limit state and restarts SearXNG instances.
#
# Usage:
# ./searxng-reset.sh # Full reset (flush all + restart all)
# ./searxng-reset.sh --status # Show engine error counts
# ./searxng-reset.sh --check # Quick health check
# ./searxng-reset.sh --one 2 # Reset only instance 2
#
set -euo pipefail
INSTANCES=(1 2 3)
LB_CONTAINER="didiAI-web-searxng"
SEARXNG_URL="http://localhost:55100"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
check_health() {
echo "=== Health Check ==="
echo ""
# LB
local lb_status
lb_status=$(curl -s --max-time 5 "${SEARXNG_URL}/healthz" 2>/dev/null) || true
if [[ "$lb_status" == "OK" ]]; then
echo -e "Load balancer (55100): ${GREEN}UP${NC}"
else
echo -e "Load balancer (55100): ${RED}DOWN${NC}"
fi
# Individual instances
for i in "${INSTANCES[@]}"; do
local container="didiAI-web-searxng-${i}"
local status
status=$(docker inspect --format '{{.State.Health.Status}}' "$container" 2>/dev/null) || status="not found"
if [[ "$status" == "healthy" ]]; then
echo -e " Instance ${i}: ${GREEN}${status}${NC}"
else
echo -e " Instance ${i}: ${RED}${status}${NC}"
fi
done
# Test search
echo ""
local results
results=$(curl -s --max-time 10 "${SEARXNG_URL}/search?q=test&format=json" 2>/dev/null \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('results',[])))" 2>/dev/null) || results=0
if [[ "$results" -gt 0 ]]; then
echo -e "Search test: ${GREEN}OK ($results results)${NC}"
else
echo -e "Search test: ${RED}FAILED (0 results)${NC}"
fi
}
show_status() {
echo "=== Engine Errors (all instances) ==="
echo ""
for i in "${INSTANCES[@]}"; do
local container="didiAI-web-searxng-${i}"
echo -e "${YELLOW}Instance ${i} ($container):${NC}"
local captcha_count
captcha_count=$(docker logs "$container" 2>&1 | grep -ci 'CAPTCHA' 2>/dev/null) || captcha_count=0
local toomany_count
toomany_count=$(docker logs "$container" 2>&1 | grep -ci 'TooManyRequests' 2>/dev/null) || toomany_count=0
if [[ $captcha_count -gt 0 || $toomany_count -gt 0 ]]; then
echo " CAPTCHA: $captcha_count | TooManyRequests: $toomany_count"
docker logs "$container" 2>&1 \
| grep -iE 'CAPTCHA|TooMany' \
| grep -oP 'engines\.\K[^:]+' \
| sort | uniq -c | sort -rn \
| sed 's/^/ /' || true
else
echo -e " ${GREEN}Clean (no errors)${NC}"
fi
echo ""
done
}
reset_instance() {
local i=$1
local container="didiAI-web-searxng-${i}"
local redis="didiAI-web-searxng-redis-${i}"
echo -n " [${i}] Flush Redis... "
if docker exec "$redis" valkey-cli FLUSHALL > /dev/null 2>&1; then
echo -e "${GREEN}OK${NC}"
else
echo -e "${YELLOW}WARN${NC}"
fi
echo -n " [${i}] Restart SearXNG... "
docker restart "$container" > /dev/null 2>&1
echo -e "${GREEN}OK${NC}"
}
do_reset() {
local targets=("${@}")
if [[ ${#targets[@]} -eq 0 ]]; then
targets=("${INSTANCES[@]}")
fi
echo "=== SearXNG Reset ==="
echo "Resetting instances: ${targets[*]}"
echo ""
for i in "${targets[@]}"; do
reset_instance "$i"
done
# Wait for health
echo ""
echo -n "Waiting for startup... "
local attempts=0
while [[ $attempts -lt 15 ]]; do
sleep 2
local healthy=0
for i in "${targets[@]}"; do
local status
status=$(docker inspect --format '{{.State.Health.Status}}' "didiAI-web-searxng-${i}" 2>/dev/null) || status="none"
[[ "$status" == "healthy" ]] && healthy=$((healthy + 1))
done
if [[ $healthy -eq ${#targets[@]} ]]; then
echo -e "${GREEN}All ${healthy} instances UP${NC}"
echo ""
check_health
return 0
fi
attempts=$((attempts + 1))
done
echo -e "${YELLOW}Some instances still starting (check with --check)${NC}"
}
# Parse arguments
case "${1:-}" in
--status|-s)
show_status
;;
--check|-c)
check_health
;;
--one|-o)
[[ -z "${2:-}" ]] && echo "Usage: $0 --one <1|2|3>" && exit 1
do_reset "$2"
;;
--help|-h)
sed -n '2,12p' "$0" | sed 's/^# //' | sed 's/^#//'
;;
*)
do_reset
;;
esac