Skip to content

Commit

Permalink
add get GC candidate (goharbor#12314)
Browse files Browse the repository at this point in the history
* add get GC candidate

select non referenced blobs from table blob and exclude the ones in the time windows.

Signed-off-by: wang yan <wangyan@vmware.com>
Signed-off-by: molinber <bertrand.molin@credit-agricole.net>
  • Loading branch information
wy65701436 authored and molinber committed Jul 22, 2020
1 parent b4a3d12 commit 95664e6
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/pkg/blob/dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ type DAO interface {

// DeleteBlob delete blob
DeleteBlob(ctx context.Context, id int64) (err error)

// GetBlobsNotRefedByProjectBlob get the blobs that are not referenced by the table project_blob and also not in the reserve window(in hours)
GetBlobsNotRefedByProjectBlob(ctx context.Context, timeWindowHours int64) ([]*models.Blob, error)
}

// New returns an instance of the default DAO
Expand Down Expand Up @@ -389,3 +392,19 @@ func (d *dao) DeleteBlob(ctx context.Context, id int64) error {
}
return nil
}

func (d *dao) GetBlobsNotRefedByProjectBlob(ctx context.Context, timeWindowHours int64) ([]*models.Blob, error) {
var noneRefed []*models.Blob
ormer, err := orm.FromContext(ctx)
if err != nil {
return noneRefed, err
}

sql := fmt.Sprintf(`SELECT b.id, b.digest, b.content_type, b.status FROM blob AS b LEFT JOIN project_blob pb ON b.id = pb.blob_id WHERE pb.id IS NULL AND b.update_time <= now() - interval '%d hours';`, timeWindowHours)
_, err = ormer.Raw(sql).QueryRows(&noneRefed)
if err != nil {
return noneRefed, err
}

return noneRefed, nil
}
28 changes: 28 additions & 0 deletions src/pkg/blob/dao/dao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,34 @@ func (suite *DaoTestSuite) TestDelete() {
suite.Require().Nil(err)
}

func (suite *DaoTestSuite) TestGetBlobsNotRefedByProjectBlob() {
ctx := suite.Context()

blobs, err := suite.dao.GetBlobsNotRefedByProjectBlob(ctx, 0)
suite.Require().Nil(err)
beforeAdd := len(blobs)

suite.dao.CreateBlob(ctx, &models.Blob{Digest: suite.DigestString()})
suite.dao.CreateBlob(ctx, &models.Blob{Digest: suite.DigestString()})
digest := suite.DigestString()
suite.dao.CreateBlob(ctx, &models.Blob{Digest: digest})

blob, err := suite.dao.GetBlobByDigest(ctx, digest)
suite.Nil(err)

projectID := int64(1)
_, err = suite.dao.CreateProjectBlob(ctx, projectID, blob.ID)
suite.Nil(err)

blobs, err = suite.dao.GetBlobsNotRefedByProjectBlob(ctx, 0)
suite.Require().Nil(err)
suite.Require().Equal(2+beforeAdd, len(blobs))

blobs, err = suite.dao.GetBlobsNotRefedByProjectBlob(ctx, 2)
suite.Require().Nil(err)
suite.Require().Equal(0, len(blobs))
}

func TestDaoTestSuite(t *testing.T) {
suite.Run(t, &DaoTestSuite{})
}
7 changes: 7 additions & 0 deletions src/pkg/blob/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ type Manager interface {

// DeleteBlob delete blob
Delete(ctx context.Context, id int64) (err error)

// UselessBlobs useless blob is the blob that is not used in any of projects.
UselessBlobs(ctx context.Context, timeWindowHours int64) ([]*models.Blob, error)
}

type manager struct {
Expand Down Expand Up @@ -129,6 +132,10 @@ func (m *manager) Delete(ctx context.Context, id int64) error {
return m.dao.DeleteBlob(ctx, id)
}

func (m *manager) UselessBlobs(ctx context.Context, timeWindowHours int64) ([]*models.Blob, error) {
return m.dao.GetBlobsNotRefedByProjectBlob(ctx, timeWindowHours)
}

// NewManager returns blob manager
func NewManager() Manager {
return &manager{dao: dao.New()}
Expand Down
26 changes: 26 additions & 0 deletions src/pkg/blob/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,32 @@ func (suite *ManagerTestSuite) TestUpdateStatus() {
}
}

func (suite *ManagerTestSuite) TestUselessBlobs() {
ctx := suite.Context()

blobs, err := Mgr.UselessBlobs(ctx, 0)
suite.Require().Nil(err)
beforeAdd := len(blobs)

Mgr.Create(ctx, suite.DigestString(), "media type", 100)
Mgr.Create(ctx, suite.DigestString(), "media type", 100)
digest := suite.DigestString()
blobID, err := Mgr.Create(ctx, digest, "media type", 100)
suite.Nil(err)

projectID := int64(1)
_, err = Mgr.AssociateWithProject(ctx, blobID, projectID)
suite.Nil(err)

blobs, err = Mgr.UselessBlobs(ctx, 0)
suite.Require().Nil(err)
suite.Require().Equal(2+beforeAdd, len(blobs))

blobs, err = Mgr.UselessBlobs(ctx, 2)
suite.Require().Nil(err)
suite.Require().Equal(0, len(blobs))
}

func TestManagerTestSuite(t *testing.T) {
suite.Run(t, &ManagerTestSuite{})
}
23 changes: 23 additions & 0 deletions src/testing/pkg/blob/manager.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 95664e6

Please sign in to comment.