// Activates any builds if their BatchTimes have elapsed. func (repoTracker *RepoTracker) activateElapsedBuilds(v *version.Version) (err error) { projectId := repoTracker.ProjectRef.Identifier hasActivated := false now := time.Now() for i, status := range v.BuildVariants { // last comparison is to check that ActivateAt is actually set if !status.Activated && now.After(status.ActivateAt) && !status.ActivateAt.IsZero() { evergreen.Logger.Logf(slogger.INFO, "activating variant %v for project %v, revision %v", status.BuildVariant, projectId, v.Revision) // Go copies the slice value, we want to modify the actual value status.Activated = true status.ActivateAt = now v.BuildVariants[i] = status b, err := build.FindOne(build.ById(status.BuildId)) if err != nil { evergreen.Logger.Logf(slogger.ERROR, "error retrieving build for project %v, variant %v, build %v: %v", projectId, status.BuildVariant, status.BuildId, err) continue } evergreen.Logger.Logf(slogger.INFO, "activating build %v for project %v, variant %v", status.BuildId, projectId, status.BuildVariant) // Don't need to set the version in here since we do it ourselves in a single update if err = model.SetBuildActivation(b.Id, true); err != nil { evergreen.Logger.Logf(slogger.ERROR, "error activating build %v for project %v, variant %v: %v", b.Id, projectId, status.BuildVariant, err) continue } hasActivated = true } } // If any variants were activated, update the stored version so that we don't // attempt to activate them again if hasActivated { return v.UpdateBuildVariants() } return nil }
func (uis *UIServer) modifyBuild(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) user := MustHaveUser(r) if projCtx.Build == 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"` Active bool `json:"active"` Abort bool `json:"abort"` Priority string `json:"priority"` TaskIds []string `json:"taskIds"` }{} err = json.Unmarshal(reqBody, &putParams) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // determine what action needs to be taken switch putParams.Action { case "abort": if err := model.AbortBuild(projCtx.Build.Id, user.Id); err != nil { http.Error(w, fmt.Sprintf("Error aborting build %v", projCtx.Build.Id), http.StatusInternalServerError) return } model.RefreshTasksCache(projCtx.Build.Id) 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 priority > evergreen.MaxTaskPriority { if !uis.isSuperUser(user) { http.Error(w, fmt.Sprintf("Insufficient access to set priority %v, can only set prior less than or equal to %v", priority, evergreen.MaxTaskPriority), http.StatusBadRequest) return } } err = model.SetBuildPriority(projCtx.Build.Id, priority) if err != nil { http.Error(w, fmt.Sprintf("Error setting priority on build %v", projCtx.Build.Id), http.StatusInternalServerError) return } case "set_active": err := model.SetBuildActivation(projCtx.Build.Id, putParams.Active, user.Id) if err != nil { http.Error(w, fmt.Sprintf("Error marking build %v as activated=%v", projCtx.Build.Id, putParams.Active), http.StatusInternalServerError) return } case "restart": if err := model.RestartBuild(projCtx.Build.Id, putParams.TaskIds, putParams.Abort, user.Id); err != nil { http.Error(w, fmt.Sprintf("Error restarting build %v", projCtx.Build.Id), http.StatusInternalServerError) return } default: uis.WriteJSON(w, http.StatusBadRequest, "Unrecognized action") return } // After updating the build, fetch updated version to serve back to client projCtx.Build, err = build.FindOne(build.ById(projCtx.Build.Id)) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) return } updatedBuild := uiBuild{ Build: *projCtx.Build, CurrentTime: time.Now().UnixNano(), Elapsed: time.Now().Sub(projCtx.Build.StartTime), RepoOwner: projCtx.ProjectRef.Owner, Repo: projCtx.ProjectRef.Repo, Version: *projCtx.Version, } uiTasks, err := getUiTaskCache(projCtx.Build) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, err) return } updatedBuild.Tasks = uiTasks uis.WriteJSON(w, http.StatusOK, updatedBuild) }
func (uis *UIServer) modifyBuild(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Build == 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"` Active bool `json:"active"` Abort bool `json:"abort"` Priority string `json:"priority"` }{} err = json.Unmarshal(reqBody, &putParams) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // determine what action needs to be taken switch putParams.Action { case "abort": if err := model.AbortBuild(projCtx.Build.Id); err != nil { http.Error(w, fmt.Sprintf("Error aborting build %v", projCtx.Build.Id), http.StatusInternalServerError) return } model.RefreshTasksCache(projCtx.Build.Id) uis.WriteJSON(w, http.StatusOK, "Successfully marked tasks as aborted") 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 } err = model.SetBuildPriority(projCtx.Build.Id, priority) if err != nil { http.Error(w, fmt.Sprintf("Error setting priority on build %v", projCtx.Build.Id), http.StatusInternalServerError) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash(fmt.Sprintf("Priority for build set to %v.", priority))) uis.WriteJSON(w, http.StatusOK, "Successfully set priority") return case "set_active": err := model.SetBuildActivation(projCtx.Build.Id, putParams.Active) if err != nil { http.Error(w, fmt.Sprintf("Error marking build %v as activated=%v", projCtx.Build.Id, putParams.Active), http.StatusInternalServerError) return } if putParams.Active { PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Build scheduled.")) } else { PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Build unscheduled.")) } uis.WriteJSON(w, http.StatusOK, fmt.Sprintf("Successfully marked build as active=%v", putParams.Active)) return case "restart": if err := model.RestartBuild(projCtx.Build.Id, putParams.Abort); err != nil { http.Error(w, fmt.Sprintf("Error restarting build %v", projCtx.Build.Id), http.StatusInternalServerError) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash(fmt.Sprintf("Build %v restarted.", projCtx.Build.Id))) uis.WriteJSON(w, http.StatusOK, fmt.Sprintf("Successfully restarted build", putParams.Active)) return default: uis.WriteJSON(w, http.StatusBadRequest, "Unrecognized action") return } }