func (b *Build) ExecuteRemote(repo string, cache bool, manifest string, ch chan error) { started := time.Now() b.Status = "building" err := b.Save() if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "remote", "at": "b.Save"}) b.buildError(err, ch) return } args, err := b.buildArgs(cache, manifest) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "remote", "at": "b.buildArgs"}) b.buildError(err, ch) return } args = append(args, b.App, repo) err = b.execute(args, nil, ch) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "remote", "at": "b.execute"}) b.buildError(err, ch) return } NotifySuccess("build:create", map[string]string{"id": b.Id, "app": b.App}) fmt.Printf("ns=kernel cn=build at=ExecuteRemote state=success step=build.execute app=%q build=%q\n", b.App, b.Id) helpers.TrackSuccess("build", map[string]interface{}{"type": "remote", "elapsed": time.Now().Sub(started).Nanoseconds() / 1000000}) }
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 (b *Build) ExecuteIndex(index Index, cache bool, manifest string, ch chan error) { started := time.Now() b.Status = "building" err := b.Save() if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "remote", "at": "b.Save"}) b.buildError(err, ch) return } args, err := b.buildArgs(cache, manifest) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "index", "at": "b.buildArgs"}) b.buildError(err, ch) return } dir, err := ioutil.TempDir("", "source") if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "index", "at": "ioutil.TempDir"}) b.buildError(err, ch) return } err = os.Chmod(dir, 0755) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "index", "at": "os.Chmod"}) b.buildError(err, ch) return } err = index.Download(dir) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "index", "at": "index.Download"}) b.buildError(err, ch) return } tgz, err := createTarball(dir) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "index", "at": "createTarball"}) b.buildError(err, ch) return } args = append(args, b.App, "-") err = b.execute(args, bytes.NewReader(tgz), ch) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"type": "index", "at": "b.execute"}) b.buildError(err, ch) return } NotifySuccess("build:create", map[string]string{"id": b.Id, "app": b.App}) fmt.Printf("ns=kernel cn=build at=ExecuteIndex state=success step=build.execute app=%q build=%q\n", b.App, b.Id) helpers.TrackSuccess("build", map[string]interface{}{"type": "index", "elapsed": time.Now().Sub(started).Nanoseconds() / 1000000}) }
func BuildCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { build := models.NewBuild(mux.Vars(r)["app"]) build.Description = r.FormValue("description") manifest := r.FormValue("manifest") // empty value will default "docker-compose.yml" in cmd/build // use deprecated "config" param if set and "manifest" is not if config := r.FormValue("config"); config != "" && manifest == "" { manifest = config } if build.IsRunning() { err := fmt.Errorf("Another build is currently running. Please try again later.") helpers.TrackError("build", err, map[string]interface{}{"at": "build.IsRunning"}) return httperr.Server(err) } err := r.ParseMultipartForm(50 * 1024 * 1024) if err != nil && err != http.ErrNotMultipart { helpers.TrackError("build", err, map[string]interface{}{"at": "ParseMultipartForm"}) return httperr.Server(err) } err = build.Save() if err != nil { helpers.TrackError("build", err, map[string]interface{}{"at": "build.Save"}) return httperr.Server(err) } resources, err := models.ListResources(os.Getenv("RACK")) if err != nil { helpers.TrackError("build", err, map[string]interface{}{"at": "models.ListResources"}) return httperr.Server(err) } ch := make(chan error) 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) } 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 { helpers.TrackError("build", err, map[string]interface{}{"at": "models.S3PutFile"}) return httperr.Server(err) } go build.ExecuteLocal(source, cache, manifest, ch) err = <-ch if err != nil { helpers.TrackError("build", err, map[string]interface{}{"at": "models.ExecuteLocal"}) return httperr.Server(err) } else { return RenderJson(rw, build) } } if repo := r.FormValue("repo"); repo != "" { go build.ExecuteRemote(repo, cache, manifest, ch) err = <-ch if err != nil { helpers.TrackError("build", err, map[string]interface{}{"at": "build.ExecuteRemote"}) return httperr.Server(err) } else { return RenderJson(rw, build) } } if data := r.FormValue("index"); data != "" { var index models.Index err := json.Unmarshal([]byte(data), &index) if err != nil { return httperr.Server(err) } go build.ExecuteIndex(index, cache, manifest, ch) err = <-ch if err != nil { helpers.TrackError("build", err, map[string]interface{}{"at": "build.ExecuteIndex"}) return httperr.Server(err) } else { return RenderJson(rw, build) } } return httperr.Errorf(403, "no source or repo") }