fix pull image that includes a sha

when pulling an image that includes a sha such as:

centos/nginx-112-centos7@sha256:42330f7f29ba1ad67819f4ff3ae2472f62de13a827a74736a5098728462212e7

the final image name in libpod should not contain portions of the sha itself nor the sha
identifier.  and like docker, we provide a 'none' tag as well.

this should fix #877

Signed-off-by: baude <bbaude@redhat.com>

Closes: #1085
Approved by: mheon
This commit is contained in:
baude
2018-07-12 13:44:26 -05:00
committed by Atomic Bot
parent a2dde5a50d
commit 6f1dd44b29
4 changed files with 40 additions and 8 deletions

View File

@ -1055,3 +1055,9 @@ func (i *Image) Comment(ctx context.Context, manifestType string) (string, error
}
return ociv1Img.History[0].Comment, nil
}
// HasShaInInputName returns a bool as to whether the user provide an image name that includes
// a reference to a specific sha
func (i *Image) HasShaInInputName() bool {
return strings.Contains(i.InputName, "@sha256:")
}

View File

@ -2,6 +2,7 @@ package image
import (
"fmt"
"strings"
"github.com/containers/image/docker/reference"
)
@ -33,6 +34,9 @@ func decompose(input string) (imageParts, error) {
}
if !isTagged {
tag = "latest"
if strings.Contains(input, "@sha256:") {
tag = "none"
}
} else {
tag = ntag.Tag()
}

View File

@ -49,9 +49,10 @@ var (
)
type pullStruct struct {
image string
srcRef types.ImageReference
dstRef types.ImageReference
image string
srcRef types.ImageReference
dstRef types.ImageReference
shaPullName string
}
func (ir *Runtime) getPullStruct(srcRef types.ImageReference, destName string) (*pullStruct, error) {
@ -247,13 +248,22 @@ func (i *Image) pullImage(ctx context.Context, writer io.Writer, authfile, signa
// createNamesToPull looks at a decomposed image and determines the possible
// images names to try pulling in combination with the registries.conf file as well
func (i *Image) createNamesToPull() ([]*pullStruct, error) {
var pullNames []*pullStruct
var (
pullNames []*pullStruct
imageName string
)
decomposedImage, err := decompose(i.InputName)
if err != nil {
return nil, err
}
if decomposedImage.hasRegistry {
srcRef, err := alltransports.ParseImageName(decomposedImage.assembleWithTransport())
if i.HasShaInInputName() {
imageName = fmt.Sprintf("%s%s", decomposedImage.transport, i.InputName)
} else {
imageName = decomposedImage.assembleWithTransport()
}
srcRef, err := alltransports.ParseImageName(imageName)
if err != nil {
return nil, errors.Wrapf(err, "unable to parse '%s'", i.InputName)
}
@ -261,6 +271,9 @@ func (i *Image) createNamesToPull() ([]*pullStruct, error) {
image: i.InputName,
srcRef: srcRef,
}
if i.HasShaInInputName() {
ps.shaPullName = decomposedImage.assemble()
}
pullNames = append(pullNames, &ps)
} else {
@ -275,7 +288,11 @@ func (i *Image) createNamesToPull() ([]*pullStruct, error) {
}
for _, registry := range searchRegistries {
decomposedImage.registry = registry
srcRef, err := alltransports.ParseImageName(decomposedImage.assembleWithTransport())
imageName := decomposedImage.assembleWithTransport()
if i.HasShaInInputName() {
imageName = fmt.Sprintf("%s%s/%s", decomposedImage.transport, registry, i.InputName)
}
srcRef, err := alltransports.ParseImageName(imageName)
if err != nil {
return nil, errors.Wrapf(err, "unable to parse '%s'", i.InputName)
}
@ -287,8 +304,13 @@ func (i *Image) createNamesToPull() ([]*pullStruct, error) {
}
}
// Here we construct the destination reference
for _, pStruct := range pullNames {
destRef, err := is.Transport.ParseStoreReference(i.imageruntime.store, pStruct.image)
dstName := pStruct.image
if pStruct.shaPullName != "" {
dstName = pStruct.shaPullName
}
destRef, err := is.Transport.ParseStoreReference(i.imageruntime.store, dstName)
if err != nil {
return nil, errors.Wrapf(err, "error parsing dest reference name")
}

View File

@ -74,7 +74,7 @@ var _ = Describe("Podman pull", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"rmi", "alpine:latest"})
session = podmanTest.Podman([]string{"rmi", "alpine:none"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})