diff --git a/BUGS.md b/BUGS.md index 0cf5ec5..9f94ebf 100644 --- a/BUGS.md +++ b/BUGS.md @@ -580,6 +580,15 @@ against what it holds, a request against the page that should have made it. 5. ✅ **"Everything is up to date." sat in a 20px sliver of a card**, flush to its border, where the package list it shares the card with is meant to be. +6. ✅ **A terminal of the hub's was asked for on a node.** Found in Firefox against the live + console, which says out loud what Chromium swallows: `wss://…/api/nodes/grid/terminals/ + adfdeecb/attach`, where `adfdeecb` was one of the hub's — `grid` had no terminals at all. A + pane builds its address when it connects, from whichever machine the console is pointed at + *now*; switch machine while one is reconnecting and the reconnect goes to the new one. The + address is fixed when the pane opens. The same was true of a service's log socket, and is + fixed with it. Verified by walking the console around the fleet with a terminal open and + checking every socket against the machine that actually owns what it asked for. + ## Checked and fine Machine titles on every page and against an offline or never-reached machine; the colour a diff --git a/web/src/Services.tsx b/web/src/Services.tsx index 98208fd..2a2cd0d 100644 --- a/web/src/Services.tsx +++ b/web/src/Services.tsx @@ -52,9 +52,12 @@ export function Logs({ unit }: { unit: string }) { let readyTimer: number | undefined let sock: WebSocket | null = null let retry: number | undefined + // fixed when the log opens, for the same reason as a terminal's: a reconnect must not + // follow the console to another machine + const url = wsURLPath(`/api/services/${encodeURIComponent(unit)}/logs/tail?n=200`) const connect = () => { if (closed) return - const s = new WebSocket(wsURLPath(`/api/services/${encodeURIComponent(unit)}/logs/tail?n=200`)) + const s = new WebSocket(url) sock = s s.onopen = () => { setLive(true); setErr(''); readyTimer = window.setTimeout(() => setReady(true), 1500) } s.onmessage = (ev) => { diff --git a/web/src/TerminalPane.tsx b/web/src/TerminalPane.tsx index 3666376..6b19196 100644 --- a/web/src/TerminalPane.tsx +++ b/web/src/TerminalPane.tsx @@ -60,9 +60,13 @@ export default function TerminalPane({ id, active, register, onStatus, onExit }: sendResize() } + // The address is fixed when the pane opens, not rebuilt on each attempt: it carries which + // machine this terminal belongs to, and the console may have moved to another machine + // before a reconnect fires — which had the hub's terminals being asked for on a node. + const url = wsURL(id) const connect = () => { if (closed) return - const sock = new WebSocket(wsURL(id)) + const sock = new WebSocket(url) sock.binaryType = 'arraybuffer' ws = sock sock.onopen = () => { retry = 0; setConn('open'); cbs.current.onStatus(true); lastSize = ''; doFit(); while (queued.length) sock.send(enc.encode(queued.shift()!)) }