修复 Server-Provision 按目标状态准备工具包
新增目标机已有 SpacetimeDB 与 otelcol-contrib 时复用本机安装的准备逻辑 补充 Prepare Provision Tools 传入 SPACETIME_ROOT,避免非默认路径检查错目录 新增 Server-Provision 工具准备回归检查脚本,防止已有工具时仍触发下载 更新开发运维文档与 Hermes 共享记忆,沉淀先检查目标机状态再准备文件的约定
This commit is contained in:
@@ -109,6 +109,7 @@
|
|||||||
|
|
||||||
- 背景:`Genarrative-Server-Provision` 的 `DEPLOY_TARGET=development` 语义是部署到 dev 服务器,不是构建机 dry-run。旧流水线把 development 映射到 `linux && genarrative-build`,还先在 build 节点准备 `provision-tools/` 再 stash 给后续阶段,导致真实 dev 初始化可能跑到 Jenkins controller / build 节点;脚本还安装 clang / lld / pkg-config / OpenSSL headers / sccache 等构建链依赖,超出了服务器初始化职责。
|
- 背景:`Genarrative-Server-Provision` 的 `DEPLOY_TARGET=development` 语义是部署到 dev 服务器,不是构建机 dry-run。旧流水线把 development 映射到 `linux && genarrative-build`,还先在 build 节点准备 `provision-tools/` 再 stash 给后续阶段,导致真实 dev 初始化可能跑到 Jenkins controller / build 节点;脚本还安装 clang / lld / pkg-config / OpenSSL headers / sccache 等构建链依赖,超出了服务器初始化职责。
|
||||||
- 决策:Server-Provision 只做服务器初始化,全程运行在目标部署 agent:development 使用 `linux && genarrative-dev-deploy`,release 使用 `linux && genarrative-release-deploy`。`Prepare Provision Tools` 与 `Provision Server` 在同一个目标 agent workspace 顺序执行,不再切到 `linux && genarrative-build`,不再 `stash/unstash` 工具包。`scripts/jenkins-server-provision.sh` 不再安装 clang / lld / pkg-config / libssl-dev / sccache;非 dry-run 仍要求目标 dev / release agent 具备 root 权限,因为 provision 会写 systemd、Nginx、`/etc` 和系统用户。Job 的 `Pipeline script from SCM` 与 Jenkinsfile 参数 `SOURCE_GIT_REMOTE_URL` 都必须使用本机路径或目标 agent 可访问的内网 Git 源,不允许公网 Git fallback。
|
- 决策:Server-Provision 只做服务器初始化,全程运行在目标部署 agent:development 使用 `linux && genarrative-dev-deploy`,release 使用 `linux && genarrative-release-deploy`。`Prepare Provision Tools` 与 `Provision Server` 在同一个目标 agent workspace 顺序执行,不再切到 `linux && genarrative-build`,不再 `stash/unstash` 工具包。`scripts/jenkins-server-provision.sh` 不再安装 clang / lld / pkg-config / libssl-dev / sccache;非 dry-run 仍要求目标 dev / release agent 具备 root 权限,因为 provision 会写 systemd、Nginx、`/etc` 和系统用户。Job 的 `Pipeline script from SCM` 与 Jenkinsfile 参数 `SOURCE_GIT_REMOTE_URL` 都必须使用本机路径或目标 agent 可访问的内网 Git 源,不允许公网 Git fallback。
|
||||||
|
- 追加决策(2026-06-10):`Prepare Provision Tools` 必须先读取目标机现状,再准备需要的文件。目标机 `/usr/local/bin/otelcol-contrib` 版本匹配 `OTELCOL_VERSION` 时直接复用;`${SPACETIME_ROOT}/bin/current/spacetimedb-cli` 和 `spacetimedb-standalone` 存在且 CLI 版本匹配 `SPACETIME_EXPECTED_VERSION` 或 `SPACETIME_DOWNLOAD_ROOT` 中的版本时,直接复用当前安装生成 `provision-tools/`。只有目标机缺失、不可执行或版本不匹配时,才消费 `PROVISION_DOWNLOADS_DIR` 中的本地包或进入下载分支。
|
||||||
- 影响范围:`jenkins/Jenkinsfile.production-server-provision`、`scripts/jenkins-server-provision.sh`、生产运维文档、Server-Provision 排障口径。
|
- 影响范围:`jenkins/Jenkinsfile.production-server-provision`、`scripts/jenkins-server-provision.sh`、生产运维文档、Server-Provision 排障口径。
|
||||||
- 验证方式:Jenkins 日志中 Server-Provision 的 `Prepare`、`Checkout Provision Files`、`Prepare Provision Tools` 和 `Provision Server` 都在目标 dev / release agent 上执行;日志不出现 `Running on Jenkins`、`linux && genarrative-build`、`stash 'server-provision-tools'`、`Git 主地址拉取失败...改用备用地址`、`https://git.genarrative.world/GenarrativeAI/Genarrative.git` 或构建依赖 / sccache 安装步骤;`bash -n scripts/jenkins-server-provision.sh` 和编码检查通过。
|
- 验证方式:Jenkins 日志中 Server-Provision 的 `Prepare`、`Checkout Provision Files`、`Prepare Provision Tools` 和 `Provision Server` 都在目标 dev / release agent 上执行;日志不出现 `Running on Jenkins`、`linux && genarrative-build`、`stash 'server-provision-tools'`、`Git 主地址拉取失败...改用备用地址`、`https://git.genarrative.world/GenarrativeAI/Genarrative.git` 或构建依赖 / sccache 安装步骤;`bash -n scripts/jenkins-server-provision.sh` 和编码检查通过。
|
||||||
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||||
|
|||||||
@@ -1314,6 +1314,14 @@
|
|||||||
- 验证:Jenkins 日志中 `Provision Target` 下的 `Prepare`、`Checkout Provision Files`、`Prepare Provision Tools` 和 `Provision Server` 都应运行在目标 dev / release agent;日志不应出现 `stash 'server-provision-tools'`、目标阶段 `unstash`、`Git 主地址拉取失败...改用备用地址` 或 `https://git.genarrative.world/GenarrativeAI/Genarrative.git`。
|
- 验证:Jenkins 日志中 `Provision Target` 下的 `Prepare`、`Checkout Provision Files`、`Prepare Provision Tools` 和 `Provision Server` 都应运行在目标 dev / release agent;日志不应出现 `stash 'server-provision-tools'`、目标阶段 `unstash`、`Git 主地址拉取失败...改用备用地址` 或 `https://git.genarrative.world/GenarrativeAI/Genarrative.git`。
|
||||||
- 关联:`jenkins/Jenkinsfile.production-server-provision`、`scripts/prepare-server-provision-tools.sh`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
- 关联:`jenkins/Jenkinsfile.production-server-provision`、`scripts/prepare-server-provision-tools.sh`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||||
|
|
||||||
|
## Server-Provision 不要无条件下载工具包
|
||||||
|
|
||||||
|
- 现象:目标 dev / release 机器已经安装正确版本的 SpacetimeDB 或 `otelcol-contrib`,但 `Prepare Provision Tools` 仍每次下载 release tarball,网络慢或 GitHub 不稳时会把服务器初始化卡在准备阶段。
|
||||||
|
- 原因:工具准备阶段如果只按“生成交付包”理解,会忽略它已经运行在目标部署 agent 上这一事实;此时目标机本地的 `/usr/local/bin/otelcol-contrib` 与 `${SPACETIME_ROOT}/bin/current` 就是可信状态源。
|
||||||
|
- 处理:`scripts/prepare-server-provision-tools.sh` 必须先检查目标机状态:`otelcol-contrib --version` 命中 `OTELCOL_VERSION` 时复制现有二进制;`spacetimedb-cli --version` 命中 `SPACETIME_EXPECTED_VERSION` 或 `SPACETIME_DOWNLOAD_ROOT` 推导出的版本且 standalone 同时存在时,复制 `${SPACETIME_ROOT}/bin` 并生成 wrapper。只有缺失、不可执行或版本不匹配时,才查 `PROVISION_DOWNLOADS_DIR` 或下载源。
|
||||||
|
- 验证:运行 `bash scripts/check-server-provision-tools.sh`;Jenkins 日志应先出现“检查目标机 ...”,已有版本命中时出现“复用目标机已有 ...”,且不出现“下载 ...”。
|
||||||
|
- 关联:`scripts/prepare-server-provision-tools.sh`、`jenkins/Jenkinsfile.production-server-provision`、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||||
|
|
||||||
## 个人任务 scope 不得扩成 work/site/module
|
## 个人任务 scope 不得扩成 work/site/module
|
||||||
|
|
||||||
- 现象:个人任务配置为 `work` / `site` / `module` 后进度串桶或静默按 0 处理。
|
- 现象:个人任务配置为 `work` / `site` / `module` 后进度串桶或静默按 0 处理。
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ dev 服务器上的 Gitea 内网入口固定为 `http://10.2.0.10/GenarrativeAI/
|
|||||||
- `GENARRATIVE_API_MAX_CONCURRENT_REQUESTS=512` 开启应用内 HTTP 并发背压;`GENARRATIVE_API_GALLERY_MAX_CONCURRENT_REQUESTS=320`、`GENARRATIVE_API_DETAIL_MAX_CONCURRENT_REQUESTS=64`、`GENARRATIVE_API_ADMIN_MAX_CONCURRENT_REQUESTS=16` 分别限制公开列表、公开详情和后台 API 热路径。超过许可时直接返回 `429 Too Many Requests` 和 `Retry-After: 1`,`/healthz` 与 `/readyz` 不受该限制。这些值不是 RPS 限速;如果压测中 429 上升但内存和 p95 收敛,说明背压正在保护进程。直连 `api-server` 的极高 RPS 压测若出现 `connection refused`,通常已经打到 TCP 监听 / accept 层,应同时检查 backlog、Nginx upstream keepalive 和前置限流。
|
- `GENARRATIVE_API_MAX_CONCURRENT_REQUESTS=512` 开启应用内 HTTP 并发背压;`GENARRATIVE_API_GALLERY_MAX_CONCURRENT_REQUESTS=320`、`GENARRATIVE_API_DETAIL_MAX_CONCURRENT_REQUESTS=64`、`GENARRATIVE_API_ADMIN_MAX_CONCURRENT_REQUESTS=16` 分别限制公开列表、公开详情和后台 API 热路径。超过许可时直接返回 `429 Too Many Requests` 和 `Retry-After: 1`,`/healthz` 与 `/readyz` 不受该限制。这些值不是 RPS 限速;如果压测中 429 上升但内存和 p95 收敛,说明背压正在保护进程。直连 `api-server` 的极高 RPS 压测若出现 `connection refused`,通常已经打到 TCP 监听 / accept 层,应同时检查 backlog、Nginx upstream keepalive 和前置限流。
|
||||||
- `api-server` 正常运行时 `/healthz` 返回进程存活状态,`/readyz` 返回是否仍接收新流量;收到 `SIGINT` / `SIGTERM` 后会先把 readiness 标记为不可用,再让 Axum 停止接新连接并等待已有 HTTP 请求排空。systemd 仍以 `KillSignal=SIGINT` 停服务,`TimeoutStopSec=90` 作为长请求排空上限。
|
- `api-server` 正常运行时 `/healthz` 返回进程存活状态,`/readyz` 返回是否仍接收新流量;收到 `SIGINT` / `SIGTERM` 后会先把 readiness 标记为不可用,再让 Axum 停止接新连接并等待已有 HTTP 请求排空。systemd 仍以 `KillSignal=SIGINT` 停服务,`TimeoutStopSec=90` 作为长请求排空上限。
|
||||||
- `genarrative-api.service` 设置 `LimitNOFILE=65535`、`TasksMax=2048`;上线后用 `systemctl show genarrative-api.service -p LimitNOFILE -p TasksMax -p TimeoutStopUSec` 和 `cat /proc/$(pidof api-server)/limits` 核对。
|
- `genarrative-api.service` 设置 `LimitNOFILE=65535`、`TasksMax=2048`;上线后用 `systemctl show genarrative-api.service -p LimitNOFILE -p TasksMax -p TimeoutStopUSec` 和 `cat /proc/$(pidof api-server)/limits` 核对。
|
||||||
- Server provision 不再通过 Windows helper 下载,也不再通过 Linux build 节点中转工具包。`Prepare Provision Tools` 在目标 dev / release agent 工作区内准备 SpacetimeDB `2.4.1` 的 `spacetime-x86_64-unknown-linux-gnu.tar.gz` 和 `otelcol-contrib_0.151.0_linux_amd64.tar.gz` 并生成 `provision-tools/`;如果目标服务器下载需要代理,在 `PROVISION_DOWNLOAD_PROXY` 配置目标机可访问的 HTTP 代理。
|
- Server provision 不再通过 Windows helper 下载,也不再通过 Linux build 节点中转工具包。`Prepare Provision Tools` 在目标 dev / release agent 工作区内先检查 `/usr/local/bin/otelcol-contrib` 与 `${SPACETIME_ROOT}/bin/current`:版本已满足时直接复用目标机现有文件生成 `provision-tools/`,只有缺失或版本不匹配时才使用 `PROVISION_DOWNLOADS_DIR` 里的本地包或从配置的下载源准备 SpacetimeDB `2.4.1` / `otelcol-contrib 0.151.0`;如果目标服务器下载需要代理,在 `PROVISION_DOWNLOAD_PROXY` 配置目标机可访问的 HTTP 代理。
|
||||||
- 除 `Genarrative-Server-Provision` 外,`Genarrative-Stdb-Module-Build`、`Genarrative-Web-Build`、`Genarrative-Api-Build`、`Genarrative-*Deploy`、`Genarrative-Database-Import/Export`、`Genarrative-Full-Build-And-Deploy` 和 `Genarrative-Notify-Email` 的生产流水线现都以 Linux agent 为主,仍按各自 Jenkinsfile 的 checkout 口径执行。Server provision 不使用公网备用 Git 源。
|
- 除 `Genarrative-Server-Provision` 外,`Genarrative-Stdb-Module-Build`、`Genarrative-Web-Build`、`Genarrative-Api-Build`、`Genarrative-*Deploy`、`Genarrative-Database-Import/Export`、`Genarrative-Full-Build-And-Deploy` 和 `Genarrative-Notify-Email` 的生产流水线现都以 Linux agent 为主,仍按各自 Jenkinsfile 的 checkout 口径执行。Server provision 不使用公网备用 Git 源。
|
||||||
- `otelcol-contrib.service` 作为可选系统服务加入 provision,默认监听 `127.0.0.1:4317/4318` 并使用 `deploy/otelcol/genarrative-debug.yaml`。api-server 是否发送 OTLP 仍由 `GENARRATIVE_OTEL_ENABLED` 控制,服务 unit 见 `deploy/systemd/otelcol-contrib.service`。
|
- `otelcol-contrib.service` 作为可选系统服务加入 provision,默认监听 `127.0.0.1:4317/4318` 并使用 `deploy/otelcol/genarrative-debug.yaml`。api-server 是否发送 OTLP 仍由 `GENARRATIVE_OTEL_ENABLED` 控制,服务 unit 见 `deploy/systemd/otelcol-contrib.service`。
|
||||||
- Nginx `/api/` 与 `/admin/api/` 通过 `genarrative_api` upstream 代理到 `127.0.0.1:8082`,upstream keepalive 为 64;`limit_conn` 负责连接 / 并发保护,`limit_req` 负责入口 RPS 快拒绝。当前模板把公开 gallery list 单独放到 `genarrative_gallery_rps`,默认 `rate=5000r/s`、`burst=4096`、`limit_conn=320`;公开详情和普通 API 放到 `genarrative_api_rps`,后台 API 放到 `genarrative_admin_rps`。通用 `/api` location 设置 `client_max_body_size 64m` 是反代兜底,防止拼图入口页 / 新增关卡本地参考图 Data URL 或旧兼容请求在到达 `api-server` 前被默认 1 MiB 上限拦截;拼图本地参考图前后端统一限制 6MB,历史图片仍提交 `referenceImageAssetObjectId(s)`。若线上出现 `413 Request Entity Too Large` 且 access log 中 `request_time=0.000`、`upstream_status=-`,说明请求在 Nginx 层被拦截,先用 `nginx -T | grep client_max_body_size` 检查 release 模板是否已渲染并 reload,同时检查前端是否超出 6MB 或错误提交了未压缩大图。`limit_conn_status 429` 和 `limit_req_status 429` 必须在 HTTP 与 HTTPS server 中同时生效;若线上压测看到 `limiting connections by zone "genarrative_api_conn"` 却返回 503,优先检查 `nginx -T` 里 HTTPS server 是否缺少这些状态码,以及 `/api/runtime/puzzle/gallery` 是否误落到通用 `location ~ ^/api` 的 `limit_conn=64`。压测时看 `/var/log/nginx/genarrative.access.log` 中的 `request_time`、`upstream_connect_time`、`upstream_header_time`、`upstream_response_time`、`upstream_status`、`request_id`。
|
- Nginx `/api/` 与 `/admin/api/` 通过 `genarrative_api` upstream 代理到 `127.0.0.1:8082`,upstream keepalive 为 64;`limit_conn` 负责连接 / 并发保护,`limit_req` 负责入口 RPS 快拒绝。当前模板把公开 gallery list 单独放到 `genarrative_gallery_rps`,默认 `rate=5000r/s`、`burst=4096`、`limit_conn=320`;公开详情和普通 API 放到 `genarrative_api_rps`,后台 API 放到 `genarrative_admin_rps`。通用 `/api` location 设置 `client_max_body_size 64m` 是反代兜底,防止拼图入口页 / 新增关卡本地参考图 Data URL 或旧兼容请求在到达 `api-server` 前被默认 1 MiB 上限拦截;拼图本地参考图前后端统一限制 6MB,历史图片仍提交 `referenceImageAssetObjectId(s)`。若线上出现 `413 Request Entity Too Large` 且 access log 中 `request_time=0.000`、`upstream_status=-`,说明请求在 Nginx 层被拦截,先用 `nginx -T | grep client_max_body_size` 检查 release 模板是否已渲染并 reload,同时检查前端是否超出 6MB 或错误提交了未压缩大图。`limit_conn_status 429` 和 `limit_req_status 429` 必须在 HTTP 与 HTTPS server 中同时生效;若线上压测看到 `limiting connections by zone "genarrative_api_conn"` 却返回 503,优先检查 `nginx -T` 里 HTTPS server 是否缺少这些状态码,以及 `/api/runtime/puzzle/gallery` 是否误落到通用 `location ~ ^/api` 的 `limit_conn=64`。压测时看 `/var/log/nginx/genarrative.access.log` 中的 `request_time`、`upstream_connect_time`、`upstream_header_time`、`upstream_response_time`、`upstream_status`、`request_id`。
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ BASH
|
|||||||
PROVISION_DOWNLOAD_PROXY="${PROVISION_DOWNLOAD_PROXY:-}" \
|
PROVISION_DOWNLOAD_PROXY="${PROVISION_DOWNLOAD_PROXY:-}" \
|
||||||
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.4.1}" \
|
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.4.1}" \
|
||||||
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}" \
|
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}" \
|
||||||
|
SPACETIME_ROOT="${SPACETIME_ROOT:-/stdb}" \
|
||||||
scripts/prepare-server-provision-tools.sh
|
scripts/prepare-server-provision-tools.sh
|
||||||
'
|
'
|
||||||
'''
|
'''
|
||||||
|
|||||||
86
scripts/check-server-provision-tools.sh
Executable file
86
scripts/check-server-provision-tools.sh
Executable file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
TMP_ROOT="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "${TMP_ROOT}"' EXIT
|
||||||
|
|
||||||
|
WORK_DIR="${TMP_ROOT}/workspace"
|
||||||
|
FAKE_BIN_DIR="${TMP_ROOT}/fake-bin"
|
||||||
|
TARGET_BIN_DIR="${TMP_ROOT}/target-bin"
|
||||||
|
SPACETIME_ROOT_DIR="${TMP_ROOT}/stdb"
|
||||||
|
OUTPUT_LOG="${TMP_ROOT}/prepare.log"
|
||||||
|
|
||||||
|
mkdir -p \
|
||||||
|
"${WORK_DIR}" \
|
||||||
|
"${FAKE_BIN_DIR}" \
|
||||||
|
"${TARGET_BIN_DIR}" \
|
||||||
|
"${SPACETIME_ROOT_DIR}/bin/current"
|
||||||
|
|
||||||
|
cat >"${FAKE_BIN_DIR}/curl" <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "curl should not be called when target tools are already ready" >&2
|
||||||
|
exit 97
|
||||||
|
EOF
|
||||||
|
cat >"${FAKE_BIN_DIR}/wget" <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "wget should not be called when target tools are already ready" >&2
|
||||||
|
exit 97
|
||||||
|
EOF
|
||||||
|
chmod +x "${FAKE_BIN_DIR}/curl" "${FAKE_BIN_DIR}/wget"
|
||||||
|
|
||||||
|
cat >"${TARGET_BIN_DIR}/otelcol-contrib" <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "otelcol-contrib version 0.151.0"
|
||||||
|
EOF
|
||||||
|
chmod +x "${TARGET_BIN_DIR}/otelcol-contrib"
|
||||||
|
|
||||||
|
cat >"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-cli" <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "spacetimedb-cli 2.4.1"
|
||||||
|
EOF
|
||||||
|
cat >"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-standalone" <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "spacetimedb-standalone 2.4.1"
|
||||||
|
EOF
|
||||||
|
chmod +x \
|
||||||
|
"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-cli" \
|
||||||
|
"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-standalone"
|
||||||
|
|
||||||
|
if ! (
|
||||||
|
cd "${WORK_DIR}"
|
||||||
|
PATH="${FAKE_BIN_DIR}:${PATH}" \
|
||||||
|
WORKSPACE="${WORK_DIR}" \
|
||||||
|
PROVISION_TOOLS_DIR="provision-tools" \
|
||||||
|
PROVISION_DOWNLOADS_DIR="downloads" \
|
||||||
|
PROVISION_TOOLS_TMP_PARENT="${WORK_DIR}/.tmp/server-provision-tools" \
|
||||||
|
PROVISION_REQUIRE_LOCAL_DOWNLOADS="true" \
|
||||||
|
OTELCOL_TARGET_BIN="${TARGET_BIN_DIR}/otelcol-contrib" \
|
||||||
|
OTELCOL_VERSION="0.151.0" \
|
||||||
|
SPACETIME_ROOT="${SPACETIME_ROOT_DIR}" \
|
||||||
|
SPACETIME_EXPECTED_VERSION="2.4.1" \
|
||||||
|
"${REPO_ROOT}/scripts/prepare-server-provision-tools.sh" \
|
||||||
|
>"${OUTPUT_LOG}" 2>&1
|
||||||
|
); then
|
||||||
|
echo "[check-server-provision-tools] prepare-server-provision-tools.sh 执行失败。" >&2
|
||||||
|
cat "${OUTPUT_LOG}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
grep -q "复用目标机已有 otelcol-contrib" "${OUTPUT_LOG}"
|
||||||
|
grep -q "复用目标机已有 SpacetimeDB 安装" "${OUTPUT_LOG}"
|
||||||
|
grep -q "otelcol-contrib 0.151.0 target existing" "${WORK_DIR}/provision-tools/MANIFEST.txt"
|
||||||
|
grep -q "spacetime target existing" "${WORK_DIR}/provision-tools/MANIFEST.txt"
|
||||||
|
|
||||||
|
test -x "${WORK_DIR}/provision-tools/otelcol-contrib"
|
||||||
|
test -x "${WORK_DIR}/provision-tools/spacetime/spacetime"
|
||||||
|
test -x "${WORK_DIR}/provision-tools/spacetime/bin/current/spacetimedb-cli"
|
||||||
|
test -x "${WORK_DIR}/provision-tools/spacetime/bin/current/spacetimedb-standalone"
|
||||||
|
|
||||||
|
if grep -q "下载 " "${OUTPUT_LOG}"; then
|
||||||
|
echo "[check-server-provision-tools] 已有目标机工具时不应进入下载分支。" >&2
|
||||||
|
cat "${OUTPUT_LOG}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[check-server-provision-tools] OK"
|
||||||
@@ -7,9 +7,12 @@ OTELCOL_VERSION="${OTELCOL_VERSION:-0.151.0}"
|
|||||||
PREPARE_OTELCOL="${PREPARE_OTELCOL:-${ENABLE_OTELCOL:-true}}"
|
PREPARE_OTELCOL="${PREPARE_OTELCOL:-${ENABLE_OTELCOL:-true}}"
|
||||||
OTELCOL_DOWNLOAD_ROOT="${OTELCOL_DOWNLOAD_ROOT:-https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download}"
|
OTELCOL_DOWNLOAD_ROOT="${OTELCOL_DOWNLOAD_ROOT:-https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download}"
|
||||||
OTELCOL_ARCHIVE_PATH="${OTELCOL_ARCHIVE_PATH:-}"
|
OTELCOL_ARCHIVE_PATH="${OTELCOL_ARCHIVE_PATH:-}"
|
||||||
|
OTELCOL_TARGET_BIN="${OTELCOL_TARGET_BIN:-/usr/local/bin/otelcol-contrib}"
|
||||||
SPACETIME_INSTALLER_URL="${SPACETIME_INSTALLER_URL:-https://install.spacetimedb.com}"
|
SPACETIME_INSTALLER_URL="${SPACETIME_INSTALLER_URL:-https://install.spacetimedb.com}"
|
||||||
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.4.1}"
|
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.4.1}"
|
||||||
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}"
|
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}"
|
||||||
|
SPACETIME_ROOT="${SPACETIME_ROOT:-/stdb}"
|
||||||
|
SPACETIME_EXPECTED_VERSION="${SPACETIME_EXPECTED_VERSION:-}"
|
||||||
SPACETIME_ARCHIVE_PATH="${SPACETIME_ARCHIVE_PATH:-}"
|
SPACETIME_ARCHIVE_PATH="${SPACETIME_ARCHIVE_PATH:-}"
|
||||||
SPACETIME_INSTALLER_PATH="${SPACETIME_INSTALLER_PATH:-}"
|
SPACETIME_INSTALLER_PATH="${SPACETIME_INSTALLER_PATH:-}"
|
||||||
SPACETIME_UPDATE_INSTALLER_PATH="${SPACETIME_UPDATE_INSTALLER_PATH:-}"
|
SPACETIME_UPDATE_INSTALLER_PATH="${SPACETIME_UPDATE_INSTALLER_PATH:-}"
|
||||||
@@ -65,6 +68,60 @@ download_file() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolve_spacetime_expected_version() {
|
||||||
|
local download_root="${SPACETIME_DOWNLOAD_ROOT%/}"
|
||||||
|
|
||||||
|
if [[ -n "${SPACETIME_EXPECTED_VERSION}" ]]; then
|
||||||
|
printf "%s" "${SPACETIME_EXPECTED_VERSION}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${download_root}" =~ /v([0-9]+(\.[0-9]+){1,2})$ ]]; then
|
||||||
|
printf "%s" "${BASH_REMATCH[1]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
target_otelcol_ready() {
|
||||||
|
local version_output
|
||||||
|
|
||||||
|
echo "[prepare-provision-tools] 检查目标机 otelcol-contrib: ${OTELCOL_TARGET_BIN}"
|
||||||
|
if [[ ! -x "${OTELCOL_TARGET_BIN}" ]]; then
|
||||||
|
echo "[prepare-provision-tools] 目标机 otelcol-contrib 不存在或不可执行,将准备交付文件。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version_output="$("${OTELCOL_TARGET_BIN}" --version 2>/dev/null || true)"
|
||||||
|
if [[ -n "${OTELCOL_VERSION}" && "${version_output}" != *"${OTELCOL_VERSION}"* ]]; then
|
||||||
|
echo "[prepare-provision-tools] 目标机 otelcol-contrib 版本不匹配,期望 ${OTELCOL_VERSION},当前: ${version_output:-unknown}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[prepare-provision-tools] 目标机 otelcol-contrib 已满足要求: ${version_output:-version unknown}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
target_spacetime_ready() {
|
||||||
|
local target_cli="${SPACETIME_ROOT}/bin/current/spacetimedb-cli"
|
||||||
|
local target_standalone="${SPACETIME_ROOT}/bin/current/spacetimedb-standalone"
|
||||||
|
local expected_version version_output
|
||||||
|
|
||||||
|
echo "[prepare-provision-tools] 检查目标机 SpacetimeDB: ${SPACETIME_ROOT}/bin/current"
|
||||||
|
if [[ ! -x "${target_cli}" || ! -x "${target_standalone}" ]]; then
|
||||||
|
echo "[prepare-provision-tools] 目标机 SpacetimeDB current 目录不完整,将准备交付文件。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
expected_version="$(resolve_spacetime_expected_version)"
|
||||||
|
version_output="$("${target_cli}" --version 2>/dev/null || true)"
|
||||||
|
if [[ -n "${expected_version}" && "${version_output}" != *"${expected_version}"* ]]; then
|
||||||
|
echo "[prepare-provision-tools] 目标机 SpacetimeDB 版本不匹配,期望 ${expected_version},当前: ${version_output:-unknown}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[prepare-provision-tools] 目标机 SpacetimeDB 已满足要求: ${version_output:-version unknown}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
validate_relative_dir() {
|
validate_relative_dir() {
|
||||||
local label="$1"
|
local label="$1"
|
||||||
local path="$2"
|
local path="$2"
|
||||||
@@ -101,13 +158,21 @@ prepare_otelcol() {
|
|||||||
|
|
||||||
require_cmd tar
|
require_cmd tar
|
||||||
|
|
||||||
|
if target_otelcol_ready; then
|
||||||
|
echo "[prepare-provision-tools] 复用目标机已有 otelcol-contrib: ${OTELCOL_TARGET_BIN}"
|
||||||
|
install -m 0755 "${OTELCOL_TARGET_BIN}" "${target}"
|
||||||
|
"${target}" --version >/dev/null
|
||||||
|
OTELCOL_SOURCE_DESCRIPTION="target existing ${OTELCOL_TARGET_BIN}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -n "${OTELCOL_ARCHIVE_PATH}" && -f "${OTELCOL_ARCHIVE_PATH}" ]]; then
|
if [[ -n "${OTELCOL_ARCHIVE_PATH}" && -f "${OTELCOL_ARCHIVE_PATH}" ]]; then
|
||||||
source_archive="${OTELCOL_ARCHIVE_PATH}"
|
source_archive="${OTELCOL_ARCHIVE_PATH}"
|
||||||
elif [[ -n "${PROVISION_DOWNLOADS_DIR}" && -f "${downloaded_archive}" ]]; then
|
elif [[ -n "${PROVISION_DOWNLOADS_DIR}" && -f "${downloaded_archive}" ]]; then
|
||||||
source_archive="${downloaded_archive}"
|
source_archive="${downloaded_archive}"
|
||||||
fi
|
fi
|
||||||
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_archive}" ]]; then
|
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_archive}" ]]; then
|
||||||
echo "[prepare-provision-tools] 要求使用 Windows 已下载的 otelcol-contrib 包,但未找到: ${downloaded_archive}" >&2
|
echo "[prepare-provision-tools] 要求使用本地已有的 otelcol-contrib 来源,但目标机未满足且未找到下载包: ${downloaded_archive}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -146,6 +211,17 @@ prepare_spacetime() {
|
|||||||
local downloaded_installer="${PROVISION_DOWNLOADS_DIR}/spacetime-install.sh"
|
local downloaded_installer="${PROVISION_DOWNLOADS_DIR}/spacetime-install.sh"
|
||||||
local source_installer=""
|
local source_installer=""
|
||||||
|
|
||||||
|
if target_spacetime_ready; then
|
||||||
|
echo "[prepare-provision-tools] 复用目标机已有 SpacetimeDB 安装: ${SPACETIME_ROOT}/bin/current"
|
||||||
|
mkdir -p "${target_dir}"
|
||||||
|
cp -a "${SPACETIME_ROOT}/bin" "${target_dir}/bin"
|
||||||
|
chmod 0755 "${target_dir}/bin/current/spacetimedb-cli" "${target_dir}/bin/current/spacetimedb-standalone"
|
||||||
|
make_spacetime_wrapper "${target_dir}/spacetime"
|
||||||
|
"${target_dir}/spacetime" --version >/dev/null
|
||||||
|
SPACETIME_SOURCE_DESCRIPTION="target existing ${SPACETIME_ROOT}/bin/current"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p "${install_root}"
|
mkdir -p "${install_root}"
|
||||||
if [[ -n "${SPACETIME_ARCHIVE_PATH}" && -f "${SPACETIME_ARCHIVE_PATH}" ]]; then
|
if [[ -n "${SPACETIME_ARCHIVE_PATH}" && -f "${SPACETIME_ARCHIVE_PATH}" ]]; then
|
||||||
source_archive="${SPACETIME_ARCHIVE_PATH}"
|
source_archive="${SPACETIME_ARCHIVE_PATH}"
|
||||||
@@ -165,7 +241,7 @@ prepare_spacetime() {
|
|||||||
source_update="${downloaded_update}"
|
source_update="${downloaded_update}"
|
||||||
fi
|
fi
|
||||||
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_archive}" ]]; then
|
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_archive}" ]]; then
|
||||||
echo "[prepare-provision-tools] 要求使用 Windows 已下载的 SpacetimeDB release tarball,但未找到: ${downloaded_archive}" >&2
|
echo "[prepare-provision-tools] 要求使用本地已有的 SpacetimeDB release tarball,但目标机未满足且未找到下载包: ${downloaded_archive}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -185,7 +261,7 @@ prepare_spacetime() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_installer}" ]]; then
|
if [[ "${PROVISION_REQUIRE_LOCAL_DOWNLOADS}" == "true" && -z "${source_installer}" ]]; then
|
||||||
echo "[prepare-provision-tools] 要求使用 Windows 已下载的 SpacetimeDB 官方安装器脚本,但未找到: ${downloaded_installer}" >&2
|
echo "[prepare-provision-tools] 要求使用本地已有的 SpacetimeDB 官方安装器脚本,但未找到: ${downloaded_installer}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
elif [[ -n "${source_installer}" ]]; then
|
elif [[ -n "${source_installer}" ]]; then
|
||||||
echo "[prepare-provision-tools] 使用已下载的 SpacetimeDB 官方安装器脚本: ${source_installer}"
|
echo "[prepare-provision-tools] 使用已下载的 SpacetimeDB 官方安装器脚本: ${source_installer}"
|
||||||
|
|||||||
Reference in New Issue
Block a user