Skip to content

guest-agent: stream non-TTY exec output as it is produced - #490

Open
palashswapnil wants to merge 1 commit into
kernel:mainfrom
palashswapnil:fix/stream-exec-output
Open

palashswapnil wants to merge 1 commit into
kernel:mainfrom
palashswapnil:fix/stream-exec-output

Conversation

@palashswapnil

Copy link
Copy Markdown

Problem

executeNoTTY reads stdout and stderr with io.ReadAll and sends nothing until the process exits. Any long-running non-TTY exec therefore delivers no output while it runs:

  • a tail -f
  • a progress log
  • a stdin/stdout byte relay (e.g. bridging a TCP port over /instances/{id}/exec)

This showed up while using exec as a TCP relay for CDP and WebRTC to browser instances. HTTP/1.0 requests worked, because the server closes the connection and the relay exits. Keep-alive and WebSocket traffic hung forever.

Fix

Pump stdout and stderr concurrently, sending each chunk as it is read (up to 32 KiB, as before). Both pipes are still fully drained before cmd.Wait(), and the exit code is still sent last. The TTY path already streams this way.

One behaviour change: stdout and stderr chunks may now interleave in the order they are produced, instead of all stdout followed by all stderr.

Tests

  • New TestExecuteNoTTYStreamsOutputBeforeExit runs echo first; sleep 2; echo second and asserts the first chunk arrives well before exit. It fails on main ("first chunk arrived at 2.003s but command exited at 2.004s") and passes with this change.
  • go test ./lib/system/guest_agent/ passes (linux/arm64, golang:1.25).
  • Ran live on a macOS (vz) host: long-lived relays through /instances/{id}/exec now stream. That covered CDP keep-alive and WebSocket traffic, plus neko WebRTC over ICE-TCP, across a fleet of 7 instances.

🤖 Generated with Claude Code

Buffering stdout/stderr until exit stalls long-lived commands (relays, tails).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chruffins
chruffins self-requested a review October 2, 2026 18:42
@chruffins

Copy link
Copy Markdown
Contributor

hey! this seems like a straightforward improvement but I'm confused by your use case for this. is this for a project that you're using hypeman for?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants