update blob list query (#14195)

* update blob list query

Deprecate blob list parameters, and use the query for instead.

Signed-off-by: wang yan <wangyan@vmware.com>

* update per review comments

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2021-02-09 17:08:26 +08:00 committed by GitHub
parent 7231679373
commit 21d35f9702
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 193 additions and 107 deletions

View File

@ -18,6 +18,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/goharbor/harbor/src/lib/q"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema1"
@ -95,13 +96,13 @@ func (a *abstractor) abstractManifestV1Metadata(ctx context.Context, artifact *a
return err
}
digests := make([]string, len(manifest.FSLayers))
for i, fsLayer := range manifest.FSLayers {
digests[i] = fsLayer.BlobSum.String()
var ol q.OrList
for _, fsLayer := range manifest.FSLayers {
ol.Values = append(ol.Values, fsLayer.BlobSum.String())
}
// there is no layer size in v1 manifest, compute the artifact size from the blobs
blobs, err := a.blobMgr.List(ctx, blob.ListParams{BlobDigests: digests})
blobs, err := a.blobMgr.List(ctx, q.New(q.KeyWords{"digest": &ol}))
if err != nil {
log.G(ctx).Errorf("failed to get blobs of the artifact %s, error %v", artifact.Digest, err)
return err

View File

@ -356,7 +356,7 @@ func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot bool) er
return err
}
blobs, err := c.blobMgr.List(ctx, blob.ListParams{ArtifactDigest: art.Digest})
blobs, err := c.blobMgr.List(ctx, q.New(q.KeyWords{"artifactDigest": art.Digest}))
if err != nil {
return err
}

View File

@ -17,6 +17,7 @@ package blob
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/lib/q"
"time"
"github.com/docker/distribution"
@ -65,7 +66,7 @@ type Controller interface {
Get(ctx context.Context, digest string, options ...Option) (*blob.Blob, error)
// List list blobs
List(ctx context.Context, params blob.ListParams) ([]*blob.Blob, error)
List(ctx context.Context, query *q.Query) ([]*blob.Blob, error)
// Sync create blobs from `References` when they are not exist
// and update the blob content type when they are exist,
@ -178,12 +179,12 @@ func (c *controller) FindMissingAssociationsForProject(ctx context.Context, proj
return nil, nil
}
var digests []string
var ol q.OrList
for _, blob := range blobs {
digests = append(digests, blob.Digest)
ol.Values = append(ol.Values, blob.Digest)
}
associatedBlobs, err := c.blobMgr.List(ctx, blob.ListParams{BlobDigests: digests, ProjectID: projectID})
associatedBlobs, err := c.blobMgr.List(ctx, q.New(q.KeyWords{"digest": &ol, "projectID": projectID}))
if err != nil {
return nil, err
}
@ -216,13 +217,26 @@ func (c *controller) Get(ctx context.Context, digest string, options ...Option)
opts := newOptions(options...)
params := blob.ListParams{
ArtifactDigest: opts.ArtifactDigest,
BlobDigests: []string{digest},
ProjectID: opts.ProjectID,
keywords := make(map[string]interface{})
if digest != "" {
ol := q.OrList{
Values: []interface{}{
digest,
},
}
keywords["digest"] = &ol
}
if opts.ProjectID != 0 {
keywords["projectID"] = opts.ProjectID
}
if opts.ArtifactDigest != "" {
keywords["artifactDigest"] = opts.ArtifactDigest
}
query := &q.Query{
Keywords: keywords,
}
blobs, err := c.blobMgr.List(ctx, params)
blobs, err := c.blobMgr.List(ctx, query)
if err != nil {
return nil, err
} else if len(blobs) == 0 {
@ -232,8 +246,8 @@ func (c *controller) Get(ctx context.Context, digest string, options ...Option)
return blobs[0], nil
}
func (c *controller) List(ctx context.Context, params blob.ListParams) ([]*blob.Blob, error) {
return c.blobMgr.List(ctx, params)
func (c *controller) List(ctx context.Context, query *q.Query) ([]*blob.Blob, error) {
return c.blobMgr.List(ctx, query)
}
func (c *controller) Sync(ctx context.Context, references []distribution.Descriptor) error {
@ -241,12 +255,12 @@ func (c *controller) Sync(ctx context.Context, references []distribution.Descrip
return nil
}
var digests []string
var ol q.OrList
for _, reference := range references {
digests = append(digests, reference.Digest.String())
ol.Values = append(ol.Values, reference.Digest.String())
}
blobs, err := c.blobMgr.List(ctx, blob.ListParams{BlobDigests: digests})
blobs, err := c.blobMgr.List(ctx, q.New(q.KeyWords{"digest": &ol}))
if err != nil {
return err
}

View File

@ -423,17 +423,40 @@ func (gc *GarbageCollector) removeUntaggedBlobs(ctx job.Context) {
continue
}
p := result.Data
all, err := gc.blobMgr.List(ctx.SystemContext(), blob.ListParams{
ProjectID: p.ProjectID,
UpdateTime: time.Now().Add(-time.Duration(gc.timeWindowHours) * time.Hour),
})
if err != nil {
gc.logger.Errorf("failed to get blobs of project, %v", err)
continue
ps := 1000
lastBlobID := int64(0)
timeRG := q.Range{
Max: time.Now().Add(-time.Duration(gc.timeWindowHours) * time.Hour).Format(time.RFC3339),
}
if err := gc.blobMgr.CleanupAssociationsForProject(ctx.SystemContext(), p.ProjectID, all); err != nil {
gc.logger.Errorf("failed to clean untagged blobs of project, %v", err)
continue
for {
blobRG := q.Range{
Min: lastBlobID,
}
q := &q.Query{
Keywords: map[string]interface{}{
"update_time": &timeRG,
"projectID": p.ProjectID,
"id": &blobRG,
},
PageNumber: 1,
PageSize: int64(ps),
Sorting: "id",
}
blobs, err := gc.blobMgr.List(ctx.SystemContext(), q)
if err != nil {
gc.logger.Errorf("failed to get blobs of project, %v", err)
break
}
if err := gc.blobMgr.CleanupAssociationsForProject(ctx.SystemContext(), p.ProjectID, blobs); err != nil {
gc.logger.Errorf("failed to clean untagged blobs of project, %v", err)
break
}
if len(blobs) < ps {
break
}
lastBlobID = blobs[len(blobs)-1].ID
}
}
}

View File

@ -288,9 +288,8 @@ func (gc *GarbageCollector) removeUntaggedBlobs(ctx job.Context) {
continue
}
p := result.Data
all, err := gc.blobMgr.List(ctx.SystemContext(), blob.ListParams{
ProjectID: p.ProjectID,
})
all, err := gc.blobMgr.List(ctx.SystemContext(), q.New(q.KeyWords{"projectID": p.ProjectID}))
if err != nil {
gc.logger.Errorf("failed to get blobs of project, %v", err)
continue

View File

@ -19,7 +19,6 @@ import (
"fmt"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"strings"
"time"
"github.com/docker/distribution/manifest/schema2"
@ -55,7 +54,7 @@ type DAO interface {
UpdateBlobStatus(ctx context.Context, blob *models.Blob) (int64, error)
// ListBlobs list blobs by query
ListBlobs(ctx context.Context, params models.ListParams) ([]*models.Blob, error)
ListBlobs(ctx context.Context, query *q.Query) ([]*models.Blob, error)
// FindBlobsShouldUnassociatedWithProject filter the blobs which should not be associated with the project
FindBlobsShouldUnassociatedWithProject(ctx context.Context, projectID int64, blobs []*models.Blob) ([]*models.Blob, error)
@ -218,38 +217,12 @@ func (d *dao) UpdateBlob(ctx context.Context, blob *models.Blob) error {
return err
}
func (d *dao) ListBlobs(ctx context.Context, params models.ListParams) ([]*models.Blob, error) {
qs, err := orm.QuerySetter(ctx, &models.Blob{}, nil)
func (d *dao) ListBlobs(ctx context.Context, query *q.Query) ([]*models.Blob, error) {
qs, err := orm.QuerySetter(ctx, &models.Blob{}, query)
if err != nil {
return nil, err
}
if len(params.BlobDigests) > 0 {
qs = qs.Filter("digest__in", params.BlobDigests)
}
if !params.UpdateTime.IsZero() {
qs = qs.Filter("update_time__lte", params.UpdateTime)
}
if params.ArtifactDigest != "" {
params.ArtifactDigests = append(params.ArtifactDigests, params.ArtifactDigest)
}
if len(params.ArtifactDigests) > 0 {
var p []string
for _, digest := range params.ArtifactDigests {
p = append(p, `'`+orm.Escape(digest)+`'`)
}
sql := fmt.Sprintf("IN (SELECT digest_blob FROM artifact_blob WHERE digest_af IN (%s))", strings.Join(p, ","))
qs = qs.FilterRaw("digest", sql)
}
if params.ProjectID != 0 {
sql := fmt.Sprintf("IN (SELECT blob_id FROM project_blob WHERE project_id = %d)", params.ProjectID)
qs = qs.FilterRaw("id", sql)
}
blobs := []*models.Blob{}
if _, err = qs.All(&blobs); err != nil {
return nil, err

View File

@ -16,6 +16,7 @@ package dao
import (
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/blob/models"
htesting "github.com/goharbor/harbor/src/testing"
"github.com/stretchr/testify/suite"
@ -202,27 +203,42 @@ func (suite *DaoTestSuite) TestListBlobs() {
digest2 := suite.DigestString()
suite.dao.CreateBlob(ctx, &models.Blob{Digest: digest2})
blobs, err := suite.dao.ListBlobs(ctx, models.ListParams{BlobDigests: []string{digest1}})
ol := q.OrList{
Values: []interface{}{
digest1,
},
}
blobs, err := suite.dao.ListBlobs(ctx, q.New(q.KeyWords{"digest": &ol}))
if suite.Nil(err) {
suite.Len(blobs, 1)
}
blobs, err = suite.dao.ListBlobs(ctx, models.ListParams{BlobDigests: []string{digest1, digest2}})
ol = q.OrList{
Values: []interface{}{
digest1,
digest2,
},
}
blobs, err = suite.dao.ListBlobs(ctx, q.New(q.KeyWords{"digest": &ol}))
if suite.Nil(err) {
suite.Len(blobs, 2)
}
blobs, err = suite.dao.ListBlobs(ctx, models.ListParams{UpdateTime: time.Now().Add(-time.Hour)})
rg := q.Range{
Max: time.Now().Add(-time.Hour).Format(time.RFC3339),
}
blobs, err = suite.dao.ListBlobs(ctx, q.New(q.KeyWords{"update_time": &rg}))
if suite.Nil(err) {
suite.Len(blobs, 0)
}
digest3 := suite.DigestString()
suite.dao.CreateBlob(ctx, &models.Blob{Digest: digest3, UpdateTime: time.Now().Add(-time.Hour * 2)})
blobs, err = suite.dao.ListBlobs(ctx, models.ListParams{UpdateTime: time.Now().Add(-time.Hour)})
blobs, err = suite.dao.ListBlobs(ctx, q.New(q.KeyWords{"update_time": &rg}))
if suite.Nil(err) {
suite.Len(blobs, 1)
}
}
func (suite *DaoTestSuite) TestListBlobsAssociatedWithArtifact() {
@ -248,15 +264,17 @@ func (suite *DaoTestSuite) TestFindBlobsShouldUnassociatedWithProject() {
digest4 := suite.DigestString()
digest5 := suite.DigestString()
var ol q.OrList
blobDigests := []string{digest1, digest2, digest3, digest4, digest5}
for _, digest := range blobDigests {
blobID, err := suite.dao.CreateBlob(ctx, &models.Blob{Digest: digest})
if suite.Nil(err) {
suite.dao.CreateProjectBlob(ctx, projectID, blobID)
}
ol.Values = append(ol.Values, digest)
}
blobs, err := suite.dao.ListBlobs(ctx, models.ListParams{BlobDigests: blobDigests})
blobs, err := suite.dao.ListBlobs(ctx, q.New(q.KeyWords{"digest": &ol}))
suite.Nil(err)
suite.Len(blobs, 5)

View File

@ -17,6 +17,7 @@ package blob
import (
"context"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/blob/dao"
"github.com/goharbor/harbor/src/pkg/blob/models"
)
@ -24,9 +25,6 @@ import (
// Blob alias `models.Blob` to make it natural to use the Manager
type Blob = models.Blob
// ListParams alias `models.ListParams` to make it natural to use the Manager
type ListParams = models.ListParams
var (
// Mgr default blob manager
Mgr = NewManager()
@ -62,7 +60,7 @@ type Manager interface {
UpdateBlobStatus(ctx context.Context, blob *models.Blob) (int64, error)
// List returns blobs by params
List(ctx context.Context, params ListParams) ([]*Blob, error)
List(ctx context.Context, query *q.Query) ([]*Blob, error)
// DeleteBlob delete blob
Delete(ctx context.Context, id int64) (err error)
@ -129,8 +127,8 @@ func (m *manager) UpdateBlobStatus(ctx context.Context, blob *models.Blob) (int6
return m.dao.UpdateBlobStatus(ctx, blob)
}
func (m *manager) List(ctx context.Context, params ListParams) ([]*Blob, error) {
return m.dao.ListBlobs(ctx, params)
func (m *manager) List(ctx context.Context, query *q.Query) ([]*Blob, error) {
return m.dao.ListBlobs(ctx, query)
}
func (m *manager) Delete(ctx context.Context, id int64) error {

View File

@ -16,6 +16,7 @@ package blob
import (
"context"
"github.com/goharbor/harbor/src/lib/q"
htesting "github.com/goharbor/harbor/src/testing"
"github.com/stretchr/testify/suite"
"testing"
@ -34,7 +35,12 @@ func (suite *ManagerTestSuite) SetupSuite() {
}
func (suite *ManagerTestSuite) isAssociatedWithArtifact(ctx context.Context, blobDigest, artifactDigest string) (bool, error) {
blobs, err := Mgr.List(ctx, ListParams{BlobDigests: []string{blobDigest}, ArtifactDigest: artifactDigest})
ol := q.OrList{
Values: []interface{}{
blobDigest,
},
}
blobs, err := Mgr.List(ctx, q.New(q.KeyWords{"digest": &ol, "artifactDigest": artifactDigest}))
if err != nil {
return false, err
}
@ -43,7 +49,12 @@ func (suite *ManagerTestSuite) isAssociatedWithArtifact(ctx context.Context, blo
}
func (suite *ManagerTestSuite) isAssociatedWithProject(ctx context.Context, blobDigest string, projectID int64) (bool, error) {
blobs, err := Mgr.List(ctx, ListParams{BlobDigests: []string{blobDigest}, ProjectID: projectID})
ol := q.OrList{
Values: []interface{}{
blobDigest,
},
}
blobs, err := Mgr.List(ctx, q.New(q.KeyWords{"digest": &ol, "projectID": projectID}))
if err != nil {
return false, err
}
@ -117,14 +128,15 @@ func (suite *ManagerTestSuite) TestCleanupAssociationsForProject() {
ctx := suite.Context()
blobDigests := []string{digest1, digest2, digest3, digest4, digest5}
var ol q.OrList
for _, digest := range blobDigests {
blobID, err := Mgr.Create(ctx, digest, "media type", 100)
if suite.Nil(err) {
Mgr.AssociateWithProject(ctx, blobID, projectID)
}
ol.Values = append(ol.Values, digest)
}
blobs, err := Mgr.List(ctx, ListParams{BlobDigests: blobDigests})
blobs, err := Mgr.List(ctx, q.New(q.KeyWords{"digest": &ol}))
suite.Nil(err)
suite.Len(blobs, 5)
@ -213,18 +225,33 @@ func (suite *ManagerTestSuite) TestList() {
digest1 := suite.DigestString()
digest2 := suite.DigestString()
blobs, err := Mgr.List(ctx, ListParams{BlobDigests: []string{digest1, digest2}})
ol := q.OrList{
Values: []interface{}{
digest1,
digest2,
},
}
blobs, err := Mgr.List(ctx, q.New(q.KeyWords{"digest": &ol}))
suite.Nil(err)
suite.Len(blobs, 0)
Mgr.Create(ctx, digest1, "media type", 100)
Mgr.Create(ctx, digest2, "media type", 100)
blobs, err = Mgr.List(ctx, ListParams{BlobDigests: []string{digest1, digest2}})
ol = q.OrList{
Values: []interface{}{
digest1,
digest2,
},
}
blobs, err = Mgr.List(ctx, q.New(q.KeyWords{"digest": &ol}))
suite.Nil(err)
suite.Len(blobs, 2)
blobs, err = Mgr.List(ctx, models.ListParams{UpdateTime: time.Now().Add(-time.Hour)})
rg := q.Range{
Max: time.Now().Add(-time.Hour).Format(time.RFC3339),
}
blobs, err = Mgr.List(ctx, q.New(q.KeyWords{"update_time": &rg}))
if suite.Nil(err) {
suite.Len(blobs, 0)
}
@ -255,11 +282,11 @@ func (suite *ManagerTestSuite) TestListByArtifact() {
}
}
blobs, err := Mgr.List(ctx, ListParams{ArtifactDigest: artifact1})
blobs, err := Mgr.List(ctx, q.New(q.KeyWords{"artifactDigest": artifact1}))
suite.Nil(err)
suite.Len(blobs, 5)
blobs, err = Mgr.List(ctx, ListParams{ArtifactDigest: artifact2})
blobs, err = Mgr.List(ctx, q.New(q.KeyWords{"artifactDigest": artifact2}))
suite.Nil(err)
suite.Len(blobs, 3)
}

View File

@ -15,12 +15,15 @@
package models
import (
"context"
"fmt"
"github.com/astaxie/beego/orm"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2"
"github.com/goharbor/harbor/src/common/models"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"strings"
"time"
)
@ -99,11 +102,37 @@ func (b *Blob) IsManifest() bool {
// ProjectBlob alias ProjectBlob model
type ProjectBlob = models.ProjectBlob
// ListParams list params
type ListParams struct {
ArtifactDigest string // list blobs which associated with the artifact
ArtifactDigests []string // list blobs which associated with these artifacts
BlobDigests []string // list blobs which digest in the digests
ProjectID int64 // list blobs which associated with the project
UpdateTime time.Time // list blobs which update time less than updatetime
// FilterByArtifactDigest returns orm.QuerySeter with artifact digest filter
func (b *Blob) FilterByArtifactDigest(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
v, ok := value.(string)
if !ok {
return qs
}
sql := fmt.Sprintf("IN (SELECT digest_blob FROM artifact_blob WHERE digest_af IN (%s))", `'`+v+`'`)
return qs.FilterRaw("digest", sql)
}
// FilterByArtifactDigests returns orm.QuerySeter with artifact digests filter
func (b *Blob) FilterByArtifactDigests(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
artifactDigests, ok := value.([]string)
if !ok {
return qs
}
var afs []string
for _, v := range artifactDigests {
afs = append(afs, `'`+v+`'`)
}
sql := fmt.Sprintf("IN (SELECT digest_blob FROM artifact_blob WHERE digest_af IN (%s))", strings.Join(afs, ","))
return qs.FilterRaw("digest", sql)
}
// FilterByProjectID returns orm.QuerySeter with project id filter
func (b *Blob) FilterByProjectID(ctx context.Context, qs orm.QuerySeter, key string, value interface{}) orm.QuerySeter {
projectID, ok := value.(int64)
if !ok {
return qs
}
return qs.FilterRaw("id", fmt.Sprintf("IN (SELECT blob_id FROM project_blob WHERE project_id = %d)", projectID))
}

View File

@ -29,13 +29,13 @@
package blob
import (
"github.com/goharbor/harbor/src/lib/q"
"net/http"
"strings"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/blob"
"github.com/goharbor/harbor/src/pkg/distribution"
"github.com/goharbor/harbor/src/server/middleware"
"github.com/goharbor/harbor/src/server/middleware/util"
@ -91,7 +91,7 @@ func CopyArtifactMiddleware() func(http.Handler) http.Handler {
return err
}
allBlobs, err := blobController.List(ctx, blob.ListParams{ArtifactDigests: artifactDigests})
allBlobs, err := blobController.List(ctx, q.New(q.KeyWords{"artifactDigests": artifactDigests}))
if err != nil {
logger.Errorf("get blobs for artifacts %s failed, error: %v", strings.Join(artifactDigests, ", "), err)
return err

View File

@ -29,6 +29,7 @@
package quota
import (
"github.com/goharbor/harbor/src/lib/q"
"net/http"
"path"
"strconv"
@ -39,7 +40,6 @@ import (
"github.com/goharbor/harbor/src/controller/event/metadata"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/blob"
"github.com/goharbor/harbor/src/pkg/distribution"
"github.com/goharbor/harbor/src/pkg/notifier/event"
"github.com/goharbor/harbor/src/pkg/quota/types"
@ -109,7 +109,7 @@ func copyArtifactResources(r *http.Request, reference, referenceID string) (type
return nil, err
}
allBlobs, err := blobController.List(ctx, blob.ListParams{ArtifactDigests: artifactDigests})
allBlobs, err := blobController.List(ctx, q.New(q.KeyWords{"artifactDigests": artifactDigests}))
if err != nil {
logger.Errorf("get blobs for artifacts %s failed, error: %v", strings.Join(artifactDigests, ", "), err)
return nil, err

View File

@ -12,6 +12,8 @@ import (
mock "github.com/stretchr/testify/mock"
models "github.com/goharbor/harbor/src/pkg/blob/models"
q "github.com/goharbor/harbor/src/lib/q"
)
// Controller is an autogenerated mock type for the Controller type
@ -233,13 +235,13 @@ func (_m *Controller) GetAcceptedBlobSize(sessionID string) (int64, error) {
return r0, r1
}
// List provides a mock function with given fields: ctx, params
func (_m *Controller) List(ctx context.Context, params models.ListParams) ([]*models.Blob, error) {
ret := _m.Called(ctx, params)
// List provides a mock function with given fields: ctx, query
func (_m *Controller) List(ctx context.Context, query *q.Query) ([]*models.Blob, error) {
ret := _m.Called(ctx, query)
var r0 []*models.Blob
if rf, ok := ret.Get(0).(func(context.Context, models.ListParams) []*models.Blob); ok {
r0 = rf(ctx, params)
if rf, ok := ret.Get(0).(func(context.Context, *q.Query) []*models.Blob); ok {
r0 = rf(ctx, query)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*models.Blob)
@ -247,8 +249,8 @@ func (_m *Controller) List(ctx context.Context, params models.ListParams) ([]*mo
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, models.ListParams) error); ok {
r1 = rf(ctx, params)
if rf, ok := ret.Get(1).(func(context.Context, *q.Query) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}

View File

@ -7,6 +7,8 @@ import (
models "github.com/goharbor/harbor/src/pkg/blob/models"
mock "github.com/stretchr/testify/mock"
q "github.com/goharbor/harbor/src/lib/q"
)
// Manager is an autogenerated mock type for the Manager type
@ -163,13 +165,13 @@ func (_m *Manager) Get(ctx context.Context, digest string) (*models.Blob, error)
return r0, r1
}
// List provides a mock function with given fields: ctx, params
func (_m *Manager) List(ctx context.Context, params models.ListParams) ([]*models.Blob, error) {
ret := _m.Called(ctx, params)
// List provides a mock function with given fields: ctx, query
func (_m *Manager) List(ctx context.Context, query *q.Query) ([]*models.Blob, error) {
ret := _m.Called(ctx, query)
var r0 []*models.Blob
if rf, ok := ret.Get(0).(func(context.Context, models.ListParams) []*models.Blob); ok {
r0 = rf(ctx, params)
if rf, ok := ret.Get(0).(func(context.Context, *q.Query) []*models.Blob); ok {
r0 = rf(ctx, query)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*models.Blob)
@ -177,8 +179,8 @@ func (_m *Manager) List(ctx context.Context, params models.ListParams) ([]*model
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, models.ListParams) error); ok {
r1 = rf(ctx, params)
if rf, ok := ret.Get(1).(func(context.Context, *q.Query) error); ok {
r1 = rf(ctx, query)
} else {
r1 = ret.Error(1)
}