diff options
author | Qi Wang <qiwan@redhat.com> | 2020-09-26 19:49:43 -0400 |
---|---|---|
committer | Qi Wang <qiwan@redhat.com> | 2020-09-30 10:38:02 -0400 |
commit | d24ec648873698bac14047e0af128099186e38d3 (patch) | |
tree | 49facc61f8ecfcb6d076cec2d5043c2fd2cc1bc1 | |
parent | 2ee415be90b8d6ab75f9fe579fc1b8690e023d3c (diff) | |
download | podman-d24ec648873698bac14047e0af128099186e38d3.tar.gz podman-d24ec648873698bac14047e0af128099186e38d3.tar.bz2 podman-d24ec648873698bac14047e0af128099186e38d3.zip |
Use local image if input image is a manifest list
If run&create image returns error: image contains manifest list, not a runnable image, find the local image that has digest matching the digest from the list and use the image from local storage for the command.
Signed-off-by: Qi Wang <qiwan@redhat.com>
-rw-r--r-- | pkg/specgen/generate/container.go | 39 | ||||
-rw-r--r-- | test/e2e/create_test.go | 17 |
2 files changed, 55 insertions, 1 deletions
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 147ebd61b..592e194aa 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -13,6 +13,7 @@ import ( "github.com/containers/podman/v2/pkg/specgen" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -33,7 +34,43 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat _, mediaType, err := newImage.Manifest(ctx) if err != nil { - return nil, err + if errors.Cause(err) != image.ErrImageIsBareList { + return nil, err + } + // if err is not runnable image + // use the local store image with repo@digest matches with the list, if exists + manifestByte, manifestType, err := newImage.GetManifest(ctx, nil) + if err != nil { + return nil, err + } + list, err := manifest.ListFromBlob(manifestByte, manifestType) + if err != nil { + return nil, err + } + images, err := r.ImageRuntime().GetImages() + if err != nil { + return nil, err + } + findLocal := false + listDigest, err := list.ChooseInstance(r.SystemContext()) + if err != nil { + return nil, err + } + for _, img := range images { + for _, imageDigest := range img.Digests() { + if imageDigest == listDigest { + newImage = img + s.Image = img.ID() + mediaType = manifestType + findLocal = true + logrus.Debug("image contains manifest list, using image from local storage") + break + } + } + } + if !findLocal { + return nil, image.ErrImageIsBareList + } } if s.HealthConfig == nil && mediaType == manifest.DockerV2Schema2MediaType { diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 45dbe9b56..3045bc7f4 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -609,4 +609,21 @@ var _ = Describe("Podman create", func() { Expect(session.ExitCode()).ToNot(BeZero()) }) + It("create use local store image if input image contains a manifest list", func() { + session := podmanTest.Podman([]string{"pull", BB}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + session = podmanTest.Podman([]string{"manifest", "create", "mylist"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"manifest", "add", "--all", "mylist", BB}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + + session = podmanTest.Podman([]string{"create", "mylist"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + }) }) |