mirror of https://github.com/artifacthub/hub.git
Move TagsGetter to oci package (#1702)
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
This commit is contained in:
parent
f5f7fe99a2
commit
a65a0b9753
|
|
@ -52,3 +52,9 @@ type OCIPuller interface {
|
|||
password string,
|
||||
) (ocispec.Descriptor, []byte, error)
|
||||
}
|
||||
|
||||
// OCITagsGetter is the interface that wraps the Tags method, used to get all
|
||||
// the tags available for a given repository in a OCI registry.
|
||||
type OCITagsGetter interface {
|
||||
Tags(ctx context.Context, r *Repository) ([]string, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,12 +130,6 @@ type HelmIndexLoader interface {
|
|||
LoadIndex(r *Repository) (*helmrepo.IndexFile, string, error)
|
||||
}
|
||||
|
||||
// OCITagsGetter is the interface that wraps the Tags method, used to get all
|
||||
// the tags available for a given repository in a OCI registry.
|
||||
type OCITagsGetter interface {
|
||||
Tags(ctx context.Context, r *Repository) ([]string, error)
|
||||
}
|
||||
|
||||
// OLMOCIExporter describes the methods an OLMOCIExporter implementation must
|
||||
// must provide.
|
||||
type OLMOCIExporter interface {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package oci
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/artifacthub/hub/internal/hub"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
|
@ -25,3 +26,15 @@ func (m *PullerMock) PullLayer(
|
|||
data, _ := args.Get(1).([]byte)
|
||||
return desc, data, args.Error(2)
|
||||
}
|
||||
|
||||
// TagsGetterMock is a mock implementation of the hub.OCITagsGetter interface.
|
||||
type TagsGetterMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Tags implements the OCITagsGetter interface.
|
||||
func (m *TagsGetterMock) Tags(ctx context.Context, r *hub.Repository) ([]string, error) {
|
||||
args := m.Called(ctx, r)
|
||||
tags, _ := args.Get(0).([]string)
|
||||
return tags, args.Error(1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,15 @@ package oci
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/artifacthub/hub/internal/hub"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"oras.land/oras-go/pkg/content"
|
||||
ctxo "oras.land/oras-go/pkg/context"
|
||||
|
|
@ -68,3 +74,42 @@ func (p *Puller) PullLayer(
|
|||
}
|
||||
return ocispec.Descriptor{}, nil, ErrLayerNotFound
|
||||
}
|
||||
|
||||
// OCITagsGetter provides a mechanism to get all the version tags available for
|
||||
// a given repository in a OCI registry. Tags that aren't valid semver versions
|
||||
// will be filtered out.
|
||||
type TagsGetter struct{}
|
||||
|
||||
// Tags returns a list with the tags available for the provided repository.
|
||||
func (tg *TagsGetter) Tags(ctx context.Context, r *hub.Repository) ([]string, error) {
|
||||
u := strings.TrimPrefix(r.URL, hub.RepositoryOCIPrefix)
|
||||
ociRepo, err := name.NewRepository(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options := []remote.Option{
|
||||
remote.WithContext(ctx),
|
||||
}
|
||||
if r.AuthUser != "" || r.AuthPass != "" {
|
||||
options = append(options, remote.WithAuth(&authn.Basic{
|
||||
Username: r.AuthUser,
|
||||
Password: r.AuthPass,
|
||||
}))
|
||||
}
|
||||
tags, err := remote.List(ociRepo, options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tagsFiltered []string
|
||||
for _, tag := range tags {
|
||||
if _, err := semver.NewVersion(tag); err == nil {
|
||||
tagsFiltered = append(tagsFiltered, tag)
|
||||
}
|
||||
}
|
||||
sort.Slice(tagsFiltered, func(i, j int) bool {
|
||||
vi, _ := semver.NewVersion(tagsFiltered[i])
|
||||
vj, _ := semver.NewVersion(tagsFiltered[j])
|
||||
return vj.LessThan(vi)
|
||||
})
|
||||
return tagsFiltered, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ func NewManager(
|
|||
cfg: cfg,
|
||||
db: db,
|
||||
il: &HelmIndexLoader{},
|
||||
tg: &OCITagsGetter{},
|
||||
tg: &oci.TagsGetter{},
|
||||
op: &oci.Puller{},
|
||||
az: az,
|
||||
hc: hc,
|
||||
|
|
|
|||
|
|
@ -1094,7 +1094,7 @@ func TestGetRemoteDigest(t *testing.T) {
|
|||
|
||||
t.Run("helm-oci: error getting tags", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
tg := &OCITagsGetterMock{}
|
||||
tg := &oci.TagsGetterMock{}
|
||||
tg.On("Tags", ctx, helmOCI).Return(nil, tests.ErrFake)
|
||||
m := NewManager(cfg, nil, nil, nil, WithOCITagsGetter(tg))
|
||||
|
||||
|
|
@ -1106,7 +1106,7 @@ func TestGetRemoteDigest(t *testing.T) {
|
|||
|
||||
t.Run("helm-oci: success", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
tg := &OCITagsGetterMock{}
|
||||
tg := &oci.TagsGetterMock{}
|
||||
tg.On("Tags", ctx, helmOCI).Return([]string{"2.0.0", "1.0.0"}, nil)
|
||||
m := NewManager(cfg, nil, nil, nil, WithOCITagsGetter(tg))
|
||||
|
||||
|
|
|
|||
|
|
@ -182,18 +182,6 @@ func (m *ManagerMock) UpdateDigest(ctx context.Context, repositoryID, digest str
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
// OCITagsGetterMock is a mock implementation of the OCITagsGetter interface.
|
||||
type OCITagsGetterMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Tags implements the OCITagsGetter interface.
|
||||
func (m *OCITagsGetterMock) Tags(ctx context.Context, r *hub.Repository) ([]string, error) {
|
||||
args := m.Called(ctx, r)
|
||||
tags, _ := args.Get(0).([]string)
|
||||
return tags, args.Error(1)
|
||||
}
|
||||
|
||||
// OLMOCIExporterMock is a mock implementation of the OLMOCIExporter interface.
|
||||
type OLMOCIExporterMock struct {
|
||||
mock.Mock
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/artifacthub/hub/internal/hub"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
)
|
||||
|
||||
// OCITagsGetter provides a mechanism to get all the version tags available for
|
||||
// a given repository in a OCI registry. Tags that aren't valid semver versions
|
||||
// will be filtered out.
|
||||
type OCITagsGetter struct{}
|
||||
|
||||
// Tags returns a list with the tags available for the provided repository.
|
||||
func (tg *OCITagsGetter) Tags(ctx context.Context, r *hub.Repository) ([]string, error) {
|
||||
u := strings.TrimPrefix(r.URL, hub.RepositoryOCIPrefix)
|
||||
ociRepo, err := name.NewRepository(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options := []remote.Option{
|
||||
remote.WithContext(ctx),
|
||||
}
|
||||
if r.AuthUser != "" || r.AuthPass != "" {
|
||||
options = append(options, remote.WithAuth(&authn.Basic{
|
||||
Username: r.AuthUser,
|
||||
Password: r.AuthPass,
|
||||
}))
|
||||
}
|
||||
tags, err := remote.List(ociRepo, options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tagsFiltered []string
|
||||
for _, tag := range tags {
|
||||
if _, err := semver.NewVersion(tag); err == nil {
|
||||
tagsFiltered = append(tagsFiltered, tag)
|
||||
}
|
||||
}
|
||||
sort.Slice(tagsFiltered, func(i, j int) bool {
|
||||
vi, _ := semver.NewVersion(tagsFiltered[i])
|
||||
vj, _ := semver.NewVersion(tagsFiltered[j])
|
||||
return vj.LessThan(vi)
|
||||
})
|
||||
return tagsFiltered, nil
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ func NewTrackerSource(i *hub.TrackerSourceInput, opts ...func(s *TrackerSource))
|
|||
s.il = &repo.HelmIndexLoader{}
|
||||
}
|
||||
if s.tg == nil {
|
||||
s.tg = &repo.OCITagsGetter{}
|
||||
s.tg = &oci.TagsGetter{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ func TestTrackerSource(t *testing.T) {
|
|||
},
|
||||
Svc: sw.Svc,
|
||||
}
|
||||
tg := &repo.OCITagsGetterMock{}
|
||||
tg := &oci.TagsGetterMock{}
|
||||
tg.On("Tags", i.Svc.Ctx, i.Repository).Return(nil, tests.ErrFake)
|
||||
|
||||
// Run test and check expectations
|
||||
|
|
@ -332,7 +332,7 @@ func TestTrackerSource(t *testing.T) {
|
|||
},
|
||||
Svc: sw.Svc,
|
||||
}
|
||||
tg := &repo.OCITagsGetterMock{}
|
||||
tg := &oci.TagsGetterMock{}
|
||||
tg.On("Tags", i.Svc.Ctx, i.Repository).Return([]string{"1.0.0"}, nil)
|
||||
ref := strings.TrimPrefix(i.Repository.URL, hub.RepositoryOCIPrefix) + ":1.0.0"
|
||||
sw.Op.On("PullLayer", mock.Anything, ref, ChartContentLayerMediaType, "", "").
|
||||
|
|
@ -473,7 +473,7 @@ func TestTrackerSource(t *testing.T) {
|
|||
},
|
||||
Svc: sw.Svc,
|
||||
}
|
||||
tg := &repo.OCITagsGetterMock{}
|
||||
tg := &oci.TagsGetterMock{}
|
||||
tg.On("Tags", i.Svc.Ctx, i.Repository).Return([]string{"1.0.0"}, nil)
|
||||
ref := strings.TrimPrefix(i.Repository.URL, hub.RepositoryOCIPrefix) + ":1.0.0"
|
||||
data, _ := os.ReadFile("testdata/pkg1-1.0.0.tgz")
|
||||
|
|
|
|||
Loading…
Reference in New Issue