mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-15 12:15:16 +00:00
★ 上一轮清理被合并覆盖:GUI 分支含 DESKTOP-PET-NOTES.md /
SERVER-HANDOFF.md / GUI-PLAN.md,合并时取了我方版本,
但我方 main 已是 squash 产物 ⇒ 三个文件复活。
而我当时只核对了 benchmark.md 一个就宣布成功 —— 判断依据不足。
本轮逐个文件验证(不再抽样)。
删除(零代码引用)
DESKTOP-PET-NOTES.md 外部产品(Coopanion)拆解笔记
SERVER-HANDOFF.md 给服务端的待办清单,已过时
napcat-design-dna.json 设计 DNA 数据
tmp_jinabench.py 临时脚本
tmp_benchmark/ 临时跑分程序
归位(不是删)
plan.md → docs/zh/legacy-issues.md (遗留问题清单,有价值)
GUI-PLAN.md → cmd/gui/GUI-PLAN.md (含坐标换算/koffi 踩坑)
根目录那份与 cmd/gui/ 已有副本字节相同(285b84dd…),删前者
deploy-plan.sh → deploy/scripts/
deploy-waiter.sh → deploy/scripts/
deploy-sdk-site.sh → deploy/scripts/
脱敏(deploy-plan.sh 与 deploy-sdk-site.sh 含本机路径)
/home/newqqagent → ${HA_DATA}
/home/program/TrueAgent → ${REPO}
/home/program → ${HOME_DIR}
引用同步:27 处(docs/zh/deploy-runbook.md、toolcall-parallel-execution-plan.md、
scripts/capability-bench/PLAN.md、三个脚本自身的用法注释、ci.yml 注释)
根目录现状:仅 README.md / README_EN.md / LICENSE / Makefile /
go.mod / go.sum / .gitignore / .golangci.yml / .mailmap / .pi-lens.json
验证:go build ✅ 三个 sh 的 bash -n ✅
go test -short ./internal/... ./pkg/... ./cmd/... 全绿
根目录文件清单逐个核对(10 项,全为门面/配置)
Co-authored-by: pi <pi@local>
140 lines
4.9 KiB
Bash
140 lines
4.9 KiB
Bash
#!/bin/bash
|
||
# waiter 远程更新(106 / 30)
|
||
#
|
||
# 现状(更新前):
|
||
# 两台都是 8月27日构建的 /opt/waiter/waiter(11,388,177 字节),
|
||
# 以 root 跑 waiter-remote.service,配置指向 ws://192.168.2.60:9890/...
|
||
# 进程已连续运行 1 天 7.5 小时、无掉线记录 ⇒ 本次是**预防性**更新:
|
||
# · 拿到 94c74b2 的设备桥修复(未 bind 时收到 ping 会关连接)
|
||
# · 版本对齐到内核 1.4.0(docs/git-branching.md 要求客户端与内核同步)
|
||
#
|
||
# 安全设计:
|
||
# · 先备份旧二进制,失败即回滚(trap 捕获)
|
||
# · 只换二进制,**不动** waiter.yaml
|
||
# · 逐台更新并验证,**不并行**(两台都连同一网关,同时重启会同时断链)
|
||
# · 验证项:进程活着 + 设备在网关侧注册成功
|
||
#
|
||
# 用法:
|
||
# bash deploy/scripts/deploy-waiter.sh check 只读检查
|
||
# bash deploy/scripts/deploy-waiter.sh deploy <ip> 更新指定一台
|
||
# bash deploy/scripts/deploy-waiter.sh rollback <ip> 回滚指定一台
|
||
|
||
set -uo pipefail
|
||
|
||
NEW=${NEW_WAITER:-/tmp/waiter-new}
|
||
SVC=waiter-remote.service
|
||
BIN=/opt/waiter/waiter
|
||
CFG=/opt/waiter/waiter.yaml
|
||
|
||
# 106 用 admin(需 sudo),30 用 root
|
||
ssh_of() {
|
||
case "$1" in
|
||
192.168.2.106) echo "admin@$1" ;;
|
||
192.168.2.30) echo "root@$1" ;;
|
||
*) echo "" ;;
|
||
esac
|
||
}
|
||
sudo_of() { [ "$1" = "192.168.2.106" ] && echo "sudo" || echo ""; }
|
||
|
||
say() { printf '\n\033[1m%s\033[0m\n' "$*"; }
|
||
info() { printf ' %s\n' "$*"; }
|
||
|
||
do_check() {
|
||
local ip=$1 t s
|
||
t=$(ssh_of "$ip"); [ -z "$t" ] && { info "未知主机: $ip"; return 1; }
|
||
s=$(sudo_of "$ip")
|
||
info "──── $ip ────"
|
||
# ★ -n:ssh 会从 stdin 读,若不截断会**吃掉后面 read 的输入**
|
||
# ("yes" 被 ssh 消耗 ⇒ read 拿到空 ⇒ 脚本静默取消)。
|
||
# 症状是"明明喂了 yes 却说已取消",极难定位。
|
||
ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$t" "
|
||
echo -n ' 主机: '; hostname
|
||
echo -n ' 当前二进制: '; ls -la $BIN 2>/dev/null | awk '{print \$5\" 字节 \"\$6\" \"\$7\" \"\$8}'
|
||
echo -n ' 服务: '; systemctl is-active $SVC 2>/dev/null
|
||
echo -n ' 进程时长: '; ps -o etime= -p \$(pgrep -f 'waiter --daemon' | head -1) 2>/dev/null
|
||
echo -n ' 配置网关: '; grep -oE 'ws://[^\"]+' $CFG 2>/dev/null | head -1
|
||
echo -n ' 配置校验和: '; md5sum $CFG 2>/dev/null | cut -c1-32
|
||
" 2>&1
|
||
info " 新二进制: $NEW ($(stat -c %s "$NEW" 2>/dev/null) 字节)"
|
||
info " 新版本: $(/tmp/waiter-new --version 2>&1 | head -1)"
|
||
return 0
|
||
}
|
||
|
||
do_deploy() {
|
||
local ip=$1 t s
|
||
t=$(ssh_of "$ip"); [ -z "$t" ] && { info "未知主机: $ip"; return 1; }
|
||
s=$(sudo_of "$ip")
|
||
[ -f "$NEW" ] || { info "新二进制不存在: $NEW"; return 1; }
|
||
|
||
say "更新 $ip"
|
||
do_check "$ip"
|
||
|
||
echo
|
||
read -r -p "确认更新 $ip 的 waiter ? 输入 yes 继续: " ans
|
||
[ "$ans" = "yes" ] || { info "已取消"; return 1; }
|
||
|
||
# 备份 + 停服 + 替换 + 启服;失败即回滚
|
||
scp -q "$NEW" "$t:/tmp/waiter.new" || { info "上传失败"; return 1; }
|
||
info "已上传"
|
||
|
||
ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$t" "
|
||
set -e
|
||
$s cp -a $BIN $BIN.bak-\$(date +%Y%m%d-%H%M%S)
|
||
echo BACKUP=\$(ls -t $BIN.bak-* | head -1)
|
||
$s systemctl stop $SVC
|
||
$s install -m 0755 /tmp/waiter.new $BIN
|
||
rm -f /tmp/waiter.new
|
||
$s systemctl start $SVC
|
||
" 2>&1 | tail -3
|
||
info "已替换并启动"
|
||
|
||
sleep 8
|
||
say "更新后验证 $ip"
|
||
local alive=false
|
||
for i in 1 2 3 4 5; do
|
||
if ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$t" "systemctl is-active --quiet $SVC" 2>/dev/null; then
|
||
alive=true; break
|
||
fi
|
||
sleep 3
|
||
done
|
||
if [ "$alive" = true ]; then
|
||
info "✓ 服务 active"
|
||
ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$t" "
|
||
echo -n ' 新二进制: '; ls -la $BIN | awk '{print \$5\" 字节\"}'
|
||
echo -n ' 进程时长: '; ps -o etime= -p \$(pgrep -f 'waiter --daemon' | head -1) 2>/dev/null
|
||
echo -n ' 配置未变: '; md5sum $CFG | cut -c1-32
|
||
" 2>&1
|
||
info "★ 请在网关侧确认设备已重新注册(/kernel 的 channels 应出现 device/<id>)"
|
||
else
|
||
info "✗ 服务未起来 —— 回滚"
|
||
do_rollback "$ip"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
do_rollback() {
|
||
local ip=$1 t s
|
||
t=$(ssh_of "$ip"); s=$(sudo_of "$ip")
|
||
say "回滚 $ip"
|
||
ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$t" "
|
||
set -e
|
||
BAK=\$(ls -t $BIN.bak-* 2>/dev/null | head -1)
|
||
[ -n \"\$BAK\" ] || { echo '找不到备份'; exit 1; }
|
||
$s systemctl stop $SVC
|
||
$s install -m 0755 \"\$BAK\" $BIN
|
||
$s systemctl start $SVC
|
||
echo \"已回滚到 \$BAK\"
|
||
" 2>&1 | tail -2
|
||
sleep 5
|
||
info "服务: $(ssh -o BatchMode=yes "$t" "systemctl is-active $SVC" 2>/dev/null)"
|
||
}
|
||
|
||
case "${1:-check}" in
|
||
check)
|
||
for ip in 192.168.2.106 192.168.2.30; do say "检查 $ip"; do_check "$ip"; done
|
||
;;
|
||
deploy) do_deploy "${2:?用法: deploy <ip>}" ;;
|
||
rollback) do_rollback "${2:?用法: rollback <ip>}" ;;
|
||
*) echo "用法: $0 {check|deploy <ip>|rollback <ip>}"; exit 2 ;;
|
||
esac
|