Add API endpoint to pause a worker

This commit is contained in:
simon987 2019-05-05 19:09:45 -04:00
parent 8f10567bd0
commit 72c8e18044
8 changed files with 378 additions and 231 deletions

View File

@ -86,6 +86,7 @@ func New() *WebAPI {
api.router.POST("/worker/create", LogRequestMiddleware(api.CreateWorker)) api.router.POST("/worker/create", LogRequestMiddleware(api.CreateWorker))
api.router.POST("/worker/update", LogRequestMiddleware(api.UpdateWorker)) api.router.POST("/worker/update", LogRequestMiddleware(api.UpdateWorker))
api.router.POST("/worker/set_paused", LogRequestMiddleware(api.WorkerSetPaused))
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.GetWorker)) api.router.GET("/worker/get/:id", LogRequestMiddleware(api.GetWorker))
api.router.GET("/worker/stats", LogRequestMiddleware(api.GetAllWorkerStats)) api.router.GET("/worker/stats", LogRequestMiddleware(api.GetAllWorkerStats))

View File

@ -269,6 +269,11 @@ type UpdateWorkerRequest struct {
Alias string `json:"alias"` Alias string `json:"alias"`
} }
type WorkerSetPausedRequest struct {
Worker int64 `json:"worker"`
Paused bool `json:"paused"`
}
type CreateWorkerRequest struct { type CreateWorkerRequest struct {
Alias string `json:"alias"` Alias string `json:"alias"`
} }

View File

@ -200,6 +200,14 @@ func (api *WebAPI) GetTaskFromProject(r *Request) {
return return
} }
if worker.Paused {
r.Json(JsonResponse{
Ok: false,
Message: "A manager has paused you",
}, 400)
return
}
project, err := strconv.ParseInt(r.Ctx.UserValue("project").(string), 10, 64) project, err := strconv.ParseInt(r.Ctx.UserValue("project").(string), 10, 64)
if err != nil || project <= 0 { if err != nil || project <= 0 {
r.Json(JsonResponse{ r.Json(JsonResponse{

View File

@ -126,6 +126,54 @@ func (api *WebAPI) UpdateWorker(r *Request) {
} }
} }
func (api *WebAPI) WorkerSetPaused(r *Request) {
sess := api.Session.StartFasthttp(r.Ctx)
manager := sess.Get("manager")
if manager == nil || !manager.(*storage.Manager).WebsiteAdmin {
r.Json(JsonResponse{
Ok: false,
Message: "Unauthorized",
}, 403)
return
}
req := &WorkerSetPausedRequest{}
err := json.Unmarshal(r.Ctx.Request.Body(), req)
if err != nil {
r.Json(JsonResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
worker := api.Database.GetWorker(req.Worker)
if worker == nil {
r.Json(JsonResponse{
Ok: false,
Message: "Invalid worker",
}, 400)
return
}
worker.Paused = req.Paused
ok := api.Database.UpdateWorker(worker)
if ok {
r.OkJson(JsonResponse{
Ok: true,
})
} else {
r.OkJson(JsonResponse{
Ok: false,
Message: "Could not update worker",
})
}
}
func (api *WebAPI) GetAllWorkerStats(r *Request) { func (api *WebAPI) GetAllWorkerStats(r *Request) {
stats := api.Database.GetAllWorkerStats() stats := api.Database.GetAllWorkerStats()

View File

@ -8,7 +8,8 @@ CREATE TABLE worker
alias TEXT NOT NULL, alias TEXT NOT NULL,
created INTEGER NOT NULL, created INTEGER NOT NULL,
secret BYTEA NOT NULL, secret BYTEA NOT NULL,
closed_task_count INTEGER DEFAULT 0 NOT NULL closed_task_count INTEGER DEFAULT 0 NOT NULL,
paused boolean NOT NULL DEFAULT false
); );
CREATE TABLE project CREATE TABLE project

View File

@ -9,6 +9,7 @@ type Worker struct {
Created int64 `json:"created"` Created int64 `json:"created"`
Alias string `json:"alias,omitempty"` Alias string `json:"alias,omitempty"`
Secret []byte `json:"secret"` Secret []byte `json:"secret"`
Paused bool `json:"paused"`
} }
type WorkerStats struct { type WorkerStats struct {
@ -96,8 +97,8 @@ func (database *Database) GrantAccess(workerId int64, projectId int64) bool {
func (database *Database) UpdateWorker(worker *Worker) bool { func (database *Database) UpdateWorker(worker *Worker) bool {
db := database.getDB() db := database.getDB()
res, err := db.Exec(`UPDATE worker SET alias=$1 WHERE id=$2`, res, err := db.Exec(`UPDATE worker SET alias=$1, paused=$2 WHERE id=$3`,
worker.Alias, worker.Id) worker.Alias, worker.Paused, worker.Id)
handleErr(err) handleErr(err)
rowsAffected, _ := res.RowsAffected() rowsAffected, _ := res.RowsAffected()

View File

@ -6,6 +6,7 @@ import (
"github.com/simon987/task_tracker/client" "github.com/simon987/task_tracker/client"
"github.com/simon987/task_tracker/storage" "github.com/simon987/task_tracker/storage"
"net/http" "net/http"
"strings"
"testing" "testing"
) )
@ -29,6 +30,10 @@ func TestCreateGetWorker(t *testing.T) {
if w.Alias != "my_worker_alias" { if w.Alias != "my_worker_alias" {
t.Error() t.Error()
} }
if w.Paused != false {
t.Error()
}
} }
func TestGetWorkerNotFound(t *testing.T) { func TestGetWorkerNotFound(t *testing.T) {
@ -68,6 +73,10 @@ func TestUpdateAliasValid(t *testing.T) {
if w.Alias != "new alias" { if w.Alias != "new alias" {
t.Error() t.Error()
} }
if w.Paused != false {
t.Error()
}
} }
func TestCreateWorkerAliasInvalid(t *testing.T) { func TestCreateWorkerAliasInvalid(t *testing.T) {
@ -109,6 +118,74 @@ func TestInvalidAccessRequest(t *testing.T) {
} }
} }
func TestAssignTaskWhenPaused(t *testing.T) {
w := genWid()
pid := createProjectAsAdmin(api.CreateProjectRequest{
Name: "testassigntaskwhenpaused",
CloneUrl: "testassigntaskwhenpaused",
GitRepo: "testassigntaskwhenpaused",
}).Content.Id
requestAccess(api.CreateWorkerAccessRequest{
Submit: true,
Assign: true,
Project: pid,
}, w)
acceptAccessRequest(pid, w.Id, testAdminCtx)
r := createTask(api.SubmitTaskRequest{
Project: pid,
Recipe: "a",
Hash64: 1,
}, w)
if r.Ok != true {
t.Error()
}
pauseWorker(&api.WorkerSetPausedRequest{
Paused: true,
Worker: w.Id,
}, testAdminCtx)
resp := getTaskFromProject(pid, w)
if resp.Ok != false {
t.Error()
}
if !strings.Contains(resp.Message, "paused") {
t.Error()
}
}
func TestPauseInvalidWorker(t *testing.T) {
r := pauseWorker(&api.WorkerSetPausedRequest{
Paused: true,
Worker: 9999111,
}, testAdminCtx)
if r.Ok != false {
t.Error()
}
}
func TestPauseUnauthorized(t *testing.T) {
w := genWid()
r := pauseWorker(&api.WorkerSetPausedRequest{
Paused: true,
Worker: w.Id,
}, testUserCtx)
if r.Ok != false {
t.Error()
}
}
func createWorker(req api.CreateWorkerRequest) (ar client.CreateWorkerResponse) { func createWorker(req api.CreateWorkerRequest) (ar client.CreateWorkerResponse) {
r := Post("/worker/create", req, nil, nil) r := Post("/worker/create", req, nil, nil)
UnmarshalResponse(r, &ar) UnmarshalResponse(r, &ar)
@ -147,8 +224,13 @@ func rejectAccessRequest(pid int64, wid int64, s *http.Client) (ar api.JsonRespo
} }
func updateWorker(request api.UpdateWorkerRequest, w *storage.Worker) (ar api.JsonResponse) { func updateWorker(request api.UpdateWorkerRequest, w *storage.Worker) (ar api.JsonResponse) {
r := Post("/worker/update", request, w, nil) r := Post("/worker/update", request, w, nil)
UnmarshalResponse(r, &ar) UnmarshalResponse(r, &ar)
return return
} }
func pauseWorker(request *api.WorkerSetPausedRequest, s *http.Client) (ar api.JsonResponse) {
r := Post("/worker/set_paused", request, nil, s)
UnmarshalResponse(r, &ar)
return
}

View File

@ -8,7 +8,8 @@ CREATE TABLE worker
alias TEXT NOT NULL, alias TEXT NOT NULL,
created INTEGER NOT NULL, created INTEGER NOT NULL,
secret BYTEA NOT NULL, secret BYTEA NOT NULL,
closed_task_count INTEGER DEFAULT 0 NOT NULL closed_task_count INTEGER DEFAULT 0 NOT NULL,
paused boolean NOT NULL DEFAULT false
); );
CREATE TABLE project CREATE TABLE project