fix: drain piped stdout/stderr in aws waitForCloudInit and sprite destroyServer (#1929)

Same pipe-buffer deadlock pattern fixed by PRs #1903, #1915, #1920, #1922.
Two instances were missed in those passes.

Agent: code-health

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
A 2026-02-25 12:48:43 -08:00 committed by GitHub
parent b09295131a
commit fbb48514e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 13 additions and 5 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "0.10.12",
"version": "0.10.13",
"type": "module",
"bin": {
"spawn": "cli.js"

View file

@ -977,17 +977,23 @@ export async function waitForCloudInit(maxAttempts = 60): Promise<void> {
...SSH_BASE_OPTS,
...keyOpts,
`${SSH_USER}@${instanceIp}`,
"test -f /home/ubuntu/.cloud-init-complete",
"test -f /home/ubuntu/.cloud-init-complete && echo done",
],
{
stdio: [
"ignore",
"pipe",
"ignore",
"pipe",
],
},
);
if ((await proc.exited) === 0) {
// Drain both pipes before awaiting exit to prevent pipe buffer deadlock
const [stdout] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
]);
const exitCode = await proc.exited;
if (exitCode === 0 && stdout.includes("done")) {
logInfo("Cloud-init complete");
return;
}

View file

@ -634,11 +634,13 @@ export async function destroyServer(name?: string): Promise<void> {
],
},
);
// Drain stderr before awaiting exit to prevent pipe buffer deadlock
const stderrText = new Response(proc.stderr).text();
const exitCode = await proc.exited;
if (exitCode !== 0) {
logError(`Failed to destroy sprite '${target}'`);
logError(`Delete it manually: sprite destroy ${target}`);
throw new Error("Sprite destruction failed");
throw new Error(`Sprite destruction failed: ${await stderrText}`);
}
logInfo(`Sprite '${target}' destroyed`);