From bfed66f3cf0a5242029f66af803c9fe4c6ed60ef Mon Sep 17 00:00:00 2001 From: vicmcorrea Date: Sun, 11 Oct 2026 02:36:22 -0300 Subject: [PATCH 1/2] fix(cli): fail updates when installer download fails --- bend2/main.ts | 19 +++++++++++++++++-- gates/ping.ts | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/bend2/main.ts b/bend2/main.ts index 32cd6c871..3e23a8c32 100755 --- a/bend2/main.ts +++ b/bend2/main.ts @@ -171,8 +171,23 @@ function cli_guide(name: string): void { function cli_update(): void { const cmd = "curl -fsSL " + ORIGIN + "/install.sh | sh"; cli_say(2, cmd + "\n"); - process.exitCode = child.spawnSync("sh", ["-c", cmd], - { stdio: "inherit" }).status ?? 1; + const dir = fs.mkdtempSync(path.join(os.tmpdir(), "bend-update-")); + const file = path.join(dir, "install.sh"); + try { + process.exitCode = child.spawnSync("curl", ["-fsSL", ORIGIN + "/install.sh", + "-o", file], { stdio: "inherit" }).status ?? 1; + if (process.exitCode === 0) { + const fd = fs.openSync(file, "r"); + try { + process.exitCode = child.spawnSync("sh", [], + { stdio: [fd, "inherit", "inherit"] }).status ?? 1; + } finally { + fs.closeSync(fd); + } + } + } finally { + fs.rmSync(dir, { recursive: true, force: true }); + } } // check is the whole telemetry: once a day, a GET of /check?v=&os=&arch= diff --git a/gates/ping.ts b/gates/ping.ts index a72189e0a..437d5186c 100644 --- a/gates/ping.ts +++ b/gates/ping.ts @@ -277,6 +277,9 @@ try { check("a dead origin costs one run under four seconds", dead.code === 0 && dead.out.includes("usage:") && Date.now() - t0 < 4000); const was = fs.statSync(BIN).ino; + const no_upd = await bend(["update"], { BEND_ORIGIN: "http://127.0.0.1:1" }); + check("bend update fails when the installer download fails", no_upd.code !== 0 + && fs.statSync(BIN).ino === was); const upd = await bend(["update"]); check("bend update runs the installer again: " + upd.err, upd.code === 0 && upd.err.startsWith("curl -fsSL " + ORIGIN + "/install.sh | sh\n") From 8a76db3535ed7cf0609d8670a18cd0a8d47eec63 Mon Sep 17 00:00:00 2001 From: vicmcorrea Date: Sun, 11 Oct 2026 12:42:54 -0300 Subject: [PATCH 2/2] fix(cli): guard installer execution in the shell --- bend2/main.ts | 22 ++++------------------ gates/ping.ts | 3 ++- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/bend2/main.ts b/bend2/main.ts index 3e23a8c32..3e1a3f498 100755 --- a/bend2/main.ts +++ b/bend2/main.ts @@ -169,25 +169,11 @@ function cli_guide(name: string): void { // cli_update runs the installer again: the one way bend changes. The // command prints first, so the user can run it alone. function cli_update(): void { - const cmd = "curl -fsSL " + ORIGIN + "/install.sh | sh"; + const cmd = "s=$(curl -fsSL " + ORIGIN + + "/install.sh) && printf '%s\\n' \"$s\" | sh"; cli_say(2, cmd + "\n"); - const dir = fs.mkdtempSync(path.join(os.tmpdir(), "bend-update-")); - const file = path.join(dir, "install.sh"); - try { - process.exitCode = child.spawnSync("curl", ["-fsSL", ORIGIN + "/install.sh", - "-o", file], { stdio: "inherit" }).status ?? 1; - if (process.exitCode === 0) { - const fd = fs.openSync(file, "r"); - try { - process.exitCode = child.spawnSync("sh", [], - { stdio: [fd, "inherit", "inherit"] }).status ?? 1; - } finally { - fs.closeSync(fd); - } - } - } finally { - fs.rmSync(dir, { recursive: true, force: true }); - } + process.exitCode = child.spawnSync("sh", ["-c", cmd], + { stdio: "inherit" }).status ?? 1; } // check is the whole telemetry: once a day, a GET of /check?v=&os=&arch= diff --git a/gates/ping.ts b/gates/ping.ts index 437d5186c..f02e4dfec 100644 --- a/gates/ping.ts +++ b/gates/ping.ts @@ -282,7 +282,8 @@ try { && fs.statSync(BIN).ino === was); const upd = await bend(["update"]); check("bend update runs the installer again: " + upd.err, upd.code === 0 - && upd.err.startsWith("curl -fsSL " + ORIGIN + "/install.sh | sh\n") + && upd.err.startsWith("s=$(curl -fsSL " + ORIGIN + + "/install.sh) && printf '%s\\n' \"$s\" | sh\n") && plain(upd.out).includes("Bend \u2588 " + ver) && fs.statSync(BIN).ino !== was); const guide = await bend(["guide"]); const base = await bend(["base", "Map"]);