126 lines
4.1 KiB
Bash
Executable File
126 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
# shellcheck source=scripts/common.sh
|
||
source "$SCRIPT_DIR/common.sh"
|
||
|
||
ROTATE_SECRET=0
|
||
if [[ "${1:-}" == "--rotate-secret" ]]; then
|
||
ROTATE_SECRET=1
|
||
shift
|
||
fi
|
||
if [[ $# -gt 0 ]]; then
|
||
ctms_fail "未知参数: $1(支持的参数仅有 --rotate-secret)"
|
||
fi
|
||
|
||
generate_random_hex() {
|
||
local bytes="${1:-32}"
|
||
if command -v openssl >/dev/null 2>&1; then
|
||
openssl rand -hex "$bytes"
|
||
return
|
||
fi
|
||
od -An -N "$bytes" -tx1 /dev/urandom | tr -d ' \n'
|
||
}
|
||
|
||
prepare_onlyoffice_environment() {
|
||
local secret current_login_secret instance_id generated=0
|
||
secret="$(ctms_read_env_value ONLYOFFICE_JWT_SECRET || true)"
|
||
current_login_secret="$(ctms_read_env_value JWT_SECRET_KEY || true)"
|
||
instance_id="$(ctms_read_env_value ONLYOFFICE_INSTANCE_ID || true)"
|
||
|
||
if [[ "$ROTATE_SECRET" -eq 1 || ${#secret} -lt 32 || "$secret" == "$current_login_secret" ]]; then
|
||
secret="$(generate_random_hex 32)"
|
||
ctms_upsert_env_value ONLYOFFICE_JWT_SECRET "$secret"
|
||
generated=1
|
||
fi
|
||
|
||
if [[ -z "$instance_id" ]]; then
|
||
instance_id="ctms-dev-$(generate_random_hex 8)"
|
||
ctms_upsert_env_value ONLYOFFICE_INSTANCE_ID "$instance_id"
|
||
fi
|
||
|
||
ctms_upsert_env_value ONLYOFFICE_ENABLED true
|
||
ctms_upsert_env_value ONLYOFFICE_INTERNAL_URL http://onlyoffice
|
||
ctms_upsert_env_value ONLYOFFICE_STORAGE_BASE_URL http://backend:8000
|
||
ctms_upsert_env_value ONLYOFFICE_CONFIG_TTL_SECONDS 300
|
||
chmod 600 "$CTMS_ENV_FILE"
|
||
|
||
if [[ "$generated" -eq 1 ]]; then
|
||
ctms_ok "已生成新的 ONLYOFFICE 开发密钥并写入 .env(内容不会回显)"
|
||
else
|
||
ctms_ok "已复用 .env 中现有的 ONLYOFFICE 开发密钥"
|
||
fi
|
||
ctms_ok "ONLYOFFICE 开发实例标识已就绪: $instance_id"
|
||
}
|
||
|
||
wait_for_url() {
|
||
local label="$1" url="$2" attempts="${3:-90}" attempt=1
|
||
while [[ "$attempt" -le "$attempts" ]]; do
|
||
if curl -fsS "$url" >/dev/null 2>&1; then
|
||
ctms_ok "$label 已就绪"
|
||
return 0
|
||
fi
|
||
sleep 2
|
||
attempt=$(( attempt + 1 ))
|
||
done
|
||
ctms_fail "$label 未在预期时间内就绪: $url"
|
||
}
|
||
|
||
main() {
|
||
cd "$CTMS_ROOT_DIR"
|
||
ctms_require_docker_compose
|
||
ctms_require_command curl "macOS 通常已预装;Linux 可执行 apt-get install curl" \
|
||
|| ctms_fail "缺少 curl,无法执行启动健康检查"
|
||
|
||
ctms_step "准备 ONLYOFFICE 开发环境"
|
||
prepare_onlyoffice_environment
|
||
|
||
local -a compose=(
|
||
docker compose
|
||
-f "$CTMS_ROOT_DIR/docker-compose.dev.yaml"
|
||
-p ctms_dev
|
||
)
|
||
|
||
ctms_step "校验开发 Compose 配置"
|
||
"${compose[@]}" config --quiet
|
||
ctms_ok "Compose 配置有效"
|
||
|
||
ctms_step "重新构建并启动标准 ONLYOFFICE 服务"
|
||
"${compose[@]}" up -d --build --force-recreate backend onlyoffice nginx
|
||
|
||
ctms_step "验证运行状态"
|
||
wait_for_url "CTMS 后端" "http://127.0.0.1:8888/readyz" 60
|
||
wait_for_url "ONLYOFFICE Document Server" "http://127.0.0.1:8888/onlyoffice/healthcheck" 120
|
||
"${compose[@]}" exec -T backend python -c '
|
||
from app.core.config import settings
|
||
from app.main import app
|
||
|
||
paths = {route.path for route in app.routes}
|
||
required = {
|
||
"/api/v1/onlyoffice/attachments/{attachment_id}/config",
|
||
"/api/v1/onlyoffice/versions/{version_id}/config",
|
||
"/api/v1/studies/{study_id}/collaboration/files/{file_id}/editor-config",
|
||
"/api/v1/studies/{study_id}/collaboration/files/{file_id}/share-link",
|
||
"/api/v1/collaboration/shares/metadata",
|
||
"/api/v1/collaboration/shares/access",
|
||
"/api/v1/collaboration/shares/editor-config",
|
||
"/internal/onlyoffice/collaboration/sessions/{session_id}/content",
|
||
"/internal/onlyoffice/collaboration/sessions/{session_id}/callback",
|
||
}
|
||
if not settings.ONLYOFFICE_ENABLED:
|
||
raise SystemExit("ONLYOFFICE_ENABLED 未生效")
|
||
if len(settings.ONLYOFFICE_JWT_SECRET or "") < 32:
|
||
raise SystemExit("ONLYOFFICE_JWT_SECRET 未生效")
|
||
if not settings.ONLYOFFICE_INSTANCE_ID:
|
||
raise SystemExit("ONLYOFFICE_INSTANCE_ID 未生效")
|
||
missing = required - paths
|
||
if missing:
|
||
raise SystemExit(f"后端缺少 ONLYOFFICE 路由: {sorted(missing)}")
|
||
print("ONLYOFFICE backend configuration and routes are ready")
|
||
'
|
||
ctms_ok "ONLYOFFICE 开发预览环境启动完成"
|
||
}
|
||
|
||
main
|