mirror of
https://github.com/goharbor/harbor
synced 2025-04-21 17:51:41 +00:00
Support store the cron type in the schedule (#13097)
There is requirement that show the cron type(daily, weekly, etc.) on the UI, this commit adds the support for storing the cron type in the schedule model Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
1af4c5e7cb
commit
8b9727f53f
1
make/migrations/postgresql/0050_2.2.0_schema.up.sql
Normal file
1
make/migrations/postgresql/0050_2.2.0_schema.up.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE schedule ADD COLUMN IF NOT EXISTS cron_type varchar(64);
|
@ -292,7 +292,7 @@ func (c *controller) CreatePolicy(ctx context.Context, schema *policyModels.Sche
|
|||||||
schema.Trigger.Type == policyModels.TriggerTypeScheduled &&
|
schema.Trigger.Type == policyModels.TriggerTypeScheduled &&
|
||||||
len(schema.Trigger.Settings.Cron) > 0 {
|
len(schema.Trigger.Settings.Cron) > 0 {
|
||||||
// schedule and update policy
|
// schedule and update policy
|
||||||
if _, err = c.scheduler.Schedule(ctx, job.P2PPreheat, id, schema.Trigger.Settings.Cron,
|
if _, err = c.scheduler.Schedule(ctx, job.P2PPreheat, id, "", schema.Trigger.Settings.Cron,
|
||||||
SchedulerCallback, TriggerParam{PolicyID: id}); err != nil {
|
SchedulerCallback, TriggerParam{PolicyID: id}); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -384,7 +384,7 @@ func (c *controller) UpdatePolicy(ctx context.Context, schema *policyModels.Sche
|
|||||||
|
|
||||||
// schedule new
|
// schedule new
|
||||||
if needSch {
|
if needSch {
|
||||||
if _, err := c.scheduler.Schedule(ctx, job.P2PPreheat, schema.ID, cron, SchedulerCallback,
|
if _, err := c.scheduler.Schedule(ctx, job.P2PPreheat, schema.ID, "", cron, SchedulerCallback,
|
||||||
TriggerParam{PolicyID: schema.ID}); err != nil {
|
TriggerParam{PolicyID: schema.ID}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ func (s *preheatSuite) TestCreatePolicy() {
|
|||||||
FiltersStr: `[{"type":"repository","value":"harbor*"},{"type":"tag","value":"2*"}]`,
|
FiltersStr: `[{"type":"repository","value":"harbor*"},{"type":"tag","value":"2*"}]`,
|
||||||
TriggerStr: fmt.Sprintf(`{"type":"%s", "trigger_setting":{"cron":"* * * * */1"}}`, policy.TriggerTypeScheduled),
|
TriggerStr: fmt.Sprintf(`{"type":"%s", "trigger_setting":{"cron":"* * * * */1"}}`, policy.TriggerTypeScheduled),
|
||||||
}
|
}
|
||||||
s.fakeScheduler.On("Schedule", s.ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.fakeScheduler.On("Schedule", s.ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.fakePolicyMgr.On("Create", s.ctx, policy).Return(int64(1), nil)
|
s.fakePolicyMgr.On("Create", s.ctx, policy).Return(int64(1), nil)
|
||||||
s.fakePolicyMgr.On("Update", s.ctx, mock.Anything, mock.Anything).Return(nil)
|
s.fakePolicyMgr.On("Update", s.ctx, mock.Anything, mock.Anything).Return(nil)
|
||||||
s.fakeScheduler.On("UnScheduleByVendor", s.ctx, mock.Anything, mock.Anything).Return(nil)
|
s.fakeScheduler.On("UnScheduleByVendor", s.ctx, mock.Anything, mock.Anything).Return(nil)
|
||||||
|
@ -93,7 +93,7 @@ func (r *DefaultAPIController) CreateRetention(p *policy.Metadata) (int64, error
|
|||||||
if p.Trigger.Kind == policy.TriggerKindSchedule {
|
if p.Trigger.Kind == policy.TriggerKindSchedule {
|
||||||
cron, ok := p.Trigger.Settings[policy.TriggerSettingsCron]
|
cron, ok := p.Trigger.Settings[policy.TriggerSettingsCron]
|
||||||
if ok && len(cron.(string)) > 0 {
|
if ok && len(cron.(string)) > 0 {
|
||||||
if _, err = r.scheduler.Schedule(orm.Context(), schedulerVendorType, id, cron.(string), SchedulerCallback, TriggerParam{
|
if _, err = r.scheduler.Schedule(orm.Context(), schedulerVendorType, id, "", cron.(string), SchedulerCallback, TriggerParam{
|
||||||
PolicyID: id,
|
PolicyID: id,
|
||||||
Trigger: ExecutionTriggerSchedule,
|
Trigger: ExecutionTriggerSchedule,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -152,7 +152,7 @@ func (r *DefaultAPIController) UpdateRetention(p *policy.Metadata) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if needSch {
|
if needSch {
|
||||||
_, err := r.scheduler.Schedule(orm.Context(), schedulerVendorType, p.ID, p.Trigger.Settings[policy.TriggerSettingsCron].(string), SchedulerCallback, TriggerParam{
|
_, err := r.scheduler.Schedule(orm.Context(), schedulerVendorType, p.ID, "", p.Trigger.Settings[policy.TriggerSettingsCron].(string), SchedulerCallback, TriggerParam{
|
||||||
PolicyID: p.ID,
|
PolicyID: p.ID,
|
||||||
Trigger: ExecutionTriggerSchedule,
|
Trigger: ExecutionTriggerSchedule,
|
||||||
})
|
})
|
||||||
|
@ -220,7 +220,7 @@ func (s *ControllerTestSuite) TestExecution() {
|
|||||||
type fakeRetentionScheduler struct {
|
type fakeRetentionScheduler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeRetentionScheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cron string, callbackFuncName string, params interface{}) (int64, error) {
|
func (f *fakeRetentionScheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, cron string, callbackFuncName string, params interface{}) (int64, error) {
|
||||||
return 111, nil
|
return 111, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ type schedule struct {
|
|||||||
ID int64 `orm:"pk;auto;column(id)"`
|
ID int64 `orm:"pk;auto;column(id)"`
|
||||||
VendorType string `orm:"column(vendor_type)"`
|
VendorType string `orm:"column(vendor_type)"`
|
||||||
VendorID int64 `orm:"column(vendor_id)"`
|
VendorID int64 `orm:"column(vendor_id)"`
|
||||||
|
CRONType string `orm:"column(cron_type)"`
|
||||||
CRON string `orm:"column(cron)"`
|
CRON string `orm:"column(cron)"`
|
||||||
CallbackFuncName string `orm:"column(callback_func_name)"`
|
CallbackFuncName string `orm:"column(callback_func_name)"`
|
||||||
CallbackFuncParam string `orm:"column(callback_func_param)"`
|
CallbackFuncParam string `orm:"column(callback_func_param)"`
|
||||||
|
@ -40,6 +40,7 @@ type Schedule struct {
|
|||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
VendorType string `json:"vendor_type"`
|
VendorType string `json:"vendor_type"`
|
||||||
VendorID int64 `json:"vendor_id"`
|
VendorID int64 `json:"vendor_id"`
|
||||||
|
CRONType string `json:"cron_type"`
|
||||||
CRON string `json:"cron"`
|
CRON string `json:"cron"`
|
||||||
Status string `json:"status"` // status of the underlying task(jobservice job)
|
Status string `json:"status"` // status of the underlying task(jobservice job)
|
||||||
CreationTime time.Time `json:"creation_time"`
|
CreationTime time.Time `json:"creation_time"`
|
||||||
@ -57,8 +58,8 @@ type Scheduler interface {
|
|||||||
// and the "vendorID" specifies the ID of vendor if needed(e.g. policy ID for replication and retention).
|
// and the "vendorID" specifies the ID of vendor if needed(e.g. policy ID for replication and retention).
|
||||||
// The "params" is passed to the callback function as encoded json string, so the callback
|
// The "params" is passed to the callback function as encoded json string, so the callback
|
||||||
// function must decode it before using
|
// function must decode it before using
|
||||||
Schedule(ctx context.Context, vendorType string, vendorID int64, cron string,
|
Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string,
|
||||||
callbackFuncName string, params interface{}) (int64, error)
|
cron string, callbackFuncName string, params interface{}) (int64, error)
|
||||||
// UnScheduleByID the schedule specified by ID
|
// UnScheduleByID the schedule specified by ID
|
||||||
UnScheduleByID(ctx context.Context, id int64) error
|
UnScheduleByID(ctx context.Context, id int64) error
|
||||||
// UnScheduleByVendor the schedule specified by vendor
|
// UnScheduleByVendor the schedule specified by vendor
|
||||||
@ -92,11 +93,11 @@ type scheduler struct {
|
|||||||
// The implementation of "Schedule" replaces the ormer with a new one in the context
|
// The implementation of "Schedule" replaces the ormer with a new one in the context
|
||||||
// to out of control from the global transaction, and uses a new transaction that only
|
// to out of control from the global transaction, and uses a new transaction that only
|
||||||
// covers the logic inside the function
|
// covers the logic inside the function
|
||||||
func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cron string,
|
func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string,
|
||||||
callbackFuncName string, params interface{}) (int64, error) {
|
cron string, callbackFuncName string, params interface{}) (int64, error) {
|
||||||
var scheduleID int64
|
var scheduleID int64
|
||||||
f := func(ctx context.Context) error {
|
f := func(ctx context.Context) error {
|
||||||
id, err := s.schedule(ctx, vendorType, vendorID, cron, callbackFuncName, params)
|
id, err := s.schedule(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -111,8 +112,8 @@ func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID in
|
|||||||
return scheduleID, nil
|
return scheduleID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scheduler) schedule(ctx context.Context, vendorType string, vendorID int64, cron string,
|
func (s *scheduler) schedule(ctx context.Context, vendorType string, vendorID int64, cronType string,
|
||||||
callbackFuncName string, params interface{}) (int64, error) {
|
cron string, callbackFuncName string, params interface{}) (int64, error) {
|
||||||
if len(vendorType) == 0 {
|
if len(vendorType) == 0 {
|
||||||
return 0, fmt.Errorf("empty vendor type")
|
return 0, fmt.Errorf("empty vendor type")
|
||||||
}
|
}
|
||||||
@ -128,6 +129,7 @@ func (s *scheduler) schedule(ctx context.Context, vendorType string, vendorID in
|
|||||||
sched := &schedule{
|
sched := &schedule{
|
||||||
VendorType: vendorType,
|
VendorType: vendorType,
|
||||||
VendorID: vendorID,
|
VendorID: vendorID,
|
||||||
|
CRONType: cronType,
|
||||||
CRON: cron,
|
CRON: cron,
|
||||||
CallbackFuncName: callbackFuncName,
|
CallbackFuncName: callbackFuncName,
|
||||||
CreationTime: now,
|
CreationTime: now,
|
||||||
@ -265,6 +267,7 @@ func (s *scheduler) convertSchedule(ctx context.Context, schedule *schedule) (*S
|
|||||||
ID: schedule.ID,
|
ID: schedule.ID,
|
||||||
VendorType: schedule.VendorType,
|
VendorType: schedule.VendorType,
|
||||||
VendorID: schedule.VendorID,
|
VendorID: schedule.VendorID,
|
||||||
|
CRONType: schedule.CRONType,
|
||||||
CRON: schedule.CRON,
|
CRON: schedule.CRON,
|
||||||
CreationTime: schedule.CreationTime,
|
CreationTime: schedule.CreationTime,
|
||||||
UpdateTime: schedule.UpdateTime,
|
UpdateTime: schedule.UpdateTime,
|
||||||
|
@ -50,15 +50,15 @@ func (s *schedulerTestSuite) SetupTest() {
|
|||||||
|
|
||||||
func (s *schedulerTestSuite) TestSchedule() {
|
func (s *schedulerTestSuite) TestSchedule() {
|
||||||
// empty vendor type
|
// empty vendor type
|
||||||
id, err := s.scheduler.Schedule(nil, "", 0, "0 * * * * *", "callback", nil)
|
id, err := s.scheduler.Schedule(nil, "", 0, "", "0 * * * * *", "callback", nil)
|
||||||
s.NotNil(err)
|
s.NotNil(err)
|
||||||
|
|
||||||
// invalid cron
|
// invalid cron
|
||||||
id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "callback", nil)
|
id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "", "callback", nil)
|
||||||
s.NotNil(err)
|
s.NotNil(err)
|
||||||
|
|
||||||
// callback function not exist
|
// callback function not exist
|
||||||
id, err = s.scheduler.Schedule(nil, "vendor", 1, "0 * * * * *", "not-exist", nil)
|
id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "0 * * * * *", "not-exist", nil)
|
||||||
s.NotNil(err)
|
s.NotNil(err)
|
||||||
|
|
||||||
// failed to submit to jobservice
|
// failed to submit to jobservice
|
||||||
@ -71,7 +71,7 @@ func (s *schedulerTestSuite) TestSchedule() {
|
|||||||
Status: job.ErrorStatus.String(),
|
Status: job.ErrorStatus.String(),
|
||||||
}, nil)
|
}, nil)
|
||||||
s.taskMgr.On("Stop", mock.Anything, mock.Anything).Return(nil)
|
s.taskMgr.On("Stop", mock.Anything, mock.Anything).Return(nil)
|
||||||
_, err = s.scheduler.Schedule(nil, "vendor", 1, "0 * * * * *", "callback", "param")
|
_, err = s.scheduler.Schedule(nil, "vendor", 1, "", "0 * * * * *", "callback", "param")
|
||||||
s.Require().NotNil(err)
|
s.Require().NotNil(err)
|
||||||
s.dao.AssertExpectations(s.T())
|
s.dao.AssertExpectations(s.T())
|
||||||
s.execMgr.AssertExpectations(s.T())
|
s.execMgr.AssertExpectations(s.T())
|
||||||
@ -89,7 +89,7 @@ func (s *schedulerTestSuite) TestSchedule() {
|
|||||||
ExecutionID: 1,
|
ExecutionID: 1,
|
||||||
Status: job.SuccessStatus.String(),
|
Status: job.SuccessStatus.String(),
|
||||||
}, nil)
|
}, nil)
|
||||||
id, err = s.scheduler.Schedule(nil, "vendor", 1, "0 * * * * *", "callback", "param")
|
id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "0 * * * * *", "callback", "param")
|
||||||
s.Require().Nil(err)
|
s.Require().Nil(err)
|
||||||
s.Equal(int64(1), id)
|
s.Equal(int64(1), id)
|
||||||
s.dao.AssertExpectations(s.T())
|
s.dao.AssertExpectations(s.T())
|
||||||
|
@ -62,20 +62,20 @@ func (_m *Scheduler) ListSchedules(ctx context.Context, query *q.Query) ([]*sche
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule provides a mock function with given fields: ctx, vendorType, vendorID, cron, callbackFuncName, params
|
// Schedule provides a mock function with given fields: ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params
|
||||||
func (_m *Scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cron string, callbackFuncName string, params interface{}) (int64, error) {
|
func (_m *Scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, cron string, callbackFuncName string, params interface{}) (int64, error) {
|
||||||
ret := _m.Called(ctx, vendorType, vendorID, cron, callbackFuncName, params)
|
ret := _m.Called(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params)
|
||||||
|
|
||||||
var r0 int64
|
var r0 int64
|
||||||
if rf, ok := ret.Get(0).(func(context.Context, string, int64, string, string, interface{}) int64); ok {
|
if rf, ok := ret.Get(0).(func(context.Context, string, int64, string, string, string, interface{}) int64); ok {
|
||||||
r0 = rf(ctx, vendorType, vendorID, cron, callbackFuncName, params)
|
r0 = rf(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Get(0).(int64)
|
r0 = ret.Get(0).(int64)
|
||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(context.Context, string, int64, string, string, interface{}) error); ok {
|
if rf, ok := ret.Get(1).(func(context.Context, string, int64, string, string, string, interface{}) error); ok {
|
||||||
r1 = rf(ctx, vendorType, vendorID, cron, callbackFuncName, params)
|
r1 = rf(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user