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:
Wenkai Yin(尹文开) 2020-09-24 16:48:56 +08:00 committed by GitHub
parent 1af4c5e7cb
commit 8b9727f53f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 30 additions and 25 deletions

View File

@ -0,0 +1 @@
ALTER TABLE schedule ADD COLUMN IF NOT EXISTS cron_type varchar(64);

View File

@ -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
} }

View File

@ -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)

View File

@ -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,
}) })

View File

@ -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
} }

View File

@ -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)"`

View File

@ -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,

View File

@ -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())

View File

@ -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)
} }