mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-29 04:25:52 +01:00
fix(native): require verified remote process exit receipts (#17799)
Require fresh ESRCH or an exact matching zombie generation before treating a remote Runner as stopped. Preserve uncertain ownership through adoption and transport close, retire local controller resources after failed close, and check Node before remote launch. Bind the shared transport change in Copilot profile 62 while retaining historical profile decoding. Add red-green process, permission, launch, adoption and cleanup regressions. Thanks to @hsm-lv for the original investigation in #17073. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
051b425fdf
commit
718c73dafe
16 files changed
+448
-37
No files matched your search
@@ -11217,7 +11217,7 @@ export async function verifyRemoteRunnerReattachment(input: {
|
||||
command: "sh",
|
||||
args: [
|
||||
"-c",
|
||||
`${REMOTE_RECOVERY_PROCESS_CHECK_SCRIPT}; if ${REMOTE_RUNNER_PROCESS_FINGERPRINT_SCRIPT}; then :; else exit 46; fi; test "$process_fingerprint" = "$5" || exit 47` +
|
||||
REMOTE_RECOVERY_PROCESS_CHECK_SCRIPT +
|
||||
(signal ? '; kill -"$6" "$pid"' : ""),
|
||||
"paperclip-runner-recovery-check",
|
||||
identityPath,
|
||||
@@ -11230,8 +11230,12 @@ export async function verifyRemoteRunnerReattachment(input: {
|
||||
bypassSession: true,
|
||||
},
|
||||
});
|
||||
return { alive: result.exitCode === 0 && !result.timedOut,
|
||||
reason: remoteRecoveryProbeReason("process_verification", result.exitCode, result.timedOut) };
|
||||
const alive = result.exitCode === 0 && !result.timedOut;
|
||||
const reason = remoteRecoveryProbeReason("process_verification", result.exitCode, result.timedOut);
|
||||
if (!alive && reason !== "process_not_running") {
|
||||
throw new RemoteRunnerRecoveryError({ stage: "process_verification", reason });
|
||||
}
|
||||
return { alive, reason };
|
||||
};
|
||||
const verified = await check(undefined, probeDeadline);
|
||||
if (!verified.alive) throw new RemoteRunnerRecoveryError({ stage: "process_verification", reason: verified.reason });
|
||||
@@ -11417,7 +11421,7 @@ export function createRemoteRunnerProcessLauncher(input: {
|
||||
command: "sh",
|
||||
args: [
|
||||
"-c",
|
||||
'set -eu; identity_path=$1; identity_nonce=$2; runner_instance_id=$3; child_script=$4; shift 4; umask 077; identity_dir=$(dirname -- "$identity_path"); mkdir -p -- "$identity_dir"; if command -v setsid >/dev/null 2>&1; then nohup setsid sh -c "$child_script" paperclip-runner-child "$identity_path" "$identity_nonce" "$runner_instance_id" "$@" </dev/null >/dev/null 2>&1 & else nohup sh -c "$child_script" paperclip-runner-child "$identity_path" "$identity_nonce" "$runner_instance_id" "$@" </dev/null >/dev/null 2>&1 & fi',
|
||||
'set -eu; node -e "process.kill(process.pid, 0)"; identity_path=$1; identity_nonce=$2; runner_instance_id=$3; child_script=$4; shift 4; umask 077; identity_dir=$(dirname -- "$identity_path"); mkdir -p -- "$identity_dir"; if command -v setsid >/dev/null 2>&1; then nohup setsid sh -c "$child_script" paperclip-runner-child "$identity_path" "$identity_nonce" "$runner_instance_id" "$@" </dev/null >/dev/null 2>&1 & else nohup sh -c "$child_script" paperclip-runner-child "$identity_path" "$identity_nonce" "$runner_instance_id" "$@" </dev/null >/dev/null 2>&1 & fi',
|
||||
"paperclip-runner-launch",
|
||||
input.processIdentityPath,
|
||||
identityNonce,
|
||||
@@ -11496,9 +11500,7 @@ export function createRemoteRunnerProcessLauncher(input: {
|
||||
command: "sh",
|
||||
args: [
|
||||
"-c",
|
||||
REMOTE_RECOVERY_PROCESS_CHECK_SCRIPT + (identity.processStartFingerprint
|
||||
? `; if ${REMOTE_RUNNER_PROCESS_FINGERPRINT_SCRIPT}; then :; else exit 46; fi; test "$process_fingerprint" = "$5" || exit 47`
|
||||
: ""),
|
||||
REMOTE_RECOVERY_PROCESS_CHECK_SCRIPT,
|
||||
"paperclip-runner-monitor",
|
||||
input.processIdentityPath,
|
||||
identityNonce,
|
||||
|
||||
Reference in new issue
Block a user