func (as *APIServer) existingPatchRequest(w http.ResponseWriter, r *http.Request) { p, err := getPatchFromRequest(r) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } if !getGlobalLock(PatchLockTitle) { as.LoggedError(w, r, http.StatusInternalServerError, ErrLockTimeout) return } defer releaseGlobalLock(PatchLockTitle) // dispatch to handlers based on specified action switch r.FormValue("action") { case "update": name := r.FormValue("desc") err := p.SetDescription(name) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } as.WriteJSON(w, http.StatusOK, "patch updated") case "finalize": if p.Activated == true { http.Error(w, "patch is already finalized", http.StatusBadRequest) return } _, err = validator.ValidateAndFinalize(p, &as.Settings) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } as.WriteJSON(w, http.StatusOK, "patch finalized") case "cancel": err = model.CancelPatch(p) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } as.WriteJSON(w, http.StatusOK, "patch deleted") default: http.Error(w, fmt.Sprintf("Unrecognized action: %v", r.FormValue("action")), http.StatusBadRequest) } }
func (as *APIServer) submitPatch(w http.ResponseWriter, r *http.Request) { user := MustHaveUser(r) apiRequest := PatchAPIRequest{ ProjectFileName: r.FormValue("project"), ModuleName: r.FormValue("module"), Githash: r.FormValue("githash"), PatchContent: r.FormValue("patch"), BuildVariants: strings.Split(r.FormValue("buildvariants"), ","), } description := r.FormValue("desc") projId := r.FormValue("project") projectRef, err := model.FindOneProjectRef(projId) if err != nil { message := fmt.Errorf("Error locating project ref '%v': %v", projId, err) as.LoggedError(w, r, http.StatusInternalServerError, message) return } project, err := model.FindProject("", projectRef) if err != nil { message := fmt.Errorf("Error locating project '%v' from '%v': %v", projId, as.Settings.ConfigDir, err) as.LoggedError(w, r, http.StatusInternalServerError, message) return } if project == nil { as.LoggedError(w, r, http.StatusNotFound, fmt.Errorf("project %v not found", projId)) return } patchMetadata, err := apiRequest.Validate(as.Settings.Credentials[projectRef.RepoKind]) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Invalid patch: %v", err)) return } if patchMetadata == nil { as.LoggedError(w, r, http.StatusBadRequest, fmt.Errorf("patch metadata is empty")) return } if apiRequest.ModuleName != "" { as.WriteJSON(w, http.StatusBadRequest, "module not allowed when creating new patches (must be added in a subsequent request)") return } patchProjectRef, err := model.FindOneProjectRef(patchMetadata.Project.Identifier) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Invalid projectRef: %v", err)) return } if patchProjectRef == nil { as.LoggedError(w, r, http.StatusNotFound, fmt.Errorf("Empty patch project Ref")) return } commitInfo, err := thirdparty.GetCommitEvent(as.Settings.Credentials[projectRef.RepoKind], patchProjectRef.Owner, patchProjectRef.Repo, apiRequest.Githash) if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } if commitInfo == nil { as.WriteJSON(w, http.StatusBadRequest, "That commit doesn't seem to exist.") return } createTime := time.Now() patchDoc := &patch.Patch{ Id: bson.NewObjectId(), Description: description, Author: user.Id, Project: apiRequest.ProjectFileName, Githash: apiRequest.Githash, CreateTime: createTime, Status: evergreen.PatchCreated, BuildVariants: apiRequest.BuildVariants, Tasks: nil, Patches: []patch.ModulePatch{ patch.ModulePatch{ ModuleName: "", Githash: apiRequest.Githash, PatchSet: patch.PatchSet{ Patch: apiRequest.PatchContent, Summary: patchMetadata.Summaries, }, }, }, } // set the patch number based on patch author patchDoc.PatchNumber, err = user.IncPatchNumber() if err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("error computing patch num %v", err)) return } if err = patchDoc.Insert(); err != nil { as.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("error inserting patch: %v", err)) return } if strings.ToLower(r.FormValue("finalize")) == "true" { if _, err = validator.ValidateAndFinalize(patchDoc, &as.Settings); err != nil { as.LoggedError(w, r, http.StatusInternalServerError, err) return } } as.WriteJSON(w, http.StatusCreated, PatchAPIResponse{Patch: patchDoc}) }
func (uis *UIServer) schedulePatch(w http.ResponseWriter, r *http.Request) { projCtx := MustHaveProjectContext(r) if projCtx.Patch == nil { http.Error(w, "patch not found", http.StatusNotFound) return } // grab patch again, as the diff was excluded var err error projCtx.Patch, err = patch.FindOne(patch.ById(projCtx.Patch.Id)) if err != nil { http.Error(w, fmt.Sprintf("error loading patch: %v", err), http.StatusInternalServerError) return } patchUpdateReq := struct { Variants []string `json:"variants"` Tasks []string `json:"tasks"` Description string `json:"description"` }{} err = util.ReadJSONInto(r.Body, &patchUpdateReq) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if projCtx.Patch.Version != "" { // This patch has already been finalized, just add the new builds and tasks if projCtx.Version == nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Couldn't find patch for id %v", projCtx.Patch.Version)) return } // First add new tasks to existing builds, if necessary if len(patchUpdateReq.Tasks) > 0 { err = model.AddNewTasksForPatch(projCtx.Patch, projCtx.Version, patchUpdateReq.Tasks) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new tasks: `%v` for version `%v`", err, projCtx.Version.Id)) return } } if len(patchUpdateReq.Variants) > 0 { _, err := model.AddNewBuildsForPatch(projCtx.Patch, projCtx.Version, patchUpdateReq.Variants) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error creating new builds: `%v` for version `%v`", err, projCtx.Version.Id)) return } } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Builds and tasks successfully added to patch.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{projCtx.Version.Id}) } else { err = projCtx.Patch.SetVariantsAndTasks(patchUpdateReq.Variants, patchUpdateReq.Tasks) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting patch variants and tasks: %v", err)) return } if err = projCtx.Patch.SetDescription(patchUpdateReq.Description); err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error setting description: %v", err)) return } ver, err := validator.ValidateAndFinalize(projCtx.Patch, &uis.Settings) if err != nil { uis.LoggedError(w, r, http.StatusInternalServerError, fmt.Errorf("Error finalizing patch: %v", err)) return } PushFlash(uis.CookieStore, r, w, NewSuccessFlash("Patch builds are scheduled.")) uis.WriteJSON(w, http.StatusOK, struct { VersionId string `json:"version"` }{ver.Id}) } }