From bd23f21ff47766d3c8a5e696e9608341b9e6a6e2 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 17 Mar 2019 14:31:07 -0700 Subject: [PATCH] ability to pause and resume build queue --- core/sched.go | 8 +++++++ handler/api/api.go | 4 ++-- handler/api/queue/none.go | 8 +++++++ handler/api/queue/pause.go | 42 ++++++++++++++++++------------------ handler/api/queue/resume.go | 42 ++++++++++++++++++------------------ scheduler/kube/kube.go | 10 ++++++++- scheduler/kube/kube_oss.go | 8 +++++++ scheduler/nomad/nomad.go | 10 ++++++++- scheduler/nomad/nomad_oss.go | 8 +++++++ 9 files changed, 94 insertions(+), 46 deletions(-) diff --git a/core/sched.go b/core/sched.go index 9fca2474..58e2488f 100644 --- a/core/sched.go +++ b/core/sched.go @@ -44,6 +44,14 @@ type Scheduler interface { // returns true if the build has been cancelled. Cancelled(context.Context, int64) (bool, error) + // Pause pauses the scheduler and prevents new pipelines + // from being scheduled for execution. + Pause(context.Context) error + + // Resume unpauses the scheduler, allowing new pipelines + // to be scheduled for execution. + Resume(context.Context) error + // Stats provides statistics for underlying scheduler. The // data format is scheduler-specific. Stats(context.Context) (interface{}, error) diff --git a/handler/api/api.go b/handler/api/api.go index aeeb8d1d..32654b15 100644 --- a/handler/api/api.go +++ b/handler/api/api.go @@ -249,8 +249,8 @@ func (s Server) Handler() http.Handler { r.Route("/queue", func(r chi.Router) { r.Use(acl.AuthorizeAdmin) r.Get("/", queue.HandleItems(s.Stages)) - // r.Post("/", queue.HandleResume(s.Queue)) - // r.Delete("/", queue.HandlePause(s.Queue)) + r.Post("/", queue.HandleResume(s.Scheduler)) + r.Delete("/", queue.HandlePause(s.Scheduler)) }) r.Route("/user", func(r chi.Router) { diff --git a/handler/api/queue/none.go b/handler/api/queue/none.go index 3aa95f7b..0c1f9c5f 100644 --- a/handler/api/queue/none.go +++ b/handler/api/queue/none.go @@ -30,3 +30,11 @@ var notImplemented = func(w http.ResponseWriter, r *http.Request) { func HandleItems(store core.StageStore) http.HandlerFunc { return notImplemented } + +func HandlePause(core.Scheduler) http.HandlerFunc { + return notImplemented +} + +func HandleResume(core.Scheduler) http.HandlerFunc { + return notImplemented +} diff --git a/handler/api/queue/pause.go b/handler/api/queue/pause.go index 3a1b510d..cefbf3d4 100644 --- a/handler/api/queue/pause.go +++ b/handler/api/queue/pause.go @@ -6,26 +6,26 @@ package queue -// import ( -// "net/http" +import ( + "net/http" -// "github.com/drone/drone/core" -// "github.com/drone/drone/handler/api/render" -// "github.com/drone/drone/logger" -// ) + "github.com/drone/drone/core" + "github.com/drone/drone/handler/api/render" + "github.com/drone/drone/logger" +) -// // HandlePause returns an http.HandlerFunc that processes -// // an http.Request to pause the queue. -// func HandlePause(queue core.Queue) http.HandlerFunc { -// return func(w http.ResponseWriter, r *http.Request) { -// ctx := r.Context() -// err := queue.Pause(ctx) -// if err != nil { -// render.InternalError(w, err) -// logger.FromRequest(r).WithError(err). -// Errorln("api: cannot pause queue") -// return -// } -// w.WriteHeader(http.StatusNoContent) -// } -// } +// HandlePause returns an http.HandlerFunc that processes +// an http.Request to pause the scheduler. +func HandlePause(scheduler core.Scheduler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + err := scheduler.Pause(ctx) + if err != nil { + render.InternalError(w, err) + logger.FromRequest(r).WithError(err). + Errorln("api: cannot pause scheduler") + return + } + w.WriteHeader(http.StatusNoContent) + } +} diff --git a/handler/api/queue/resume.go b/handler/api/queue/resume.go index 2fd517f7..39a88e7b 100644 --- a/handler/api/queue/resume.go +++ b/handler/api/queue/resume.go @@ -6,26 +6,26 @@ package queue -// import ( -// "net/http" +import ( + "net/http" -// "github.com/drone/drone/core" -// "github.com/drone/drone/handler/api/render" -// "github.com/drone/drone/logger" -// ) + "github.com/drone/drone/core" + "github.com/drone/drone/handler/api/render" + "github.com/drone/drone/logger" +) -// // HandleResume returns an http.HandlerFunc that processes -// // an http.Request to pause the queue. -// func HandleResume(queue core.Queue) http.HandlerFunc { -// return func(w http.ResponseWriter, r *http.Request) { -// ctx := r.Context() -// err := queue.Resume(ctx) -// if err != nil { -// render.InternalError(w, err) -// logger.FromRequest(r).WithError(err). -// Errorln("api: cannot resume queue") -// return -// } -// w.WriteHeader(http.StatusNoContent) -// } -// } +// HandleResume returns an http.HandlerFunc that processes +// an http.Request to pause the scheduler. +func HandleResume(scheduler core.Scheduler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + err := scheduler.Resume(ctx) + if err != nil { + render.InternalError(w, err) + logger.FromRequest(r).WithError(err). + Errorln("api: cannot resume scheduler") + return + } + w.WriteHeader(http.StatusNoContent) + } +} diff --git a/scheduler/kube/kube.go b/scheduler/kube/kube.go index a642faa3..74ef68ca 100644 --- a/scheduler/kube/kube.go +++ b/scheduler/kube/kube.go @@ -109,7 +109,7 @@ func (s *kubeScheduler) Schedule(ctx context.Context, stage *core.Stage) error { GenerateName: name, Namespace: s.namespace(), Annotations: map[string]string{ - "io.drone": "true", + "io.drone": "true", "io.drone.stage.created": time.Unix(stage.Created, 0).String(), "io.drone.stage.scheduled": time.Now().String(), "io.drone.stage.id": fmt.Sprint(stage.ID), @@ -201,6 +201,14 @@ func (s *kubeScheduler) Stats(_ context.Context) (interface{}, error) { return nil, errors.New("not implemented") } +func (s *kubeScheduler) Pause(context.Context) error { + return errors.New("not implemented") +} + +func (s *kubeScheduler) Resume(context.Context) error { + return errors.New("not implemented") +} + func (s *kubeScheduler) namespace() string { namespace := s.config.Namespace if namespace == "" { diff --git a/scheduler/kube/kube_oss.go b/scheduler/kube/kube_oss.go index 6fab9dda..7632a4bd 100644 --- a/scheduler/kube/kube_oss.go +++ b/scheduler/kube/kube_oss.go @@ -48,3 +48,11 @@ func (noop) Cancelled(context.Context, int64) (bool, error) { func (noop) Stats(context.Context) (interface{}, error) { return nil, nil } + +func (noop) Pause(context.Context) error { + return nil +} + +func (noop) Resume(context.Context) error { + return nil +} diff --git a/scheduler/nomad/nomad.go b/scheduler/nomad/nomad.go index 78dc83f7..07732399 100644 --- a/scheduler/nomad/nomad.go +++ b/scheduler/nomad/nomad.go @@ -111,7 +111,7 @@ func (s *nomadScheduler) Schedule(ctx context.Context, stage *core.Stage) error }, }, Meta: map[string]string{ - "io.drone": "true", + "io.drone": "true", "io.drone.stage.created": time.Unix(stage.Created, 0).String(), "io.drone.stage.scheduled": time.Now().String(), "io.drone.stage.id": fmt.Sprint(stage.ID), @@ -206,6 +206,14 @@ func (s *nomadScheduler) Stats(context.Context) (interface{}, error) { return nil, errors.New("not implemented") } +func (s *nomadScheduler) Pause(context.Context) error { + return errors.New("not implemented") +} + +func (s *nomadScheduler) Resume(context.Context) error { + return errors.New("not implemented") +} + // stringToPtr returns the pointer to a string func stringToPtr(str string) *string { return &str diff --git a/scheduler/nomad/nomad_oss.go b/scheduler/nomad/nomad_oss.go index f8c756bb..0f4af18d 100644 --- a/scheduler/nomad/nomad_oss.go +++ b/scheduler/nomad/nomad_oss.go @@ -48,3 +48,11 @@ func (noop) Cancelled(context.Context, int64) (bool, error) { func (noop) Stats(context.Context) (interface{}, error) { return nil, nil } + +func (noop) Pause(context.Context) error { + return nil +} + +func (noop) Resume(context.Context) error { + return nil +}