func TestBuildGet(t *testing.T) { aws := StubAwsProvider( describeStacksCycle, build1GetItemCycle, build1GetObjectCycle, ) defer aws.Close() defer func() { //TODO: remove: as we arent updating all tests we need to set current provider back to a //clean default one (I miss rspec before) provider.CurrentProvider = new(provider.TestProviderRunner) }() b, err := provider.BuildGet("httpd", "BHINCLZYYVN") assert.Nil(t, err) assert.EqualValues(t, &structs.Build{ Id: "BHINCLZYYVN", App: "httpd", Logs: "RUNNING: docker pull httpd", Manifest: "web:\n image: httpd\n ports:\n - 80:80\n", Release: "RVFETUHHKKD", Status: "complete", Started: time.Unix(1459780456, 178278576).UTC(), Ended: time.Unix(1459780542, 440881687).UTC(), }, b) }
func BuildUpdate(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] build := vars["build"] b, err := provider.BuildGet(app, build) if err != nil { return httperr.Server(err) } if d := r.FormValue("description"); d != "" { b.Description = d } if m := r.FormValue("manifest"); m != "" { b.Manifest = m } if r := r.FormValue("reason"); r != "" { b.Reason = r } if s := r.FormValue("status"); s != "" { b.Status = s b.Ended = time.Now() } // if build was successful create a release if b.Status == "complete" && b.Manifest != "" { _, err := provider.BuildRelease(b) if err != nil { return httperr.Server(err) } } err = provider.BuildSave(b) if err != nil { return httperr.Server(err) } if b.Status == "failed" { provider.EventSend(&structs.Event{ Action: "build:create", Data: map[string]string{ "app": b.App, "id": b.Id, }, }, fmt.Errorf(b.Reason)) } return RenderJson(rw, b) }
func BuildGet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] build := vars["build"] b, err := 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) } return RenderJson(rw, b) }
func BuildLogs(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) app := vars["app"] build := vars["build"] _, err := provider.BuildGet(app, build) if err != nil { return httperr.Server(err) } // default to local docker socket host := "unix:///var/run/docker.sock" // in production loop through docker hosts that the rack is running on // to find the build if os.Getenv("DEVELOPMENT") != "true" { pss, err := models.ListProcesses(os.Getenv("RACK")) if err != nil { return httperr.Server(err) } for _, ps := range pss { client, err := ps.Docker() if err != nil { return httperr.Server(err) } res, err := client.ListContainers(docker.ListContainersOptions{ All: true, Filters: map[string][]string{ "name": []string{fmt.Sprintf("build-%s", build)}, }, }) if len(res) > 0 { host = fmt.Sprintf("http://%s:2376", ps.Host) break } } } // proxy to docker container logs // https://docs.docker.com/reference/api/docker_remote_api_v1.19/#get-container-logs client, err := docker.NewClient(host) if err != nil { return httperr.Server(err) } quit := make(chan bool) 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: ws, ErrorStream: ws, }) quit <- true return httperr.Server(err) }