summaryrefslogtreecommitdiff
path: root/libpod/image
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/image')
-rw-r--r--libpod/image/docker_registry_options.go12
-rw-r--r--libpod/image/image.go284
-rw-r--r--libpod/image/image_test.go13
-rw-r--r--libpod/image/parts.go2
-rw-r--r--libpod/image/pull.go30
-rw-r--r--libpod/image/pull_test.go6
-rw-r--r--libpod/image/search.go4
-rw-r--r--libpod/image/utils.go22
8 files changed, 238 insertions, 135 deletions
diff --git a/libpod/image/docker_registry_options.go b/libpod/image/docker_registry_options.go
index d205fe4ac..62a4af465 100644
--- a/libpod/image/docker_registry_options.go
+++ b/libpod/image/docker_registry_options.go
@@ -3,8 +3,8 @@ package image
import (
"fmt"
- "github.com/containers/image/v4/docker/reference"
- "github.com/containers/image/v4/types"
+ "github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/types"
podmanVersion "github.com/containers/libpod/version"
)
@@ -26,6 +26,10 @@ type DockerRegistryOptions struct {
// certificates and allows connecting to registries without encryption
// - or forces it on even if registries.conf has the registry configured as insecure.
DockerInsecureSkipTLSVerify types.OptionalBool
+ // If not "", overrides the use of platform.GOOS when choosing an image or verifying OS match.
+ OSChoice string
+ // If not "", overrides the use of platform.GOARCH when choosing an image or verifying architecture match.
+ ArchitectureChoice string
}
// GetSystemContext constructs a new system context from a parent context. the values in the DockerRegistryOptions, and other parameters.
@@ -35,12 +39,16 @@ func (o DockerRegistryOptions) GetSystemContext(parent *types.SystemContext, add
DockerCertPath: o.DockerCertPath,
DockerInsecureSkipTLSVerify: o.DockerInsecureSkipTLSVerify,
DockerArchiveAdditionalTags: additionalDockerArchiveTags,
+ OSChoice: o.OSChoice,
+ ArchitectureChoice: o.ArchitectureChoice,
}
if parent != nil {
sc.SignaturePolicyPath = parent.SignaturePolicyPath
sc.AuthFilePath = parent.AuthFilePath
sc.DirForceCompress = parent.DirForceCompress
sc.DockerRegistryUserAgent = parent.DockerRegistryUserAgent
+ sc.OSChoice = parent.OSChoice
+ sc.ArchitectureChoice = parent.ArchitectureChoice
}
return sc
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 9adefb5c5..c912ac2ca 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -3,26 +3,29 @@ package image
import (
"context"
"encoding/json"
+ stderrors "errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
+ "sort"
"strings"
"syscall"
"time"
- cp "github.com/containers/image/v4/copy"
- "github.com/containers/image/v4/directory"
- dockerarchive "github.com/containers/image/v4/docker/archive"
- "github.com/containers/image/v4/docker/reference"
- "github.com/containers/image/v4/manifest"
- ociarchive "github.com/containers/image/v4/oci/archive"
- is "github.com/containers/image/v4/storage"
- "github.com/containers/image/v4/tarball"
- "github.com/containers/image/v4/transports"
- "github.com/containers/image/v4/transports/alltransports"
- "github.com/containers/image/v4/types"
+ cp "github.com/containers/image/v5/copy"
+ "github.com/containers/image/v5/directory"
+ dockerarchive "github.com/containers/image/v5/docker/archive"
+ "github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/image"
+ "github.com/containers/image/v5/manifest"
+ ociarchive "github.com/containers/image/v5/oci/archive"
+ is "github.com/containers/image/v5/storage"
+ "github.com/containers/image/v5/tarball"
+ "github.com/containers/image/v5/transports"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod/driver"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/inspect"
@@ -42,8 +45,8 @@ import (
type Image struct {
// Adding these two structs for now but will cull when we near
// completion of this library.
- imgRef types.Image
- storeRef types.ImageReference
+ imgRef types.Image
+ imgSrcRef types.ImageSource
inspect.ImageData
inspect.ImageResult
inspectInfo *types.ImageInspectInfo
@@ -72,7 +75,10 @@ type InfoImage struct {
}
// ErrRepoTagNotFound is the error returned when the image id given doesn't match a rep tag in store
-var ErrRepoTagNotFound = errors.New("unable to match user input to any specific repotag")
+var ErrRepoTagNotFound = stderrors.New("unable to match user input to any specific repotag")
+
+// ErrImageIsBareList is the error returned when the image is just a list or index
+var ErrImageIsBareList = stderrors.New("image contains a manifest list or image index, but no runnable image")
// NewImageRuntimeFromStore creates an ImageRuntime based on a provided store
func NewImageRuntimeFromStore(store storage.Store) *Runtime {
@@ -294,9 +300,23 @@ func (i *Image) Digest() digest.Digest {
return i.image.Digest
}
+// Digests returns the image's digests
+func (i *Image) Digests() []digest.Digest {
+ return i.image.Digests
+}
+
+// GetManifest returns the image's manifest as a byte array
+// and manifest type as a string.
+func (i *Image) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) {
+ imgSrcRef, err := i.toImageSourceRef(ctx)
+ if err != nil {
+ return nil, "", err
+ }
+ return imgSrcRef.GetManifest(ctx, instanceDigest)
+}
+
// Manifest returns the image's manifest as a byte array
-// and manifest type as a string. The manifest type is
-// MediaTypeImageManifest from ociv1.
+// and manifest type as a string.
func (i *Image) Manifest(ctx context.Context) ([]byte, string, error) {
imgRef, err := i.toImageRef(ctx)
if err != nil {
@@ -305,29 +325,54 @@ func (i *Image) Manifest(ctx context.Context) ([]byte, string, error) {
return imgRef.Manifest(ctx)
}
-// Names returns a string array of names associated with the image
+// Names returns a string array of names associated with the image, which may be a mixture of tags and digests
func (i *Image) Names() []string {
return i.image.Names
}
-// RepoDigests returns a string array of repodigests associated with the image
-func (i *Image) RepoDigests() ([]string, error) {
- var repoDigests []string
- imageDigest := i.Digest()
-
+// RepoTags returns a string array of repotags associated with the image
+func (i *Image) RepoTags() ([]string, error) {
+ var repoTags []string
for _, name := range i.Names() {
named, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, err
}
-
- canonical, err := reference.WithDigest(reference.TrimNamed(named), imageDigest)
- if err != nil {
- return nil, err
+ if tagged, isTagged := named.(reference.NamedTagged); isTagged {
+ repoTags = append(repoTags, tagged.String())
}
+ }
+ return repoTags, nil
+}
+
+// RepoDigests returns a string array of repodigests associated with the image
+func (i *Image) RepoDigests() ([]string, error) {
+ var repoDigests []string
+ added := make(map[string]struct{})
- repoDigests = append(repoDigests, canonical.String())
+ for _, name := range i.Names() {
+ for _, imageDigest := range append(i.Digests(), i.Digest()) {
+ if imageDigest == "" {
+ continue
+ }
+
+ named, err := reference.ParseNormalizedNamed(name)
+ if err != nil {
+ return nil, err
+ }
+
+ canonical, err := reference.WithDigest(reference.TrimNamed(named), imageDigest)
+ if err != nil {
+ return nil, err
+ }
+
+ if _, alreadyInList := added[canonical.String()]; !alreadyInList {
+ repoDigests = append(repoDigests, canonical.String())
+ added[canonical.String()] = struct{}{}
+ }
+ }
}
+ sort.Strings(repoDigests)
return repoDigests, nil
}
@@ -379,26 +424,6 @@ func (i *Image) Remove(ctx context.Context, force bool) error {
return nil
}
-// TODO: Rework this method to not require an assembly of the fq name with transport
-/*
-// GetManifest tries to GET an images manifest, returns nil on success and err on failure
-func (i *Image) GetManifest() error {
- pullRef, err := alltransports.ParseImageName(i.assembleFqNameTransport())
- if err != nil {
- return errors.Errorf("unable to parse '%s'", i.Names()[0])
- }
- imageSource, err := pullRef.NewImageSource(nil)
- if err != nil {
- return errors.Wrapf(err, "unable to create new image source")
- }
- _, _, err = imageSource.GetManifest(nil)
- if err == nil {
- return nil
- }
- return err
-}
-*/
-
// getImage retrieves an image matching the given name or hash from system
// storage
// If no matching image can be found, an error is returned
@@ -612,76 +637,98 @@ func (i *Image) PushImageToReference(ctx context.Context, dest types.ImageRefere
// MatchesID returns a bool based on if the input id
// matches the image's id
+// TODO: This isn't used anywhere, so remove it
func (i *Image) MatchesID(id string) bool {
return strings.HasPrefix(i.ID(), id)
}
-// toStorageReference returns a *storageReference from an Image
-func (i *Image) toStorageReference() (types.ImageReference, error) {
- var lookupName string
- if i.storeRef == nil {
- if i.image != nil {
- lookupName = i.ID()
- } else {
- lookupName = i.InputName
- }
- storeRef, err := is.Transport.ParseStoreReference(i.imageruntime.store, lookupName)
- if err != nil {
- return nil, err
- }
- i.storeRef = storeRef
- }
- return i.storeRef, nil
-}
-
// ToImageRef returns an image reference type from an image
// TODO: Hopefully we can remove this exported function for mheon
func (i *Image) ToImageRef(ctx context.Context) (types.Image, error) {
return i.toImageRef(ctx)
}
-// toImageRef returns an Image Reference type from an image
-func (i *Image) toImageRef(ctx context.Context) (types.Image, error) {
+// toImageSourceRef returns an ImageSource Reference type from an image
+func (i *Image) toImageSourceRef(ctx context.Context) (types.ImageSource, error) {
if i == nil {
- return nil, errors.Errorf("cannot convert nil image to image reference")
+ return nil, errors.Errorf("cannot convert nil image to image source reference")
}
- if i.imgRef == nil {
+ if i.imgSrcRef == nil {
ref, err := is.Transport.ParseStoreReference(i.imageruntime.store, "@"+i.ID())
if err != nil {
return nil, errors.Wrapf(err, "error parsing reference to image %q", i.ID())
}
- imgRef, err := ref.NewImage(ctx, nil)
+ imgSrcRef, err := ref.NewImageSource(ctx, nil)
if err != nil {
- return nil, errors.Wrapf(err, "error reading image %q", i.ID())
+ return nil, errors.Wrapf(err, "error reading image %q as image source", i.ID())
}
- i.imgRef = imgRef
+ i.imgSrcRef = imgSrcRef
}
- return i.imgRef, nil
-}
-
-// sizer knows its size.
-type sizer interface {
- Size() (int64, error)
+ return i.imgSrcRef, nil
}
//Size returns the size of the image
func (i *Image) Size(ctx context.Context) (*uint64, error) {
- storeRef, err := is.Transport.ParseStoreReference(i.imageruntime.store, i.ID())
- if err != nil {
- return nil, err
+ if i.image == nil {
+ localImage, err := i.getLocalImage()
+ if err != nil {
+ return nil, err
+ }
+ i.image = localImage
}
- systemContext := &types.SystemContext{}
- img, err := storeRef.NewImageSource(ctx, systemContext)
+ if sum, err := i.imageruntime.store.ImageSize(i.ID()); err == nil && sum >= 0 {
+ usum := uint64(sum)
+ return &usum, nil
+ }
+ return nil, errors.Errorf("unable to determine size")
+}
+
+// toImageRef returns an Image Reference type from an image
+func (i *Image) toImageRef(ctx context.Context) (types.Image, error) {
+ if i == nil {
+ return nil, errors.Errorf("cannot convert nil image to image reference")
+ }
+ imgSrcRef, err := i.toImageSourceRef(ctx)
if err != nil {
return nil, err
}
- if s, ok := img.(sizer); ok {
- if sum, err := s.Size(); err == nil {
- usum := uint64(sum)
- return &usum, nil
+ if i.imgRef == nil {
+ systemContext := &types.SystemContext{}
+ unparsedDefaultInstance := image.UnparsedInstance(imgSrcRef, nil)
+ imgRef, err := image.FromUnparsedImage(ctx, systemContext, unparsedDefaultInstance)
+ if err != nil {
+ // check for a "tried-to-treat-a-bare-list-like-a-runnable-image" problem, else
+ // return info about the not-a-bare-list runnable image part of this storage.Image
+ if manifestBytes, manifestType, err2 := imgSrcRef.GetManifest(ctx, nil); err2 == nil {
+ if manifest.MIMETypeIsMultiImage(manifestType) {
+ if list, err3 := manifest.ListFromBlob(manifestBytes, manifestType); err3 == nil {
+ switch manifestType {
+ case ociv1.MediaTypeImageIndex:
+ err = errors.Wrapf(ErrImageIsBareList, "%q is an image index", i.InputName)
+ case manifest.DockerV2ListMediaType:
+ err = errors.Wrapf(ErrImageIsBareList, "%q is a manifest list", i.InputName)
+ default:
+ err = errors.Wrapf(ErrImageIsBareList, "%q", i.InputName)
+ }
+ for _, instanceDigest := range list.Instances() {
+ instance := instanceDigest
+ unparsedInstance := image.UnparsedInstance(imgSrcRef, &instance)
+ if imgRef2, err4 := image.FromUnparsedImage(ctx, systemContext, unparsedInstance); err4 == nil {
+ imgRef = imgRef2
+ err = nil
+ break
+ }
+ }
+ }
+ }
+ }
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading image %q as image", i.ID())
+ }
}
+ i.imgRef = imgRef
}
- return nil, errors.Errorf("unable to determine size")
+ return i.imgRef, nil
}
// DriverData gets the driver data from the store on a layer
@@ -708,6 +755,9 @@ type History struct {
func (i *Image) History(ctx context.Context) ([]*History, error) {
img, err := i.toImageRef(ctx)
if err != nil {
+ if errors.Cause(err) == ErrImageIsBareList {
+ return nil, nil
+ }
return nil, err
}
oci, err := img.OCIConfig(ctx)
@@ -853,7 +903,10 @@ func (i *Image) GetLabel(ctx context.Context, label string) (string, error) {
func (i *Image) Annotations(ctx context.Context) (map[string]string, error) {
imageManifest, manifestType, err := i.Manifest(ctx)
if err != nil {
- return nil, err
+ imageManifest, manifestType, err = i.GetManifest(ctx, nil)
+ if err != nil {
+ return nil, err
+ }
}
annotations := make(map[string]string)
switch manifestType {
@@ -868,24 +921,19 @@ func (i *Image) Annotations(ctx context.Context) (map[string]string, error) {
return annotations, nil
}
-// ociv1Image converts and image to an imgref and then an
-// ociv1 image type
+// ociv1Image converts an image to an imgref and then returns its config blob
+// converted to an ociv1 image type
func (i *Image) ociv1Image(ctx context.Context) (*ociv1.Image, error) {
imgRef, err := i.toImageRef(ctx)
if err != nil {
return nil, err
}
-
return imgRef.OCIConfig(ctx)
}
func (i *Image) imageInspectInfo(ctx context.Context) (*types.ImageInspectInfo, error) {
if i.inspectInfo == nil {
- sr, err := i.toStorageReference()
- if err != nil {
- return nil, err
- }
- ic, err := sr.NewImage(ctx, &types.SystemContext{})
+ ic, err := i.toImageRef(ctx)
if err != nil {
return nil, err
}
@@ -906,18 +954,23 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
ociv1Img, err := i.ociv1Image(ctx)
if err != nil {
- return nil, err
+ ociv1Img = &ociv1.Image{}
}
info, err := i.imageInspectInfo(ctx)
if err != nil {
- return nil, err
+ info = &types.ImageInspectInfo{}
}
annotations, err := i.Annotations(ctx)
if err != nil {
return nil, err
}
- size, err := i.Size(ctx)
+ size := int64(-1)
+ if usize, err := i.Size(ctx); err == nil {
+ size = int64(*usize)
+ }
+
+ repoTags, err := i.RepoTags()
if err != nil {
return nil, err
}
@@ -932,7 +985,7 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
return nil, err
}
- _, manifestType, err := i.Manifest(ctx)
+ _, manifestType, err := i.GetManifest(ctx, nil)
if err != nil {
return nil, errors.Wrapf(err, "unable to determine manifest type")
}
@@ -943,7 +996,7 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
data := &inspect.ImageData{
ID: i.ID(),
- RepoTags: i.Names(),
+ RepoTags: repoTags,
RepoDigests: repoDigests,
Comment: comment,
Created: ociv1Img.Created,
@@ -952,8 +1005,8 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
Os: ociv1Img.OS,
Config: &ociv1Img.Config,
Version: info.DockerVersion,
- Size: int64(*size),
- VirtualSize: int64(*size),
+ Size: size,
+ VirtualSize: size,
Annotations: annotations,
Digest: i.Digest(),
Labels: info.Labels,
@@ -1082,6 +1135,9 @@ func splitString(input string) string {
func (i *Image) IsParent(ctx context.Context) (bool, error) {
children, err := i.getChildren(ctx, 1)
if err != nil {
+ if errors.Cause(err) == ErrImageIsBareList {
+ return false, nil
+ }
return false, err
}
return len(children) > 0, nil
@@ -1165,6 +1221,9 @@ func (i *Image) GetParent(ctx context.Context) (*Image, error) {
// fetch the configuration for the child image
child, err := i.ociv1Image(ctx)
if err != nil {
+ if errors.Cause(err) == ErrImageIsBareList {
+ return nil, nil
+ }
return nil, err
}
for _, img := range images {
@@ -1205,12 +1264,24 @@ func (i *Image) GetParent(ctx context.Context) (*Image, error) {
// GetChildren returns a list of the imageIDs that depend on the image
func (i *Image) GetChildren(ctx context.Context) ([]string, error) {
- return i.getChildren(ctx, 0)
+ children, err := i.getChildren(ctx, 0)
+ if err != nil {
+ if errors.Cause(err) == ErrImageIsBareList {
+ return nil, nil
+ }
+ return nil, err
+ }
+ return children, nil
}
// getChildren returns a list of at most "max" imageIDs that depend on the image
func (i *Image) getChildren(ctx context.Context, max int) ([]string, error) {
var children []string
+
+ if _, err := i.toImageRef(ctx); err != nil {
+ return nil, nil
+ }
+
images, err := i.imageruntime.GetImages()
if err != nil {
return nil, err
@@ -1301,6 +1372,9 @@ func (i *Image) Comment(ctx context.Context, manifestType string) (string, error
}
ociv1Img, err := i.ociv1Image(ctx)
if err != nil {
+ if errors.Cause(err) == ErrImageIsBareList {
+ return "", nil
+ }
return "", err
}
if len(ociv1Img.History) > 0 {
diff --git a/libpod/image/image_test.go b/libpod/image/image_test.go
index ef39d09c3..5aff7d860 100644
--- a/libpod/image/image_test.go
+++ b/libpod/image/image_test.go
@@ -247,6 +247,19 @@ func TestImage_RepoDigests(t *testing.T) {
}
assert.Equal(t, test.expected, actual)
+
+ image = &Image{
+ image: &storage.Image{
+ Names: test.names,
+ Digests: []digest.Digest{dgst},
+ },
+ }
+ actual, err = image.RepoDigests()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ assert.Equal(t, test.expected, actual)
})
}
}
diff --git a/libpod/image/parts.go b/libpod/image/parts.go
index 69bc44cdd..d4677f935 100644
--- a/libpod/image/parts.go
+++ b/libpod/image/parts.go
@@ -3,7 +3,7 @@ package image
import (
"strings"
- "github.com/containers/image/v4/docker/reference"
+ "github.com/containers/image/v5/docker/reference"
"github.com/pkg/errors"
)
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index 36950b6f3..7f5dc33b9 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -7,17 +7,17 @@ import (
"path/filepath"
"strings"
- cp "github.com/containers/image/v4/copy"
- "github.com/containers/image/v4/directory"
- "github.com/containers/image/v4/docker"
- dockerarchive "github.com/containers/image/v4/docker/archive"
- "github.com/containers/image/v4/docker/tarfile"
- ociarchive "github.com/containers/image/v4/oci/archive"
- oci "github.com/containers/image/v4/oci/layout"
- is "github.com/containers/image/v4/storage"
- "github.com/containers/image/v4/transports"
- "github.com/containers/image/v4/transports/alltransports"
- "github.com/containers/image/v4/types"
+ cp "github.com/containers/image/v5/copy"
+ "github.com/containers/image/v5/directory"
+ "github.com/containers/image/v5/docker"
+ dockerarchive "github.com/containers/image/v5/docker/archive"
+ "github.com/containers/image/v5/docker/tarfile"
+ ociarchive "github.com/containers/image/v5/oci/archive"
+ oci "github.com/containers/image/v5/oci/layout"
+ is "github.com/containers/image/v5/storage"
+ "github.com/containers/image/v5/transports"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/registries"
"github.com/hashicorp/go-multierror"
@@ -223,6 +223,10 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s
var goal *pullGoal
sc := GetSystemContext(signaturePolicyPath, authfile, false)
+ if dockerOptions != nil {
+ sc.OSChoice = dockerOptions.OSChoice
+ sc.ArchitectureChoice = dockerOptions.ArchitectureChoice
+ }
sc.BlobInfoCacheDir = filepath.Join(ir.store.GraphRoot(), "cache")
srcRef, err := alltransports.ParseImageName(inputName)
if err != nil {
@@ -246,6 +250,10 @@ func (ir *Runtime) pullImageFromReference(ctx context.Context, srcRef types.Imag
defer span.Finish()
sc := GetSystemContext(signaturePolicyPath, authfile, false)
+ if dockerOptions != nil {
+ sc.OSChoice = dockerOptions.OSChoice
+ sc.ArchitectureChoice = dockerOptions.ArchitectureChoice
+ }
goal, err := ir.pullGoalFromImageReference(ctx, srcRef, transports.ImageName(srcRef), sc)
if err != nil {
return nil, errors.Wrapf(err, "error determining pull goal for image %q", transports.ImageName(srcRef))
diff --git a/libpod/image/pull_test.go b/libpod/image/pull_test.go
index 131b8b1f6..0046cdfef 100644
--- a/libpod/image/pull_test.go
+++ b/libpod/image/pull_test.go
@@ -9,9 +9,9 @@ import (
"strings"
"testing"
- "github.com/containers/image/v4/transports"
- "github.com/containers/image/v4/transports/alltransports"
- "github.com/containers/image/v4/types"
+ "github.com/containers/image/v5/transports"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
"github.com/stretchr/testify/assert"
diff --git a/libpod/image/search.go b/libpod/image/search.go
index 0313c2d6e..fd29dac45 100644
--- a/libpod/image/search.go
+++ b/libpod/image/search.go
@@ -6,8 +6,8 @@ import (
"strings"
"sync"
- "github.com/containers/image/v4/docker"
- "github.com/containers/image/v4/types"
+ "github.com/containers/image/v5/docker"
+ "github.com/containers/image/v5/types"
sysreg "github.com/containers/libpod/pkg/registries"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
diff --git a/libpod/image/utils.go b/libpod/image/utils.go
index e4ff1cfc4..b7ea63c66 100644
--- a/libpod/image/utils.go
+++ b/libpod/image/utils.go
@@ -7,10 +7,10 @@ import (
"regexp"
"strings"
- cp "github.com/containers/image/v4/copy"
- "github.com/containers/image/v4/docker/reference"
- "github.com/containers/image/v4/signature"
- "github.com/containers/image/v4/types"
+ cp "github.com/containers/image/v5/copy"
+ "github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/signature"
+ "github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/pkg/errors"
)
@@ -87,18 +87,18 @@ func hasTransport(image string) bool {
}
// ReposToMap parses the specified repotags and returns a map with repositories
-// as keys and the corresponding arrays of tags as values.
-func ReposToMap(repotags []string) (map[string][]string, error) {
- // map format is repo -> tag
+// as keys and the corresponding arrays of tags or digests-as-strings as values.
+func ReposToMap(names []string) (map[string][]string, error) {
+ // map format is repo -> []tag-or-digest
repos := make(map[string][]string)
- for _, repo := range repotags {
+ for _, name := range names {
var repository, tag string
- if len(repo) > 0 {
- named, err := reference.ParseNormalizedNamed(repo)
- repository = named.Name()
+ if len(name) > 0 {
+ named, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, err
}
+ repository = named.Name()
if ref, ok := named.(reference.NamedTagged); ok {
tag = ref.Tag()
} else if ref, ok := named.(reference.Canonical); ok {