func createDeploymentHandler(w http.ResponseWriter, r *http.Request) { currentUser := getCurrentUser(r) application := getCurrentApplication(r) target, err := findTarget(application, r.FormValue("target")) if err != nil { log.Printf("error: %s\n", err) http.NotFound(w, r) return } if !target.IsDeployer(currentUser.Name) { http.Error(w, "not authorized to deploy to this target", 403) return } commitSha := r.FormValue("commitsha") if !isValidCommitSha(commitSha) { http.Error(w, "invalid commit sha", 422) return } formStages := r.Form["stages[]"] if len(formStages) == 0 { http.Error(w, "no stages selected", 422) return } stages := []models.DeploymentStage{} for _, fs := range formStages { stages = append(stages, models.DeploymentStage(fs)) } if !target.AreValidStages(stages) { msg := "stages have wrong order or contain invalid stages. Available stages: %v" http.Error(w, fmt.Sprintf(msg, target.AvailableStages), 422) return } deployment := &models.Deployment{ UserId: currentUser.Id, CommitSha: commitSha, Branch: r.FormValue("branch"), Comment: r.FormValue("comment"), ApplicationName: application.Name, TargetName: target.Name, } err = createDeployment(db, deployment) if err != nil { log.Println("Could not save to database", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } killChan := killRegistry.Add(deployment.Id) deploymentConfig := models.NewDeploymentConfig(deployment, target, stages) manager, err := deploy.NewManager(deploymentConfig, logRouter, killChan) if err != nil { log.Println("Could not build Manager", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } manager.AnnounceStart() err = updateDeploymentState(db, deployment, models.DEPLOYMENT_ACTIVE) if err != nil { log.Println("Could not update deployment state") killRegistry.Remove(deployment.Id) http.Error(w, err.Error(), http.StatusInternalServerError) return } go func() { newState := models.DEPLOYMENT_SUCCESSFUL err = manager.Start() if err != nil { newState = models.DEPLOYMENT_FAILED } err = updateDeploymentState(db, deployment, newState) if err != nil { log.Println("Could not update deployment state") } killRegistry.Remove(deployment.Id) }() http.Redirect(w, r, deploymentUrl(application, deployment), http.StatusSeeOther) }
package deploy import ( "testing" "github.com/applikatoni/applikatoni/models" ) var preDeployment = models.DeploymentStage("PRE_DEPLOYMENT") var migrate = models.DeploymentStage("MIGRATE") var testHosts []*models.Host = []*models.Host{ {Name: "workers.applikatoni.com", Roles: []string{"workers"}}, {Name: "webcluster.applikatoni.com", Roles: []string{"web", "migrator"}}, {Name: "db.applikatoni.com", Roles: []string{"database"}}, } var testRoles []*models.Role = []*models.Role{ &models.Role{ Name: "web", ScriptTemplates: map[models.DeploymentStage]string{ preDeployment: "webfoobar", }, }, &models.Role{ Name: "workers", ScriptTemplates: map[models.DeploymentStage]string{ preDeployment: "workersfoobar", }, }, &models.Role{