mirror of
https://github.com/containers/podman.git
synced 2025-12-15 11:42:28 +08:00
Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.13.2 to 5.14.0. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.13.2...v5.14.0) --- updated-dependencies: - dependency-name: github.com/containers/image/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
121 lines
4.5 KiB
Go
121 lines
4.5 KiB
Go
package archive
|
|
|
|
import (
|
|
"github.com/containers/image/v5/docker/internal/tarfile"
|
|
"github.com/containers/image/v5/docker/reference"
|
|
"github.com/containers/image/v5/transports"
|
|
"github.com/containers/image/v5/types"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Reader manages a single Docker archive, allows listing its contents and accessing
|
|
// individual images with less overhead than creating image references individually
|
|
// (because the archive is, if necessary, copied or decompressed only once).
|
|
type Reader struct {
|
|
path string // The original, user-specified path; not the maintained temporary file, if any
|
|
archive *tarfile.Reader
|
|
}
|
|
|
|
// NewReader returns a Reader for path.
|
|
// The caller should call .Close() on the returned object.
|
|
func NewReader(sys *types.SystemContext, path string) (*Reader, error) {
|
|
archive, err := tarfile.NewReaderFromFile(sys, path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Reader{
|
|
path: path,
|
|
archive: archive,
|
|
}, nil
|
|
}
|
|
|
|
// Close deletes temporary files associated with the Reader, if any.
|
|
func (r *Reader) Close() error {
|
|
return r.archive.Close()
|
|
}
|
|
|
|
// NewReaderForReference creates a Reader from a Reader-independent imageReference, which must be from docker/archive.Transport,
|
|
// and a variant of imageReference that points at the same image within the reader.
|
|
// The caller should call .Close() on the returned Reader.
|
|
func NewReaderForReference(sys *types.SystemContext, ref types.ImageReference) (*Reader, types.ImageReference, error) {
|
|
standalone, ok := ref.(archiveReference)
|
|
if !ok {
|
|
return nil, nil, errors.Errorf("Internal error: NewReaderForReference called for a non-docker/archive ImageReference %s", transports.ImageName(ref))
|
|
}
|
|
if standalone.archiveReader != nil {
|
|
return nil, nil, errors.Errorf("Internal error: NewReaderForReference called for a reader-bound reference %s", standalone.StringWithinTransport())
|
|
}
|
|
reader, err := NewReader(sys, standalone.path)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
succeeded := false
|
|
defer func() {
|
|
if !succeeded {
|
|
reader.Close()
|
|
}
|
|
}()
|
|
readerRef, err := newReference(standalone.path, standalone.ref, standalone.sourceIndex, reader.archive, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
succeeded = true
|
|
return reader, readerRef, nil
|
|
}
|
|
|
|
// List returns the a set of references for images in the Reader,
|
|
// grouped by the image the references point to.
|
|
// The references are valid only until the Reader is closed.
|
|
func (r *Reader) List() ([][]types.ImageReference, error) {
|
|
res := [][]types.ImageReference{}
|
|
for imageIndex, image := range r.archive.Manifest {
|
|
refs := []types.ImageReference{}
|
|
for _, tag := range image.RepoTags {
|
|
parsedTag, err := reference.ParseNormalizedNamed(tag)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "Invalid tag %#v in manifest item @%d", tag, imageIndex)
|
|
}
|
|
nt, ok := parsedTag.(reference.NamedTagged)
|
|
if !ok {
|
|
return nil, errors.Errorf("Invalid tag %s (%s): does not contain a tag", tag, parsedTag.String())
|
|
}
|
|
ref, err := newReference(r.path, nt, -1, r.archive, nil)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "creating a reference for tag %#v in manifest item @%d", tag, imageIndex)
|
|
}
|
|
refs = append(refs, ref)
|
|
}
|
|
if len(refs) == 0 {
|
|
ref, err := newReference(r.path, nil, imageIndex, r.archive, nil)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "creating a reference for manifest item @%d", imageIndex)
|
|
}
|
|
refs = append(refs, ref)
|
|
}
|
|
res = append(res, refs)
|
|
}
|
|
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
|
|
}
|