Skip to content

feat: report push phase transitions during OCI image export#2797

Merged
markphelps merged 8 commits intomainfrom
mphelps/push-phase-progress
Apr 8, 2026
Merged

feat: report push phase transitions during OCI image export#2797
markphelps merged 8 commits intomainfrom
mphelps/push-phase-progress

Conversation

@markphelps
Copy link
Copy Markdown
Contributor

@markphelps markphelps commented Mar 3, 2026

Summary

  • During OCI push, the Docker image export phase (docker save → temp tarball) was completely silent — the user saw nothing while potentially large images were exported to disk before chunked upload began.
  • Extends PushProgress with a Phase field so phase transitions (exporting → pushing) flow through the existing single callback, and the CLI displays status messages like Exporting image from Docker daemon... during the silent export phase.

Design

Rather than adding a separate PhaseFn callback and ImagePhaseFn option (which would double the callback surface), PushProgress now carries two kinds of updates through one channel:

Update type Phase LayerDigest / byte fields
Phase transition set (e.g. "exporting") zero/empty
Byte progress empty set (per-layer upload progress)

The CLI dispatches on prog.Phase != "" to show status-only lines vs progress bars — both rendered through the existing ProgressWriter.

Changes

  • pkg/model/push_helpers.go — Added PushPhase type with PushPhaseExporting and PushPhasePushing constants; extended PushProgress with Phase field
  • pkg/model/image_pusher.go — Emit phase callbacks via existing progressFn at export start and push start
  • pkg/model/pusher.go — Updated PushOptions.ImageProgressFn docs to reflect unified contract
  • pkg/cli/push.go — Handle phase updates in the progress callback, showing status lines during export
  • pkg/model/image_pusher_test.go — Updated test to verify both phase transitions and byte progress

During OCI push, the Docker image export phase (docker save → temp
tarball) was completely silent — the user saw nothing while potentially
large images were exported. This adds phase reporting through the
existing PushProgress callback so the CLI can display status messages
during the export.

Rather than adding a separate callback, PushProgress is extended with
a Phase field. Phase-only updates (Phase set, byte fields zero) signal
transitions between exporting and pushing; byte-progress updates
(Phase empty) report per-layer upload progress as before. This keeps
a single callback contract for all push progress.
@markphelps markphelps requested a review from a team as a code owner March 3, 2026 18:08
Phase transitions (exporting, pushing) now print via console.Infof for
pretty CLI formatting, while per-layer progress bars continue using the
JSON progress writer.
@markphelps markphelps requested a review from michaeldwan March 4, 2026 16:07
@michaeldwan michaeldwan added this to the 0.18.0 milestone Mar 5, 2026
During OCI push, the Docker image export phase (docker save → temp
tarball) was completely silent — the user saw nothing while potentially
large images were exported. This adds phase reporting through the
existing PushProgress callback so the CLI can display status messages
during the export.

Rather than adding a separate callback, PushProgress is extended with
a Phase field. Phase-only updates (Phase set, byte fields zero) signal
transitions between exporting and pushing; byte-progress updates
(Phase empty) report per-layer upload progress as before. This keeps
a single callback contract for all push progress.
Phase transitions (exporting, pushing) now print via console.Infof for
pretty CLI formatting, while per-layer progress bars continue using the
JSON progress writer.
@michaeldwan michaeldwan force-pushed the mphelps/push-phase-progress branch from d247f38 to ee74d41 Compare March 26, 2026 15:56
@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 8, 2026

Review: The deferred cleanup calls in image_pusher.go (around line 136) are in the wrong order. defer executes LIFO, so the file is deleted before it is closed. Swap the order of the defer calls so tmpTar.Close() runs first, then os.Remove().

@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 8, 2026

Review posted: #2797 (comment)

The defer calls at lines 135-137 execute in LIFO order, meaning os.Remove() runs before tmpTar.Close(). This deletes the file before closing it, which works on Unix but is incorrect and may fail on Windows. Swap the order so Close() runs first.

github run

markphelps and others added 3 commits April 8, 2026 16:00
…icate/cog into mphelps/push-phase-progress

* 'mphelps/push-phase-progress' of https://github.com/replicate/cog: (95 commits)
  feat: add metric name validation (#2911)
  Rename `cog run` to `cog exec` (#2916)
  chore(deps): bump github.com/google/go-containerregistry (#2884)
  fix: replace removed libgl1-mesa-glx in tensorflow integration test (#2914)
  ci: enforce stub freshness in CI, fix existing stub drift (#2912)
  feat: add schema-compare command to test harness (#2891)
  chore(deps): bump uuid from 1.22.0 to 1.23.0 in /crates (#2887)
  chore(deps): bump github.com/hashicorp/go-version from 1.7.0 to 1.9.0 (#2909)
  chore(deps): bump insta from 1.46.3 to 1.47.2 in /crates (#2908)
  fix: support list[X] | None inputs + integration tests for PEP 604 union File/Path coercion (#2882)
  ci: exclude Dependabot PRs from auto-code review (#2910)
  chore(deps): bump actions/checkout from 4 to 6 (#2904)
  chore(deps): bump github.com/testcontainers/testcontainers-go/modules/registry (#2886)
  fix: metrics bugs in coglet prediction server (#2896)
  Bump version to 0.17.2 (#2903)
  fix(coglet): propagate metric scope to async event loop thread (#2902)
  chore: remove unnecessary nolint directive in test (#2803)
  feat(coglet): add Sentry error reporting for infrastructure errors (#2865)
  fix: homebrew cask postflight xattr references wrong binary name (#2899)
  fix: include custom metrics in cog predict --json output (#2897)
  ...
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 8, 2026

I'm Bonk, and I've done a quick review of your PR.

Summary: Adds phase transition reporting (exportingpushing) to OCI image push via a unified callback mechanism, replacing the previously silent Docker export phase.

Issue:

  1. Go: Potential defer order issue - The deferred cleanup in image_pusher.go:137-140 needs verification. The current anonymous function calls tmpTar.Close() then os.Remove(). While this appears correct (Close before Remove), the PR comments suggest there may have been confusion. Please double-check that the file is closed before removal to avoid issues on Windows.

github run

@markphelps markphelps enabled auto-merge April 8, 2026 20:12
@markphelps markphelps added this pull request to the merge queue Apr 8, 2026
@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 8, 2026

After careful review, I don't see any actionable issues. The defer order concern from the previous review was based on a misunderstanding - the code uses an anonymous function where statements execute in written order (Close → Remove), not LIFO. This is correct.

The PR properly:

  • Adds phase reporting via the unified callback mechanism
  • Maintains backward compatibility
  • Includes comprehensive tests
  • Handles cleanup correctly

LGTM

github run

Merged via the queue into main with commit 1dd39f9 Apr 8, 2026
36 checks passed
@markphelps markphelps deleted the mphelps/push-phase-progress branch April 8, 2026 20:22
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