Skip to content

Stream image-pull progress for container builds - #2734

Open
fnando wants to merge 1 commit into
mainfrom
container-pull-streaming
Open

fnando wants to merge 1 commit into
mainfrom
container-pull-streaming

Conversation

@fnando

@fnando fnando commented Sep 18, 2026

Copy link
Copy Markdown
Member

What

Replaces the container build's image-pull output: stellar contract build --image <ref> --pull now streams the engine's high-level status lines (Pulling from, Digest, Status) through the normal print output and captures per-layer stderr, surfacing it only if the pull fails. The pull logic moves to a reusable shared::Args::pull_image, and the container-local pull_image/PullImageFailed are removed in favor of shared::Error::PullImageFailed { image, stderr } (which already flows through Error::Engine).

Why

Split out of #2709 (verifiable builds) at review request: the streaming-pull helper is independent of --verifiable and improves the existing --image build on its own. Pulling it into its own PR keeps #2709 focused and lets this land separately.

Known limitations

N/A

Copilot AI balanced review requested due to automatic review settings September 18, 2026 18:42
@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX Sep 18, 2026
@fnando fnando self-assigned this Sep 18, 2026
@fnando fnando moved this from Backlog (Not Ready) to Needs Review in DevX Sep 18, 2026
@fnando
fnando requested review from a team and leighmcculloch September 18, 2026 18:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new command behavior lacks required integration coverage for successful and failed pulls.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Moves image-pull handling into the shared container engine layer and improves build pull output and failures.

Changes:

  • Streams high-level pull status while capturing noisy layer output.
  • Reports engine stderr when pulls fail.
File summaries
File Description
contract/build/container.rs Uses the shared pull helper.
container/shared.rs Implements streaming and failure capture.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

/// stderr is captured rather than shown and surfaced only when the pull
/// fails, as `PullImageFailed`, so a failed pull can report the engine's own
/// error. A missing engine binary surfaces via `io_error` as `NotFound`.
pub(crate) async fn pull_image(&self, image: &str, print: &Print) -> Result<(), Error> {
@fnando
fnando added this pull request to stack #2735 September 18, 2026 19:00

@leighmcculloch leighmcculloch left a comment

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.

Couple minor things but lgtm.

let stream_stdout = async {
if let Some(stdout) = stdout {
let mut lines = BufReader::new(stdout).lines();
while let Ok(Some(line)) = lines.next_line().await {

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.

This loops stops if there's a read error, but the pipe will still be open and the command keeps running and I think this means that the OS pipe buffer behind the pipe has the risk of filling and blocking the command being run from completing. Essentially a deadlock.

docker
.pull_image(image, print)
.await
.map_err(Error::Engine)?;

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.

I don't think the map err is required here with the way the error is defined from I noticed a #[from] above for it anyway.

pub(crate) async fn pull_image(&self, image: &str, print: &Print) -> Result<(), Error> {
let mut child = self
.pull_command(image)
.stdout(Stdio::piped())

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.

How does this work when --quiet is used?

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

Labels

None yet

Projects

Status: Needs Review

Development

Successfully merging this pull request may close these issues.

3 participants