Add cron running API (#12421)
* Add cron running API Signed-off-by: Andrew Thornton <art27@cantab.net> * Apply suggestions from code review * placate-swagger Signed-off-by: Andrew Thornton <art27@cantab.net> * return not found Signed-off-by: Andrew Thornton <art27@cantab.net> * Apply suggestions from code review Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
							parent
							
								
									ee047312a1
								
							
						
					
					
						commit
						2ae8c7ab1c
					
				
					 6 changed files with 232 additions and 0 deletions
				
			
		|  | @ -37,6 +37,14 @@ func (opts ListOptions) setEnginePagination(e Engine) Engine { | ||||||
| 	return e.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | 	return e.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // GetStartEnd returns the start and end of the ListOptions
 | ||||||
|  | func (opts ListOptions) GetStartEnd() (start, end int) { | ||||||
|  | 	opts.setDefaultValues() | ||||||
|  | 	start = (opts.Page - 1) * opts.PageSize | ||||||
|  | 	end = start + opts.Page | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (opts ListOptions) setDefaultValues() { | func (opts ListOptions) setDefaultValues() { | ||||||
| 	if opts.PageSize <= 0 { | 	if opts.PageSize <= 0 { | ||||||
| 		opts.PageSize = setting.API.DefaultPagingNum | 		opts.PageSize = setting.API.DefaultPagingNum | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								modules/structs/cron.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								modules/structs/cron.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | // Copyright 2020 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package structs | ||||||
|  | 
 | ||||||
|  | import "time" | ||||||
|  | 
 | ||||||
|  | // Cron represents a Cron task
 | ||||||
|  | type Cron struct { | ||||||
|  | 	Name      string    `json:"name"` | ||||||
|  | 	Schedule  string    `json:"schedule"` | ||||||
|  | 	Next      time.Time `json:"next"` | ||||||
|  | 	Prev      time.Time `json:"prev"` | ||||||
|  | 	ExecTimes int64     `json:"exec_times"` | ||||||
|  | } | ||||||
							
								
								
									
										86
									
								
								routers/api/v1/admin/cron.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								routers/api/v1/admin/cron.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | // Copyright 2020 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package admin | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/context" | ||||||
|  | 	"code.gitea.io/gitea/modules/cron" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ListCronTasks api for getting cron tasks
 | ||||||
|  | func ListCronTasks(ctx *context.APIContext) { | ||||||
|  | 	// swagger:operation GET /admin/cron admin adminCronList
 | ||||||
|  | 	// ---
 | ||||||
|  | 	// summary: List cron tasks
 | ||||||
|  | 	// produces:
 | ||||||
|  | 	// - application/json
 | ||||||
|  | 	// parameters:
 | ||||||
|  | 	// - name: page
 | ||||||
|  | 	//   in: query
 | ||||||
|  | 	//   description: page number of results to return (1-based)
 | ||||||
|  | 	//   type: integer
 | ||||||
|  | 	// - name: limit
 | ||||||
|  | 	//   in: query
 | ||||||
|  | 	//   description: page size of results
 | ||||||
|  | 	//   type: integer
 | ||||||
|  | 	// responses:
 | ||||||
|  | 	//   "200":
 | ||||||
|  | 	//     "$ref": "#/responses/CronList"
 | ||||||
|  | 	//   "403":
 | ||||||
|  | 	//     "$ref": "#/responses/forbidden"
 | ||||||
|  | 	tasks := cron.ListTasks() | ||||||
|  | 	listOpts := utils.GetListOptions(ctx) | ||||||
|  | 	start, end := listOpts.GetStartEnd() | ||||||
|  | 
 | ||||||
|  | 	if len(tasks) > listOpts.PageSize { | ||||||
|  | 		tasks = tasks[start:end] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	res := make([]structs.Cron, len(tasks)) | ||||||
|  | 	for i, task := range tasks { | ||||||
|  | 		res[i] = structs.Cron{ | ||||||
|  | 			Name:      task.Name, | ||||||
|  | 			Schedule:  task.Spec, | ||||||
|  | 			Next:      task.Next, | ||||||
|  | 			Prev:      task.Prev, | ||||||
|  | 			ExecTimes: task.ExecTimes, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	ctx.JSON(http.StatusOK, res) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PostCronTask api for getting cron tasks
 | ||||||
|  | func PostCronTask(ctx *context.APIContext) { | ||||||
|  | 	// swagger:operation POST /admin/cron/{task} admin adminCronRun
 | ||||||
|  | 	// ---
 | ||||||
|  | 	// summary: Run cron task
 | ||||||
|  | 	// produces:
 | ||||||
|  | 	// - application/json
 | ||||||
|  | 	// parameters:
 | ||||||
|  | 	// - name: task
 | ||||||
|  | 	//   in: path
 | ||||||
|  | 	//   description: task to run
 | ||||||
|  | 	//   type: string
 | ||||||
|  | 	//   required: true
 | ||||||
|  | 	// responses:
 | ||||||
|  | 	//   "204":
 | ||||||
|  | 	//     "$ref": "#/responses/empty"
 | ||||||
|  | 	//   "404":
 | ||||||
|  | 	//     "$ref": "#/responses/notFound"
 | ||||||
|  | 	task := cron.GetTask(ctx.Params(":task")) | ||||||
|  | 	if task == nil { | ||||||
|  | 		ctx.NotFound() | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	task.Run() | ||||||
|  | 	log.Trace("Cron Task %s started by admin(%s)", task.Name, ctx.User.Name) | ||||||
|  | 
 | ||||||
|  | 	ctx.Status(http.StatusNoContent) | ||||||
|  | } | ||||||
|  | @ -934,6 +934,10 @@ func RegisterRoutes(m *macaron.Macaron) { | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 		m.Group("/admin", func() { | 		m.Group("/admin", func() { | ||||||
|  | 			m.Group("/cron", func() { | ||||||
|  | 				m.Get("", admin.ListCronTasks) | ||||||
|  | 				m.Post("/:task", admin.PostCronTask) | ||||||
|  | 			}) | ||||||
| 			m.Get("/orgs", admin.GetAllOrgs) | 			m.Get("/orgs", admin.GetAllOrgs) | ||||||
| 			m.Group("/users", func() { | 			m.Group("/users", func() { | ||||||
| 				m.Get("", admin.GetAllUsers) | 				m.Get("", admin.GetAllUsers) | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								routers/api/v1/swagger/cron.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								routers/api/v1/swagger/cron.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | // Copyright 2020 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package swagger | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // CronList
 | ||||||
|  | // swagger:response CronList
 | ||||||
|  | type swaggerResponseCronList struct { | ||||||
|  | 	// in:body
 | ||||||
|  | 	Body []api.Cron `json:"body"` | ||||||
|  | } | ||||||
|  | @ -23,6 +23,69 @@ | ||||||
|   }, |   }, | ||||||
|   "basePath": "{{AppSubUrl}}/api/v1", |   "basePath": "{{AppSubUrl}}/api/v1", | ||||||
|   "paths": { |   "paths": { | ||||||
|  |     "/admin/cron": { | ||||||
|  |       "get": { | ||||||
|  |         "produces": [ | ||||||
|  |           "application/json" | ||||||
|  |         ], | ||||||
|  |         "tags": [ | ||||||
|  |           "admin" | ||||||
|  |         ], | ||||||
|  |         "summary": "List cron tasks", | ||||||
|  |         "operationId": "adminCronList", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "type": "integer", | ||||||
|  |             "description": "page number of results to return (1-based)", | ||||||
|  |             "name": "page", | ||||||
|  |             "in": "query" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "type": "integer", | ||||||
|  |             "description": "page size of results", | ||||||
|  |             "name": "limit", | ||||||
|  |             "in": "query" | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "$ref": "#/responses/CronList" | ||||||
|  |           }, | ||||||
|  |           "403": { | ||||||
|  |             "$ref": "#/responses/forbidden" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/admin/cron/{task}": { | ||||||
|  |       "post": { | ||||||
|  |         "produces": [ | ||||||
|  |           "application/json" | ||||||
|  |         ], | ||||||
|  |         "tags": [ | ||||||
|  |           "admin" | ||||||
|  |         ], | ||||||
|  |         "summary": "Run cron task", | ||||||
|  |         "operationId": "adminCronRun", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "type": "string", | ||||||
|  |             "description": "task to run", | ||||||
|  |             "name": "task", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "204": { | ||||||
|  |             "$ref": "#/responses/empty" | ||||||
|  |           }, | ||||||
|  |           "404": { | ||||||
|  |             "$ref": "#/responses/notFound" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "/admin/orgs": { |     "/admin/orgs": { | ||||||
|       "get": { |       "get": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
|  | @ -11931,6 +11994,36 @@ | ||||||
|       }, |       }, | ||||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" |       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||||
|     }, |     }, | ||||||
|  |     "Cron": { | ||||||
|  |       "description": "Cron represents a Cron task", | ||||||
|  |       "type": "object", | ||||||
|  |       "properties": { | ||||||
|  |         "exec_times": { | ||||||
|  |           "type": "integer", | ||||||
|  |           "format": "int64", | ||||||
|  |           "x-go-name": "ExecTimes" | ||||||
|  |         }, | ||||||
|  |         "name": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "Name" | ||||||
|  |         }, | ||||||
|  |         "next": { | ||||||
|  |           "type": "string", | ||||||
|  |           "format": "date-time", | ||||||
|  |           "x-go-name": "Next" | ||||||
|  |         }, | ||||||
|  |         "prev": { | ||||||
|  |           "type": "string", | ||||||
|  |           "format": "date-time", | ||||||
|  |           "x-go-name": "Prev" | ||||||
|  |         }, | ||||||
|  |         "schedule": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "Schedule" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||||
|  |     }, | ||||||
|     "DeleteEmailOption": { |     "DeleteEmailOption": { | ||||||
|       "description": "DeleteEmailOption options when deleting email addresses", |       "description": "DeleteEmailOption options when deleting email addresses", | ||||||
|       "type": "object", |       "type": "object", | ||||||
|  | @ -15027,6 +15120,15 @@ | ||||||
|         "$ref": "#/definitions/ContentsResponse" |         "$ref": "#/definitions/ContentsResponse" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "CronList": { | ||||||
|  |       "description": "CronList", | ||||||
|  |       "schema": { | ||||||
|  |         "type": "array", | ||||||
|  |         "items": { | ||||||
|  |           "$ref": "#/definitions/Cron" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "DeployKey": { |     "DeployKey": { | ||||||
|       "description": "DeployKey", |       "description": "DeployKey", | ||||||
|       "schema": { |       "schema": { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue