Skip to content

Commit

Permalink
libpod/image: Use ParseNormalizedNamed in RepoDigests
Browse files Browse the repository at this point in the history
Avoid generating
quay.io/openshift-release-dev/ocp-release@sha256@sha256:239... and
similar when the image name is already digest-based [1].  It's not
clear exactly how we get into this state, but as shown by the unit
tests, the new code handles this case correctly (while the previous
code does not).

[1]: containers#2086

Signed-off-by: W. Trevor King <wking@tremily.us>
  • Loading branch information
wking committed Jan 9, 2019
1 parent c9d63fe commit f539fd2
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 5 deletions.
18 changes: 15 additions & 3 deletions libpod/image/image.go
Expand Up @@ -305,12 +305,24 @@ func (i *Image) Names() []string {
}

// RepoDigests returns a string array of repodigests associated with the image
func (i *Image) RepoDigests() []string {
func (i *Image) RepoDigests() ([]string, error) {
var repoDigests []string
digest := i.Digest()

for _, name := range i.Names() {
repoDigests = append(repoDigests, strings.SplitN(name, ":", 2)[0]+"@"+i.Digest().String())
named, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, err
}

canonical, err := reference.WithDigest(reference.TrimNamed(named), digest)
if err != nil {
return nil, err
}

repoDigests = append(repoDigests, canonical.String())
}
return repoDigests
return repoDigests, nil
}

// Created returns the time the image was created
Expand Down
46 changes: 46 additions & 0 deletions libpod/image/image_test.go
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"github.com/containers/storage"
"github.com/opencontainers/go-digest"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -192,6 +193,51 @@ func TestImage_MatchRepoTag(t *testing.T) {
cleanup(workdir, ir)
}

// TestImage_RepoDigests tests RepoDigest generation.
func TestImage_RepoDigests(t *testing.T) {
dgst, err := digest.Parse("sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc")
if err != nil {
t.Fatal(err)
}

for _, test := range []struct {
name string
names []string
expected []string
}{
{
name: "empty",
names: []string{},
expected: nil,
},
{
name: "tagged",
names: []string{"docker.io/library/busybox:latest"},
expected: []string{"docker.io/library/busybox@sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"},
},
{
name: "digest",
names: []string{"docker.io/library/busybox@sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"},
expected: []string{"docker.io/library/busybox@sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"},
},
} {
t.Run(test.name, func(t *testing.T) {
image := &Image{
image: &storage.Image{
Names: test.names,
Digest: dgst,
},
}
actual, err := image.RepoDigests()
if err != nil {
t.Fatal(err)
}

assert.Equal(t, test.expected, actual)
})
}
}

// Test_splitString tests the splitString function in image that
// takes input and splits on / and returns the last array item
func Test_splitString(t *testing.T) {
Expand Down
13 changes: 11 additions & 2 deletions pkg/varlinkapi/images.go
Expand Up @@ -41,13 +41,18 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error {
for _, image := range images {
labels, _ := image.Labels(getContext())
containers, _ := image.Containers()
repoDigests, err := image.RepoDigests()
if err != nil {
return err
}

size, _ := image.Size(getContext())

i := iopodman.ImageInList{
Id: image.ID(),
ParentId: image.Parent,
RepoTags: image.Names(),
RepoDigests: image.RepoDigests(),
RepoDigests: repoDigests,
Created: image.Created().String(),
Size: int64(*size),
VirtualSize: image.VirtualSize,
Expand All @@ -73,6 +78,10 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, name string) error {
if err != nil {
return err
}
repoDigests, err := newImage.RepoDigests()
if err != nil {
return err
}
size, err := newImage.Size(getContext())
if err != nil {
return err
Expand All @@ -82,7 +91,7 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, name string) error {
Id: newImage.ID(),
ParentId: newImage.Parent,
RepoTags: newImage.Names(),
RepoDigests: newImage.RepoDigests(),
RepoDigests: repoDigests,
Created: newImage.Created().String(),
Size: int64(*size),
VirtualSize: newImage.VirtualSize,
Expand Down

0 comments on commit f539fd2

Please sign in to comment.