mirror of https://github.com/containers/image.git
Add docker/archive.Reader.ManifestTagsForReference
to allow Podman default to localhost/$tag for unqualified $tag values in docker-archive tarnballs. (Note that only projectatomic/docker creates such tarballs; almost no-one else should use this.) Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
parent
9e23cf4b16
commit
2de48430e9
|
|
@ -96,3 +96,25 @@ func (r *Reader) List() ([][]types.ImageReference, error) {
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ManifestTagsForReference returns the set of tags “matching” ref in reader, as strings
|
||||||
|
// (i.e. exposing the short names before normalization).
|
||||||
|
// The function reports an error if ref does not identify a single image.
|
||||||
|
// If ref contains a NamedTagged reference, only a single tag “matching” ref is returned;
|
||||||
|
// If ref contains a source index, or neither a NamedTagged nor a source index, all tags
|
||||||
|
// matching the image are returned.
|
||||||
|
// Almost all users should use List() or ImageReference.DockerReference() instead.
|
||||||
|
func (r *Reader) ManifestTagsForReference(ref types.ImageReference) ([]string, error) {
|
||||||
|
archiveRef, ok := ref.(archiveReference)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("Internal error: ManifestTagsForReference called for a non-docker/archive ImageReference %s", transports.ImageName(ref))
|
||||||
|
}
|
||||||
|
manifestItem, tagIndex, err := r.archive.ChooseManifestItem(archiveRef.ref, archiveRef.sourceIndex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if tagIndex != -1 {
|
||||||
|
return []string{manifestItem.RepoTags[tagIndex]}, nil
|
||||||
|
}
|
||||||
|
return manifestItem.RepoTags, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,41 +130,43 @@ func (r *Reader) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// chooseManifestItem selects a manifest item from r.Manifest matching (ref, sourceIndex), one or
|
// ChooseManifestItem selects a manifest item from r.Manifest matching (ref, sourceIndex), one or
|
||||||
// both of which should be (nil, -1).
|
// both of which should be (nil, -1).
|
||||||
func (r *Reader) chooseManifestItem(ref reference.NamedTagged, sourceIndex int) (*ManifestItem, error) {
|
// On success, it returns the manifest item and an index of the matching tag, if a tag was used
|
||||||
|
// for matching; the index is -1 if a tag was not used.
|
||||||
|
func (r *Reader) ChooseManifestItem(ref reference.NamedTagged, sourceIndex int) (*ManifestItem, int, error) {
|
||||||
switch {
|
switch {
|
||||||
case ref != nil && sourceIndex != -1:
|
case ref != nil && sourceIndex != -1:
|
||||||
return nil, errors.Errorf("Internal error: Cannot have both ref %s and source index @%d",
|
return nil, -1, errors.Errorf("Internal error: Cannot have both ref %s and source index @%d",
|
||||||
ref.String(), sourceIndex)
|
ref.String(), sourceIndex)
|
||||||
|
|
||||||
case ref != nil:
|
case ref != nil:
|
||||||
refString := ref.String()
|
refString := ref.String()
|
||||||
for i := range r.Manifest {
|
for i := range r.Manifest {
|
||||||
for _, tag := range r.Manifest[i].RepoTags {
|
for tagIndex, tag := range r.Manifest[i].RepoTags {
|
||||||
parsedTag, err := reference.ParseNormalizedNamed(tag)
|
parsedTag, err := reference.ParseNormalizedNamed(tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "Invalid tag %#v in manifest.json item @%d", tag, i)
|
return nil, -1, errors.Wrapf(err, "Invalid tag %#v in manifest.json item @%d", tag, i)
|
||||||
}
|
}
|
||||||
if parsedTag.String() == refString {
|
if parsedTag.String() == refString {
|
||||||
return &r.Manifest[i], nil
|
return &r.Manifest[i], tagIndex, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, errors.Errorf("Tag %#v not found", refString)
|
return nil, -1, errors.Errorf("Tag %#v not found", refString)
|
||||||
|
|
||||||
case sourceIndex != -1:
|
case sourceIndex != -1:
|
||||||
if sourceIndex >= len(r.Manifest) {
|
if sourceIndex >= len(r.Manifest) {
|
||||||
return nil, errors.Errorf("Invalid source index @%d, only %d manifest items available",
|
return nil, -1, errors.Errorf("Invalid source index @%d, only %d manifest items available",
|
||||||
sourceIndex, len(r.Manifest))
|
sourceIndex, len(r.Manifest))
|
||||||
}
|
}
|
||||||
return &r.Manifest[sourceIndex], nil
|
return &r.Manifest[sourceIndex], -1, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if len(r.Manifest) != 1 {
|
if len(r.Manifest) != 1 {
|
||||||
return nil, errors.Errorf("Unexpected tar manifest.json: expected 1 item, got %d", len(r.Manifest))
|
return nil, -1, errors.Errorf("Unexpected tar manifest.json: expected 1 item, got %d", len(r.Manifest))
|
||||||
}
|
}
|
||||||
return &r.Manifest[0], nil
|
return &r.Manifest[0], -1, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func (s *Source) ensureCachedDataIsPresent() error {
|
||||||
// ensureCachedDataIsPresentPrivate is a private implementation detail of ensureCachedDataIsPresent.
|
// ensureCachedDataIsPresentPrivate is a private implementation detail of ensureCachedDataIsPresent.
|
||||||
// Call ensureCachedDataIsPresent instead.
|
// Call ensureCachedDataIsPresent instead.
|
||||||
func (s *Source) ensureCachedDataIsPresentPrivate() error {
|
func (s *Source) ensureCachedDataIsPresentPrivate() error {
|
||||||
tarManifest, err := s.archive.chooseManifestItem(s.ref, s.sourceIndex)
|
tarManifest, _, err := s.archive.ChooseManifestItem(s.ref, s.sourceIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue