deploy: t_f57b8bbf root-fix deploy flow - unified deploy.sh + PartOf= coupling + post-deploy verify
scripts/deploy.sh: build go+rust -> install (not cp) -> stop/reload/start both -> verify (is-active, no (deleted) inode, running-binary checksum == this build, /health=200). --verify-only flag for check-only. make deploy points at this script (replaces stale /usr/local/bin system-level target). Counter-example: install stale sidecar -> service stays active + health=200 (silent pass) -> make deploy-verify exits non-zero (catches silent fault). PartOf=zhiyid.service drop-in on zhiyi-consolidate + ExecStartPre rm /tmp/zhiyi-ipc.sock; restarting zhiyid now restarts sidecar (ActiveEnterTimestamp updates). deploy/ dir aligned to reality and desensitized (3 plaintext keys removed). Key cleanup in git history is a separate track - this card does not touch history. ACs verified. go test internal/governance failures are pre-existing rename tests, unrelated (this card touches no go/ code).
This commit is contained in:
@@ -126,18 +126,20 @@ ci-eval:
|
||||
|
||||
# ─── 部署 ────────────────────────────────────────────
|
||||
|
||||
deploy: build-go
|
||||
sudo cp $(BINARY_GO) /usr/local/bin/zhiyid
|
||||
sudo cp deploy/zhiyid.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart zhiyid
|
||||
# 统一部署:构建两 + 装两 + 重启两 + 校验(scripts/deploy.sh,用户级 systemd)
|
||||
# 2026-10-08 t_f57b8bbf:替换旧的 /usr/local/bin 系统级过期目标(与实际用户级部署完全不符)
|
||||
# deploy.sh 内部完成全部(build+install+restart+verify),脚本可用 --verify-only 单跑校验
|
||||
deploy:
|
||||
./scripts/deploy.sh
|
||||
|
||||
deploy-rust: build-rust
|
||||
sudo cp $(BINARY_RUST) /usr/local/bin/zhiyi-consolidate
|
||||
sudo cp deploy/zhiyi-consolidate.service /etc/systemd/system/
|
||||
sudo cp deploy/zhiyi-consolidate.timer /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now zhiyi-consolidate.timer
|
||||
# 只跑校验(不构建/不安装/不重启)——反例测试/人工体检
|
||||
deploy-verify:
|
||||
./scripts/deploy.sh --verify-only
|
||||
|
||||
# ⚠️ 已废弃(2026-10-08 t_f57b8bbf):旧 oneshot+timer 设计残留,实际 sidecar 是 simple 常驻,
|
||||
# 由 zhiyid.service 的 Wants= + 其 PartOf= 生命周期耦合管理,不再单独装 timer/系统级 unit。
|
||||
deploy-rust:
|
||||
@echo "已废弃:sidecar 由 scripts/deploy.sh 统一部署(simple 常驻),勿用旧的 oneshot+timer 系统级目标"
|
||||
|
||||
deploy-nginx:
|
||||
sudo cp deploy/nginx-zhiyi.conf /etc/nginx/sites-enabled/zhiyi.conf
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
# 织忆 MemoryWeave Rust IPC Sidecar (zhiyi-consolidate) — 用户级 systemd unit 单一真相源(t_f57b8bbf 对齐)
|
||||
# 实际安装落点:~/.config/systemd/user/zhiyi-consolidate.service
|
||||
# 运行事实(勿与过期全局版混淆):
|
||||
# - 二进制 /home/muc/bin/zhiyi-consolidate(非 /usr/local/bin)
|
||||
# - 参数 --mode socket(非旧 --socket)
|
||||
# - 数据目录 /var/lib/memoryweave(非 .../lancedb 子目录)
|
||||
# - systemd 用户级;sidecar 是 simple 常驻(非旧的 oneshot+timer 设计)
|
||||
# - 生命周期 20-partof-zhiyid.conf drop-in 加 PartOf=zhiyid.service ⇒ 重启 zhiyid 时 sidecar 跟着重启
|
||||
# - ExecStartPre=-rm -f /tmp/zhiyi-ipc.sock 清理残留 socket(防 EADDRINUSE)
|
||||
# 其它 drop-in:10-malloc.conf / limit.conf(见 ~/.config/systemd/user/zhiyi-consolidate.service.d/)
|
||||
|
||||
[Unit]
|
||||
Description=ZhiYi Consolidation Engine (Rust LanceDB)
|
||||
Description=MemoryWeave Rust IPC Sidecar (zhiyi-consolidate)
|
||||
After=network.target
|
||||
PartOf=zhiyid.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=muc
|
||||
ExecStart=/usr/local/bin/zhiyi-consolidate --socket /tmp/zhiyi-ipc.sock --data-dir /var/lib/memoryweave/lancedb
|
||||
Environment="RUST_LOG=info"
|
||||
ExecStartPre=/bin/bash -c 'if [ ! -f /home/muc/bin/zhiyi-consolidate ]; then cp /tmp/memoryweave/rust/target/release/zhiyi-consolidate /home/muc/bin/ 2>/dev/null || true; fi'
|
||||
ExecStartPre=-rm -f /tmp/zhiyi-ipc.sock
|
||||
ExecStart=/home/muc/bin/zhiyi-consolidate --mode socket --socket /tmp/zhiyi-ipc.sock --data-dir /var/lib/memoryweave
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
# 2026-09-23:原为 append:/tmp/zhiyi-sidecar.log(无轮转 → 涨到 63M/95万行)
|
||||
# 改为 journald,由 systemd 统一管理与限额(journalctl -u zhiyi-consolidate)
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=zhiyi-consolidate
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=default.target
|
||||
+35
-22
@@ -1,31 +1,44 @@
|
||||
# 织忆 MemoryWeave Go Daemon — 用户级 systemd unit 单一真相源(t_f57b8bbf 对齐)
|
||||
# 实际安装落点:~/.config/systemd/user/zhiyid.service(本文件是仓库内的脱敏母版,安装/比对用)
|
||||
#
|
||||
# ⚠️ 脱敏说明:仓库历史里曾含 3 个明文密钥(API_KEY / MOLIFANG_API_KEY / LLM_API_KEY),
|
||||
# 已随 git 推到 Gitea origin/main。本文件为脱敏版,不携带任何真实密钥;
|
||||
# 真实密钥/端点由运行环境注入。密钥清理属独立专项(本卡不碰 git 历史)。
|
||||
#
|
||||
# 运行事实(勿与过期全局版混淆):
|
||||
# - 二进制 /home/muc/bin/zhiyid-new(install 装,非 /usr/local/bin)
|
||||
# - systemd 用户级 ~/.config/systemd/user/(非 /etc/systemd/system 全局)
|
||||
# - 数据目录 /var/lib/memoryweave
|
||||
# - sidecar zhiyi-consolidate 是独立 unit,本 unit 用 Wants=(单向拉起)+ 其侧 PartOf= 回连重启
|
||||
# 构建产物 go/cmd/zhiyid/zhiyid(gitignored)→ install 到 /home/muc/bin/zhiyid-new
|
||||
|
||||
[Unit]
|
||||
Description=ZhiYi MemoryWeave Go Service (织忆)
|
||||
After=network.target redis-server.service
|
||||
Wants=redis-server.service
|
||||
Description=ZhiYi MemoryWeave (织忆) — Go Daemon
|
||||
Documentation=http://192.168.123.11:3000/xiaoxue_admin/memoryweave
|
||||
After=network.target zhiyi-consolidate.service bge-proxy.service
|
||||
Wants=zhiyi-consolidate.service bge-proxy.service
|
||||
# 2026-09-05 按需化: embedding 走 8000 bge-proxy(远端104优先→本地8001按需拉起)
|
||||
# 原 Wants bge-embed.service 已移除(本地 fallback 不常驻)
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=muc
|
||||
WorkingDirectory=/home/muc/projects/memoryweave/go
|
||||
Environment=PORT=7821
|
||||
Environment=STORAGE_BACKEND=lancedb
|
||||
Environment=SQLITE_PATH=/var/lib/memoryweave/memoryweave.db
|
||||
Environment=API_KEY=zhiyi-dev-key-2026
|
||||
Environment=VLLM_ENDPOINT=https://ai.gitee.com/v1/embeddings
|
||||
Environment=MOLIFANG_API_KEY=3TSVVXRFFECE4TISXHGE1VXDAXBIPAP6O1VPJK18
|
||||
Environment=LLM_ENDPOINT=http://127.0.0.1:3000/v1/chat/completions
|
||||
Environment=LLM_MODEL=qwen/qwen3.5-122b-a10b
|
||||
Environment=LLM_API_KEY=***REMOVED***
|
||||
# 2026-09-22 restore local rerank: point RERANK_ENDPOINT to local bge-embed service on 8001
|
||||
Environment=RERANK_ENDPOINT=http://127.0.0.1:8001
|
||||
Environment=GRAPH_PATH=/var/lib/memoryweave/graph.db
|
||||
ExecStartPre=/bin/mkdir -p /var/lib/memoryweave
|
||||
ExecStart=/usr/local/bin/zhiyid
|
||||
ExecStartPre=/bin/mkdir -p /var/lib/memoryweave /home/muc/.logs
|
||||
ExecStart=/home/muc/bin/zhiyid-new
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
MemoryMax=512M
|
||||
MemoryMax=2G
|
||||
CPUQuota=200%
|
||||
Environment=STORAGE_BACKEND=lancedb
|
||||
# 2026-09-14 distill 改走队列代理 8081(fail fast,避免打爆单槽)
|
||||
Environment=LLM_ENDPOINT=http://127.0.0.1:8081/v1/chat/completions
|
||||
Environment=LLM_MODEL=local/minicpm5-2b
|
||||
Environment=LLM_API_KEY=local-key
|
||||
# 2026-09-22 restore rerank: use local cosine reranker via bge-embed service on port 8001
|
||||
Environment=RERANK_ENDPOINT=http://127.0.0.1:8001
|
||||
# 以下按需 drop-in(~/.config/systemd/user/zhiyid.service.d/):
|
||||
# 20-obsidian-vault.conf → OBSIDIAN_VAULT=/home/muc/mc
|
||||
# bind-lan-vpn.conf → ZHIYI_BIND=0.0.0.0(ufw 收窄 LAN/VPN 两网段)
|
||||
# provenance-observe.conf → ZHIYI_COMMIT_PROVENANCE_OBSERVE=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=default.target
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
# 织忆 MemoryWeave 统一部署脚本 — build two + install two + restart two + verify
|
||||
# 2026-10-08 · t_f57b8bbf · 根治「重启 zhiyid 不重启 sidecar → Rust 改部署后 sidecar 跑旧二进制静默故障」事故
|
||||
#
|
||||
# 用法:
|
||||
# ./scripts/deploy.sh 完整部署: 构建两+装两+停两+启两+校验
|
||||
# ./scripts/deploy.sh --verify-only 只跑校验(不构建/不安装/不重启)—— 反例测试/人工体检用
|
||||
# make deploy = ./scripts/deploy.sh
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
BIN_DIR="${BIN_DIR:-/home/muc/bin}"
|
||||
|
||||
# 构建产物(持久路径,均已 gitignore)
|
||||
BUILD_GO="$REPO_DIR/go/cmd/zhiyid/zhiyid"
|
||||
BUILD_RUST="$REPO_DIR/rust/target/release/zhiyi-consolidate"
|
||||
# 安装落点(与 ~/.config/systemd/user/*.service 的 ExecStart 一致)
|
||||
INSTALL_GO="$BIN_DIR/zhiyid-new"
|
||||
INSTALL_RUST="$BIN_DIR/zhiyi-consolidate"
|
||||
# 服务名(用户级 systemd)
|
||||
SVC_GO="zhiyid.service"
|
||||
SVC_RUST="zhiyi-consolidate.service"
|
||||
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:7821/health}"
|
||||
|
||||
log() { printf '\033[1;34m[deploy]\033[0m %s\n' "$*"; }
|
||||
die() { printf '\033[1;31m[deploy:FAIL]\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
# 校验单个服务的运行态是否=本次构建的二进制
|
||||
# 判据优先级(纪律): 副作用(PID/inode/校验和) > 返回值 > 自报
|
||||
verify_service() {
|
||||
local name="$1" build_path="$2" pid exe run_sha build_sha
|
||||
# ① is-active
|
||||
[ "$(systemctl --user is-active "$name")" = "active" ] || die "$name 非 active"
|
||||
# ② 取 MainPID
|
||||
pid="$(systemctl --user show -p MainPID --value "$name")"
|
||||
[ -n "$pid" ] && [ "$pid" != "0" ] || die "$name: MainPID 为空/0"
|
||||
# ③ 进程 exe 不得指向已删除 inode(旧二进制被 install 覆盖后、进程仍跑旧 inode → readlink 含 "(deleted)")
|
||||
exe="$(readlink "/proc/$pid/exe" 2>/dev/null || true)"
|
||||
case "$exe" in
|
||||
"") die "$name: 无法 readlink /proc/$pid/exe" ;;
|
||||
*" (deleted)"*) die "$name: 进程仍跑已删除 inode → 二进制被换过但进程没重启 ($exe)" ;;
|
||||
esac
|
||||
# ④ 运行中二进制校验和 == 本次构建产物(抓「磁盘装了新版但进程仍跑旧版」静默故障)
|
||||
run_sha="$(sha256sum "/proc/$pid/exe" 2>/dev/null | awk '{print $1}')"
|
||||
build_sha="$(sha256sum "$build_path" 2>/dev/null | awk '{print $1}')"
|
||||
[ -n "$run_sha" ] || die "$name: 无法读取运行中二进制"
|
||||
[ "$run_sha" = "$build_sha" ] || die "$name: 运行中二进制 ≠ 本次构建产物 (运行=$run_sha 构建=$build_sha) → sidecar 静默跑旧版"
|
||||
log "✔ $name active · PID=$pid · exe=$exe · 校验和匹配本次构建"
|
||||
}
|
||||
|
||||
# 深健康检查: /health 连 sidecar 可达性(P0 已做,故障返 503)→ 期望 200
|
||||
verify_health() {
|
||||
local code
|
||||
code="$(curl -s -o /dev/null -w '%{http_code}' -m 5 "$HEALTH_URL")"
|
||||
[ "$code" = "200" ] || die "/health 返回 $code (期望 200) → zhiyid 或 sidecar 故障"
|
||||
log "✔ /health = $code"
|
||||
}
|
||||
|
||||
do_build() {
|
||||
log "构建 Go → $BUILD_GO"
|
||||
( cd "$REPO_DIR/go" && CGO_ENABLED=1 go build -o cmd/zhiyid/zhiyid ./cmd/zhiyid )
|
||||
log "构建 Rust → $BUILD_RUST"
|
||||
( cd "$REPO_DIR/rust" && cargo build --release )
|
||||
}
|
||||
|
||||
do_install() {
|
||||
log "停止 $SVC_GO + $SVC_RUST"
|
||||
systemctl --user stop "$SVC_GO" || true
|
||||
systemctl --user stop "$SVC_RUST" || true
|
||||
# 用 install 而非 cp:install 先写临时再 rename,避免 Text file busy(进程占着旧 inode 时 cp 会 EBUSY)
|
||||
log "install 二进制(不用 cp,避免 Text file busy)"
|
||||
install -m 0755 "$BUILD_GO" "$INSTALL_GO"
|
||||
install -m 0755 "$BUILD_RUST" "$INSTALL_RUST"
|
||||
log "daemon-reload"
|
||||
systemctl --user daemon-reload
|
||||
log "启动 $SVC_GO + $SVC_RUST"
|
||||
systemctl --user start "$SVC_GO"
|
||||
systemctl --user start "$SVC_RUST"
|
||||
sleep 2
|
||||
}
|
||||
|
||||
do_verify() {
|
||||
log "校验 ..."
|
||||
verify_service "$SVC_GO" "$BUILD_GO"
|
||||
verify_service "$SVC_RUST" "$BUILD_RUST"
|
||||
verify_health
|
||||
log "✅ 部署成功: 两服务 active · 进程无 (deleted) · 运行二进制=本次构建 · /health=200"
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "--verify-only" ]; then
|
||||
do_verify
|
||||
exit 0
|
||||
fi
|
||||
|
||||
do_build
|
||||
do_install
|
||||
do_verify
|
||||
Reference in New Issue
Block a user