Ejemplo n.º 1
0
func GetRepoKey(c *gin.Context) {
	repo := session.Repo(c)
	keys, err := store.GetKey(c, repo)
	if err != nil {
		c.AbortWithError(http.StatusNotFound, err)
	} else {
		c.String(http.StatusOK, keys.Public)
	}
}
Ejemplo n.º 2
0
func ShowRepoConf(c *gin.Context) {

	user := session.User(c)
	repo := session.Repo(c)
	key, _ := store.GetKey(c, repo)

	token, _ := token.New(
		token.CsrfToken,
		user.Login,
	).Sign(user.Hash)

	c.HTML(200, "repo_config.html", gin.H{
		"User": user,
		"Repo": repo,
		"Key":  key,
		"Csrf": token,
		"Link": httputil.GetURL(c.Request),
	})
}
Ejemplo n.º 3
0
func PostSecure(c *gin.Context) {
	repo := session.Repo(c)

	in, err := ioutil.ReadAll(c.Request.Body)
	if err != nil {
		c.AbortWithError(http.StatusBadRequest, err)
		return
	}

	// we found some strange characters included in
	// the yaml file when entered into a browser textarea.
	// these need to be removed
	in = bytes.Replace(in, []byte{'\xA0'}, []byte{' '}, -1)

	// make sure the Yaml is valid format to prevent
	// a malformed value from being used in the build
	err = yaml.Unmarshal(in, &yaml.MapSlice{})
	if err != nil {
		c.String(http.StatusBadRequest, err.Error())
		return
	}

	key, err := store.GetKey(c, repo)
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	// encrypts using go-jose
	out, err := crypto.Encrypt(string(in), key.Private)
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}
	c.String(http.StatusOK, out)
}
Ejemplo n.º 4
0
func PostBuild(c *gin.Context) {

	remote_ := remote.FromContext(c)
	repo := session.Repo(c)
	fork := c.DefaultQuery("fork", "false")

	num, err := strconv.Atoi(c.Param("number"))
	if err != nil {
		c.AbortWithError(http.StatusBadRequest, err)
		return
	}

	user, err := store.GetUser(c, repo.UserID)
	if err != nil {
		log.Errorf("failure to find repo owner %s. %s", repo.FullName, err)
		c.AbortWithError(500, err)
		return
	}

	build, err := store.GetBuildNumber(c, repo, num)
	if err != nil {
		log.Errorf("failure to get build %d. %s", num, err)
		c.AbortWithError(404, err)
		return
	}

	// if the remote has a refresh token, the current access token
	// may be stale. Therefore, we should refresh prior to dispatching
	// the job.
	if refresher, ok := remote_.(remote.Refresher); ok {
		ok, _ := refresher.Refresh(user)
		if ok {
			store.UpdateUser(c, user)
		}
	}

	// fetch the .drone.yml file from the database
	raw, sec, err := remote_.Script(user, repo, build)
	if err != nil {
		log.Errorf("failure to get .drone.yml for %s. %s", repo.FullName, err)
		c.AbortWithError(404, err)
		return
	}

	key, _ := store.GetKey(c, repo)
	netrc, err := remote_.Netrc(user, repo)
	if err != nil {
		log.Errorf("failure to generate netrc for %s. %s", repo.FullName, err)
		c.AbortWithError(500, err)
		return
	}

	jobs, err := store.GetJobList(c, build)
	if err != nil {
		log.Errorf("failure to get build %d jobs. %s", build.Number, err)
		c.AbortWithError(404, err)
		return
	}

	// must not restart a running build
	if build.Status == model.StatusPending || build.Status == model.StatusRunning {
		c.String(409, "Cannot re-start a started build")
		return
	}

	// forking the build creates a duplicate of the build
	// and then executes. This retains prior build history.
	if forkit, _ := strconv.ParseBool(fork); forkit {
		build.ID = 0
		build.Number = 0
		for _, job := range jobs {
			job.ID = 0
			job.NodeID = 0
		}
		err := store.CreateBuild(c, build, jobs...)
		if err != nil {
			c.String(500, err.Error())
			return
		}
	}

	// todo move this to database tier
	// and wrap inside a transaction
	build.Status = model.StatusPending
	build.Started = 0
	build.Finished = 0
	build.Enqueued = time.Now().UTC().Unix()
	for _, job := range jobs {
		job.Status = model.StatusPending
		job.Started = 0
		job.Finished = 0
		job.ExitCode = 0
		job.NodeID = 0
		job.Enqueued = build.Enqueued
		store.UpdateJob(c, job)
	}

	err = store.UpdateBuild(c, build)
	if err != nil {
		c.AbortWithStatus(500)
		return
	}

	c.JSON(202, build)

	// get the previous build so taht we can send
	// on status change notifications
	last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)

	engine_ := context.Engine(c)
	go engine_.Schedule(c.Copy(), &engine.Task{
		User:      user,
		Repo:      repo,
		Build:     build,
		BuildPrev: last,
		Jobs:      jobs,
		Keys:      key,
		Netrc:     netrc,
		Config:    string(raw),
		Secret:    string(sec),
		System: &model.System{
			Link:    httputil.GetURL(c.Request),
			Plugins: strings.Split(os.Getenv("PLUGIN_FILTER"), " "),
			Globals: strings.Split(os.Getenv("PLUGIN_PARAMS"), " "),
		},
	})

}