fix(acpx): detect wrapper orphan on any PPID change, not just init re… · openclaw/openclaw@71f84f9
t2wei
·
2026-06-23
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -251,6 +251,15 @@ describe("prepareAcpxCodexAuthConfig", () => {
|
251 | 251 | expect(wrapper).not.toMatch( |
252 | 252 | /forceKillTimer = setTimeout\(\(\) => killChildTree\("SIGKILL"\), 1_500\);\s*forceKillTimer\.unref\?\.\(\);\s*process\.exit\(1\);/s, |
253 | 253 | ); |
| 254 | +// Orphan detection must trigger on any PPID change, not only when the new |
| 255 | +// PPID is init (1). Systemd user services and container init reparent |
| 256 | +// orphaned processes to a session manager or container init (PID != 1), |
| 257 | +// and the older `process.ppid !== 1` guard would silently leak the codex |
| 258 | +// adapter tree there. |
| 259 | +expect(wrapper).not.toContain("process.ppid !== 1"); |
| 260 | +expect(wrapper).toMatch( |
| 261 | +/setInterval\(\(\) => \{[\s\S]*?if \(process\.ppid === originalParentPid\) \{\s*return;\s*\}/, |
| 262 | +); |
254 | 263 | }); |
255 | 264 | |
256 | 265 | it("uses the bundled Claude ACP dependency by default when it is installed", async () => { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -475,7 +475,13 @@ const parentWatcher =
|
475 | 475 | process.platform === "win32" |
476 | 476 | ? undefined |
477 | 477 | : setInterval(() => { |
478 | | - if (process.ppid === originalParentPid || process.ppid !== 1) { |
| 478 | + // Orphan detection: parent PID changed means our original parent died. |
| 479 | + // The new parent could be PID 1 (init) on bare-metal hosts, OR a |
| 480 | + // systemd user-session manager, OR a container init, OR a session |
| 481 | + // leader — depending on environment. Previously this only triggered |
| 482 | + // on PPID == 1, which missed all systemd-managed deployments and |
| 483 | + // leaked codex-acp adapter trees on every gateway restart. |
| 484 | + if (process.ppid === originalParentPid) { |
479 | 485 | return; |
480 | 486 | } |
481 | 487 | if (orphanCleanupStarted) { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -658,6 +658,7 @@ describe("ci workflow guards", () => {
|
658 | 658 | expect(generateJob.if).toBe("${{ inputs.qa_evidence_run_id == '' }}"); |
659 | 659 | expect(generateJob.uses).toBe("./.github/workflows/qa-profile-evidence.yml"); |
660 | 660 | expect(generateJob.with).toMatchObject({ |
| 661 | +// Keep the caller's ref while the callee verifies it against expected_sha. |
661 | 662 | ref: "${{ inputs.ref }}", |
662 | 663 | expected_sha: "${{ needs.validate_selected_ref.outputs.selected_revision }}", |
663 | 664 | qa_profile: "release", |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。