Merge pull request #7075 from wy65701436/cron-str

update gc api to support raw cron string
This commit is contained in:
Daniel Jiang 2019-03-06 13:36:52 +08:00 committed by GitHub
commit 002094dbbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 66 deletions

View File

@ -4671,15 +4671,10 @@ definitions:
properties:
type:
type: string
description: The schedule type. The valid values are daily weekly and None. 'None' means to cancel the schedule.
weekday:
type: integer
format: int8
description: 'Optional, only used when the type is weekly. The valid values are 1-7.'
offtime:
type: integer
format: int64
description: 'The time offset with the UTC 00:00 in seconds.'
description: The schedule type. The valid values are hourly, daily weekly, custom and None. 'None' means to cancel the schedule.
cron:
type: string
description: A cron expression, a time-based job scheduler.
SearchResult:
type: object
description: The chart search result item

View File

@ -22,16 +22,20 @@ import (
"github.com/astaxie/beego/validation"
"github.com/goharbor/harbor/src/common/job"
"github.com/goharbor/harbor/src/common/job/models"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/common/utils/log"
"github.com/goharbor/harbor/src/core/config"
"github.com/robfig/cron"
)
const (
// ScheduleHourly : 'Hourly'
ScheduleHourly = "Hourly"
// ScheduleDaily : 'Daily'
ScheduleDaily = "Daily"
// ScheduleWeekly : 'Weekly'
ScheduleWeekly = "Weekly"
// ScheduleCustom : 'Custom'
ScheduleCustom = "Custom"
// ScheduleManual : 'Manual'
ScheduleManual = "Manual"
// ScheduleNone : 'None'
@ -48,12 +52,10 @@ type GCReq struct {
// ScheduleParam defines the parameter of schedule trigger
type ScheduleParam struct {
// Daily, Weekly, Manual, None
// Daily, Weekly, Custom, Manual, None
Type string `json:"type"`
// Optional, only used when type is 'weekly'
Weekday int8 `json:"weekday"`
// The time offset with the UTC 00:00 in seconds
Offtime int64 `json:"offtime"`
// The cron string of scheduled job
Cron string `json:"cron"`
}
// GCRep holds the response of query gc
@ -75,9 +77,9 @@ func (gr *GCReq) Valid(v *validation.Validation) {
return
}
switch gr.Schedule.Type {
case ScheduleDaily, ScheduleWeekly:
if gr.Schedule.Offtime < 0 || gr.Schedule.Offtime > 3600*24 {
v.SetError("offtime", fmt.Sprintf("Invalid schedule trigger parameter offtime: %d", gr.Schedule.Offtime))
case ScheduleHourly, ScheduleDaily, ScheduleWeekly, ScheduleCustom:
if _, err := cron.Parse(gr.Schedule.Cron); err != nil {
v.SetError("cron", fmt.Sprintf("Invalid schedule trigger parameter cron: %s", gr.Schedule.Cron))
}
case ScheduleManual, ScheduleNone:
default:
@ -85,26 +87,15 @@ func (gr *GCReq) Valid(v *validation.Validation) {
}
}
// ToJob converts request to a job reconiged by job service.
func (gr *GCReq) ToJob() (*models.JobData, error) {
// ToJob converts request to a job recognized by job service.
func (gr *GCReq) ToJob() *models.JobData {
metadata := &models.JobMetadata{
JobKind: gr.JobKind(),
Cron: gr.Schedule.Cron,
// GC job must be unique ...
IsUnique: true,
}
switch gr.Schedule.Type {
case ScheduleDaily:
h, m, s := utils.ParseOfftime(gr.Schedule.Offtime)
metadata.Cron = fmt.Sprintf("%d %d %d * * *", s, m, h)
case ScheduleWeekly:
h, m, s := utils.ParseOfftime(gr.Schedule.Offtime)
metadata.Cron = fmt.Sprintf("%d %d %d * * %d", s, m, h, gr.Schedule.Weekday%7)
case ScheduleManual, ScheduleNone:
default:
return nil, fmt.Errorf("unsupported schedule trigger type: %s", gr.Schedule.Type)
}
jobData := &models.JobData{
Name: job.ImageGC,
Parameters: gr.Parameters,
@ -112,7 +103,7 @@ func (gr *GCReq) ToJob() (*models.JobData, error) {
StatusHook: fmt.Sprintf("%s/service/notifications/jobs/adminjob/%d",
config.InternalCoreURL(), gr.ID),
}
return jobData, nil
return jobData
}
// IsPeriodic ...
@ -123,7 +114,7 @@ func (gr *GCReq) IsPeriodic() bool {
// JobKind ...
func (gr *GCReq) JobKind() string {
switch gr.Schedule.Type {
case ScheduleDaily, ScheduleWeekly:
case ScheduleHourly, ScheduleDaily, ScheduleWeekly, ScheduleCustom:
return job.JobKindPeriodic
case ScheduleManual:
return job.JobKindGeneric

View File

@ -41,16 +41,15 @@ func TestMain(m *testing.M) {
func TestToJob(t *testing.T) {
schedule := &ScheduleParam{
Type: "Daily",
Offtime: 200,
Type: "Daily",
Cron: "20 3 0 * * *",
}
adminjob := &GCReq{
Schedule: schedule,
}
job, err := adminjob.ToJob()
assert.Nil(t, err)
job := adminjob.ToJob()
assert.Equal(t, job.Name, "IMAGE_GC")
assert.Equal(t, job.Metadata.JobKind, common_job.JobKindPeriodic)
assert.Equal(t, job.Metadata.Cron, "20 3 0 * * *")
@ -65,29 +64,15 @@ func TestToJobManual(t *testing.T) {
Schedule: schedule,
}
job, err := adminjob.ToJob()
assert.Nil(t, err)
job := adminjob.ToJob()
assert.Equal(t, job.Name, "IMAGE_GC")
assert.Equal(t, job.Metadata.JobKind, common_job.JobKindGeneric)
}
func TestToJobErr(t *testing.T) {
schedule := &ScheduleParam{
Type: "test",
}
adminjob := &GCReq{
Schedule: schedule,
}
_, err := adminjob.ToJob()
assert.NotNil(t, err)
}
func TestIsPeriodic(t *testing.T) {
schedule := &ScheduleParam{
Type: "Daily",
Offtime: 200,
Type: "Daily",
Cron: "20 3 0 * * *",
}
adminjob := &GCReq{
@ -100,8 +85,8 @@ func TestIsPeriodic(t *testing.T) {
func TestJobKind(t *testing.T) {
schedule := &ScheduleParam{
Type: "Daily",
Offtime: 200,
Type: "Daily",
Cron: "20 3 0 * * *",
}
adminjob := &GCReq{
Schedule: schedule,
@ -121,12 +106,12 @@ func TestJobKind(t *testing.T) {
func TestCronString(t *testing.T) {
schedule := &ScheduleParam{
Type: "Daily",
Offtime: 102,
Type: "Daily",
Cron: "20 3 0 * * *",
}
adminjob := &GCReq{
Schedule: schedule,
}
cronStr := adminjob.CronString()
assert.True(t, strings.EqualFold(cronStr, "{\"type\":\"Daily\",\"Weekday\":0,\"Offtime\":102}"))
assert.True(t, strings.EqualFold(cronStr, "{\"type\":\"Daily\",\"Cron\":\"20 3 0 * * *\"}"))
}

View File

@ -214,7 +214,7 @@ func (gc *GCAPI) GetLog() {
// submitJob submits a job to job service per request
func (gc *GCAPI) submitJob(gr *models.GCReq) {
// cannot post multiple schdule for GC job.
// cannot post multiple schedule for GC job.
if gr.IsPeriodic() {
jobs, err := dao.GetAdminJobs(&common_models.AdminJobQuery{
Name: common_job.ImageGC,
@ -243,7 +243,7 @@ func (gc *GCAPI) submitJob(gr *models.GCReq) {
gr.Parameters = map[string]interface{}{
"redis_url_reg": os.Getenv("_REDIS_URL_REG"),
}
job, err := gr.ToJob()
job := gr.ToJob()
if err != nil {
gc.HandleInternalServerError(fmt.Sprintf("%v", err))
return

View File

@ -54,7 +54,7 @@ func TestConvertToGCRep(t *testing.T) {
ID: 1,
Name: "IMAGE_GC",
Kind: "Generic",
Cron: "{\"Type\":\"Manual\",\"Weekday\":0,\"Offtime\":0}",
Cron: "{\"Type\":\"Daily\",\"Cron\":\"20 3 0 * * *\"}",
Status: "pending",
Deleted: false,
},
@ -63,9 +63,8 @@ func TestConvertToGCRep(t *testing.T) {
Name: "IMAGE_GC",
Kind: "Generic",
Schedule: &api_modes.ScheduleParam{
Type: "Manual",
Weekday: 0,
Offtime: 0,
Type: "Daily",
Cron: "20 3 0 * * *",
},
Status: "pending",
Deleted: false,