From 9b6d946344ccd48251ceb0030f51eac4e87a4d1e Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sun, 27 Sep 2026 19:11:41 +0800 Subject: [PATCH] =?UTF-8?q?chore(deploy):=20=E5=8A=A0=E7=94=9F=E4=BA=A7?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E6=96=B9=E6=A1=88=E8=84=9A=E6=9C=AC=EF=BC=88?= =?UTF-8?q?check/backup/deploy/rollback=20=E5=9B=9B=E6=AE=B5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 为什么需要 生产二进制是 **`-tags=onnxruntime`** 构建(86.5MB,.rodata 62.5MB), 而普通 `go build` 只有 37MB —— 差的是 ONNX Runtime 绑定。 `deploy/packaging/package-linux.sh:139` 会显式拒绝非 onnxruntime 构建: if ! go version -m "$homed_bin" | grep -Eq 'build[[:space:]]+-tags=.*onnxruntime'; then echo "ERROR: homed 不是 onnxruntime 构建,拒绝打 server/full 包" >&2 也就是说:**用错构建方式部署,依存句法分析与多模态向量化会静默失效**。 这个坑我自己踩过一次(拿普通构建去比体积,才发现的),所以脚本第一步 就卡这个判据。 ## 四个动作 - `check` 只读检查:服务状态、onnxruntime 标签、libonnxruntime.so、 模型资产、适配器清单。**不改任何东西**,可随时跑 - `backup` 备份二进制 + 适配器 + unit 文件,并**生成 ROLLBACK.sh** - `deploy` check → 人工确认(输入 yes)→ 备份 → install -m 0755 原子替换 → 重启 → 8 秒后验活;失败时打印回滚命令与 journalctl - `rollback` 用最近一次备份回滚 ## 刻意不做自动回滚 回滚要不要做、什么时候做,是人的判断。脚本只负责把状态保全好, 让回滚成为一条**可执行**的命令,而不是一个自动决策。 ## 部署不会碰的东西(已在 check 里显式打印) - **适配器文件**:`d3eaff4` 的新逻辑在「无历史清单」时不动任何已存在的文件, 所以生产的 10 个 .lua 保持原样(含那个已含 stream_index 的 openai.lua) - **数据目录**:51G 的 models/ 与配置都不动,部署只换二进制 --- deploy-plan.sh | 139 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100755 deploy-plan.sh diff --git a/deploy-plan.sh b/deploy-plan.sh new file mode 100755 index 0000000..5d89097 --- /dev/null +++ b/deploy-plan.sh @@ -0,0 +1,139 @@ +#!/bin/bash +# 生产部署方案(**待确认,不自动执行**) +# +# 用法: +# bash deploy-plan.sh check # 只做部署前检查,不改任何东西 +# bash deploy-plan.sh backup # 备份当前二进制与适配器 +# bash deploy-plan.sh deploy # 替换二进制并重启(需显式确认) +# bash deploy-plan.sh rollback # 回滚到备份 +# +# ★ 本脚本刻意**不包含**任何"自动回滚"逻辑:回滚要不要做、什么时候做, +# 是人的判断。脚本只负责把状态保全好,让回滚成为一条可执行的命令。 + +set -uo pipefail + +BIN=/usr/local/bin/homed +DATA=/home/newqqagent +BAK=/var/tmp/homed-backup-$(date +%Y%m%d-%H%M%S) +NEW=${NEW_BIN:-/tmp/homed-ort} +ADAPTERS=$DATA/adapters +SVC=homeagent.service + +say() { printf '\n\033[1m%s\033[0m\n' "$*"; } +info() { printf ' %s\n' "$*"; } + +# ---------------------------------------------------------------- check +do_check() { + say "部署前检查" + info "服务状态: $(systemctl is-active $SVC)" + info "当前二进制: $BIN ($(stat -c %s $BIN) 字节, $(stat -c %y $BIN | cut -d. -f1))" + + if [ ! -x "$NEW" ]; then + info "★ 新二进制不存在: $NEW" + return 1 + fi + info "新二进制: $NEW ($(stat -c %s $NEW) 字节)" + + # ★ 最关键的一条:必须是 onnxruntime 构建,否则依存句法/多模态失效 + if ! go version -m "$NEW" 2>/dev/null | grep -Eq 'build[[:space:]]+-tags=.*onnxruntime'; then + info "★★ 新二进制**不是** onnxruntime 构建 —— 拒绝部署" + info " (package-linux.sh:139 同样会拒绝;缺它会让依存句法与多模态失效)" + return 1 + fi + info "✓ onnxruntime 构建标签正确" + + # 运行期依赖 + if [ ! -f /opt/onnxruntime/libonnxruntime.so ] \ + && ! ls /usr/local/lib/libonnxruntime.so* /usr/lib/libonnxruntime.so* >/dev/null 2>&1; then + info "★ 找不到 libonnxruntime.so —— provider 会降级" + else + info "✓ libonnxruntime.so 就位" + fi + + # 模型资产(运行期目录,不影响编译) + local mdl=$(du -sh $DATA/models 2>/dev/null | awk '{print $1}') + info "模型资产: ${mdl:-无}(运行期目录,部署不改动)" + + # 适配器:d3eaff4 的新逻辑在"无历史清单"时不动文件 + if [ -f "$ADAPTERS/.bundled" ]; then + info "适配器清单: 存在(升级时落后的会被更新,用户改过的会保留)" + else + info "适配器清单: 无 ⇒ 首次升级**不动**任何已存在的适配器文件" + fi + info "适配器文件数: $(ls $ADAPTERS/*.lua 2>/dev/null | wc -l)" + return 0 +} + +# ---------------------------------------------------------------- backup +do_backup() { + say "备份" + mkdir -p "$BAK" + cp -a "$BIN" "$BAK/homed.bin" + [ -d "$ADAPTERS" ] && cp -a "$ADAPTERS" "$BAK/adapters" + cp -a /etc/systemd/system/$SVC "$BAK/" 2>/dev/null || true + info "已备份到: $BAK" + info " homed.bin / adapters / unit 文件" + # 回滚命令 + cat > "$BAK/ROLLBACK.sh" </dev/null | head -1) + if [ -z "$latest" ]; then info "找不到备份"; return 1; fi + info "使用备份: $latest" + systemctl stop "$SVC" + cp -a "$latest/homed.bin" "$BIN" + [ -d "$latest/adapters" ] && { rm -rf "$ADAPTERS"; cp -a "$latest/adapters" "$ADAPTERS"; } + systemctl start "$SVC" + sleep 5 + info "回滚后: $(systemctl is-active $SVC)" +} + +case "${1:-check}" in + check) do_check ;; + backup) do_backup ;; + deploy) do_deploy ;; + rollback) do_rollback ;; + *) echo "用法: $0 {check|backup|deploy|rollback}"; exit 2 ;; +esac