// avoids type-checking json params for the below function func (uis *UIServer) taskModify(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Task == nil { http.Error(w, "Not Found", http.StatusNotFound) return } reqBody, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer r.Body.Close() putParams := struct { Action string `json:"action"` Priority string `json:"priority"` // for the set_active option Active bool `json:"active"` }{} err = json.Unmarshal(reqBody, &putParams) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } authUser := GetUser(r) authName := authUser.DisplayName() // determine what action needs to be taken switch putParams.Action { case "restart": if err := projCtx.Task.TryReset(authName, evergreen.UIPackage, projCtx.Project, nil); err != nil { http.Error(w, fmt.Sprintf("Error restarting task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Task is now marked to restart.")) uis.WriteJSON(w, http.StatusOK, "Task successfully restarted") return case "abort": if err := projCtx.Task.Abort(authName, true); err != nil { http.Error(w, fmt.Sprintf("Error aborting task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Task is now aborting.")) uis.WriteJSON(w, http.StatusOK, "Task successfully restarted") return case "set_active": active := putParams.Active if err := model.SetTaskActivated(projCtx.Task.Id, authName, active); err != nil { http.Error(w, fmt.Sprintf("Error activating task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } if active { PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Task is now scheduled.")) } else { PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Task is now unscheduled.")) } uis.WriteJSON(w, http.StatusOK, "Task successfully activated") return case "set_priority": priority, err := strconv.Atoi(putParams.Priority) if err != nil { http.Error(w, "Bad priority value, must be int", http.StatusBadRequest) return } if err = projCtx.Task.SetPriority(priority); err != nil { http.Error(w, fmt.Sprintf("Error setting task priority %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash(fmt.Sprintf("Priority for task set to %v.", priority))) uis.WriteJSON(w, http.StatusOK, "Successfully set priority") return default: uis.WriteJSON(w, http.StatusBadRequest, "Unrecognized action: "+putParams.Action) } }
func (as *APIServer) EndTask(w http.ResponseWriter, r *http.Request) { finishTime := time.Now() taskEndResponse := &apimodels.TaskEndResponse{} task := MustHaveTask(r) details := &apimodels.TaskEndDetail{} if err := util.ReadJSONInto(r.Body, details); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Check that finishing status is a valid constant if details.Status != evergreen.TaskSucceeded && details.Status != evergreen.TaskFailed && details.Status != evergreen.TaskUndispatched { msg := fmt.Errorf("Invalid end status '%v' for task %v", details.Status, task.Id) as.LoggedError(w, r, http.StatusBadRequest, msg) return } projectRef, err := model.FindOneProjectRef(task.Project) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) } if projectRef == nil { as.LoggedError(w, r, http.StatusNotFound, fmt.Errorf("empty projectRef for task")) return } project, err := model.FindProject("", projectRef) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } if !getGlobalLock(r.RemoteAddr, task.Id) { as.LoggedError(w, r, http.StatusInternalServerError, ErrLockTimeout) return } defer releaseGlobalLock(r.RemoteAddr, task.Id) // mark task as finished err = task.MarkEnd(APIServerLockTitle, finishTime, details, project, projectRef.DeactivatePrevious) if err != nil { message := fmt.Errorf("Error calling mark finish on task %v : %v", task.Id, err) as.LoggedError(w, r, http.StatusInternalServerError, message) return } if task.Requester != evergreen.PatchVersionRequester { alerts.RunTaskFailureTriggers(task) } else { //TODO(EVG-223) process patch-specific triggers } // if task was aborted, reset to inactive if details.Status == evergreen.TaskUndispatched { if err = model.SetTaskActivated(task.Id, "", false); err != nil { message := fmt.Sprintf("Error deactivating task after abort: %v", err) evergreen.Logger.Logf(slogger.ERROR, message) taskEndResponse.Message = message as.WriteJSON(w, http.StatusInternalServerError, taskEndResponse) return } as.taskFinished(w, task, finishTime) return } // update the bookkeeping entry for the task err = bookkeeping.UpdateExpectedDuration(task, task.TimeTaken) if err != nil { evergreen.Logger.Logf(slogger.ERROR, "Error updating expected duration: %v", err) } // log the task as finished evergreen.Logger.Logf(slogger.INFO, "Successfully marked task %v as finished", task.Id) // construct and return the appropriate response for the agent as.taskFinished(w, task, finishTime) }
// avoids type-checking json params for the below function func (uis *UIServer) taskModify(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Task == nil { http.Error(w, "Not Found", http.StatusNotFound) return } reqBody, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer r.Body.Close() putParams := struct { Action string `json:"action"` Priority string `json:"priority"` // for the set_active option Active bool `json:"active"` }{} err = json.Unmarshal(reqBody, &putParams) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } authUser := GetUser(r) authName := authUser.DisplayName() // determine what action needs to be taken switch putParams.Action { case "restart": if err := projCtx.Task.TryReset(authName, evergreen.UIPackage, projCtx.Project, nil); err != nil { http.Error(w, fmt.Sprintf("Error restarting task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = model.FindTask(projCtx.Task.Id) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return case "abort": if err := projCtx.Task.Abort(authName, true); err != nil { http.Error(w, fmt.Sprintf("Error aborting task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = model.FindTask(projCtx.Task.Id) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return case "set_active": active := putParams.Active if err := model.SetTaskActivated(projCtx.Task.Id, authName, active); err != nil { http.Error(w, fmt.Sprintf("Error activating task %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = model.FindTask(projCtx.Task.Id) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return case "set_priority": priority, err := strconv.ParseInt(putParams.Priority, 10, 64) if err != nil { http.Error(w, "Bad priority value, must be int", http.StatusBadRequest) return } if err = projCtx.Task.SetPriority(priority); err != nil { http.Error(w, fmt.Sprintf("Error setting task priority %v: %v", projCtx.Task.Id, err), http.StatusInternalServerError) return } // Reload the task from db, send it back projCtx.Task, err = model.FindTask(projCtx.Task.Id) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) } uis.WriteJSON(w, http.StatusOK, projCtx.Task) return default: uis.WriteJSON(w, http.StatusBadRequest, "Unrecognized action: "+putParams.Action) } }