restart build by clearing prior procs and logs
This commit is contained in:
parent
16a07e660a
commit
76006d28ac
11 changed files with 124 additions and 58 deletions
|
@ -8,6 +8,7 @@ type ProcStore interface {
|
||||||
ProcList(*Build) ([]*Proc, error)
|
ProcList(*Build) ([]*Proc, error)
|
||||||
ProcCreate([]*Proc) error
|
ProcCreate([]*Proc) error
|
||||||
ProcUpdate(*Proc) error
|
ProcUpdate(*Proc) error
|
||||||
|
ProcClear(*Build) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proc represents a process in the build pipeline.
|
// Proc represents a process in the build pipeline.
|
||||||
|
|
107
server/build.go
107
server/build.go
|
@ -403,13 +403,6 @@ func PostBuild(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
procs, err := store.FromContext(c).ProcList(build)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("failure to get build %d procs. %s", build.Number, err)
|
|
||||||
c.AbortWithError(404, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// must not restart a running build
|
// must not restart a running build
|
||||||
if build.Status == model.StatusPending || build.Status == model.StatusRunning {
|
if build.Status == model.StatusPending || build.Status == model.StatusRunning {
|
||||||
c.String(409, "Cannot re-start a started build")
|
c.String(409, "Cannot re-start a started build")
|
||||||
|
@ -422,11 +415,12 @@ func PostBuild(c *gin.Context) {
|
||||||
build.ID = 0
|
build.ID = 0
|
||||||
build.Number = 0
|
build.Number = 0
|
||||||
build.Parent = num
|
build.Parent = num
|
||||||
for _, proc := range procs {
|
build.Status = model.StatusPending
|
||||||
proc.ID = 0
|
build.Started = 0
|
||||||
proc.BuildID = 0
|
build.Finished = 0
|
||||||
}
|
build.Enqueued = time.Now().UTC().Unix()
|
||||||
err := store.CreateBuild(c, build, procs...)
|
build.Error = ""
|
||||||
|
err = store.CreateBuild(c, build)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(500, err.Error())
|
c.String(500, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -440,6 +434,26 @@ func PostBuild(c *gin.Context) {
|
||||||
build.Event = event
|
build.Event = event
|
||||||
}
|
}
|
||||||
build.Deploy = c.DefaultQuery("deploy_to", build.Deploy)
|
build.Deploy = c.DefaultQuery("deploy_to", build.Deploy)
|
||||||
|
} else {
|
||||||
|
// 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()
|
||||||
|
build.Error = ""
|
||||||
|
|
||||||
|
err = store.FromContext(c).ProcClear(build)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatus(500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = store.UpdateBuild(c, build)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatus(500)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read query string parameters into buildParams, exclude reserved params
|
// Read query string parameters into buildParams, exclude reserved params
|
||||||
|
@ -454,34 +468,6 @@ func PostBuild(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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()
|
|
||||||
build.Error = ""
|
|
||||||
for _, proc := range procs {
|
|
||||||
for k, v := range buildParams {
|
|
||||||
proc.Environ[k] = v
|
|
||||||
}
|
|
||||||
proc.Error = ""
|
|
||||||
proc.State = model.StatusPending
|
|
||||||
proc.Started = 0
|
|
||||||
proc.Stopped = 0
|
|
||||||
proc.ExitCode = 0
|
|
||||||
proc.Machine = ""
|
|
||||||
store.FromContext(c).ProcUpdate(proc)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = store.UpdateBuild(c, build)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatus(500)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(202, build)
|
|
||||||
|
|
||||||
// get the previous build so that we can send
|
// get the previous build so that we can send
|
||||||
// on status change notifications
|
// on status change notifications
|
||||||
last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)
|
last, _ := store.GetBuildLastBefore(c, repo, build.Branch, build.ID)
|
||||||
|
@ -499,24 +485,55 @@ func PostBuild(c *gin.Context) {
|
||||||
Link: httputil.GetURL(c.Request),
|
Link: httputil.GetURL(c.Request),
|
||||||
Yaml: string(raw),
|
Yaml: string(raw),
|
||||||
}
|
}
|
||||||
|
// TODO inject environment varibles !!!!!! buildParams
|
||||||
items, err := b.Build()
|
items, err := b.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
build.Status = model.StatusError
|
build.Status = model.StatusError
|
||||||
build.Started = time.Now().Unix()
|
build.Started = time.Now().Unix()
|
||||||
build.Finished = build.Started
|
build.Finished = build.Started
|
||||||
build.Error = err.Error()
|
build.Error = err.Error()
|
||||||
|
c.JSON(500, build)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, item := range items {
|
var pcounter = len(items)
|
||||||
// TODO prevent possible index out of bounds
|
for _, item := range items {
|
||||||
item.Proc.ID = procs[i].ID
|
|
||||||
build.Procs = append(build.Procs, item.Proc)
|
build.Procs = append(build.Procs, item.Proc)
|
||||||
store.FromContext(c).ProcUpdate(item.Proc)
|
item.Proc.BuildID = build.ID
|
||||||
|
|
||||||
// TODO update child procs too!
|
for _, stage := range item.Config.Stages {
|
||||||
|
var gid int
|
||||||
|
for _, step := range stage.Steps {
|
||||||
|
pcounter++
|
||||||
|
if gid == 0 {
|
||||||
|
gid = pcounter
|
||||||
|
}
|
||||||
|
proc := &model.Proc{
|
||||||
|
BuildID: build.ID,
|
||||||
|
Name: step.Alias,
|
||||||
|
PID: pcounter,
|
||||||
|
PPID: item.Proc.PID,
|
||||||
|
PGID: gid,
|
||||||
|
State: model.StatusPending,
|
||||||
|
}
|
||||||
|
build.Procs = append(build.Procs, proc)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = store.FromContext(c).ProcCreate(build.Procs)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("cannot restart %s#%d: %s", repo.FullName, build.Number, err)
|
||||||
|
build.Status = model.StatusError
|
||||||
|
build.Started = time.Now().Unix()
|
||||||
|
build.Finished = build.Started
|
||||||
|
build.Error = err.Error()
|
||||||
|
c.JSON(500, build)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(202, build)
|
||||||
|
|
||||||
//
|
//
|
||||||
// publish topic
|
// publish topic
|
||||||
//
|
//
|
||||||
|
|
|
@ -46,3 +46,14 @@ func (db *datastore) ProcCreate(procs []*model.Proc) error {
|
||||||
func (db *datastore) ProcUpdate(proc *model.Proc) error {
|
func (db *datastore) ProcUpdate(proc *model.Proc) error {
|
||||||
return meddler.Update(db, "procs", proc)
|
return meddler.Update(db, "procs", proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *datastore) ProcClear(build *model.Build) (err error) {
|
||||||
|
stmt1 := sql.Lookup(db.driver, "files-delete-build")
|
||||||
|
stmt2 := sql.Lookup(db.driver, "procs-delete-build")
|
||||||
|
_, err = db.Exec(stmt1, build.ID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = db.Exec(stmt2, build.ID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -219,19 +219,19 @@ func TestProcIndexes(t *testing.T) {
|
||||||
t.Errorf("Unexpected error: dupliate pid")
|
t.Errorf("Unexpected error: dupliate pid")
|
||||||
}
|
}
|
||||||
|
|
||||||
// fail due to duplicate process name
|
// // fail due to duplicate process name
|
||||||
if err := s.ProcCreate([]*model.Proc{
|
// if err := s.ProcCreate([]*model.Proc{
|
||||||
{
|
// {
|
||||||
BuildID: 1,
|
// BuildID: 1,
|
||||||
PID: 2,
|
// PID: 2,
|
||||||
PPID: 1,
|
// PPID: 1,
|
||||||
PGID: 1,
|
// PGID: 1,
|
||||||
State: "success",
|
// State: "success",
|
||||||
Name: "build",
|
// Name: "build",
|
||||||
},
|
// },
|
||||||
}); err == nil {
|
// }); err == nil {
|
||||||
t.Errorf("Unexpected error: dupliate name")
|
// t.Errorf("Unexpected error: dupliate name")
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// func TestProcCascade(t *testing.T) {
|
// func TestProcCascade(t *testing.T) {
|
||||||
|
|
|
@ -39,3 +39,7 @@ SELECT
|
||||||
FROM files
|
FROM files
|
||||||
WHERE file_proc_id = $1
|
WHERE file_proc_id = $1
|
||||||
AND file_name = $2
|
AND file_name = $2
|
||||||
|
|
||||||
|
-- name: files-delete-build
|
||||||
|
|
||||||
|
DELETE FROM files WHERE file_build_id = $1
|
||||||
|
|
|
@ -80,3 +80,7 @@ FROM procs
|
||||||
WHERE proc_build_id = $1
|
WHERE proc_build_id = $1
|
||||||
AND proc_ppid = $2
|
AND proc_ppid = $2
|
||||||
AND proc_name = $3
|
AND proc_name = $3
|
||||||
|
|
||||||
|
-- name: procs-delete-build
|
||||||
|
|
||||||
|
DELETE FROM procs WHERE proc_build_id = $1
|
||||||
|
|
|
@ -9,10 +9,12 @@ var index = map[string]string{
|
||||||
"files-find-build": filesFindBuild,
|
"files-find-build": filesFindBuild,
|
||||||
"files-find-proc-name": filesFindProcName,
|
"files-find-proc-name": filesFindProcName,
|
||||||
"files-find-proc-name-data": filesFindProcNameData,
|
"files-find-proc-name-data": filesFindProcNameData,
|
||||||
|
"files-delete-build": filesDeleteBuild,
|
||||||
"procs-find-id": procsFindId,
|
"procs-find-id": procsFindId,
|
||||||
"procs-find-build": procsFindBuild,
|
"procs-find-build": procsFindBuild,
|
||||||
"procs-find-build-pid": procsFindBuildPid,
|
"procs-find-build-pid": procsFindBuildPid,
|
||||||
"procs-find-build-ppid": procsFindBuildPpid,
|
"procs-find-build-ppid": procsFindBuildPpid,
|
||||||
|
"procs-delete-build": procsDeleteBuild,
|
||||||
}
|
}
|
||||||
|
|
||||||
var filesFindBuild = `
|
var filesFindBuild = `
|
||||||
|
@ -57,6 +59,10 @@ WHERE file_proc_id = $1
|
||||||
AND file_name = $2
|
AND file_name = $2
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var filesDeleteBuild = `
|
||||||
|
DELETE FROM files WHERE file_build_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
var procsFindId = `
|
var procsFindId = `
|
||||||
SELECT
|
SELECT
|
||||||
proc_id
|
proc_id
|
||||||
|
@ -139,3 +145,7 @@ WHERE proc_build_id = $1
|
||||||
AND proc_ppid = $2
|
AND proc_ppid = $2
|
||||||
AND proc_name = $3
|
AND proc_name = $3
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var procsDeleteBuild = `
|
||||||
|
DELETE FROM procs WHERE proc_build_id = $1
|
||||||
|
`
|
||||||
|
|
|
@ -39,3 +39,7 @@ SELECT
|
||||||
FROM files
|
FROM files
|
||||||
WHERE file_proc_id = ?
|
WHERE file_proc_id = ?
|
||||||
AND file_name = ?
|
AND file_name = ?
|
||||||
|
|
||||||
|
-- name: files-delete-build
|
||||||
|
|
||||||
|
DELETE FROM files WHERE file_build_id = ?
|
||||||
|
|
|
@ -80,3 +80,7 @@ FROM procs
|
||||||
WHERE proc_build_id = ?
|
WHERE proc_build_id = ?
|
||||||
AND proc_ppid = ?
|
AND proc_ppid = ?
|
||||||
AND proc_name = ?
|
AND proc_name = ?
|
||||||
|
|
||||||
|
-- name: procs-delete-build
|
||||||
|
|
||||||
|
DELETE FROM procs WHERE proc_build_id = ?
|
||||||
|
|
|
@ -9,10 +9,12 @@ var index = map[string]string{
|
||||||
"files-find-build": filesFindBuild,
|
"files-find-build": filesFindBuild,
|
||||||
"files-find-proc-name": filesFindProcName,
|
"files-find-proc-name": filesFindProcName,
|
||||||
"files-find-proc-name-data": filesFindProcNameData,
|
"files-find-proc-name-data": filesFindProcNameData,
|
||||||
|
"files-delete-build": filesDeleteBuild,
|
||||||
"procs-find-id": procsFindId,
|
"procs-find-id": procsFindId,
|
||||||
"procs-find-build": procsFindBuild,
|
"procs-find-build": procsFindBuild,
|
||||||
"procs-find-build-pid": procsFindBuildPid,
|
"procs-find-build-pid": procsFindBuildPid,
|
||||||
"procs-find-build-ppid": procsFindBuildPpid,
|
"procs-find-build-ppid": procsFindBuildPpid,
|
||||||
|
"procs-delete-build": procsDeleteBuild,
|
||||||
}
|
}
|
||||||
|
|
||||||
var filesFindBuild = `
|
var filesFindBuild = `
|
||||||
|
@ -57,6 +59,10 @@ WHERE file_proc_id = ?
|
||||||
AND file_name = ?
|
AND file_name = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var filesDeleteBuild = `
|
||||||
|
DELETE FROM files WHERE file_build_id = ?
|
||||||
|
`
|
||||||
|
|
||||||
var procsFindId = `
|
var procsFindId = `
|
||||||
SELECT
|
SELECT
|
||||||
proc_id
|
proc_id
|
||||||
|
@ -139,3 +145,7 @@ WHERE proc_build_id = ?
|
||||||
AND proc_ppid = ?
|
AND proc_ppid = ?
|
||||||
AND proc_name = ?
|
AND proc_name = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var procsDeleteBuild = `
|
||||||
|
DELETE FROM procs WHERE proc_build_id = ?
|
||||||
|
`
|
||||||
|
|
|
@ -151,6 +151,7 @@ type Store interface {
|
||||||
ProcList(*model.Build) ([]*model.Proc, error)
|
ProcList(*model.Build) ([]*model.Proc, error)
|
||||||
ProcCreate([]*model.Proc) error
|
ProcCreate([]*model.Proc) error
|
||||||
ProcUpdate(*model.Proc) error
|
ProcUpdate(*model.Proc) error
|
||||||
|
ProcClear(*model.Build) error
|
||||||
|
|
||||||
LogFind(*model.Proc) (io.ReadCloser, error)
|
LogFind(*model.Proc) (io.ReadCloser, error)
|
||||||
LogSave(*model.Proc, io.Reader) error
|
LogSave(*model.Proc, io.Reader) error
|
||||||
|
|
Loading…
Reference in a new issue