Files
sub2api-cn-relay-manager/scripts/deploy/verify_crm_deployment.sh
phamnazage-jpg 47ced19c7b fix(deploy): production CRM deployment improvements
- Fix deploy_crm_only.sh: non-destructive hot reload
  - Enhanced stop logic with pgrep + fuser for port release
  - Added 3-layer verification (process/control/user)
  - Check /proc/$pid/exe for (deleted) marker
  - Never delete DB

- Fix portal script contracts: crm_session → crm_subject
  - deploy_tksea_portal.sh: use $cookie_crm_subject
  - test_tksea_portal_assets.sh: assert crm_subject exists
  - nginx.example.conf: updated trusted subject header

- Add systemd service management
  - sub2api-crm.service.template
  - install_crm_systemd.sh
  - verify_crm_deployment.sh

Update docs/plans/2026-06-04-next-version-plan.md with deployment findings.
2026-06-10 15:44:45 +08:00

130 lines
3.9 KiB
Bash

#!/bin/bash
# verify_crm_deployment.sh - 部署后三层验证脚本
set -e
CRM_DIR="${1:-/home/ubuntu/crm-only-20260602_18190}"
PORT=$(echo "${CRM_DIR}" | grep -oE '[0-9]+' | tail -1)
PORT="${PORT:-18190}"
ERRORS=0
echo "============================================"
echo "CRM 部署三层验证"
echo "============================================"
echo "目录: ${CRM_DIR}"
echo "端口: ${PORT}"
echo ""
# === Layer 1: 进程层 ===
echo "[1/3] 进程层验证"
# 检查 PID 文件
if [ -f "${CRM_DIR}/crm.pid" ]; then
PID=$(cat "${CRM_DIR}/crm.pid")
echo " PID 文件: ${PID}"
# 检查进程存在
if ps -p "${PID}" >/dev/null 2>&1; then
echo " ✓ 进程存在"
# 检查 /proc/$PID/exe
EXE=$(readlink "/proc/${PID}/exe" 2>/dev/null || echo "unknown")
echo " /proc/${PID}/exe: ${EXE}"
if echo "${EXE}" | grep -q "(deleted)"; then
echo " ✗ ERROR: Binary has (deleted) marker - old process still running"
ERRORS=$((ERRORS + 1))
else
echo " ✓ Binary state: OK"
fi
else
echo " ✗ ERROR: PID ${PID} not running"
ERRORS=$((ERRORS + 1))
fi
else
echo " ! PID 文件不存在 (可能使用 systemd)"
# 尝试 pgrep
NEW_PID=$(pgrep -f 'sub2api-cn-relay-manager-server' | head -1)
if [ -n "${NEW_PID}" ]; then
echo " ✓ Found running process: ${NEW_PID}"
else
echo " ✗ ERROR: No running process found"
ERRORS=$((ERRORS + 1))
fi
fi
echo ""
# === Layer 2: 控制面层 ===
echo "[2/3] 控制面层验证"
# Test endpoints
ENDPOINTS=(
"healthz:健康检查"
"api/portal/session:Portal Session"
"api/portal/logical-groups:Logical Groups"
)
for item in "${ENDPOINTS[@]}"; do
IFS=':' read -r endpoint name <<< "${item}"
STATUS=$(curl -s "http://127.0.0.1:${PORT}/${endpoint}" -w '%{http_code}' -o /dev/null 2>/dev/null || echo "000")
if [ "${STATUS}" = "200" ]; then
echo "${name}: HTTP ${STATUS}"
elif [ "${STATUS}" = "401" ] || [ "${STATUS}" = "403" ]; then
echo " ~ ${name}: HTTP ${STATUS} (expected for protected endpoint)"
else
echo "${name}: HTTP ${STATUS}"
ERRORS=$((ERRORS + 1))
fi
done
# 检查 login_enabled
SESSION_RESP=$(curl -s "http://127.0.0.1:${PORT}/api/portal/session" 2>/dev/null || echo "{}")
if echo "${SESSION_RESP}" | grep -q '"login_enabled":true'; then
echo " ✓ Portal login enabled"
elif echo "${SESSION_RESP}" | grep -q '"login_enabled":false'; then
echo " ✗ ERROR: Portal login disabled (SUB2API_CRM_PORTAL_SESSION_SECRET not set)"
ERRORS=$((ERRORS + 1))
else
echo " ! Cannot determine login_enabled state"
fi
echo ""
# === Layer 3: 用户面层 ===
echo "[3/3] 用户面层验证"
# 检查 nginx 配置
if [ -f /etc/nginx/sites-enabled/crm.sub.tksea.top.conf ] || [ -f /etc/nginx/sites-available/crm.sub.tksea.top.conf ]; then
echo " ✓ Nginx config exists"
# 检查 nginx 是否指向正确端口
NGINX_CONF=$(cat /etc/nginx/sites-enabled/crm.sub.tksea.top.conf 2>/dev/null || cat /etc/nginx/sites-available/crm.sub.tksea.top.conf 2>/dev/null)
if echo "${NGINX_CONF}" | grep -q "127.0.0.1:${PORT}"; then
echo " ✓ Nginx points to port ${PORT}"
else
echo " ! WARNING: Nginx may not point to correct port"
fi
else
echo " ! Nginx config not found in standard location"
fi
# 检查外部访问 (可选,可能因网络限制失败)
# EXTERN_RESP=$(curl -s "https://crm.sub.tksea.top/api/portal/session" --connect-timeout 3 2>/dev/null || echo "")
# if [ -n "${EXTERN_RESP}" ]; then
# echo " ✓ External access working"
# fi
echo ""
echo "============================================"
if [ ${ERRORS} -eq 0 ]; then
echo "✓ 全部验证通过"
exit 0
else
echo "✗ 发现 ${ERRORS} 个错误"
exit 1
fi