diff --git a/src/pkg/scan/sbom/sbom.go b/src/pkg/scan/sbom/sbom.go index bae6188866b..8aaf5da3378 100644 --- a/src/pkg/scan/sbom/sbom.go +++ b/src/pkg/scan/sbom/sbom.go @@ -244,6 +244,14 @@ func (h *scanHandler) delete(ctx context.Context, art *artifact.Artifact, mimeTy if err != nil { return err } + // check if any report has running task associate with it + taskMgr := h.TaskMgrFunc() + for _, rpt := range sbomReports { + if !taskMgr.IsTaskFinished(ctx, rpt.UUID) { + return errors.ConflictError(nil).WithMessage("a previous sbom generate process is running") + } + } + for _, rpt := range sbomReports { if rpt.MimeType != v1.MimeTypeSBOMReport { continue diff --git a/src/pkg/scan/sbom/sbom_test.go b/src/pkg/scan/sbom/sbom_test.go index 4b4c3645b19..04a3c2ece5c 100644 --- a/src/pkg/scan/sbom/sbom_test.go +++ b/src/pkg/scan/sbom/sbom_test.go @@ -219,6 +219,7 @@ func (suite *SBOMTestSuite) TestMakeReportPlaceHolder() { mock.OnAnything(suite.sbomManager, "Create").Return("uuid", nil).Once() mock.OnAnything(suite.sbomManager, "Delete").Return(nil).Once() mock.OnAnything(suite.taskMgr, "ListScanTasksByReportUUID").Return([]*task.Task{{Status: "Success"}}, nil) + mock.OnAnything(suite.taskMgr, "IsTaskFinished").Return(true).Once() mock.OnAnything(suite.artifactCtl, "Get").Return(art, nil) mock.OnAnything(suite.artifactCtl, "Delete").Return(nil) rps, err := suite.handler.MakePlaceHolder(ctx, art, r) diff --git a/src/pkg/task/mock_task_manager_test.go b/src/pkg/task/mock_task_manager_test.go index 271833460e3..2c99c1b553e 100644 --- a/src/pkg/task/mock_task_manager_test.go +++ b/src/pkg/task/mock_task_manager_test.go @@ -197,6 +197,24 @@ func (_m *mockTaskManager) GetLogByJobID(ctx context.Context, jobID string) ([]b return r0, r1 } +// IsTaskFinished provides a mock function with given fields: ctx, reportID +func (_m *mockTaskManager) IsTaskFinished(ctx context.Context, reportID string) bool { + ret := _m.Called(ctx, reportID) + + if len(ret) == 0 { + panic("no return value specified for IsTaskFinished") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok { + r0 = rf(ctx, reportID) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + // List provides a mock function with given fields: ctx, query func (_m *mockTaskManager) List(ctx context.Context, query *q.Query) ([]*Task, error) { ret := _m.Called(ctx, query) diff --git a/src/pkg/task/task.go b/src/pkg/task/task.go index 859953909a1..fa82c14ed05 100644 --- a/src/pkg/task/task.go +++ b/src/pkg/task/task.go @@ -69,6 +69,8 @@ type Manager interface { ListScanTasksByReportUUID(ctx context.Context, uuid string) (tasks []*Task, err error) // RetrieveStatusFromTask retrieve status from task RetrieveStatusFromTask(ctx context.Context, reportID string) string + // IsTaskFinished checks if the scan task is finished by report UUID + IsTaskFinished(ctx context.Context, reportID string) bool } // NewManager creates an instance of the default task manager @@ -299,3 +301,11 @@ func (m *manager) RetrieveStatusFromTask(ctx context.Context, reportID string) s } return "" } + +func (m *manager) IsTaskFinished(ctx context.Context, reportID string) bool { + status := m.RetrieveStatusFromTask(ctx, reportID) + if len(status) == 0 { + return true + } + return job.Status(status).Final() +} diff --git a/src/testing/pkg/task/manager.go b/src/testing/pkg/task/manager.go index 1359afd009e..299b8658095 100644 --- a/src/testing/pkg/task/manager.go +++ b/src/testing/pkg/task/manager.go @@ -199,6 +199,24 @@ func (_m *Manager) GetLogByJobID(ctx context.Context, jobID string) ([]byte, err return r0, r1 } +// IsTaskFinished provides a mock function with given fields: ctx, reportID +func (_m *Manager) IsTaskFinished(ctx context.Context, reportID string) bool { + ret := _m.Called(ctx, reportID) + + if len(ret) == 0 { + panic("no return value specified for IsTaskFinished") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok { + r0 = rf(ctx, reportID) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + // List provides a mock function with given fields: ctx, query func (_m *Manager) List(ctx context.Context, query *q.Query) ([]*task.Task, error) { ret := _m.Called(ctx, query)