Skip to content

fix(push): accept a registry with a path in cross-mount hints - #877

Merged
malt3 merged 1 commit into
bazel-contrib:mainfrom
kechen-xai:fix-cross-mount-registry-path
Nov 11, 2026
Merged

malt3 merged 1 commit into
bazel-contrib:mainfrom
kechen-xai:fix-cross-mount-registry-path

Conversation

@kechen-xai

Copy link
Copy Markdown
Contributor

Problem

A push destination may name its registry as a host followed by a path, for example registry = "reg.example.com/project/images" with repository = "app". Pushes join registry and repository before parsing them (img push blob, img deploy), so this form works there.

A cross-mount hint carries the same registry string, and VFS.Layer parsed it on its own with name.NewRegistry, which accepts a host only. With such a destination, every push that resolves a layer through a hint fails before sending a request:

Error: push at build time failed: pushing manifests: getting layer sha256:…: parsing cross-mount registry "reg.example.com/project/images": registries must be valid RFC 3986 URI authorities: reg.example.com/project/images

This breaks the manifest push of push at build time (push_at_build_time_content=all or blobs_and_manifests), where each img push blob result becomes a hint. The blob pushes of the same build succeed, so the build fails only at its last push action.

Fix

VFS.Layer splits the hint's registry at the first slash, parses the host as the registry, and puts the path in front of the repository. The mount reference for the example above is registry reg.example.com, repository project/images/app, which is what the destination itself parses to.

A registry without a path resolves as before, including a host without a dot (registry) and a hint with no registry. That is why the hint is not parsed with name.NewRepository(registry + "/" + repository): for those two forms it would read the first path segment differently than name.NewRegistry does today.

Tests

  • TestVFSLayerCrossMountHintRegistryForms covers host, host and port, host without a dot, host and path, host with port and path, a trailing slash, and no registry. The three path cases fail without the fix, with the error above.
  • TestVFSLayerRejectsInvalidCrossMountRegistry checks that an invalid host still fails and that the error quotes the registry as written.
  • bazel test @rules_img_tool//pkg/deployvfs/... @rules_img_tool//pkg/push/... @rules_img_tool//cmd/push/... @rules_img_tool//cmd/deploy/... @rules_img_tool//cmd/deploymetadata/... passes.
  • By hand: img push manifest for a one-image index with registry localhost:5917/proj/images, against a stub registry that logs requests. The 0.3.24 binary fails with the error above. The patched binary exits 0, mounts the layers with from=proj/images/<repository>, and writes both manifests and the tag.

A push destination may name its registry as a host followed by a path,
for example `registry = "reg.example.com/project/images"` with
`repository = "app"`. Pushes join registry and repository before parsing
them (`img push blob`, `img deploy`), so this form works there.

A cross-mount hint carries the same registry string, and `VFS.Layer`
parsed it on its own with `name.NewRegistry`, which accepts a host only.
With such a destination, every push that resolves a layer through a hint
failed before sending a request:

    parsing cross-mount registry "reg.example.com/project/images":
    registries must be valid RFC 3986 URI authorities

This breaks the manifest push of push at build time, where each
`img push blob` result becomes a hint, and any other push whose hint
names such a registry.

`VFS.Layer` now splits the hint's registry at the first slash, parses the
host as the registry, and puts the path in front of the repository. A
registry without a path resolves as before, including a host without a
dot and a hint with no registry.

@malt3 malt3 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks!

@malt3
malt3 enabled auto-merge November 11, 2026 18:34
@malt3
malt3 added this pull request to the merge queue Nov 11, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 11, 2026
@malt3
malt3 added this pull request to the merge queue Nov 11, 2026
Merged via the queue into bazel-contrib:main with commit dcb021d Nov 11, 2026
13 checks passed
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