mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-03 06:28:06 +01:00
update gc api to support raw cron string
Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
parent
dffb971366
commit
e373167546
@ -4671,15 +4671,10 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
description: The schedule type. The valid values are daily, weekly and None. 'None' means to cancel the schedule.
|
description: The schedule type. The valid values are hourly, daily, weekly, custom and None. 'None' means to cancel the schedule.
|
||||||
weekday:
|
cron:
|
||||||
type: integer
|
type: string
|
||||||
format: int8
|
description: A cron expression, a time-based job scheduler.
|
||||||
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.'
|
|
||||||
SearchResult:
|
SearchResult:
|
||||||
type: object
|
type: object
|
||||||
description: The chart search result item
|
description: The chart search result item
|
||||||
|
@ -22,16 +22,20 @@ import (
|
|||||||
"github.com/astaxie/beego/validation"
|
"github.com/astaxie/beego/validation"
|
||||||
"github.com/goharbor/harbor/src/common/job"
|
"github.com/goharbor/harbor/src/common/job"
|
||||||
"github.com/goharbor/harbor/src/common/job/models"
|
"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/common/utils/log"
|
||||||
"github.com/goharbor/harbor/src/core/config"
|
"github.com/goharbor/harbor/src/core/config"
|
||||||
|
"github.com/robfig/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// ScheduleHourly : 'Hourly'
|
||||||
|
ScheduleHourly = "Hourly"
|
||||||
// ScheduleDaily : 'Daily'
|
// ScheduleDaily : 'Daily'
|
||||||
ScheduleDaily = "Daily"
|
ScheduleDaily = "Daily"
|
||||||
// ScheduleWeekly : 'Weekly'
|
// ScheduleWeekly : 'Weekly'
|
||||||
ScheduleWeekly = "Weekly"
|
ScheduleWeekly = "Weekly"
|
||||||
|
// ScheduleCustom : 'Custom'
|
||||||
|
ScheduleCustom = "Custom"
|
||||||
// ScheduleManual : 'Manual'
|
// ScheduleManual : 'Manual'
|
||||||
ScheduleManual = "Manual"
|
ScheduleManual = "Manual"
|
||||||
// ScheduleNone : 'None'
|
// ScheduleNone : 'None'
|
||||||
@ -48,12 +52,10 @@ type GCReq struct {
|
|||||||
|
|
||||||
// ScheduleParam defines the parameter of schedule trigger
|
// ScheduleParam defines the parameter of schedule trigger
|
||||||
type ScheduleParam struct {
|
type ScheduleParam struct {
|
||||||
// Daily, Weekly, Manual, None
|
// Daily, Weekly, Custom, Manual, None
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
// Optional, only used when type is 'weekly'
|
// The cron string of scheduled job
|
||||||
Weekday int8 `json:"weekday"`
|
Cron string `json:"cron"`
|
||||||
// The time offset with the UTC 00:00 in seconds
|
|
||||||
Offtime int64 `json:"offtime"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCRep holds the response of query gc
|
// GCRep holds the response of query gc
|
||||||
@ -75,9 +77,9 @@ func (gr *GCReq) Valid(v *validation.Validation) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch gr.Schedule.Type {
|
switch gr.Schedule.Type {
|
||||||
case ScheduleDaily, ScheduleWeekly:
|
case ScheduleHourly, ScheduleDaily, ScheduleWeekly, ScheduleCustom:
|
||||||
if gr.Schedule.Offtime < 0 || gr.Schedule.Offtime > 3600*24 {
|
if _, err := cron.Parse(gr.Schedule.Cron); err != nil {
|
||||||
v.SetError("offtime", fmt.Sprintf("Invalid schedule trigger parameter offtime: %d", gr.Schedule.Offtime))
|
v.SetError("cron", fmt.Sprintf("Invalid schedule trigger parameter cron: %s", gr.Schedule.Cron))
|
||||||
}
|
}
|
||||||
case ScheduleManual, ScheduleNone:
|
case ScheduleManual, ScheduleNone:
|
||||||
default:
|
default:
|
||||||
@ -85,26 +87,15 @@ func (gr *GCReq) Valid(v *validation.Validation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToJob converts request to a job reconiged by job service.
|
// ToJob converts request to a job recognized by job service.
|
||||||
func (gr *GCReq) ToJob() (*models.JobData, error) {
|
func (gr *GCReq) ToJob() *models.JobData {
|
||||||
metadata := &models.JobMetadata{
|
metadata := &models.JobMetadata{
|
||||||
JobKind: gr.JobKind(),
|
JobKind: gr.JobKind(),
|
||||||
|
Cron: gr.Schedule.Cron,
|
||||||
// GC job must be unique ...
|
// GC job must be unique ...
|
||||||
IsUnique: true,
|
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{
|
jobData := &models.JobData{
|
||||||
Name: job.ImageGC,
|
Name: job.ImageGC,
|
||||||
Parameters: gr.Parameters,
|
Parameters: gr.Parameters,
|
||||||
@ -112,7 +103,7 @@ func (gr *GCReq) ToJob() (*models.JobData, error) {
|
|||||||
StatusHook: fmt.Sprintf("%s/service/notifications/jobs/adminjob/%d",
|
StatusHook: fmt.Sprintf("%s/service/notifications/jobs/adminjob/%d",
|
||||||
config.InternalCoreURL(), gr.ID),
|
config.InternalCoreURL(), gr.ID),
|
||||||
}
|
}
|
||||||
return jobData, nil
|
return jobData
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPeriodic ...
|
// IsPeriodic ...
|
||||||
@ -123,7 +114,7 @@ func (gr *GCReq) IsPeriodic() bool {
|
|||||||
// JobKind ...
|
// JobKind ...
|
||||||
func (gr *GCReq) JobKind() string {
|
func (gr *GCReq) JobKind() string {
|
||||||
switch gr.Schedule.Type {
|
switch gr.Schedule.Type {
|
||||||
case ScheduleDaily, ScheduleWeekly:
|
case ScheduleHourly, ScheduleDaily, ScheduleWeekly, ScheduleCustom:
|
||||||
return job.JobKindPeriodic
|
return job.JobKindPeriodic
|
||||||
case ScheduleManual:
|
case ScheduleManual:
|
||||||
return job.JobKindGeneric
|
return job.JobKindGeneric
|
||||||
|
@ -41,16 +41,15 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
func TestToJob(t *testing.T) {
|
func TestToJob(t *testing.T) {
|
||||||
schedule := &ScheduleParam{
|
schedule := &ScheduleParam{
|
||||||
Type: "Daily",
|
Type: "Daily",
|
||||||
Offtime: 200,
|
Cron: "20 3 0 * * *",
|
||||||
}
|
}
|
||||||
|
|
||||||
adminjob := &GCReq{
|
adminjob := &GCReq{
|
||||||
Schedule: schedule,
|
Schedule: schedule,
|
||||||
}
|
}
|
||||||
|
|
||||||
job, err := adminjob.ToJob()
|
job := adminjob.ToJob()
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, job.Name, "IMAGE_GC")
|
assert.Equal(t, job.Name, "IMAGE_GC")
|
||||||
assert.Equal(t, job.Metadata.JobKind, common_job.JobKindPeriodic)
|
assert.Equal(t, job.Metadata.JobKind, common_job.JobKindPeriodic)
|
||||||
assert.Equal(t, job.Metadata.Cron, "20 3 0 * * *")
|
assert.Equal(t, job.Metadata.Cron, "20 3 0 * * *")
|
||||||
@ -65,29 +64,15 @@ func TestToJobManual(t *testing.T) {
|
|||||||
Schedule: schedule,
|
Schedule: schedule,
|
||||||
}
|
}
|
||||||
|
|
||||||
job, err := adminjob.ToJob()
|
job := adminjob.ToJob()
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, job.Name, "IMAGE_GC")
|
assert.Equal(t, job.Name, "IMAGE_GC")
|
||||||
assert.Equal(t, job.Metadata.JobKind, common_job.JobKindGeneric)
|
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) {
|
func TestIsPeriodic(t *testing.T) {
|
||||||
schedule := &ScheduleParam{
|
schedule := &ScheduleParam{
|
||||||
Type: "Daily",
|
Type: "Daily",
|
||||||
Offtime: 200,
|
Cron: "20 3 0 * * *",
|
||||||
}
|
}
|
||||||
|
|
||||||
adminjob := &GCReq{
|
adminjob := &GCReq{
|
||||||
@ -100,8 +85,8 @@ func TestIsPeriodic(t *testing.T) {
|
|||||||
|
|
||||||
func TestJobKind(t *testing.T) {
|
func TestJobKind(t *testing.T) {
|
||||||
schedule := &ScheduleParam{
|
schedule := &ScheduleParam{
|
||||||
Type: "Daily",
|
Type: "Daily",
|
||||||
Offtime: 200,
|
Cron: "20 3 0 * * *",
|
||||||
}
|
}
|
||||||
adminjob := &GCReq{
|
adminjob := &GCReq{
|
||||||
Schedule: schedule,
|
Schedule: schedule,
|
||||||
@ -121,12 +106,12 @@ func TestJobKind(t *testing.T) {
|
|||||||
|
|
||||||
func TestCronString(t *testing.T) {
|
func TestCronString(t *testing.T) {
|
||||||
schedule := &ScheduleParam{
|
schedule := &ScheduleParam{
|
||||||
Type: "Daily",
|
Type: "Daily",
|
||||||
Offtime: 102,
|
Cron: "20 3 0 * * *",
|
||||||
}
|
}
|
||||||
adminjob := &GCReq{
|
adminjob := &GCReq{
|
||||||
Schedule: schedule,
|
Schedule: schedule,
|
||||||
}
|
}
|
||||||
cronStr := adminjob.CronString()
|
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 * * *\"}"))
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ func (gc *GCAPI) GetLog() {
|
|||||||
|
|
||||||
// submitJob submits a job to job service per request
|
// submitJob submits a job to job service per request
|
||||||
func (gc *GCAPI) submitJob(gr *models.GCReq) {
|
func (gc *GCAPI) submitJob(gr *models.GCReq) {
|
||||||
// cannot post multiple schdule for GC job.
|
// cannot post multiple schedule for GC job.
|
||||||
if gr.IsPeriodic() {
|
if gr.IsPeriodic() {
|
||||||
jobs, err := dao.GetAdminJobs(&common_models.AdminJobQuery{
|
jobs, err := dao.GetAdminJobs(&common_models.AdminJobQuery{
|
||||||
Name: common_job.ImageGC,
|
Name: common_job.ImageGC,
|
||||||
@ -243,7 +243,7 @@ func (gc *GCAPI) submitJob(gr *models.GCReq) {
|
|||||||
gr.Parameters = map[string]interface{}{
|
gr.Parameters = map[string]interface{}{
|
||||||
"redis_url_reg": os.Getenv("_REDIS_URL_REG"),
|
"redis_url_reg": os.Getenv("_REDIS_URL_REG"),
|
||||||
}
|
}
|
||||||
job, err := gr.ToJob()
|
job := gr.ToJob()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gc.HandleInternalServerError(fmt.Sprintf("%v", err))
|
gc.HandleInternalServerError(fmt.Sprintf("%v", err))
|
||||||
return
|
return
|
||||||
|
@ -54,7 +54,7 @@ func TestConvertToGCRep(t *testing.T) {
|
|||||||
ID: 1,
|
ID: 1,
|
||||||
Name: "IMAGE_GC",
|
Name: "IMAGE_GC",
|
||||||
Kind: "Generic",
|
Kind: "Generic",
|
||||||
Cron: "{\"Type\":\"Manual\",\"Weekday\":0,\"Offtime\":0}",
|
Cron: "{\"Type\":\"Daily\",\"Cron\":\"20 3 0 * * *\"}",
|
||||||
Status: "pending",
|
Status: "pending",
|
||||||
Deleted: false,
|
Deleted: false,
|
||||||
},
|
},
|
||||||
@ -63,9 +63,8 @@ func TestConvertToGCRep(t *testing.T) {
|
|||||||
Name: "IMAGE_GC",
|
Name: "IMAGE_GC",
|
||||||
Kind: "Generic",
|
Kind: "Generic",
|
||||||
Schedule: &api_modes.ScheduleParam{
|
Schedule: &api_modes.ScheduleParam{
|
||||||
Type: "Manual",
|
Type: "Daily",
|
||||||
Weekday: 0,
|
Cron: "20 3 0 * * *",
|
||||||
Offtime: 0,
|
|
||||||
},
|
},
|
||||||
Status: "pending",
|
Status: "pending",
|
||||||
Deleted: false,
|
Deleted: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user