Example #1
0
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)
}
Example #2
0
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)
}
Example #3
0
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)
}
Example #4
0
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)
}