From 670dfb0c7a1ad714b36a3ab486fbe8e2960522c3 Mon Sep 17 00:00:00 2001 From: Qiufeng Date: Tue, 4 Aug 2026 22:31:20 +0800 Subject: [PATCH] fix: preserve updater across systemd restart --- README.md | 22 +++++++++++----------- docs/online-install-and-update.md | 22 ++++++++++++---------- install.sh | 3 +++ tests/release-scripts.test.sh | 8 ++++++++ 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ae37d82..d399b61 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ PostgreSQL-only 正式构建: ```bash cd oa-backend -./gradlew clean bootJar -PreleaseVersion=0.3.6 -PproductionBuild=true +./gradlew clean bootJar -PreleaseVersion=0.3.7 -PproductionBuild=true ``` 正式 JAR 必须包含 PostgreSQL 驱动,并且不得包含 `sqlite-jdbc` 或 `hibernate-community-dialects`。 @@ -214,18 +214,18 @@ curl -fsSL https://git.example.com/awaioi/ERP/raw/branch/main/install.sh \ set -e tmp="$(mktemp)" trap 'rm -f -- "$tmp"' EXIT - curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.6/install.sh -o "$tmp" - printf '%s %s\n' '76917da519895bec815bb5492b12f0894e8cff26d6754cb9b2569b45e52ed83c' "$tmp" | sha256sum -c - + curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.7/install.sh -o "$tmp" + printf '%s %s\n' '88328b3086ece360d3c05d4a22bee06b03ed3639a454c1fe7b9c04b1da80a980' "$tmp" | sha256sum -c - sudo -E bash "$tmp" \ --gitea-url http://38.76.196.225:10099 \ --repository awaioi/ERP \ - --version 0.3.6 \ + --version 0.3.7 \ --public-url http://38.76.196.225:8091 \ --allow-insecure ) ``` -只有 `v0.3.6` Release 发布后这条命令才可下载安装包。固定 tag 和 SHA-256 只用于保护当前 HTTP 引导脚本不被传输途中篡改;Release 资产仍会继续执行 Ed25519 和 SHA-256 双重校验。HTTP 会暴露请求、Release 元数据和可能使用的访问令牌,不得作为长期生产方案。 +只有 `v0.3.7` Release 发布后这条命令才可下载安装包。固定 tag 和 SHA-256 只用于保护当前 HTTP 引导脚本不被传输途中篡改;Release 资产仍会继续执行 Ed25519 和 SHA-256 双重校验。HTTP 会暴露请求、Release 元数据和可能使用的访问令牌,不得作为长期生产方案。 ### 完整卸载后重装 @@ -236,7 +236,7 @@ curl -fsSL https://git.example.com/awaioi/ERP/raw/branch/main/install.sh \ set -e tmp="$(mktemp)" trap 'rm -f -- "$tmp"' EXIT - curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.6/uninstall.sh -o "$tmp" + curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.7/uninstall.sh -o "$tmp" printf '%s %s\n' '98c56fed2fd4d01874e4ab5a1a4f3ec42ec3e29b315ffd87385a95488d587546' "$tmp" | sha256sum -c - sudo -E bash "$tmp" --purge-database --yes ) @@ -301,13 +301,13 @@ location / { 4. 校验 `manifest.json` 中的版本、`database=postgresql` 和 `rollbackCompatible=true`。 5. 可选执行 `pg_dump`,将新版本写入独立目录。 6. 原子切换 `current` 符号链接,并停止旧 Java 进程。 -7. systemd/launchd 拉起新版本,更新助手等待新的 PID 和 `/api/oa/health`。 +7. systemd/launchd 拉起新版本,更新助手等待新的 PID 和 `/api/oa/health`;Linux unit 使用 `KillMode=process`,确保更新助手不会随旧 Java 进程一起被 systemd 清理。 8. 新版本不健康时切回上一链接,终止故障进程并再次验证旧版本健康状态。 同一安装目录使用操作系统文件锁,不能并发执行两个更新任务。也可以手工触发: ```bash -/opt/kaidi-erp/current/bin/erp-update install 0.3.6 +/opt/kaidi-erp/current/bin/erp-update install 0.3.7 ``` 应用回滚不等于数据库回滚。包含不可逆 Flyway 迁移的版本必须先保证旧应用仍兼容新结构,并建议在安装配置中启用: @@ -348,8 +348,8 @@ base64 < ~/.config/kaidi-erp/release-signing-key.pem | tr -d '\n' ```bash git switch main git pull --ff-only origin main -git tag -a v0.3.6 -m 'Kaidi ERP v0.3.6' -git push origin v0.3.6 +git tag -a v0.3.7 -m 'Kaidi ERP v0.3.7' +git push origin v0.3.7 ``` 发布完成后必须确认 Release 页面存在四个资产,并使用仓库中的 `distribution/release-public-key.pem` 验证签名。私钥与该公钥不匹配时打包脚本会直接失败。 @@ -358,7 +358,7 @@ git push origin v0.3.6 ```bash ERP_RELEASE_PRIVATE_KEY_FILE="$HOME/.config/kaidi-erp/release-signing-key.pem" \ - bash scripts/package-release.sh 0.3.6 + bash scripts/package-release.sh 0.3.7 ``` ## 配置参考 diff --git a/docs/online-install-and-update.md b/docs/online-install-and-update.md index 922efde..33f1a2d 100644 --- a/docs/online-install-and-update.md +++ b/docs/online-install-and-update.md @@ -24,11 +24,13 @@ Gitea Actions runner 需要预装 Java 17 或更高版本、Node.js/npm、Python base64 < ~/.config/kaidi-erp/release-signing-key.pem | tr -d '\n' ``` -发布稳定版本: +发布稳定版本(先确认发布提交已经同步到 `main` 和 `dev`): ```bash -git tag v0.3.6 -git push origin v0.3.6 +git switch main +git pull --ff-only origin main +git tag -a v0.3.7 -m 'Kaidi ERP v0.3.7' +git push origin v0.3.7 ``` ## 首次安装 @@ -52,17 +54,17 @@ Linux 生产服务要求主机使用 systemd;没有 systemd 的容器、WSL 当前 `http://38.76.196.225:10099` 仅用于开发测试,安装器必须同时传入 `--allow-insecure`。在没有 HTTPS 的情况下,必须从固定 tag 下载引导脚本并验证本版本记录的 SHA-256,禁止把可变的 `main` 分支脚本直接管道给 root。HTTP 仍会暴露请求、Release 元数据和 Gitea token,不应作为生产部署方式。 -当前 `v0.3.6` 安装命令: +当前 `v0.3.7` 安装命令: ```bash ( set -e tmp="$(mktemp)" trap 'rm -f -- "$tmp"' EXIT - curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.6/install.sh -o "$tmp" - printf '%s %s\n' '76917da519895bec815bb5492b12f0894e8cff26d6754cb9b2569b45e52ed83c' "$tmp" | sha256sum -c - + curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.7/install.sh -o "$tmp" + printf '%s %s\n' '88328b3086ece360d3c05d4a22bee06b03ed3639a454c1fe7b9c04b1da80a980' "$tmp" | sha256sum -c - sudo -E bash "$tmp" --gitea-url http://38.76.196.225:10099 \ - --repository awaioi/ERP --version 0.3.6 \ + --repository awaioi/ERP --version 0.3.7 \ --public-url http://38.76.196.225:8091 --allow-insecure ) ``` @@ -74,7 +76,7 @@ Linux 生产服务要求主机使用 systemd;没有 systemd 的容器、WSL set -e tmp="$(mktemp)" trap 'rm -f -- "$tmp"' EXIT - curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.6/uninstall.sh -o "$tmp" + curl -fsSL http://38.76.196.225:10099/awaioi/ERP/raw/tag/v0.3.7/uninstall.sh -o "$tmp" printf '%s %s\n' '98c56fed2fd4d01874e4ab5a1a4f3ec42ec3e29b315ffd87385a95488d587546' "$tmp" | sha256sum -c - sudo -E bash "$tmp" --purge-database --yes ) @@ -93,13 +95,13 @@ Linux 生产服务要求主机使用 systemd;没有 systemd 的容器、WSL 1. 下载正式归档、`SHA256SUMS` 和签名并验证 Ed25519/SHA-256;独立安装器资产只在首次安装使用。 2. 拒绝路径穿越、符号链接和结构不完整的安装包。 3. 可选执行 `pg_dump`,再写入独立版本目录。 -4. 原子切换 `current` 链接并终止旧进程,由 systemd 或 launchd 拉起新版本。 +4. 原子切换 `current` 链接并终止旧进程,由 systemd 或 launchd 拉起新版本;Linux unit 使用 `KillMode=process`,让更新助手继续执行健康检查和必要的回滚。 5. 等待健康检查;失败时切回上一版本并再次验证健康状态。 更新过程使用操作系统文件锁,同一安装目录同时只允许一个更新任务。手动触发可执行: ```bash -/opt/kaidi-erp/current/bin/erp-update install 0.3.6 +/opt/kaidi-erp/current/bin/erp-update install 0.3.7 ``` 在线更新依赖安装器注册的 systemd 或 launchd 服务来拉起新旧版本。使用 `--no-service` 时后台更新默认关闭;如由其他进程管理器接管,须先确认它会在 ERP 进程退出后自动重启,再手工启用 `OA_UPDATE_ENABLED=true`。健康检查默认最多等待 120 秒、每 2 秒轮询一次,可分别通过 `ERP_UPDATE_HEALTH_TIMEOUT_SECONDS` 和 `ERP_UPDATE_HEALTH_POLL_SECONDS` 调整。 diff --git a/install.sh b/install.sh index 6d9897d..fdb48d2 100755 --- a/install.sh +++ b/install.sh @@ -435,6 +435,8 @@ start_service() { fi if [[ "$PLATFORM" == "linux" ]]; then + # The updater shares this service cgroup and must outlive the Java process + # to verify the restarted release and roll back a failed health check. cat > /etc/systemd/system/kaidi-erp.service <