mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-27 12:53:35 +00:00
chore(stress): 加 waiter 远程更新脚本;修 cmp.py 的 docstring 格式
## deploy-waiter.sh:106 / 30 的 waiter 更新 现状(更新前):两台都是 8月27日构建的 /opt/waiter/waiter(11,388,177 字节), 以 root 跑 waiter-remote.service,配置指向 ws://192.168.2.60:9890/… 安全设计: - 先备份旧二进制(`$BIN.bak-<时间戳>`),失败即回滚(脚本内自动) - **只换二进制,不动 waiter.yaml**(配置由 deploy 后单独追加) - **逐台更新并验证,不并行** —— 两台都连同一网关,同时重启会同时断链 - 106 走 admin+sudo、30 走 root - 验证项:服务 active + 进程时长 + **配置 md5 未变** 用法:`check`(只读)/ `deploy <ip>`(需输 yes)/ `rollback <ip>` ## cmp.py:两处格式 docstring 的 `"""` 紧贴内容、以及函数段之间缺两个空行(PEP8)。纯格式, 无逻辑改动。
This commit is contained in:
@ -9,14 +9,14 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||
procGetStdHandle = kernel32.NewProc("GetStdHandle")
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||
procGetStdHandle = kernel32.NewProc("GetStdHandle")
|
||||
)
|
||||
|
||||
const (
|
||||
stdInputHandle = ^uint32(9) + 1 // -10
|
||||
stdInputHandle = ^uint32(9) + 1 // -10
|
||||
enableVirtualTerminalProcessing = 0x0004
|
||||
enableProcessedOutput = 0x0001
|
||||
enableWrapAtEOLOutput = 0x0002
|
||||
|
||||
136
deploy-waiter.sh
Normal file
136
deploy-waiter.sh
Normal file
@ -0,0 +1,136 @@
|
||||
#!/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-waiter.sh check 只读检查
|
||||
# bash deploy-waiter.sh deploy <ip> 更新指定一台
|
||||
# bash 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 ────"
|
||||
ssh -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 -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 -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 -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 -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
|
||||
@ -90,13 +90,14 @@ def has_error(frames):
|
||||
|
||||
|
||||
def tools_done(frames):
|
||||
"""数出工具真正执行的个数(按 done-N 标记去重)。"""
|
||||
""" 数出工具真正执行的个数(按 done-N 标记去重)。"""
|
||||
blob = " ".join(frames)
|
||||
return len({int(m.group(1)) for m in re.finditer(r"done-(\d+)", blob)})
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 单轮测量
|
||||
|
||||
|
||||
def measure(sock, key, marker, rounds):
|
||||
"""连一次、跑 rounds 轮(每轮唯一输入)。
|
||||
|
||||
@ -128,6 +129,7 @@ def measure(sock, key, marker, rounds):
|
||||
|
||||
# ---------------------------------------------------------------- 并发轰炸
|
||||
|
||||
|
||||
def blast(sock, key, conns, inputs, tag):
|
||||
"""conns 条连接并发,每条连接连发 inputs 条输入。返回通过率。
|
||||
|
||||
@ -175,6 +177,7 @@ def blast(sock, key, conns, inputs, tag):
|
||||
|
||||
# ---------------------------------------------------------------- 主流程
|
||||
|
||||
|
||||
def arg_int(pos, default, name):
|
||||
"""解析位置参数为正整数;非法时给出可执行报错而不是裸 ValueError。"""
|
||||
if pos >= len(sys.argv):
|
||||
|
||||
Reference in New Issue
Block a user