5759c1862e
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。 含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。 Co-Authored-By: Claude <noreply@anthropic.com>
85 lines
2.6 KiB
Bash
Executable File
85 lines
2.6 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
# Atomic Nginx upstream switch with validation and automatic config rollback.
|
|
# This script performs no action unless invoked with preflight, go, legacy, or status.
|
|
|
|
action=${1:-status}
|
|
active_include=${NGINX_ACTIVE_INCLUDE:-}
|
|
go_upstream=${GO_UPSTREAM:-gateway-api:8080}
|
|
legacy_upstream=${LEGACY_UPSTREAM:-legacy-gateway:8000}
|
|
go_health=${GO_HEALTH_URL:-http://127.0.0.1:8080/readyz}
|
|
legacy_health=${LEGACY_HEALTH_URL:-http://127.0.0.1:8000/readyz}
|
|
public_health=${PUBLIC_HEALTH_URL:-}
|
|
nginx_bin=${NGINX_BIN:-nginx}
|
|
|
|
probe() {
|
|
curl -fsS --max-time 5 "$1" >/dev/null
|
|
}
|
|
|
|
preflight() {
|
|
probe "$go_health"
|
|
probe "$legacy_health"
|
|
"$nginx_bin" -t
|
|
echo "preflight ok: Go and legacy are ready; Nginx configuration is valid"
|
|
}
|
|
|
|
status() {
|
|
if [ -z "$active_include" ] || [ ! -f "$active_include" ]; then
|
|
echo "active upstream include is not configured or does not exist"
|
|
exit 1
|
|
fi
|
|
sed -n '1,3p' "$active_include"
|
|
}
|
|
|
|
switch_to() {
|
|
target_name=$1
|
|
target_address=$2
|
|
target_health=$3
|
|
if [ -z "$active_include" ]; then
|
|
echo "NGINX_ACTIVE_INCLUDE is required" >&2
|
|
exit 2
|
|
fi
|
|
probe "$target_health"
|
|
directory=$(dirname "$active_include")
|
|
timestamp=$(date -u +%Y%m%dT%H%M%SZ)
|
|
backup="${active_include}.backup.${timestamp}"
|
|
temporary="${directory}/.ai-gateway-upstream.${timestamp}.tmp"
|
|
if [ -f "$active_include" ]; then
|
|
cp -p "$active_include" "$backup"
|
|
fi
|
|
umask 027
|
|
{
|
|
echo "# ai-gateway-active=${target_name} switched_at=${timestamp}"
|
|
echo "upstream ai_gateway_active {"
|
|
echo " server ${target_address};"
|
|
echo " keepalive 128;"
|
|
echo "}"
|
|
} >"$temporary"
|
|
mv "$temporary" "$active_include"
|
|
if ! "$nginx_bin" -t; then
|
|
if [ -f "$backup" ]; then mv "$backup" "$active_include"; fi
|
|
echo "Nginx validation failed; previous include restored" >&2
|
|
exit 1
|
|
fi
|
|
if ! "$nginx_bin" -s reload; then
|
|
if [ -f "$backup" ]; then mv "$backup" "$active_include"; "$nginx_bin" -s reload || true; fi
|
|
echo "Nginx reload failed; previous include restored" >&2
|
|
exit 1
|
|
fi
|
|
if [ -n "$public_health" ] && ! probe "$public_health"; then
|
|
if [ -f "$backup" ]; then mv "$backup" "$active_include"; "$nginx_bin" -t; "$nginx_bin" -s reload; fi
|
|
echo "public health probe failed; traffic rolled back" >&2
|
|
exit 1
|
|
fi
|
|
echo "active upstream switched to ${target_name}; backup: ${backup}"
|
|
}
|
|
|
|
case "$action" in
|
|
preflight) preflight ;;
|
|
status) status ;;
|
|
go) switch_to go "$go_upstream" "$go_health" ;;
|
|
legacy|rollback) switch_to legacy "$legacy_upstream" "$legacy_health" ;;
|
|
*) echo "usage: $0 {preflight|status|go|legacy|rollback}" >&2; exit 2 ;;
|
|
esac
|