func BuildGet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] build := vars["build"] b, err := models.Provider().BuildGet(app, build) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil && strings.HasPrefix(err.Error(), "no such build") { return httperr.Errorf(404, err.Error()) } if err != nil { return httperr.Server(err) } l, err := models.Provider().BuildLogs(app, build) if err != nil { return httperr.Server(err) } b.Logs = l return RenderJson(rw, b) }
// BuildDelete deletes a build. Makes sure not to delete a build that is contained in the active release func BuildDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) appName := vars["app"] buildID := vars["build"] active, err := isBuildActive(appName, buildID) if err != nil { return httperr.Errorf(404, err.Error()) } if active { return httperr.Errorf(400, "cannot delete build contained in active release") } err = models.Provider().ReleaseDelete(appName, buildID) if err != nil { return httperr.Server(err) } build, err := models.Provider().BuildDelete(appName, buildID) if err != nil { return httperr.Server(err) } return RenderJson(rw, build) }
// ForkRelease creates a new release based on the app's release func ForkRelease(app *structs.App) (*structs.Release, error) { release := structs.NewRelease(app.Name) if app.Release != "" { r, err := models.Provider().ReleaseGet(app.Name, app.Release) if err != nil { return nil, err } id := release.Id created := release.Created release = r release.Id = id release.Created = created } env, err := models.Provider().EnvironmentGet(app.Name) if err != nil { fmt.Printf("fn=ForkRelease level=error msg=\"error getting environment: %s\"", err) } release.Env = env.Raw() return &structs.Release{ Id: release.Id, App: release.App, Build: release.Build, Env: release.Env, Manifest: release.Manifest, Created: release.Created, }, nil }
func BuildCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] cache := !(r.FormValue("cache") == "false") manifest := r.FormValue("manifest") description := r.FormValue("description") repo := r.FormValue("repo") index := r.FormValue("index") source, _, err := r.FormFile("source") if err != nil && err != http.ErrMissingFile && err != http.ErrNotMultipart { helpers.TrackError("build", err, map[string]interface{}{"at": "FormFile"}) return httperr.Server(err) } // Log into private registries that we might pull from // TODO: move to prodiver BuildCreate err = models.LoginPrivateRegistries() if err != nil { return httperr.Server(err) } a, err := models.GetApp(app) if err != nil { return httperr.Server(err) } // Log into registry that we will push to _, err = models.AppDockerLogin(*a) if err != nil { return httperr.Server(err) } var b *structs.Build // if source file was posted, build from tar if source != nil { b, err = models.Provider().BuildCreateTar(app, source, r.FormValue("manifest"), r.FormValue("description"), cache) } else if repo != "" { b, err = models.Provider().BuildCreateRepo(app, repo, r.FormValue("manifest"), r.FormValue("description"), cache) } else if index != "" { var i structs.Index err := json.Unmarshal([]byte(index), &i) if err != nil { return httperr.Server(err) } b, err = models.Provider().BuildCreateIndex(app, i, manifest, description, cache) } else { return httperr.Errorf(403, "no source, repo or index") } if err != nil { return httperr.Server(err) } return RenderJson(rw, b) }
func BuildList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] l := r.URL.Query().Get("limit") var err error var limit int if l == "" { limit = 20 } else { limit, err = strconv.Atoi(l) if err != nil { return httperr.Errorf(400, err.Error()) } } builds, err := models.Provider().BuildList(app, int64(limit)) 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 AppLogs(ws *websocket.Conn) *httperr.Error { app := mux.Vars(ws.Request())["app"] header := ws.Request().Header var err error follow := true if header.Get("Follow") == "false" { follow = false } since := 2 * time.Minute if s := header.Get("Since"); s != "" { since, err = time.ParseDuration(s) if err != nil { return httperr.Errorf(403, "Invalid duration %s", s) } } err = models.Provider().LogStream(app, ws, structs.LogStreamOptions{ Filter: header.Get("Filter"), Follow: follow, Since: time.Now().Add(-1 * since), }) if err != nil { if strings.HasSuffix(err.Error(), "write: broken pipe") { return nil } return httperr.Server(err) } return nil }
// SystemLogs returns the logs for the Rack func SystemLogs(ws *websocket.Conn) *httperr.Error { header := ws.Request().Header var err error follow := true if header.Get("Follow") == "false" { follow = false } since := 2 * time.Minute if s := header.Get("Since"); s != "" { since, err = time.ParseDuration(s) if err != nil { return httperr.Errorf(403, "Invalid duration %s", s) } } err = models.Provider().SystemLogs(ws, structs.LogStreamOptions{ Filter: header.Get("Filter"), Follow: follow, Since: time.Now().Add(-1 * since), }) if err != nil { return httperr.Server(err) } return nil }
func ProcessRunAttached(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) header := ws.Request().Header app := vars["app"] process := vars["process"] command := header.Get("Command") release := header.Get("Release") height, _ := strconv.Atoi(header.Get("Height")) width, _ := strconv.Atoi(header.Get("Width")) _, err := models.Provider().ProcessRun(app, process, structs.ProcessRunOptions{ Command: command, Height: height, Width: width, Release: release, Stream: ws, }) if provider.ErrorNotFound(err) { return httperr.New(404, err) } if err != nil { return httperr.Server(err) } return nil }
// BuildDelete deletes a build. Makes sure not to delete a build that is contained in the active release func BuildDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) appName := vars["app"] buildID := vars["build"] err := models.Provider().ReleaseDelete(appName, buildID) if err != nil { return httperr.Server(err) } build, err := models.Provider().BuildDelete(appName, buildID) if err != nil { return httperr.Server(err) } return RenderJson(rw, build) }
func SystemCapacity(rw http.ResponseWriter, r *http.Request) *httperr.Error { capacity, err := models.Provider().CapacityGet() if err != nil { return httperr.Server(err) } return RenderJson(rw, capacity) }
func RegistryList(rw http.ResponseWriter, r *http.Request) *httperr.Error { registries, err := models.Provider().RegistryList() if err != nil { return httperr.Server(err) } return RenderJson(rw, registries) }
func SystemShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { rack, err := models.Provider().SystemGet() if err != nil { return httperr.Server(err) } return RenderJson(rw, rack) }
// SystemReleases lists the latest releases of the rack func SystemReleases(rw http.ResponseWriter, r *http.Request) *httperr.Error { releases, err := models.Provider().SystemReleases() if err != nil { return httperr.Server(err) } return RenderJson(rw, releases) }
func InstancesList(rw http.ResponseWriter, r *http.Request) *httperr.Error { instances, err := models.Provider().InstanceList() if err != nil { return httperr.Server(err) } return RenderJson(rw, instances) }
func InstanceTerminate(rw http.ResponseWriter, r *http.Request) *httperr.Error { id := mux.Vars(r)["id"] if err := models.Provider().InstanceTerminate(id); err != nil { return httperr.Server(err) } return RenderSuccess(rw) }
func RegistryDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { server := r.FormValue("server") if err := models.Provider().RegistryDelete(server); 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.Provider().ServiceGet(service) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such service: %s", service) } if err != nil { return httperr.Server(err) } s, err = models.Provider().ServiceDelete(service) if err != nil { return httperr.Server(err) } return RenderJson(rw, s) }
func FormationList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] formation, err := models.Provider().FormationList(app) if err != nil { return httperr.Server(err) } return RenderJson(rw, formation) }
func CertificateDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { id := mux.Vars(r)["id"] err := models.Provider().CertificateDelete(id) if err != nil { return httperr.Server(err) } return RenderSuccess(rw) }
func CertificateGenerate(rw http.ResponseWriter, r *http.Request) *httperr.Error { domains := strings.Split(r.FormValue("domains"), ",") cert, err := models.Provider().CertificateGenerate(domains) if err != nil { return httperr.Server(err) } return RenderJson(rw, cert) }
func CertificateList(rw http.ResponseWriter, r *http.Request) *httperr.Error { certs, err := models.Provider().CertificateList() if err != nil { return httperr.Server(err) } sort.Sort(certs) return RenderJson(rw, certs) }
func BuildLogs(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) app := vars["app"] build := vars["build"] if err := models.Provider().BuildLogs(app, build, ws); err != nil { return httperr.Server(err) } return nil }
func RegistryCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { server := GetForm(r, "server") username := GetForm(r, "username") password := GetForm(r, "password") registry, err := models.Provider().RegistryAdd(server, username, password) if err != nil { return httperr.Server(err) } return RenderJson(rw, registry) }
func CertificateCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { pub := r.FormValue("public") key := r.FormValue("private") chain := r.FormValue("chain") cert, err := models.Provider().CertificateCreate(pub, key, chain) if err != nil { return httperr.Server(err) } return RenderJson(rw, cert) }
func LinkCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { service := mux.Vars(r)["service"] s, err := models.Provider().ServiceGet(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 link service with status: %s", s.Status) } s, err = models.Provider().ServiceLink(service, GetForm(r, "app"), GetForm(r, "process")) if err != nil { return httperr.Server(err) } return RenderJson(rw, s) }
func SystemUpdate(rw http.ResponseWriter, r *http.Request) *httperr.Error { rack, err := models.Provider().SystemGet() if err != nil { return httperr.Server(err) } // update based on form input if cc := GetForm(r, "count"); cc != "" { c, err := strconv.Atoi(cc) if err != nil { return httperr.Errorf(403, "count must be numeric") } switch { case os.Getenv("AUTOSCALE") == "true": return httperr.Errorf(403, "scaling count prohibited when autoscale enabled") case c == -1: // -1 indicates no change case c <= 1: return httperr.Errorf(403, "count must be greater than 1") default: rack.Count = c } } if t := GetForm(r, "type"); t != "" { rack.Type = t } if v := GetForm(r, "version"); v != "" { rack.Version = v } err = models.Provider().SystemSave(*rack) if err != nil { return httperr.Server(err) } return RenderJson(rw, rack) }
func ReleaseList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] releases, err := models.Provider().ReleaseList(app, 20) if awsError(err) == "ValidationError" { return httperr.Errorf(404, "no such app: %s", app) } if err != nil { return httperr.Server(err) } return RenderJson(rw, releases) }
func BuildCopy(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) srcApp := vars["app"] build := vars["build"] dest := r.FormValue("app") b, err := models.Provider().BuildCopy(srcApp, build, dest) if err != nil { return httperr.Server(err) } return RenderJson(rw, b) }
func AppCancel(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] err := models.Provider().AppCancel(app) if provider.ErrorNotFound(err) { return httperr.NotFound(err) } if err != nil { return httperr.Server(err) } return RenderSuccess(rw) }
func ProcessList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] ps, err := models.Provider().ProcessList(app) if provider.ErrorNotFound(err) { return httperr.NotFound(err) } if err != nil { return httperr.Server(err) } sort.Sort(ps) return RenderJson(rw, ps) }