// clean up a task whose heartbeat has timed out func cleanUpTimedOutHeartbeat(t task.Task, project model.Project, host *host.Host) error { // mock up the failure details of the task detail := &apimodels.TaskEndDetail{ Description: task.AgentHeartbeat, TimedOut: true, Status: evergreen.TaskFailed, } // try to reset the task if err := model.TryResetTask(t.Id, "", RunnerName, &project, detail); err != nil { return fmt.Errorf("error trying to reset task %v: %v", t.Id, err) } // clear out the host's running task if err := host.UpdateRunningTask(t.Id, "", time.Now()); err != nil { return fmt.Errorf("error clearing running task %v from host %v: %v", t.Id, host.Id, err) } // success return nil }
// 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 := model.TryResetTask(projCtx.Task.Id, 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 = task.FindOne(task.ById(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 := model.AbortTask(projCtx.Task.Id, 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 = task.FindOne(task.ById(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.SetActiveState(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 = task.FindOne(task.ById(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 = task.FindOne(task.ById(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) } }