Terminal: show the shell's error output, so a missing shell is explained
CI / test (push) Successful in 6m9s
Release / release (push) Successful in 5m54s

The shell's stderr was discarded, so a shell that could not start looked like an
immediate disconnect. It now goes to the terminal like other output, followed by
the exit code. An end-to-end test covers a machine with no shell. Builds against
Bamboo v0.1.10, which says why when there is no shell to run.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-31 02:05:48 -06:00
1 parent 35d4000bc4
commit 7481b2d01c
4 files changed
+43 -3

No files matched your search

+27
View File
@@ -137,6 +137,33 @@ func TestWebTerminalWithoutAnyOpenPort(t *testing.T) {
t.Errorf("the test opened a port after all: %+v", maps.Mappings)
}
// a machine with no shell (the published container image has none) says why, instead of the
// terminal just disconnecting: the shell's error output reaches the browser, then the exit code
if sshd.Supported {
t.Setenv("SHELL", "/nonexistent/shell")
ws := dial()
defer ws.Close()
var out bytes.Buffer
var exit termMsg
for exit.Type != "exit" {
ws.SetReadDeadline(time.Now().Add(15 * time.Second))
var f []byte
if err := websocket.Message.Receive(ws, &f); err != nil {
t.Fatalf("waiting for the shell to end (got %q): %v", out.String(), err)
}
if len(f) > 0 && f[0] == '{' {
if m := parseTermMsg(f); m.Type == "exit" {
exit = m
}
continue
}
out.Write(f)
}
if exit.Code != 127 || !strings.Contains(out.String(), "no shell to run") {
t.Errorf("a missing shell: exit %d, output %q", exit.Code, out.String())
}
}
// the SSH server still decides who gets in
other := newSSHSigner(t)
if err := os.WriteFile(keys, ssh.MarshalAuthorizedKey(other.PublicKey()), 0o600); err != nil {