mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-20 07:37:38 +01:00
feat: add task controller
Signed-off-by: chlins <chlins.zhang@gmail.com>
This commit is contained in:
parent
2efc4f230d
commit
2863e68718
80
src/controller/task/controller.go
Normal file
80
src/controller/task/controller.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/goharbor/harbor/src/lib/q"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/task"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Ctl is a global task controller instance
|
||||||
|
Ctl = NewController()
|
||||||
|
)
|
||||||
|
|
||||||
|
// Controller manages the task
|
||||||
|
type Controller interface {
|
||||||
|
// Create submits the job to jobservice and creates a corresponding task record.
|
||||||
|
// An execution must be created first and the task will be linked to it.
|
||||||
|
// The "extraAttrs" can be used to set the customized attributes.
|
||||||
|
Create(ctx context.Context, executionID int64, job *task.Job, extraAttrs ...map[string]interface{}) (id int64, err error)
|
||||||
|
// Stop the specified task.
|
||||||
|
Stop(ctx context.Context, id int64) (err error)
|
||||||
|
// Get the specified task.
|
||||||
|
Get(ctx context.Context, id int64) (task *task.Task, err error)
|
||||||
|
// List the tasks according to the query.
|
||||||
|
List(ctx context.Context, query *q.Query) (tasks []*task.Task, err error)
|
||||||
|
// Get the log of the specified task.
|
||||||
|
GetLog(ctx context.Context, id int64) (log []byte, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewController creates an instance of the default task controller.
|
||||||
|
func NewController() Controller {
|
||||||
|
return &controller{
|
||||||
|
mgr: task.Mgr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// controller defines the default task controller.
|
||||||
|
type controller struct {
|
||||||
|
mgr task.Manager
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create submits the job to jobservice and creates a corresponding task record.
|
||||||
|
func (c *controller) Create(ctx context.Context, executionID int64, job *task.Job, extraAttrs ...map[string]interface{}) (id int64, err error) {
|
||||||
|
return c.mgr.Create(ctx, executionID, job, extraAttrs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the specified task.
|
||||||
|
func (c *controller) Stop(ctx context.Context, id int64) (err error) {
|
||||||
|
return c.mgr.Stop(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the specified task.
|
||||||
|
func (c *controller) Get(ctx context.Context, id int64) (task *task.Task, err error) {
|
||||||
|
return c.mgr.Get(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List the tasks according to the query.
|
||||||
|
func (c *controller) List(ctx context.Context, query *q.Query) (tasks []*task.Task, err error) {
|
||||||
|
return c.mgr.List(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the log of the specified task.
|
||||||
|
func (c *controller) GetLog(ctx context.Context, id int64) (log []byte, err error) {
|
||||||
|
return c.mgr.GetLog(ctx, id)
|
||||||
|
}
|
82
src/controller/task/controller_test.go
Normal file
82
src/controller/task/controller_test.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
model "github.com/goharbor/harbor/src/pkg/task"
|
||||||
|
"github.com/goharbor/harbor/src/testing/mock"
|
||||||
|
"github.com/goharbor/harbor/src/testing/pkg/task"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
)
|
||||||
|
|
||||||
|
type controllerTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
ctl *controller
|
||||||
|
mgr *task.FakeManager
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestControllerTestSuite tests controller.
|
||||||
|
func TestControllerTestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, &controllerTestSuite{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupTest setups the testing env.
|
||||||
|
func (c *controllerTestSuite) SetupTest() {
|
||||||
|
c.mgr = &task.FakeManager{}
|
||||||
|
c.ctl = &controller{mgr: c.mgr}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCreate tests create.
|
||||||
|
func (c *controllerTestSuite) TestCreate() {
|
||||||
|
c.mgr.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
|
id, err := c.ctl.Create(nil, 1, nil)
|
||||||
|
c.NoError(err)
|
||||||
|
c.Equal(int64(1), id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestStop tests stop.
|
||||||
|
func (c *controllerTestSuite) TestStop() {
|
||||||
|
c.mgr.On("Stop", mock.Anything, mock.Anything).Return(nil)
|
||||||
|
err := c.ctl.Stop(nil, 1)
|
||||||
|
c.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGet tests get.
|
||||||
|
func (c *controllerTestSuite) TestGet() {
|
||||||
|
c.mgr.On("Get", mock.Anything, int64(1)).Return(&model.Task{ID: 1}, nil)
|
||||||
|
t, err := c.ctl.Get(nil, 1)
|
||||||
|
c.NoError(err)
|
||||||
|
c.Equal(int64(1), t.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestList tests list.
|
||||||
|
func (c *controllerTestSuite) TestList() {
|
||||||
|
c.mgr.On("List", mock.Anything, mock.Anything).Return([]*model.Task{
|
||||||
|
{ID: 1}, {ID: 2},
|
||||||
|
}, nil)
|
||||||
|
ts, err := c.ctl.List(nil, nil)
|
||||||
|
c.NoError(err)
|
||||||
|
c.Len(ts, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGetLog tests get log.
|
||||||
|
func (c *controllerTestSuite) TestGetLog() {
|
||||||
|
c.mgr.On("GetLog", mock.Anything, mock.Anything).Return([]byte("logs"), nil)
|
||||||
|
l, err := c.ctl.GetLog(nil, 1)
|
||||||
|
c.NoError(err)
|
||||||
|
c.Equal([]byte("logs"), l)
|
||||||
|
}
|
105
src/controller/task/execution_controller.go
Normal file
105
src/controller/task/execution_controller.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/goharbor/harbor/src/lib/q"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/task"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExecutionController manages the execution.
|
||||||
|
type ExecutionController interface {
|
||||||
|
// Create an execution. The "vendorType" specifies the type of vendor (e.g. replication, scan, gc, retention, etc.),
|
||||||
|
// and the "vendorID" specifies the ID of vendor if needed(e.g. policy ID for replication and retention).
|
||||||
|
// The "extraAttrs" can be used to set the customized attributes.
|
||||||
|
Create(ctx context.Context, vendorType string, vendorID int64, trigger string,
|
||||||
|
extraAttrs ...map[string]interface{}) (id int64, err error)
|
||||||
|
// MarkDone marks the status of the specified execution as success.
|
||||||
|
// It must be called to update the execution status if the created execution contains no tasks.
|
||||||
|
// In other cases, the execution status can be calculated from the referenced tasks automatically
|
||||||
|
// and no need to update it explicitly.
|
||||||
|
MarkDone(ctx context.Context, id int64, message string) (err error)
|
||||||
|
// MarkError marks the status of the specified execution as error.
|
||||||
|
// It must be called to update the execution status when failed to create tasks.
|
||||||
|
// In other cases, the execution status can be calculated from the referenced tasks automatically
|
||||||
|
// and no need to update it explicitly.
|
||||||
|
MarkError(ctx context.Context, id int64, message string) (err error)
|
||||||
|
// Stop all linked tasks of the specified execution.
|
||||||
|
Stop(ctx context.Context, id int64) (err error)
|
||||||
|
// Delete the specified execution and its tasks.
|
||||||
|
Delete(ctx context.Context, id int64) (err error)
|
||||||
|
// Get the specified execution.
|
||||||
|
Get(ctx context.Context, id int64) (execution *task.Execution, err error)
|
||||||
|
// List executions according to the query.
|
||||||
|
List(ctx context.Context, query *q.Query) (executions []*task.Execution, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// executionController defines the execution controller.
|
||||||
|
type executionController struct {
|
||||||
|
mgr task.ExecutionManager
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewController creates an instance of the default execution controller.
|
||||||
|
func NewExecutionController() ExecutionController {
|
||||||
|
return &executionController{
|
||||||
|
mgr: task.ExecMgr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an execution. The "vendorType" specifies the type of vendor (e.g. replication, scan, gc, retention, etc.),
|
||||||
|
// and the "vendorID" specifies the ID of vendor if needed(e.g. policy ID for replication and retention).
|
||||||
|
// The "extraAttrs" can be used to set the customized attributes.
|
||||||
|
func (ec *executionController) Create(ctx context.Context, vendorType string, vendorID int64, trigger string,
|
||||||
|
extraAttrs ...map[string]interface{}) (id int64, err error) {
|
||||||
|
return ec.mgr.Create(ctx, vendorType, vendorID, trigger, extraAttrs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkDone marks the status of the specified execution as success.
|
||||||
|
// It must be called to update the execution status if the created execution contains no tasks.
|
||||||
|
// In other cases, the execution status can be calculated from the referenced tasks automatically
|
||||||
|
// and no need to update it explicitly.
|
||||||
|
func (ec *executionController) MarkDone(ctx context.Context, id int64, message string) (err error) {
|
||||||
|
return ec.mgr.MarkDone(ctx, id, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkError marks the status of the specified execution as error.
|
||||||
|
// It must be called to update the execution status when failed to create tasks.
|
||||||
|
// In other cases, the execution status can be calculated from the referenced tasks automatically
|
||||||
|
// and no need to update it explicitly.
|
||||||
|
func (ec *executionController) MarkError(ctx context.Context, id int64, message string) (err error) {
|
||||||
|
return ec.mgr.MarkError(ctx, id, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop all linked tasks of the specified execution.
|
||||||
|
func (ec *executionController) Stop(ctx context.Context, id int64) (err error) {
|
||||||
|
return ec.mgr.Stop(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the specified execution and its tasks.
|
||||||
|
func (ec *executionController) Delete(ctx context.Context, id int64) (err error) {
|
||||||
|
return ec.mgr.Delete(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the specified execution.
|
||||||
|
func (ec *executionController) Get(ctx context.Context, id int64) (execution *task.Execution, err error) {
|
||||||
|
return ec.mgr.Get(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List executions according to the query.
|
||||||
|
func (ec *executionController) List(ctx context.Context, query *q.Query) (executions []*task.Execution, err error) {
|
||||||
|
return ec.mgr.List(ctx, query)
|
||||||
|
}
|
98
src/controller/task/execution_controller_test.go
Normal file
98
src/controller/task/execution_controller_test.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
model "github.com/goharbor/harbor/src/pkg/task"
|
||||||
|
"github.com/goharbor/harbor/src/testing/mock"
|
||||||
|
"github.com/goharbor/harbor/src/testing/pkg/task"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
)
|
||||||
|
|
||||||
|
type executionControllerTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
ctl *executionController
|
||||||
|
mgr *task.FakeExecutionManager
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExecutionControllerTestSuite tests controller.
|
||||||
|
func TestExecutionControllerTestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, &executionControllerTestSuite{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupTest setups the testing env.
|
||||||
|
func (ec *executionControllerTestSuite) SetupTest() {
|
||||||
|
ec.mgr = &task.FakeExecutionManager{}
|
||||||
|
ec.ctl = &executionController{
|
||||||
|
mgr: ec.mgr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCreate tests create.
|
||||||
|
func (ec *executionControllerTestSuite) TestCreate() {
|
||||||
|
ec.mgr.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
|
id, err := ec.ctl.Create(nil, "", 1, "")
|
||||||
|
ec.NoError(err)
|
||||||
|
ec.Equal(int64(1), id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestMarkDown tests mark down.
|
||||||
|
func (ec *executionControllerTestSuite) TestMarkDone() {
|
||||||
|
ec.mgr.On("MarkDone", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||||
|
err := ec.ctl.MarkDone(nil, 1, "")
|
||||||
|
ec.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestMarkError tests mark error.
|
||||||
|
func (ec *executionControllerTestSuite) TestMarkError() {
|
||||||
|
ec.mgr.On("MarkError", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||||
|
err := ec.ctl.MarkError(nil, 1, "")
|
||||||
|
ec.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestStop tests stop.
|
||||||
|
func (ec *executionControllerTestSuite) TestStop() {
|
||||||
|
ec.mgr.On("Stop", mock.Anything, mock.Anything).Return(nil)
|
||||||
|
err := ec.ctl.Stop(nil, 1)
|
||||||
|
ec.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDelete tests delete.
|
||||||
|
func (ec *executionControllerTestSuite) TestDelete() {
|
||||||
|
ec.mgr.On("Delete", mock.Anything, mock.Anything).Return(nil)
|
||||||
|
err := ec.ctl.Delete(nil, 1)
|
||||||
|
ec.NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGet tests get.
|
||||||
|
func (ec *executionControllerTestSuite) TestGet() {
|
||||||
|
ec.mgr.On("Get", mock.Anything, mock.Anything).Return(&model.Execution{ID: 1}, nil)
|
||||||
|
e, err := ec.ctl.Get(nil, 1)
|
||||||
|
ec.NoError(err)
|
||||||
|
ec.Equal(int64(1), e.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestList tests list.
|
||||||
|
func (ec *executionControllerTestSuite) TestList() {
|
||||||
|
ec.mgr.On("List", mock.Anything, mock.Anything).Return([]*model.Execution{
|
||||||
|
{ID: 1},
|
||||||
|
{ID: 2},
|
||||||
|
}, nil)
|
||||||
|
es, err := ec.ctl.List(nil, nil)
|
||||||
|
ec.NoError(err)
|
||||||
|
ec.Len(es, 2)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user