2026-05-18 19:49:31 +08:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
|
. "$ROOT_DIR/scripts/lib.sh"
|
|
|
|
|
load_env
|
|
|
|
|
|
|
|
|
|
strip_protocol() {
|
|
|
|
|
local value="$1"
|
|
|
|
|
value="${value#https://}"
|
|
|
|
|
value="${value#http://}"
|
|
|
|
|
printf '%s' "$value"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ws_url() {
|
|
|
|
|
local value="$1"
|
|
|
|
|
local host
|
|
|
|
|
host="$(strip_protocol "$value")"
|
|
|
|
|
if [ -z "$host" ]; then
|
|
|
|
|
printf ''
|
|
|
|
|
else
|
|
|
|
|
printf 'wss://%s/ws/im' "$host"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
audit "render-config" "STARTED" "rendering runtime files"
|
|
|
|
|
progress "render-config" "STARTED" "rendering runtime files"
|
|
|
|
|
|
|
|
|
|
mkdir -p "$ROOT_DIR/config/docs" "$ROOT_DIR/config/sdk"
|
|
|
|
|
|
|
|
|
|
cat > "$ROOT_DIR/config/docs/docs-runtime.json" <<EOF
|
|
|
|
|
{
|
|
|
|
|
"deployment": "PRIVATE",
|
|
|
|
|
"privateVersion": "${PRIVATE_VERSION:-2026.05.18-private.1}",
|
|
|
|
|
"domains": {
|
|
|
|
|
"console": "${CONSOLE_DOMAIN:-}",
|
|
|
|
|
"docs": "${DOCS_DOMAIN:-}",
|
|
|
|
|
"file": "${FILE_DOMAIN:-}",
|
|
|
|
|
"im": "${IM_DOMAIN:-}",
|
|
|
|
|
"update": "${UPDATE_DOMAIN:-}",
|
|
|
|
|
"license": "${LICENSE_DOMAIN:-}",
|
|
|
|
|
"push": "${PUSH_DOMAIN:-}"
|
|
|
|
|
},
|
|
|
|
|
"features": {
|
|
|
|
|
"file": ${ENABLE_FILE:-true},
|
|
|
|
|
"im": ${ENABLE_IM:-false},
|
|
|
|
|
"push": ${ENABLE_PUSH:-false},
|
|
|
|
|
"update": ${ENABLE_UPDATE:-false},
|
|
|
|
|
"license": ${ENABLE_LICENSE:-false}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
cat > "$ROOT_DIR/config/sdk/xuqm-private-sdk.json" <<EOF
|
|
|
|
|
{
|
|
|
|
|
"schemaVersion": 1,
|
|
|
|
|
"configVersion": "${PRIVATE_VERSION:-2026.05.18-private.1}",
|
|
|
|
|
"deployment": "PRIVATE",
|
|
|
|
|
"appKey": "${TENANT_BOOTSTRAP_APP_KEY:-ak_private_default}",
|
|
|
|
|
"controlBaseUrl": "${CONSOLE_DOMAIN:-}",
|
|
|
|
|
"fileBaseUrl": "${FILE_DOMAIN:-}",
|
|
|
|
|
"imApiBaseUrl": "${IM_DOMAIN:-}",
|
|
|
|
|
"imWsUrl": "$(ws_url "${IM_DOMAIN:-}")",
|
|
|
|
|
"pushBaseUrl": "${PUSH_DOMAIN:-}",
|
|
|
|
|
"updateBaseUrl": "${UPDATE_DOMAIN:-}",
|
|
|
|
|
"licenseBaseUrl": "${LICENSE_DOMAIN:-}",
|
|
|
|
|
"docsBaseUrl": "${DOCS_DOMAIN:-}",
|
|
|
|
|
"features": {
|
|
|
|
|
"file": ${ENABLE_FILE:-true},
|
|
|
|
|
"im": ${ENABLE_IM:-false},
|
|
|
|
|
"push": ${ENABLE_PUSH:-false},
|
|
|
|
|
"update": ${ENABLE_UPDATE:-false},
|
|
|
|
|
"license": ${ENABLE_LICENSE:-false}
|
|
|
|
|
},
|
|
|
|
|
"connectTimeoutMs": 10000,
|
|
|
|
|
"readTimeoutMs": 30000,
|
|
|
|
|
"logLevel": "WARN"
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
cat > "$ROOT_DIR/.deploy-state/current.json" <<EOF
|
|
|
|
|
{
|
|
|
|
|
"privateVersion": "${PRIVATE_VERSION:-2026.05.18-private.1}",
|
|
|
|
|
"profiles": ["${COMPOSE_PROFILES:-base}"],
|
|
|
|
|
"mysql": {"mode": "${MYSQL_MODE:-external}", "status": "UNKNOWN"},
|
|
|
|
|
"redis": {"mode": "${REDIS_MODE:-external}", "status": "UNKNOWN"},
|
|
|
|
|
"services": {
|
|
|
|
|
"file": ${ENABLE_FILE:-true},
|
|
|
|
|
"im": ${ENABLE_IM:-false},
|
|
|
|
|
"push": ${ENABLE_PUSH:-false},
|
|
|
|
|
"update": ${ENABLE_UPDATE:-false},
|
|
|
|
|
"license": ${ENABLE_LICENSE:-false}
|
|
|
|
|
},
|
|
|
|
|
"lastHealthcheck": null
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
|
feat: implement complete private deployment scripts (P1-P4)
- upgrade.sh/rollback.sh: backup→pull→rolling restart→healthcheck→auto-rollback
- backup.sh/restore.sh: mysqldump+redis BGSAVE+config tar, SHA256 manifest, restore with checksum verification
- healthcheck.sh: Docker/container/MySQL/Redis/HTTP/disk checks, JSON output to .deploy-state/
- doctor.sh: sanitized diagnostics archive, vendor API TCP connectivity, cert expiry
- export-offline-bundle.sh: docker pull+save for all profile images, load-images.sh, SHA256
- configure.sh: interactive/non-interactive mode, MySQL/Redis mode selection, domain prompts
- enable-service.sh: domain validation, docker pull + compose up, healthcheck
- disable-service.sh: compose stop+rm, profile removal, render-config
- renew-cert.sh: acme.sh/certbot, --dry-run, backup old cert, nginx reload on success
- alert-webhook.sh: WeCom/DingTalk/Feishu webhook, message sanitization
- bench.sh: ab/wrk/curl benchmark, JSON report with docker stats
- rotate-secrets.sh: JWT and internal token rotation
- vendor credential templates: push.env and store-submit.env with full credential comments
- render-config.sh: auto-sync SDK URL env vars (SDK_FILE_SERVICE_URL, SDK_IM_API_URL, SDK_IM_WS_URL)
- All scripts pass bash -n syntax check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 20:49:25 +08:00
|
|
|
# Keep SDK internal URL env vars in sync with domain config
|
|
|
|
|
[ -n "${FILE_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/config/xuqm.env" "SDK_FILE_SERVICE_URL" "${FILE_DOMAIN}"
|
|
|
|
|
[ -n "${IM_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/config/xuqm.env" "SDK_IM_API_URL" "${IM_DOMAIN}"
|
|
|
|
|
[ -n "${IM_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/config/xuqm.env" "SDK_IM_WS_URL" "$(ws_url "${IM_DOMAIN}")"
|
|
|
|
|
|
2026-05-18 19:49:31 +08:00
|
|
|
audit "render-config" "DONE" "runtime files rendered"
|
|
|
|
|
progress "render-config" "DONE" "runtime files rendered"
|