Skip to content

feat: allow capturing full output to stdout, modernize API#9

Merged
talos-bot merged 2 commits intosiderolabs:mainfrom
mcanevet:fix-stdout-circbuf-truncation
Feb 23, 2026
Merged

feat: allow capturing full output to stdout, modernize API#9
talos-bot merged 2 commits intosiderolabs:mainfrom
mcanevet:fix-stdout-circbuf-truncation

Conversation

@mcanevet
Copy link
Copy Markdown
Contributor

Problem

RunContext allocates the stdout circbuf with MaxStderrLen (4096 bytes), the same constant used for stderr. A circbuf silently discards earlier bytes once the limit is reached, so any subprocess that writes more than 4 KiB to stdout gets its output truncated with no error returned to the caller.

Stderr is naturally short (error messages), so 4 KiB is fine there. Stdout has no such bound — commands that emit structured data (JSON payloads, certificates, encoded blobs, etc.) can easily exceed 4 KiB.

Fix

Add MaxStdoutLen = 1 MiB and use it for the stdout buffer. MaxStderrLen is unchanged.

Test

TestLargeStdout generates 6000 bytes of stdout (> old 4096-byte limit) and asserts the full output is returned untruncated.

@smira
Copy link
Copy Markdown
Member

smira commented Feb 23, 2026

Nice catch! I wonder if we should not use circular buffer here at all.

@mcanevet mcanevet force-pushed the fix-stdout-circbuf-truncation branch from f7d7790 to a9f9327 Compare February 23, 2026 09:27
@mcanevet
Copy link
Copy Markdown
Contributor Author

@smira as you like. Just tell me what you prefer.

@smira
Copy link
Copy Markdown
Member

smira commented Feb 23, 2026

Let me think about this a bit more, I certainly don't like the interface of this function, neither I like the idea of allocating 1 MiB for every command execution.

mcanevet and others added 2 commits February 23, 2026 13:53
Deprecate old functions, introduce a better extensible replacement
with `RunWithOptions`.

The stdout circbuf was sharing MaxStderrLen (4096 bytes) with stderr.
Subprocess stdout can be arbitrarily large — for example a command that
produces structured data (JSON, certificates, encoded blobs) can easily
exceed 4096 bytes, resulting in silent mid-stream truncation with no
error returned to the caller.

Add MaxStdoutLen = 1 MiB and use it for the stdout buffer.  MaxStderrLen
remains at 4096 bytes since error output is naturally short.

Add TestLargeStdout regression test that generates 6000 bytes of stdout and
asserts the full output is returned untruncated.

Signed-off-by: Mickaël Canévet <mickael.canevet@proton.ch>
Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
Rekres with latest.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
@smira smira force-pushed the fix-stdout-circbuf-truncation branch from a9f9327 to 5f31ba9 Compare February 23, 2026 09:54
@smira smira self-assigned this Feb 23, 2026
@smira
Copy link
Copy Markdown
Member

smira commented Feb 23, 2026

Let me think about this a bit more, I certainly don't like the interface of this function, neither I like the idea of allocating 1 MiB for every command execution.

I did some refactoring, and I hope this API will be better and more clear.

@smira smira changed the title fix: use a 1 MiB buffer for stdout to prevent silent truncation feat: allow capturing full output to stdout, modernize API Feb 23, 2026
module github.com/siderolabs/go-cmd

go 1.23.2
go 1.24.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe go1.25 atleast?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would we bump the minimum? we can backport more freely if we don't aggressively bump

@github-project-automation github-project-automation bot moved this from In Review to Approved in Planning Feb 23, 2026
@smira
Copy link
Copy Markdown
Member

smira commented Feb 23, 2026

/m

@talos-bot talos-bot merged commit 5f31ba9 into siderolabs:main Feb 23, 2026
15 checks passed
@github-project-automation github-project-automation bot moved this from Approved to Done in Planning Feb 23, 2026
smira added a commit to smira/talos that referenced this pull request Feb 23, 2026
See:

* siderolabs/go-blockdevice#147
* siderolabs/go-cmd#9

Lots of changes through the code as I deprecated `Run`, `RunWithContext`
methods and allow only new `RunWithOptions` to clean up the library
usage.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
smira added a commit to smira/talos that referenced this pull request Mar 18, 2026
See:

* siderolabs/go-blockdevice#147
* siderolabs/go-cmd#9

Lots of changes through the code as I deprecated `Run`, `RunWithContext`
methods and allow only new `RunWithOptions` to clean up the library
usage.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
(cherry picked from commit 7cf1de2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants