{{ message }}
Repository navigation
[release/2.2] core/unpack: fetch layers of every config-sharing manifest - #14140
Merged
samuelkarp merged 1 commit intoSep 11, 2026
Merged
Conversation
An index can carry more than one manifest that shares a config. A config lists uncompressed layer digests, so packaging the same layers with different compression (which `podman manifest push --add-compression` does) produces manifests with identical configs and the same config digest. Right now, when the unpacker visits a manifest, it stores its layers in a map keyed by its config's digest, so they can be unpacked later once the config descriptor is visited. Because that map holds only one manifest's layers per digest, when more than one manifest shares a config, only the last visited manifest's layers are stored (and unpacked), and the others' layers are never fetched. Image pulls still report success, but a later export or push of the image fails with NotFound. Fix this by changing the map to store the layers for all manifests pointing at a specific config (instead of just one manifest). This means manifests sharing the same config result in more than one set of layers being stored for the same config digest. Because manifests that share a config unpack to the same snapshot chain, we only need to unpack the first manifest's layers, and fetch the others (so their blobs reach the content store). Unpack skips fetching a layer whose snapshot already exists, so once a second manifest shares the config, the first manifest's layers are also fetched explicitly; a config named by a single manifest keeps that skip. Note that for indexes with more than one config-sharing manifest, this will now result in additional download time and storage for those layers. Don't store anything for a manifest with no layers; an empty slice reaching the unpack would fail the pull. (cherry picked from commit 3c5d9fe) Include the registry test helper needed by the regression tests. Assisted-by: Claude Code Signed-off-by: Chris Henzie <chrishenzie@gmail.com>
fuweid
approved these changes
Sep 11, 2026
samuelkarp
approved these changes
Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

An index can carry more than one manifest that shares a config. A config lists uncompressed layer digests, so packaging the same layers with different compression (which
podman manifest push --add-compressiondoes) produces manifests with identical configs and the same config digest.Right now, when the unpacker visits a manifest, it stores its layers in a map keyed by its config's digest, so they can be unpacked later once the config descriptor is visited. Because that map holds only one manifest's layers per digest, when more than one manifest shares a config, only the last visited manifest's layers are stored (and unpacked), and the others' layers are never fetched. Image pulls still report success, but a later export or push of the image fails with NotFound.
Fix this by changing the map to store the layers for all manifests pointing at a specific config (instead of just one manifest). This means manifests sharing the same config result in more than one set of layers being stored for the same config digest. Because manifests that share a config unpack to the same snapshot chain, we only need to unpack the first manifest's layers, and fetch the others (so their blobs reach the content store). Unpack skips fetching a layer whose snapshot already exists, so once a second manifest shares the config, the first manifest's layers are also fetched explicitly; a config named by a single manifest keeps that skip. Note that for indexes with more than one config-sharing manifest, this will now result in additional download time and storage for those layers.
Don't store anything for a manifest with no layers; an empty slice reaching the unpack would fail the pull.
(cherry picked from commit 3c5d9fe)
Include the registry test helper needed by the regression tests.
Assisted-by: Claude Code