mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
fix(exe-dev): translate SSH 'invalid format' stderr into actionable key-format message (PAPA-450)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
980bfc7301
commit
c1ae76c6e5
2 files changed
+40
No files matched your search
@@ -346,6 +346,38 @@ describe("exe.dev sandbox provider plugin", () => {
|
||||
expect(String(fetchMock.mock.calls[1]?.[1]?.body ?? "")).toBe("rm --json 'paperclip-env-run'");
|
||||
});
|
||||
|
||||
it("surfaces invalid SSH key-format guidance during lease acquisition", async () => {
|
||||
fetchMock.mockResolvedValueOnce(
|
||||
new Response(JSON.stringify({
|
||||
vm_name: "paperclip-env-run",
|
||||
ssh_dest: "paperclip-env-run.exe.xyz",
|
||||
https_url: "https://paperclip-env-run.exe.xyz",
|
||||
status: "running",
|
||||
}), { status: 200 }),
|
||||
);
|
||||
fetchMock.mockResolvedValueOnce(new Response("{}", { status: 200 }));
|
||||
queueSpawnResult({
|
||||
code: 255,
|
||||
stderr: 'Load key "/tmp/paperclip-exe-dev-ssh-abc/id_ed25519": invalid format\n',
|
||||
});
|
||||
|
||||
await expect(plugin.definition.onEnvironmentAcquireLease?.({
|
||||
driverKey: "exe-dev",
|
||||
companyId: "company-1",
|
||||
environmentId: "env-1",
|
||||
runId: "run-1",
|
||||
config: {
|
||||
apiKey: "api-key",
|
||||
sshPrivateKey: "not-actually-a-key",
|
||||
timeoutMs: 300000,
|
||||
},
|
||||
})).rejects.toThrow(
|
||||
"the configured SSH private key isn't an OpenSSH-format private key",
|
||||
);
|
||||
|
||||
expect(String(fetchMock.mock.calls[1]?.[1]?.body ?? "")).toBe("rm --json 'paperclip-env-run'");
|
||||
});
|
||||
|
||||
it("redacts sensitive lifecycle flags in API errors", async () => {
|
||||
fetchMock.mockResolvedValueOnce(new Response("upstream boom", { status: 500 }));
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ const SSH_SIGKILL_GRACE_MS = 250;
|
||||
const MAX_VM_RECORD_DEPTH = 4;
|
||||
const EXE_DEV_SSH_ONBOARDING_MARKER = "Please complete registration by running: ssh exe.dev";
|
||||
const EXE_DEV_SSH_EMAIL_PROMPT = "Please enter your email address:";
|
||||
const EXE_DEV_SSH_INVALID_KEY_FORMAT = /Load key [^\n]*invalid format/i;
|
||||
|
||||
// exe.dev's `--setup-script` runs at VM init as the unprivileged `exedev` user, which
|
||||
// has passwordless sudo. The Paperclip sandbox callback bridge is a Node script, so
|
||||
@@ -498,6 +499,13 @@ function formatSshFailure(
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
if (EXE_DEV_SSH_INVALID_KEY_FORMAT.test(combinedOutput)) {
|
||||
return [
|
||||
`Failed to ${action} exe.dev VM ${vmName}: the configured SSH private key isn't an OpenSSH-format private key.`,
|
||||
"Confirm the secret starts with `-----BEGIN … PRIVATE KEY-----` and isn't the `.pub` file or a PuTTY `.ppk` export.",
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
return `Failed to ${action} exe.dev VM ${vmName}: ${result.stderr.trim() || result.stdout.trim() || "unknown error"}`;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user