From a6a81b075502720377353b90fc680d8d7b26b37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=8B=A4=E6=B0=91?= Date: Tue, 19 May 2026 15:14:23 +0800 Subject: [PATCH] feat(deploy): generic deploy.sh with API-based tenant migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename deploy-szyx.sh → deploy.sh, remove all customer-specific branding - Migrate mode: prompt for pmk_ key, call public platform export API, pipe to private import API — no MySQL credentials needed - Remove bcrypt dependency (no longer used in script logic) - Update install.sh and verify.sh references Co-Authored-By: Claude Sonnet 4.6 --- install.sh | 2 +- scripts/{deploy-szyx.sh => deploy.sh} | 159 ++++++++++++-------------- scripts/verify.sh | 2 +- 3 files changed, 78 insertions(+), 85 deletions(-) rename scripts/{deploy-szyx.sh => deploy.sh} (87%) diff --git a/install.sh b/install.sh index aa87f98..784d82a 100755 --- a/install.sh +++ b/install.sh @@ -194,4 +194,4 @@ printf '\n%b 依赖安装完毕,即将进入交互式部署向导 ...%b\n\n' export DEPLOY_HOST cd "$INSTALL_DIR" -exec bash scripts/deploy-szyx.sh +exec bash scripts/deploy.sh diff --git a/scripts/deploy-szyx.sh b/scripts/deploy.sh similarity index 87% rename from scripts/deploy-szyx.sh rename to scripts/deploy.sh index 809dc46..1e2982d 100755 --- a/scripts/deploy-szyx.sh +++ b/scripts/deploy.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -# deploy-szyx.sh — 数字医信私有化一键部署脚本 +# deploy.sh — XuqmGroup 私有化一键部署脚本 # # 用途:在目标机器上完成以下全部步骤: # 0. 交互式选择租户初始化方式(新建 / 迁移)并收集必要信息 -# 1. 预检(Docker、Compose、python3-bcrypt、磁盘、端口) +# 1. 预检(Docker、Compose、磁盘、端口) # 2. 写入配置(.env / secrets.env / xuqm.env / bootstrap.env / nginx) # 3. 登录 ACR 镜像仓库 # 4. 启动基础设施容器(MySQL、Redis)并等待就绪 # 5. 拉取镜像并启动所有业务容器(base + im + push + update + license) # 6. Schema 扩展(is_default / deletable 列 + 删除保护触发器)+ 系统应用初始化 -# 7. 租户初始化(新建:验证 bootstrap 结果;迁移:执行 migrate-tenant.sh) +# 7. 租户初始化(新建:填写信息并验证;迁移:凭迁移密钥调用 API 导入) # 8. 运行一键验证脚本确认所有服务正常 # # 幂等性:可重复执行。已运行的容器不会被重建。 @@ -17,8 +17,7 @@ # # 前提: # - Docker 和 Docker Compose v2 已安装 -# - python3 和 python3-bcrypt 已安装(用于密码哈希和认证) -# - 迁移模式还需要 mysql 客户端 +# - python3 和 curl 已安装 # - 在 XuqmGroup-PrivateDeploy 仓库根目录下执行本脚本 # # 覆盖默认值(可通过环境变量传入): @@ -30,11 +29,9 @@ set -euo pipefail # --------------------------------------------------------------------------- -# 常量 — 数字医信专属配置 +# 常量 # --------------------------------------------------------------------------- -CUSTOMER_NAME="数字医信" -CUSTOMER_SHORT="szyx" # 镜像仓库 REGISTRY="crpi-n44qjpuucgjt8e8c.cn-beijing.personal.cr.aliyuncs.com/xuqmgroup" @@ -57,12 +54,8 @@ MYSQL_USERNAME="xuqm" # Redis(managed 模式) REDIS_PASSWORD="${REDIS_PASSWORD:-XuqmRedis@2026}" -# 源生产 MySQL(迁移模式的默认值,交互时可覆盖) -SRC_HOST="39.107.53.187" -SRC_PORT="3306" -SRC_USER="xuqm" -SRC_PASSWORD="Xuqm@2026" -SRC_DB="xuqm_tenant" +# 公有化平台地址(迁移时调用 export API) +PUBLIC_PLATFORM_URL="https://dev.xuqinmin.com" # --------------------------------------------------------------------------- # 内部变量 @@ -93,7 +86,7 @@ container_running() { cd "$ROOT_DIR" printf '\n\033[1;35m══════════════════════════════════════════════════\033[0m\n' -printf '\033[1;35m %s 私有化一键部署脚本(全量部署)\033[0m\n' "$CUSTOMER_NAME" +printf '\033[1;35m XuqmGroup 私有化一键部署脚本(全量部署)\033[0m\n' printf '\033[1;35m══════════════════════════════════════════════════\033[0m\n' printf ' 部署目录: %s\n' "$ROOT_DIR" printf ' 目标主机: %s\n' "$DEPLOY_HOST" @@ -106,15 +99,15 @@ printf ' 服务集: base + im + push + update + license\n\n' # --------------------------------------------------------------------------- command -v python3 >/dev/null 2>&1 || \ - fail "python3 未安装(租户密码哈希需要): apt install -y python3 python3-bcrypt" -python3 -c "import bcrypt" 2>/dev/null || \ - fail "python3-bcrypt 未安装: pip3 install bcrypt 或 apt install -y python3-bcrypt" + fail "python3 未安装: apt install -y python3" +command -v curl >/dev/null 2>&1 || \ + fail "curl 未安装: apt install -y curl" printf '\033[1;33m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m\n' printf '\033[1;33m 租户初始化方式\033[0m\n' printf '\033[1;33m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\033[0m\n' printf ' 1) 新建租户 — 填写租户信息,系统将为您创建全新账号\n' -printf ' 2) 迁移租户 — 从生产 MySQL 导入现有租户数据(需主账号认证)\n\n' +printf ' 2) 迁移租户 — 从公有平台导入现有租户数据(需迁移密钥)\n\n' DEPLOY_MODE="" while [ -z "$DEPLOY_MODE" ]; do @@ -165,49 +158,26 @@ if [ "$DEPLOY_MODE" = "new" ]; then else # ── 迁移模式:先收集 SRC 配置 + 认证,再继续后续步骤 ── - printf '\n ── 迁移源 MySQL 配置(回车使用默认值)──\n' - read -rp " 源 MySQL 主机 [${SRC_HOST}]: " _inp; [ -n "$_inp" ] && SRC_HOST="$_inp" - read -rp " 源 MySQL 端口 [${SRC_PORT}]: " _inp; [ -n "$_inp" ] && SRC_PORT="$_inp" - read -rp " 源 MySQL 用户 [${SRC_USER}]: " _inp; [ -n "$_inp" ] && SRC_USER="$_inp" - read -rsp " 源 MySQL 密码 [(隐藏,回车保留默认)]: " _inp; printf '\n'; [ -n "$_inp" ] && SRC_PASSWORD="$_inp" - read -rp " 源数据库名 [${SRC_DB}]: " _inp; [ -n "$_inp" ] && SRC_DB="$_inp" + # ── 迁移模式:获取迁移密钥 ── + printf '\n\033[1;33m 请先访问租户平台安全中心生成迁移密钥:\033[0m\n' + printf ' 地址: %s\n' "$PUBLIC_PLATFORM_URL" + printf ' 路径: 安全中心 → 私有化部署迁移 → 生成迁移密钥\n' + printf ' (密钥仅在生成时显示一次,请及时复制后回到此处)\n\n' - printf '\n ── 租户主账号认证 ──\n' - while [ -z "$DEPLOY_TENANT_EMAIL" ]; do - read -rp " 租户主账号邮箱: " DEPLOY_TENANT_EMAIL - printf '%s' "$DEPLOY_TENANT_EMAIL" | grep -qE '^[^@]+@[^@]+\.[^@]+$' || { - warn "邮箱格式不正确,请重新输入" - DEPLOY_TENANT_EMAIL="" + _MIGRATE_KEY="" + while [ -z "$_MIGRATE_KEY" ]; do + read -rsp " 请粘贴迁移密钥: " _MIGRATE_KEY; printf '\n' + [[ "$_MIGRATE_KEY" == pmk_* ]] || { + warn "密钥格式不正确(应以 pmk_ 开头),请重新输入" + _MIGRATE_KEY="" } done + ok "迁移密钥已接收" - read -rsp " 租户主账号密码(仅用于认证,不存储明文): " _MIGRATE_PASSWORD; printf '\n' - [ -n "$_MIGRATE_PASSWORD" ] || fail "密码不能为空" - - command -v mysql >/dev/null 2>&1 || \ - fail "迁移模式需要 mysql 客户端: apt install -y mysql-client" - - printf ' 正在连接生产 MySQL 进行身份认证 ...\n' - _SRC_HASH=$(MYSQL_PWD="$SRC_PASSWORD" mysql \ - -h "$SRC_HOST" -P "$SRC_PORT" -u "$SRC_USER" \ - --connect-timeout=10 "$SRC_DB" \ - -N -e "SELECT password FROM t_tenant WHERE email='${DEPLOY_TENANT_EMAIL}' AND type='MAIN' LIMIT 1" 2>/dev/null || true) - [ -n "$_SRC_HASH" ] || \ - fail "生产 MySQL 中未找到租户 ${DEPLOY_TENANT_EMAIL},或无法连接到 ${SRC_HOST}:${SRC_PORT}" - - _AUTH_OK=$(MIGRATE_PW="$_MIGRATE_PASSWORD" MIGRATE_HASH="$_SRC_HASH" python3 -c " -import bcrypt, os -pw = os.environ['MIGRATE_PW'].encode('utf-8') -h = os.environ['MIGRATE_HASH'].encode('utf-8') -print('ok' if bcrypt.checkpw(pw, h) else 'fail') -") - unset _MIGRATE_PASSWORD _SRC_HASH - [ "$_AUTH_OK" = "ok" ] || fail "密码认证失败,请确认主账号密码后重试" - ok "生产租户 ${DEPLOY_TENANT_EMAIL} 身份认证通过" - - DEPLOY_TENANT_USERNAME="$DEPLOY_TENANT_EMAIL" + DEPLOY_TENANT_EMAIL="migrate_placeholder@private.local" + DEPLOY_TENANT_USERNAME="migrate_placeholder" DEPLOY_TENANT_NICKNAME="" - _BOOTSTRAP_PASSWORD="change-me-on-first-login" + _BOOTSTRAP_PASSWORD="already-migrated-do-not-use" fi # --------------------------------------------------------------------------- @@ -239,12 +209,12 @@ done # --------------------------------------------------------------------------- # Step 2 — 写入配置 # --------------------------------------------------------------------------- -step "写入数字医信专属配置(全服务)" +step "写入配置(全服务)" # .env — 主配置文件,包含所有 profile cat > "$ROOT_DIR/.env" < "$ROOT_DIR/config/secrets.env" < "$ROOT_DIR/config/xuqm.env" </dev/null || echo 0)" if [ "${_EXIST_CNT:-0}" -ge 1 ]; then printf '\n \033[1;31m⚠ 警告:数据库中已存在租户数据!\033[0m\n' - printf ' 迁移操作将 \033[1;31m删除所有现有租户信息\033[0m(账号、应用、功能配置),\n' - printf ' 并替换为生产环境租户 \033[1m%s\033[0m 的数据。\n\n' "$DEPLOY_TENANT_EMAIL" + printf ' 迁移操作将 \033[1;31m删除所有现有租户信息\033[0m(账号、应用、功能配置)。\n\n' read -rp " 确认删除并继续迁移?请输入 yes: " _confirm [ "$_confirm" = "yes" ] || fail "操作已取消" fi - printf ' 连通性检查生产 MySQL %s ...\n' "$SRC_HOST" - MYSQL_PWD="$SRC_PASSWORD" mysql \ - -h "$SRC_HOST" -P "$SRC_PORT" -u "$SRC_USER" \ - --connect-timeout=10 "$SRC_DB" \ - -e "SELECT 1" >/dev/null 2>&1 \ - || fail "无法连接生产 MySQL ${SRC_HOST}:${SRC_PORT},请检查网络或凭据" - ok "生产 MySQL 连通" + printf ' 正在从公有平台导出租户数据 ...\n' + _EXPORT_BODY=$(python3 -c "import json, sys; print(json.dumps({'migrationKey': sys.argv[1]}))" "$_MIGRATE_KEY") + _EXPORT_RESP=$(curl -sf --max-time 30 -X POST \ + -H "Content-Type: application/json" \ + -d "$_EXPORT_BODY" \ + "${PUBLIC_PLATFORM_URL}/api/migrate/export") \ + || fail "导出失败:请确认迁移密钥有效且未过期(${PUBLIC_PLATFORM_URL})" - bash "$ROOT_DIR/scripts/migrate-tenant.sh" \ - --src-host "$SRC_HOST" \ - --src-port "$SRC_PORT" \ - --src-user "$SRC_USER" \ - --src-password "$SRC_PASSWORD" \ - --src-db "$SRC_DB" \ - --tenant "$DEPLOY_TENANT_EMAIL" + _EXPORT_DATA=$(printf '%s' "$_EXPORT_RESP" | python3 -c " +import json, sys +resp = json.load(sys.stdin) +code = resp.get('code', 0) +if code != 200: + sys.exit('导出失败: ' + resp.get('message', 'unknown error')) +print(json.dumps(resp['data'])) +") || fail "解析导出数据失败" + ok "租户数据已从公有平台导出" - # 迁移完成后更新 bootstrap.env,防止重启时重新创建占位租户 - cat > "$ROOT_DIR/config/tenant/bootstrap.env" < "$ROOT_DIR/config/tenant/bootstrap.env" <