Skip to content

Commit

Permalink
Add tag list to the API (#436)
Browse files Browse the repository at this point in the history
Signed-off-by: Joao Pereira <joaod@vmware.com>

Signed-off-by: Joao Pereira <joaod@vmware.com>
  • Loading branch information
joaopapereira authored Sep 29, 2022
1 parent d5c9d0c commit 006d04d
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 32 deletions.
37 changes: 5 additions & 32 deletions pkg/imgpkg/cmd/tag_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ package cmd
import (
"github.com/cppforlife/go-cli-ui/ui"
uitable "github.com/cppforlife/go-cli-ui/ui/table"
regname "github.com/google/go-containerregistry/pkg/name"
"github.com/spf13/cobra"
"github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry"
v1 "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/v1"
)

type TagListOptions struct {
Expand Down Expand Up @@ -38,17 +37,7 @@ func NewTagListCmd(o *TagListOptions) *cobra.Command {
}

func (t *TagListOptions) Run() error {
reg, err := registry.NewSimpleRegistry(t.RegistryFlags.AsRegistryOpts())
if err != nil {
return err
}

ref, err := regname.ParseReference(t.ImageFlags.Image, regname.WeakValidation)
if err != nil {
return err
}

tags, err := reg.ListTags(ref.Context())
tagInfo, err := v1.TagList(t.ImageFlags.Image, t.Digests, t.RegistryFlags.AsRegistryOpts())
if err != nil {
return err
}
Expand All @@ -70,26 +59,10 @@ func (t *TagListOptions) Run() error {
},
}

for _, tag := range tags {
var digest string

if t.Digests {
tagRef, err := regname.NewTag(ref.Context().String()+":"+tag, regname.WeakValidation)
if err != nil {
return err
}

hash, err := reg.Digest(tagRef)
if err != nil {
return err
}

digest = hash.String()
}

for _, tag := range tagInfo.Tags {
table.Rows = append(table.Rows, []uitable.Value{
uitable.NewValueString(tag),
uitable.NewValueString(digest),
uitable.NewValueString(tag.Tag),
uitable.NewValueString(tag.Digest),
})
}

Expand Down
69 changes: 69 additions & 0 deletions pkg/imgpkg/v1/tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

package v1

import (
regname "github.com/google/go-containerregistry/pkg/name"
"github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry"
)

// TagInfo Contains the tag name and the digest associated with the tag
// TagInfo.Digest might be empty if caller ask for it not to be retrieved
type TagInfo struct {
Tag string
Digest string
}

// TagsInfo Contains all the tags associated with the repository on Image
type TagsInfo struct {
Repository string
Tags []TagInfo
}

// TagList Retrieve all the tags associated with a repository
// imageRef contains the address for the repository
// getDigests when set to true, provides
func TagList(imageRef string, getDigests bool, registryOpts registry.Opts) (TagsInfo, error) {
reg, err := registry.NewSimpleRegistry(registryOpts)
if err != nil {
return TagsInfo{}, err
}

ref, err := regname.ParseReference(imageRef, regname.WeakValidation)
if err != nil {
return TagsInfo{}, err
}

tags, err := reg.ListTags(ref.Context())
if err != nil {
return TagsInfo{}, err
}

tagList := TagsInfo{
Repository: ref.Context().String(),
}

for _, tag := range tags {
tagInfo := TagInfo{
Tag: tag,
}

if getDigests {
tagRef, err := regname.NewTag(ref.Context().String()+":"+tag, regname.WeakValidation)
if err != nil {
return TagsInfo{}, err
}

hash, err := reg.Digest(tagRef)
if err != nil {
return TagsInfo{}, err
}

tagInfo.Digest = hash.String()
}
tagList.Tags = append(tagList.Tags, tagInfo)
}

return tagList, nil
}
104 changes: 104 additions & 0 deletions pkg/imgpkg/v1/tag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

package v1_test

import (
"testing"

"github.com/stretchr/testify/require"
"github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry"
v1 "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/v1"
"github.com/vmware-tanzu/carvel-imgpkg/test/helpers"
)

func TestTagList(t *testing.T) {
fakeRegistry := helpers.NewFakeRegistry(t, &helpers.Logger{LogLevel: helpers.LogDebug})

img1 := fakeRegistry.WithRandomImage("some/image-1")
img21 := fakeRegistry.WithRandomImage("some/image-2")
img22 := fakeRegistry.WithRandomImage("some/image-2")
// This image needs to be last because it will get the latest tag
img2 := fakeRegistry.WithRandomImage("some/image-2")
fakeRegistry.Tag(img21.RefDigest, "tag-2-1")
fakeRegistry.Tag(img22.RefDigest, "tag-2-2")

defer fakeRegistry.CleanUp()
fakeRegistry.Build()

t.Run("when only latest tag is present, it returns 1 tag", func(t *testing.T) {
tagList, err := v1.TagList(img1.RefDigest, false, registry.Opts{})
require.NoError(t, err)

require.Equal(t, v1.TagsInfo{
Repository: fakeRegistry.ReferenceOnTestServer("some/image-1"),
Tags: []v1.TagInfo{
{
Tag: "latest",
Digest: "",
},
},
}, tagList)
})

t.Run("when only latest tag is present and getDigests is set to true, it returns 1 tag and the associated digest", func(t *testing.T) {
tagList, err := v1.TagList(img1.RefDigest, true, registry.Opts{})
require.NoError(t, err)

require.Equal(t, v1.TagsInfo{
Repository: fakeRegistry.ReferenceOnTestServer("some/image-1"),
Tags: []v1.TagInfo{
{
Tag: "latest",
Digest: img1.Digest,
},
},
}, tagList)
})

t.Run("when multiple tags are present, it returns all tags", func(t *testing.T) {
tagList, err := v1.TagList(img2.RefDigest, false, registry.Opts{})
require.NoError(t, err)

require.Equal(t, v1.TagsInfo{
Repository: fakeRegistry.ReferenceOnTestServer("some/image-2"),
Tags: []v1.TagInfo{
{
Tag: "latest",
Digest: "",
},
{
Tag: "tag-2-1",
Digest: "",
},
{
Tag: "tag-2-2",
Digest: "",
},
},
}, tagList)
})

t.Run("when multiple tags are present and getDigests is set to true, it returns all tags and the associated digests", func(t *testing.T) {
tagList, err := v1.TagList(img2.RefDigest, true, registry.Opts{})
require.NoError(t, err)

require.Equal(t, v1.TagsInfo{
Repository: fakeRegistry.ReferenceOnTestServer("some/image-2"),
Tags: []v1.TagInfo{
{
Tag: "latest",
Digest: img2.Digest,
},
{
Tag: "tag-2-1",
Digest: img21.Digest,
},
{
Tag: "tag-2-2",
Digest: img22.Digest,
},
},
}, tagList)
})
}

0 comments on commit 006d04d

Please sign in to comment.