fix(auto-deploy): prevent self-kill when pm2 restart runs inside webhook handler #44
Reference in New Issue
Block a user
Delete Branch "fix/auto-deploy-self-kill"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
post_deploy commands that restart the current process (pm2 restart {pm2_name}) now use nohup+sleep to defer execution, allowing the webhook handler to return normally before the restart happens. Fix by jiangwei-infra, synced from install dir.审查结果:REQUEST_CHANGES
方向正确(PR #43 review 我确实指出了 self-kill 问题),但实现有 2 个必修问题。
❌ 必修:
M1: nohup 后台进程无法检测失败
> /dev/null 2>&1吞掉所有输出,且不等待进程完成,意味着:→ 建议:至少重定向到日志文件(如
>> /tmp/openclaw/auto-deploy.log 2>&1),并保留_send_deploy_failure_mail的触发机制(可用退出码文件约定:失败写/tmp/auto-deploy-failed,下次 tick 时检查)→ 或者更简单:直接用
asyncio.create_subprocess_exec执行sleep 2 && pm2 restart,先await asyncio.sleep(2)再启动子进程。这样 subprocess 在父进程死后会被 pm2 新进程继承,不需要 nohup。M2: 字符串匹配太脆弱
匹配
pm2 restart sanguo-moziplus-v2但不匹配:pm2 restart sanguo-moziplus-v2 --update-envpm2 restart sanguo-moziplus-v2(多空格)systemctl restart sanguo)→ 建议:检测当前进程是否会被杀,而非匹配命令字符串。最简单的方式是检查
os.environ.get("PM2_HOME")或os.getppid()是否为 pm2。或者直接检测 cmd 是否包含pm2 restart+ 当前进程名(从 pm2 配置读取)。⚠️ 建议:
S1: pm2_name 字段终于被使用了
PR #43 review 我备注过 pm2_name 冗余,现在有了用途(M2 的匹配)。如果 M2 改为更可靠的方式,pm2_name 可能又变冗余。设计时考虑清楚这个字段的长期用途。
已修复 M1 + M2,请重新 Review。
M1 修复:nohup 替换为
asyncio.sleep(2)+ 正常 subprocess 执行。进程被 restart 杀掉时 catchProcessLookupError/TimeoutError作为预期行为。M2 修复:改为检查
PM2_HOME环境变量 +re.search(rf"pm2\s+restart\s+{re.escape(pm2_name)}", cmd)正则匹配,支持多空格和--update-env等参数。S1:pm2_name 在 M2 正则匹配中有明确用途。
测试 405 passed, 3 skipped。