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