func EnvironmentDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] name := vars["name"] env, err := models.GetEnvironment(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } delete(env, name) releaseId, err := models.PutEnvironment(app, env) if err != nil { return httperr.Server(err) } rw.Header().Set("Release-Id", releaseId) env, err = models.GetEnvironment(app) if err != nil { return httperr.Server(err) } return RenderJson(rw, env) }
func ReleasePromote(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] release := vars["release"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } rr, err := models.GetRelease(app, release) if err != nil && strings.HasPrefix(err.Error(), "no such release") { return httperr.Errorf(404, "no such release: %s", release) } if err != nil { return httperr.Server(err) } err = rr.Promote() if awsError(err) == "ValidationError" { return httperr.Errorf(403, err.(awserr.Error).Message()) } if err != nil { return httperr.Server(err) } return RenderJson(rw, rr) }
func ReleaseShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] release := vars["release"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } rr, err := models.GetRelease(app, release) if err != nil && strings.HasPrefix(err.Error(), "no such release") { return httperr.Errorf(404, "no such release: %s", release) } fmt.Printf("err %+v\n", err) if err != nil { return httperr.Server(err) } return RenderJson(rw, rr) }
func ProcessShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } p, err := models.GetProcess(app, process) if err != nil { return httperr.Server(err) } err = p.FetchStats() if err != nil { return httperr.Server(err) } return RenderJson(rw, p) }
func FormationSet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] count := GetForm(r, "count") memory := GetForm(r, "memory") _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } err = models.SetFormation(app, process, count, memory) if ae, ok := err.(awserr.Error); ok { if ae.Code() == "ValidationError" { switch { case strings.Index(ae.Error(), "No updates are to be performed") > -1: return httperr.Errorf(403, "no updates are to be performed: %s", app) case strings.Index(ae.Error(), "can not be updated") > -1: return httperr.Errorf(403, "app is already updating: %s", app) } } } if err != nil { return httperr.Server(err) } return RenderSuccess(rw) }
func ServiceDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { service := mux.Vars(r)["service"] s, err := models.GetService(service) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such service: %s", service) } if err != nil { return httperr.Server(err) } err = s.Delete() if err != nil { return httperr.Server(err) } s, err = models.GetService(service) if err != nil { return httperr.Server(err) } return RenderJson(rw, s) }
func EnvironmentSet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] _, err := models.GetEnvironment(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } body, err := ioutil.ReadAll(r.Body) if err != nil { return httperr.Server(err) } releaseId, err := models.PutEnvironment(app, models.LoadEnvironment(body)) if err != nil { return httperr.Server(err) } rw.Header().Set("Release-Id", releaseId) env, err := models.GetEnvironment(app) if err != nil { return httperr.Server(err) } return RenderJson(rw, env) }
func LinkDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] service := mux.Vars(r)["service"] s, err := models.GetService(service) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such service: %s", service) } if err != nil { return httperr.Server(err) } if s.Status != "running" { return httperr.Errorf(403, "can not unlink service with status: %s", s.Status) } if s.Type != "papertrail" { return httperr.Errorf(403, "unlinking is not yet implemented for service type: %s", s.Type) } a, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } err = s.UnlinkPapertrail(*a) if err != nil { return httperr.Server(err) } return RenderJson(rw, s) }
func EnvironmentList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] env, err := models.GetEnvironment(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } return RenderJson(rw, env) }
func BuildLogs(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) app := vars["app"] build := vars["build"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } _, err = models.GetBuild(app, build) if err != nil { return httperr.Server(err) } // proxy to docker container logs // https://docs.docker.com/reference/api/docker_remote_api_v1.19/#get-container-logs client, err := docker.NewClient("unix:///var/run/docker.sock") if err != nil { return httperr.Server(err) } r, w := io.Pipe() quit := make(chan bool) go scanLines(r, ws) go keepAlive(ws, quit) err = client.Logs(docker.LogsOptions{ Container: fmt.Sprintf("build-%s", build), Follow: true, Stdout: true, Stderr: true, Tail: "all", RawTerminal: false, OutputStream: w, ErrorStream: w, }) quit <- true return httperr.Server(err) }
func FormationList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } formation, err := models.ListFormation(app) if err != nil { return httperr.Server(err) } return RenderJson(rw, formation) }
func ProcessExecAttached(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) app := vars["app"] pid := vars["pid"] command := ws.Request().Header.Get("Command") a, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } return httperr.Server(a.ExecAttached(pid, command, ws)) }
func ProcessList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } processes, err := models.ListProcesses(app) if err != nil { return httperr.Server(err) } final := models.Processes{} if r.URL.Query().Get("stats") != "false" { psch := make(chan models.Process) errch := make(chan error) for _, p := range processes { p := p go p.FetchStatsAsync(psch, errch) } for _, _ = range processes { err := <-errch if err != nil { return httperr.Server(err) } final = append(final, <-psch) } } else { final = processes } sort.Sort(final) return RenderJson(rw, final) }
func ServiceLogs(ws *websocket.Conn) *httperr.Error { service := mux.Vars(ws.Request())["service"] s, err := models.GetService(service) if err != nil { return httperr.Server(err) } logs := make(chan []byte) done := make(chan bool) s.SubscribeLogs(logs, done) for data := range logs { ws.Write(data) } return nil }
func ProcessRunDetached(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] command := GetForm(r, "command") a, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } err = a.RunDetached(process, command) if err != nil { return httperr.Server(err) } return RenderSuccess(rw) }
func BuildList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] builds, err := models.ListBuilds(app) if err != nil { return httperr.Server(err) } _, err = models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } return RenderJson(rw, builds) }
func ReleaseList(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } releases, err := models.ListReleases(app) if err != nil { return httperr.Server(err) } return RenderJson(rw, releases) }
func BuildGet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] build := vars["build"] _, err := models.GetApp(app) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } b, err := models.GetBuild(app, build) if err != nil && strings.HasPrefix(err.Error(), "no such build") { return httperr.Errorf(404, err.Error()) } if err != nil { return httperr.Server(err) } return RenderJson(rw, b) }
func BuildCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { build := models.NewBuild(mux.Vars(r)["app"]) err := r.ParseMultipartForm(50 * 1024 * 1024) if err != nil && err != http.ErrNotMultipart { return httperr.Server(err) } err = build.Save() if err != nil { return httperr.Server(err) } resources, err := models.ListResources(os.Getenv("RACK")) if err != nil { return httperr.Server(err) } ch := make(chan error) source, _, err := r.FormFile("source") if err != nil && err != http.ErrMissingFile && err != http.ErrNotMultipart { return httperr.Server(err) } cache := !(r.FormValue("cache") == "false") if source != nil { err = models.S3PutFile(resources["RegistryBucket"].Id, fmt.Sprintf("builds/%s.tgz", build.Id), source, false) if err != nil { return httperr.Server(err) } go build.ExecuteLocal(source, cache, ch) err = <-ch if err != nil { return httperr.Server(err) } else { return RenderJson(rw, build) } } if repo := r.FormValue("repo"); repo != "" { go build.ExecuteRemote(repo, cache, ch) err = <-ch if err != nil { return httperr.Server(err) } else { return RenderJson(rw, build) } } return httperr.Errorf(403, "no source or repo") }