From 64c4d61758e4bcdc34fd0cb0bcbf42525b74ef30 Mon Sep 17 00:00:00 2001 From: Gergely Brautigam Date: Mon, 1 Oct 2018 22:12:28 +0200 Subject: [PATCH 1/9] Fledling work of cancelling a pipeline run. --- handlers/handler.go | 1 + handlers/pipeline.go | 41 +++++++++++++++++++++++++++++++++++++++++ scheduler/scheduler.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/handlers/handler.go b/handlers/handler.go index 00459034..1425aef4 100644 --- a/handlers/handler.go +++ b/handlers/handler.go @@ -65,6 +65,7 @@ func InitHandlers(e *echo.Echo) error { e.GET(p+"pipeline/:pipelineid", PipelineGet) e.PUT(p+"pipeline/:pipelineid", PipelineUpdate) e.DELETE(p+"pipeline/:pipelineid", PipelineDelete) + e.POST(p+"pipeline/:pipelineid/:runid/stop", PipelineStop) e.POST(p+"pipeline/:pipelineid/start", PipelineStart) e.GET(p+"pipeline/latest", PipelineGetAllWithLatestRun) e.POST(p+"pipeline/githook", GitWebHook) diff --git a/handlers/pipeline.go b/handlers/pipeline.go index 0ae962ee..aec9c09f 100644 --- a/handlers/pipeline.go +++ b/handlers/pipeline.go @@ -273,6 +273,47 @@ func PipelineStart(c echo.Context) error { return c.String(http.StatusNotFound, errPipelineNotFound.Error()) } +// PipelineStop stops a running pipeline. +func PipelineStop(c echo.Context) error { + schedulerService, _ := services.SchedulerService() + pipelineIDStr := c.Param("pipelineid") + + // Look for arguments. + // We do not check for errors here cause arguments are optional. + args := []gaia.Argument{} + c.Bind(&args) + + // Convert string to int because id is int + pipelineID, err := strconv.Atoi(pipelineIDStr) + if err != nil { + return c.String(http.StatusBadRequest, errInvalidPipelineID.Error()) + } + + // Convert string to int because id is int + runID, err := strconv.Atoi(c.Param("runid")) + if err != nil { + return c.String(http.StatusBadRequest, errPipelineRunNotFound.Error()) + } + + // Look up pipeline for the given id + var foundPipeline gaia.Pipeline + for pipeline := range pipeline.GlobalActivePipelines.Iter() { + if pipeline.ID == pipelineID { + foundPipeline = pipeline + } + } + + if foundPipeline.Name != "" { + err = schedulerService.StopPipelineRun(&foundPipeline, runID) + if err != nil { + c.String(http.StatusBadRequest, err.Error()) + } + } + + // Pipeline not found + return c.String(http.StatusNotFound, errPipelineNotFound.Error()) +} + type getAllWithLatestRun struct { Pipeline gaia.Pipeline `json:"p"` PipelineRun gaia.PipelineRun `json:"r"` diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index af84f616..ce0ba0cf 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -77,6 +77,7 @@ type GaiaScheduler interface { Init() error SchedulePipeline(p *gaia.Pipeline, args []gaia.Argument) (*gaia.PipelineRun, error) SetPipelineJobs(p *gaia.Pipeline) error + StopPipelineRun(p *gaia.Pipeline, runID int) error } var _ GaiaScheduler = (*Scheduler)(nil) @@ -260,6 +261,37 @@ func (s *Scheduler) schedule() { } } +// StopPipelineRun will prematurely cancel a pipeline run by killing all of its +// jobs and running processes immediately. +func (s *Scheduler) StopPipelineRun(p *gaia.Pipeline, runID int) error { + + // 1. Get all running Jobs + // 2. Set state to failed and send a finish signal + // 3. Store the result + + // Get jobs + // jobs, err := s.getPipelineJobs(p) + // if err != nil { + // gaia.Cfg.Logger.Error("cannot get pipeline jobs during schedule", "error", err.Error(), "pipeline", p) + // return err + // } + + pr, err := s.storeService.PipelineGetRunByPipelineIDAndID(p.ID, runID) + if err != nil { + return err + } + if pr.Status != gaia.RunRunning { + return errors.New("pipeline is not in running state") + } + for _, job := range pr.Jobs { + if job.Status == gaia.JobRunning || job.Status == gaia.JobWaitingExec { + job.Status = gaia.JobFailed + job.FailPipeline = true + } + } + return nil +} + var schedulerLock = sync.RWMutex{} // SchedulePipeline schedules a pipeline. We create a new schedule object From fb49037ad62a15848967967af05c2cdd629e7816 Mon Sep 17 00:00:00 2001 From: Gergely Brautigam Date: Mon, 1 Oct 2018 23:11:57 +0200 Subject: [PATCH 2/9] Have the front-end work done. --- frontend/client/views/pipeline/detail.vue | 61 +++++++++++++++++++++++ handlers/handler.go | 2 +- handlers/pipeline.go | 41 --------------- handlers/pipeline_run.go | 40 +++++++++++++++ scheduler/scheduler.go | 9 +--- 5 files changed, 103 insertions(+), 50 deletions(-) diff --git a/frontend/client/views/pipeline/detail.vue b/frontend/client/views/pipeline/detail.vue index 5640c249..abde0428 100755 --- a/frontend/client/views/pipeline/detail.vue +++ b/frontend/client/views/pipeline/detail.vue @@ -47,13 +47,40 @@ {{ props.row.status }} {{ calculateDuration(props.row.startdate, props.row.finishdate) }} + + +
No pipeline runs found in database.
+ + + +
+
+
+
+

+ Do you really want to cancel this run? +

+
+ +
+
+
+
+ @@ -61,15 +88,20 @@