Add pushes API for exporting images to remote registries - #353
Conversation
3529276 to
143d09b
Compare
912ae22 to
f2ee13c
Compare
8eefe9c to
d90000d
Compare
90d7da1 to
9302c19
Compare
|
reviewed — solid, well-tested layer 3: clean handler wiring, thorough error mapping, good happy-path tests. the bugs, nits, and the interface/timing structural items are fixed in Structural / Maintainability (open)
Questions (open)
Notes
status: all review findings addressed except the listed deferrals |
9302c19 to
fa579f0
Compare
fa579f0 to
b244f44
Compare
b244f44 to
dbd4c99
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 22a1dfe. Configure here.
-->
✱ stlc build✅ go code · compare
✅ typescript code · compare
Diagnostics: 💡 0 new / 5 total note
Build metadata
This comment is auto-generated by stlc and is kept up to date as you push. |
22a1dfe to
846fef3
Compare
POST /pushes creates a push job exporting a ready hypeman image from
the OCI cache to a remote registry; GET /pushes and GET /pushes/{id}
expose job state. Requests may lend registry credentials, which the
push manager borrows for that job only and never persists; without
them the server's own credentials resolve via the Docker keychain.
Routes use the existing image:read/image:write scopes, the push queue
concurrency is configurable, and in-flight push digests are composed
into the OCI cache GC roots.
- Pin x-enum-varnames on PushStatus so generated constants carry the PushStatus prefix like the other enums, avoiding bare Failed/Queued names in the oapi package. - Treat an empty credentials object the same as absent credentials so the server's default credential resolution stays in effect instead of pushing with an empty auth config.
Without a pushes resource, generated SDK clients omit the push API even though the server exposes it. Mirrors the builds resource mapping.
846fef3 to
7448f03
Compare

Layer 3 of remote registry push support (stacked on #348, #350).
What
The HTTP surface for outbound pushes, docker-aligned credentials included.
API (openapi.yaml → generated)
POST /pushes→ 202 + Push job. Body:image(hypeman image, must beready),target(full remote ref), optionalinsecure, optionalcredentialsGET /pushes(newest first),GET /pushes/{id}queued → pushing → pushed/failedwith queue position, error, layers/bytes, timestampsCredentials — borrow, don't store
credentials(username/password/registry_token, mirroring docker config.json fields) map to anauthn.AuthConfigand are borrowed for that single push only — never persisted (asserted in layer 2) or loggedimage:write(POST) /image:read(GET) — no new scope plumbing, existing tokens workWiring
ProvidePushManager(resolver = image manager, concurrency fromlimits.max_concurrent_pushes, default 2)ApiService.PushManager+ wire regencompositeOCICacheRootsin main.go feeds the OCI cache GC both the registry's BuildKit cache tags and the push manager's in-flight digests (imagepush.ManagergainsLiveCacheManifestDigeststo satisfyocicachegc.RootsProvider)Tests
Handler-level with a fake push manager (hermetic, follows the images_test pattern): request + credentials mapping, nil-credentials fallback, full error-status mapping table, get-not-found, list empty/all with layers/bytes mapping.
Notes
lib/oapi/oapi.goregenerated viamake oapi-generate(pinned oapi-codegen v2.5.1); the embedded-spec blob diff includes the pre-existing compression drift any regen under the current Go toolchain produces on main toowire_gen.goregenerated with wire v0.6.0GET /pushes/{id}(builds-style events can be a follow-up)Verification
go build -tags containers_image_openpgp ./...— full tree buildslib/scopes,lib/providers,cmd/api/config, and all push/image packages passNote
Medium Risk
Touches image export, transient registry credentials in requests, and OCI cache GC roots—incorrect GC or credential handling could break pushes or delete blobs mid-upload, but scope is bounded to new push paths and existing image scopes.
Overview
Adds HTTP endpoints to queue and track outbound image pushes from the local OCI cache to remote registries:
POST /pushes(202),GET /pushes, andGET /pushes/{id}. Handlers delegate toimagepush.Manager, map domain errors to 400/404/409 responses, and translate push jobs to OpenAPIPushobjects (optionallayers/bytesomitted when zero).Credentials are borrowed per request only: optional
credentials(username/password/registry_token) becomeauthn.AuthConfig; absent or empty objects staynilso the server’s default Docker keychain resolution is unchanged.Wiring and limits:
PushManageris injected via Wire/ProvidePushManagerwithlimits.max_concurrent_pushes(default 2). Auth scopes reuse existing image:write / image:read for push routes.OCI cache GC: In-flight push manifest digests are merged with registry BuildKit roots through
compositeOCICacheRoots;imagepush.ManagerimplementsLiveCacheManifestDigestsforocicachegc.RootsProvider.OpenAPI/oapi client and server code is regenerated; handler tests cover credential mapping, error mapping, and list/get behavior.
Reviewed by Cursor Bugbot for commit 7448f03. Bugbot is set up for automated code reviews on this repo. Configure here.