mirror of
https://github.com/goharbor/harbor
synced 2025-04-20 20:28:55 +00:00
fix: skip to delete scan reports if the digest still referenced (#19110)
fix: skip to delete scan reports if the digest still referenced by other artifacts Avoid to delete the scan reports in case the artifact deleted but still referenced by the other artifacts. Signed-off-by: chlins <chenyuzh@vmware.com>
This commit is contained in:
parent
403b616a5a
commit
a036e4a7b0
|
@ -33,6 +33,8 @@ import (
|
||||||
"github.com/goharbor/harbor/src/lib/log"
|
"github.com/goharbor/harbor/src/lib/log"
|
||||||
"github.com/goharbor/harbor/src/lib/orm"
|
"github.com/goharbor/harbor/src/lib/orm"
|
||||||
"github.com/goharbor/harbor/src/lib/q"
|
"github.com/goharbor/harbor/src/lib/q"
|
||||||
|
"github.com/goharbor/harbor/src/pkg"
|
||||||
|
pkgArt "github.com/goharbor/harbor/src/pkg/artifact"
|
||||||
"github.com/goharbor/harbor/src/pkg/scan/report"
|
"github.com/goharbor/harbor/src/pkg/scan/report"
|
||||||
"github.com/goharbor/harbor/src/pkg/task"
|
"github.com/goharbor/harbor/src/pkg/task"
|
||||||
)
|
)
|
||||||
|
@ -70,6 +72,8 @@ type Handler struct {
|
||||||
execMgr task.ExecutionManager
|
execMgr task.ExecutionManager
|
||||||
// reportMgr for managing scan reports
|
// reportMgr for managing scan reports
|
||||||
reportMgr report.Manager
|
reportMgr report.Manager
|
||||||
|
// artMgr for managing artifacts
|
||||||
|
artMgr pkgArt.Manager
|
||||||
|
|
||||||
once sync.Once
|
once sync.Once
|
||||||
// pullCountStore caches the pull count group by repository
|
// pullCountStore caches the pull count group by repository
|
||||||
|
@ -262,6 +266,7 @@ func (a *Handler) onPush(ctx context.Context, event *event.ArtifactEvent) error
|
||||||
func (a *Handler) onDelete(ctx context.Context, event *event.ArtifactEvent) error {
|
func (a *Handler) onDelete(ctx context.Context, event *event.ArtifactEvent) error {
|
||||||
execMgr := task.ExecMgr
|
execMgr := task.ExecMgr
|
||||||
reportMgr := report.Mgr
|
reportMgr := report.Mgr
|
||||||
|
artMgr := pkg.ArtifactMgr
|
||||||
// for UT mock
|
// for UT mock
|
||||||
if a.execMgr != nil {
|
if a.execMgr != nil {
|
||||||
execMgr = a.execMgr
|
execMgr = a.execMgr
|
||||||
|
@ -269,6 +274,9 @@ func (a *Handler) onDelete(ctx context.Context, event *event.ArtifactEvent) erro
|
||||||
if a.reportMgr != nil {
|
if a.reportMgr != nil {
|
||||||
reportMgr = a.reportMgr
|
reportMgr = a.reportMgr
|
||||||
}
|
}
|
||||||
|
if a.artMgr != nil {
|
||||||
|
artMgr = a.artMgr
|
||||||
|
}
|
||||||
|
|
||||||
ids := []int64{event.Artifact.ID}
|
ids := []int64{event.Artifact.ID}
|
||||||
digests := []string{event.Artifact.Digest}
|
digests := []string{event.Artifact.Digest}
|
||||||
|
@ -278,7 +286,20 @@ func (a *Handler) onDelete(ctx context.Context, event *event.ArtifactEvent) erro
|
||||||
digests = append(digests, ref.ChildDigest)
|
digests = append(digests, ref.ChildDigest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check if the digest also referenced by other artifacts, should exclude it to delete the scan report if still referenced by others.
|
||||||
|
unrefDigests := []string{}
|
||||||
|
for _, digest := range digests {
|
||||||
|
// with the base=* to query all artifacts includes untagged and references
|
||||||
|
count, err := artMgr.Count(ctx, q.New(q.KeyWords{"digest": digest, "base": "*"}))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to count the artifact with the digest %s, error: %v", digest, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
unrefDigests = append(unrefDigests, digest)
|
||||||
|
}
|
||||||
|
}
|
||||||
// clean up the scan executions of this artifact and it's references by id
|
// clean up the scan executions of this artifact and it's references by id
|
||||||
log.Debugf("delete the associated scan executions of artifacts %v as the artifacts have been deleted", ids)
|
log.Debugf("delete the associated scan executions of artifacts %v as the artifacts have been deleted", ids)
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
@ -288,9 +309,9 @@ func (a *Handler) onDelete(ctx context.Context, event *event.ArtifactEvent) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up the scan reports of this artifact and it's references by digest
|
// clean up the scan reports of this artifact and it's references by digest
|
||||||
log.Debugf("delete the associated scan reports of artifacts %v as the artifacts have been deleted", digests)
|
log.Debugf("delete the associated scan reports of artifacts %v as the artifacts have been deleted", unrefDigests)
|
||||||
if err := reportMgr.DeleteByDigests(ctx, digests...); err != nil {
|
if err := reportMgr.DeleteByDigests(ctx, unrefDigests...); err != nil {
|
||||||
log.Errorf("failed to delete scan reports of artifact %v, error: %v", digests, err)
|
log.Errorf("failed to delete scan reports of artifact %v, error: %v", unrefDigests, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -35,6 +35,8 @@ import (
|
||||||
"github.com/goharbor/harbor/src/pkg/tag"
|
"github.com/goharbor/harbor/src/pkg/tag"
|
||||||
tagmodel "github.com/goharbor/harbor/src/pkg/tag/model/tag"
|
tagmodel "github.com/goharbor/harbor/src/pkg/tag/model/tag"
|
||||||
scannerCtlMock "github.com/goharbor/harbor/src/testing/controller/scanner"
|
scannerCtlMock "github.com/goharbor/harbor/src/testing/controller/scanner"
|
||||||
|
"github.com/goharbor/harbor/src/testing/mock"
|
||||||
|
artMock "github.com/goharbor/harbor/src/testing/pkg/artifact"
|
||||||
projectMock "github.com/goharbor/harbor/src/testing/pkg/project"
|
projectMock "github.com/goharbor/harbor/src/testing/pkg/project"
|
||||||
reportMock "github.com/goharbor/harbor/src/testing/pkg/scan/report"
|
reportMock "github.com/goharbor/harbor/src/testing/pkg/scan/report"
|
||||||
taskMock "github.com/goharbor/harbor/src/testing/pkg/task"
|
taskMock "github.com/goharbor/harbor/src/testing/pkg/task"
|
||||||
|
@ -50,6 +52,7 @@ type ArtifactHandlerTestSuite struct {
|
||||||
scannerCtl scanner.Controller
|
scannerCtl scanner.Controller
|
||||||
reportMgr *reportMock.Manager
|
reportMgr *reportMock.Manager
|
||||||
execMgr *taskMock.ExecutionManager
|
execMgr *taskMock.ExecutionManager
|
||||||
|
artMgr *artMock.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestArtifactHandler tests ArtifactHandler.
|
// TestArtifactHandler tests ArtifactHandler.
|
||||||
|
@ -66,7 +69,8 @@ func (suite *ArtifactHandlerTestSuite) SetupSuite() {
|
||||||
suite.scannerCtl = &scannerCtlMock.Controller{}
|
suite.scannerCtl = &scannerCtlMock.Controller{}
|
||||||
suite.execMgr = &taskMock.ExecutionManager{}
|
suite.execMgr = &taskMock.ExecutionManager{}
|
||||||
suite.reportMgr = &reportMock.Manager{}
|
suite.reportMgr = &reportMock.Manager{}
|
||||||
suite.handler = &Handler{execMgr: suite.execMgr, reportMgr: suite.reportMgr}
|
suite.artMgr = &artMock.Manager{}
|
||||||
|
suite.handler = &Handler{execMgr: suite.execMgr, reportMgr: suite.reportMgr, artMgr: suite.artMgr}
|
||||||
|
|
||||||
// mock artifact
|
// mock artifact
|
||||||
_, err := pkg.ArtifactMgr.Create(suite.ctx, &artifact.Artifact{ID: 1, RepositoryID: 1})
|
_, err := pkg.ArtifactMgr.Create(suite.ctx, &artifact.Artifact{ID: 1, RepositoryID: 1})
|
||||||
|
@ -163,6 +167,7 @@ func (suite *ArtifactHandlerTestSuite) TestOnDelete() {
|
||||||
suite.execMgr.On("DeleteByVendor", suite.ctx, "IMAGE_SCAN", int64(1)).Return(nil).Times(1)
|
suite.execMgr.On("DeleteByVendor", suite.ctx, "IMAGE_SCAN", int64(1)).Return(nil).Times(1)
|
||||||
suite.execMgr.On("DeleteByVendor", suite.ctx, "IMAGE_SCAN", int64(2)).Return(nil).Times(1)
|
suite.execMgr.On("DeleteByVendor", suite.ctx, "IMAGE_SCAN", int64(2)).Return(nil).Times(1)
|
||||||
suite.execMgr.On("DeleteByVendor", suite.ctx, "IMAGE_SCAN", int64(3)).Return(nil).Times(1)
|
suite.execMgr.On("DeleteByVendor", suite.ctx, "IMAGE_SCAN", int64(3)).Return(nil).Times(1)
|
||||||
|
suite.artMgr.On("Count", suite.ctx, mock.Anything).Return(int64(0), nil).Times(3)
|
||||||
suite.reportMgr.On("DeleteByDigests", suite.ctx, "mock-digest", "ref-1", "ref-2").Return(nil).Times(1)
|
suite.reportMgr.On("DeleteByDigests", suite.ctx, "mock-digest", "ref-1", "ref-2").Return(nil).Times(1)
|
||||||
err := suite.handler.onDelete(suite.ctx, evt)
|
err := suite.handler.onDelete(suite.ctx, evt)
|
||||||
suite.Nil(err, "onDelete should return nil")
|
suite.Nil(err, "onDelete should return nil")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user