use separate log table

This commit is contained in:
Brad Rydzewski 2017-04-03 18:34:37 +09:00
parent ec88661d9e
commit 0daee76aa8
7 changed files with 147 additions and 124 deletions

View file

@ -1,7 +0,0 @@
package model
// type Log struct {
// ID int64 `meddler:"log_id,pk"`
// JobID int64 `meddler:"log_job_id"`
// Data []byte `meddler:"log_data"`
// }

View file

@ -104,7 +104,7 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
repo.GET("", server.GetRepo) repo.GET("", server.GetRepo)
repo.GET("/builds", server.GetBuilds) repo.GET("/builds", server.GetBuilds)
repo.GET("/builds/:number", server.GetBuild) repo.GET("/builds/:number", server.GetBuild)
repo.GET("/logs/:number/:job", server.GetBuildLogs) repo.GET("/logs/:number/:ppid/:proc", server.GetBuildLogs)
repo.POST("/sign", session.MustPush, server.Sign) repo.POST("/sign", session.MustPush, server.Sign)
repo.GET("/secrets", session.MustPush, server.GetSecrets) repo.GET("/secrets", session.MustPush, server.GetSecrets)

View file

@ -77,7 +77,8 @@ func GetBuildLogs(c *gin.Context) {
// parse the build number and job sequence number from // parse the build number and job sequence number from
// the repquest parameter. // the repquest parameter.
num, _ := strconv.Atoi(c.Params.ByName("number")) num, _ := strconv.Atoi(c.Params.ByName("number"))
seq, _ := strconv.Atoi(c.Params.ByName("job")) ppid, _ := strconv.Atoi(c.Params.ByName("ppid"))
name := c.Params.ByName("proc")
build, err := store.GetBuildNumber(c, repo, num) build, err := store.GetBuildNumber(c, repo, num)
if err != nil { if err != nil {
@ -85,13 +86,13 @@ func GetBuildLogs(c *gin.Context) {
return return
} }
proc, err := store.FromContext(c).ProcFind(build, seq) proc, err := store.FromContext(c).ProcChild(build, ppid, name)
if err != nil { if err != nil {
c.AbortWithError(404, err) c.AbortWithError(404, err)
return return
} }
rc, err := store.FromContext(c).FileRead(proc, "logs.json") rc, err := store.FromContext(c).LogFind(proc)
if err != nil { if err != nil {
c.AbortWithError(404, err) c.AbortWithError(404, err)
return return

View file

@ -111,15 +111,21 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error {
return err return err
} }
proc, err := s.store.ProcLoad(procID) pproc, err := s.store.ProcLoad(procID)
if err != nil { if err != nil {
log.Printf("error: rpc.update: cannot find proc with id %d: %s", procID, err) log.Printf("error: rpc.update: cannot find pproc with id %d: %s", procID, err)
return err return err
} }
build, err := s.store.GetBuild(proc.BuildID) build, err := s.store.GetBuild(pproc.BuildID)
if err != nil { if err != nil {
log.Printf("error: cannot find build with id %d: %s", proc.BuildID, err) log.Printf("error: cannot find build with id %d: %s", pproc.BuildID, err)
return err
}
proc, err := s.store.ProcChild(build, pproc.PID, state.Proc)
if err != nil {
log.Printf("error: cannot find proc with name %s: %s", state.Proc, err)
return err return err
} }
@ -133,6 +139,10 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error {
proc.Stopped = state.Finished proc.Stopped = state.Finished
proc.ExitCode = state.ExitCode proc.ExitCode = state.ExitCode
proc.Error = state.Error proc.Error = state.Error
proc.State = model.StatusSuccess
if state.ExitCode != 0 || state.Error != "" {
proc.State = model.StatusFailure
}
} else { } else {
proc.Started = state.Started proc.Started = state.Started
proc.State = model.StatusRunning proc.State = model.StatusRunning
@ -165,12 +175,31 @@ func (s *RPC) Upload(c context.Context, id string, file *rpc.File) error {
return err return err
} }
proc, err := s.store.ProcLoad(procID) pproc, err := s.store.ProcLoad(procID)
if err != nil { if err != nil {
log.Printf("error: cannot find proc with id %d: %s", procID, err) log.Printf("error: cannot find parent proc with id %d: %s", procID, err)
return err return err
} }
build, err := s.store.GetBuild(pproc.BuildID)
if err != nil {
log.Printf("error: cannot find build with id %d: %s", pproc.BuildID, err)
return err
}
proc, err := s.store.ProcChild(build, pproc.PID, file.Proc)
if err != nil {
log.Printf("error: cannot find child proc with name %s: %s", file.Proc, err)
return err
}
if file.Mime == "application/json+logs" {
return s.store.LogSave(
proc,
bytes.NewBuffer(file.Data),
)
}
return s.store.FileCreate(&model.File{ return s.store.FileCreate(&model.File{
BuildID: proc.BuildID, BuildID: proc.BuildID,
ProcID: proc.ID, ProcID: proc.ID,
@ -261,19 +290,13 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
return err return err
} }
if build.Status == model.StatusPending {
build.Status = model.StatusRunning
build.Started = state.Started
if err := s.store.UpdateBuild(build); err != nil {
log.Printf("error: done: cannot update build_id %d state: %s", build.ID, err)
}
}
proc.Started = state.Started
proc.State = model.StatusRunning
proc.Stopped = state.Finished proc.Stopped = state.Finished
proc.Error = state.Error proc.Error = state.Error
proc.ExitCode = state.ExitCode proc.ExitCode = state.ExitCode
proc.State = model.StatusSuccess
if proc.ExitCode != 0 || proc.Error != "" {
proc.State = model.StatusFailure
}
if err := s.store.ProcUpdate(proc); err != nil { if err := s.store.ProcUpdate(proc); err != nil {
log.Printf("error: done: cannot update proc_id %d state: %s", procID, err) log.Printf("error: done: cannot update proc_id %d state: %s", procID, err)
} }
@ -287,7 +310,7 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
// TODO handle this error // TODO handle this error
procs, _ := s.store.ProcList(build) procs, _ := s.store.ProcList(build)
for _, p := range procs { for _, p := range procs {
if !proc.Running() && p.PPID == proc.PID { if p.Running() && p.PPID == proc.PID {
p.State = model.StatusSkipped p.State = model.StatusSkipped
if p.Started != 0 { if p.Started != 0 {
p.State = model.StatusKilled p.State = model.StatusKilled
@ -297,12 +320,11 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
log.Printf("error: done: cannot update proc_id %d child state: %s", p.ID, err) log.Printf("error: done: cannot update proc_id %d child state: %s", p.ID, err)
} }
} }
if !proc.Running() && p.PPID == 0 { if !p.Running() && p.PPID == 0 {
done = true done = true
if p.Failing() { if p.Failing() {
status = model.StatusFailure status = model.StatusFailure
} }
continue
} }
} }
if done { if done {

View file

@ -1,37 +1,42 @@
package datastore package datastore
// import (
// import ( "bytes"
// "bytes" "io"
// "io" "io/ioutil"
// "io/ioutil"
// "github.com/drone/drone/model"
// "github.com/drone/drone/model" "github.com/russross/meddler"
// "github.com/russross/meddler" )
// )
// func (db *datastore) LogFind(proc *model.Proc) (io.ReadCloser, error) {
// func (db *datastore) ReadLog(job *model.Job) (io.ReadCloser, error) { var log = new(logData)
// var log = new(model.Log) var err = meddler.QueryRow(db, log, rebind(logQuery), proc.ID)
// var err = meddler.QueryRow(db, log, rebind(logQuery), job.ID) var buf = bytes.NewBuffer(log.Data)
// var buf = bytes.NewBuffer(log.Data) return ioutil.NopCloser(buf), err
// return ioutil.NopCloser(buf), err }
// }
// func (db *datastore) LogSave(proc *model.Proc, r io.Reader) error {
// func (db *datastore) WriteLog(job *model.Job, r io.Reader) error { var log = new(logData)
// var log = new(model.Log) var err = meddler.QueryRow(db, log, rebind(logQuery), proc.ID)
// var err = meddler.QueryRow(db, log, rebind(logQuery), job.ID) if err != nil {
// if err != nil { log = &logData{ProcID: proc.ID}
// log = &model.Log{JobID: job.ID} }
// } log.Data, _ = ioutil.ReadAll(r)
// log.Data, _ = ioutil.ReadAll(r) return meddler.Save(db, logTable, log)
// return meddler.Save(db, logTable, log) }
// }
// type logData struct {
// const logTable = "logs" ID int64 `meddler:"log_id,pk"`
// ProcID int64 `meddler:"log_job_id"`
// const logQuery = ` Data []byte `meddler:"log_data"`
// SELECT * }
// FROM logs
// WHERE log_job_id=? const logTable = "logs"
// LIMIT 1
// ` const logQuery = `
SELECT *
FROM logs
WHERE log_job_id=?
LIMIT 1
`

View file

@ -1,61 +1,60 @@
package datastore package datastore
// import (
// import ( "bytes"
// "bytes" "io/ioutil"
// "io/ioutil" "testing"
// "testing"
// "github.com/drone/drone/model"
// "github.com/drone/drone/model" "github.com/franela/goblin"
// "github.com/franela/goblin" )
// )
// func TestLogs(t *testing.T) {
// func TestLogs(t *testing.T) { db := openTest()
// db := openTest() defer db.Close()
// defer db.Close()
// s := From(db)
// s := From(db) g := goblin.Goblin(t)
// g := goblin.Goblin(t) g.Describe("Logs", func() {
// g.Describe("Logs", func() {
// // before each test be sure to purge the package
// // before each test be sure to purge the package // table data from the database.
// // table data from the database. g.BeforeEach(func() {
// g.BeforeEach(func() { db.Exec("DELETE FROM logs")
// db.Exec("DELETE FROM logs") })
// })
// g.It("Should create a log", func() {
// g.It("Should create a log", func() { proc := model.Proc{
// job := model.Job{ ID: 1,
// ID: 1, }
// } buf := bytes.NewBufferString("echo hi")
// buf := bytes.NewBufferString("echo hi") err := s.LogSave(&proc, buf)
// err := s.WriteLog(&job, buf) g.Assert(err == nil).IsTrue()
// g.Assert(err == nil).IsTrue()
// rc, err := s.LogFind(&proc)
// rc, err := s.ReadLog(&job) g.Assert(err == nil).IsTrue()
// g.Assert(err == nil).IsTrue() defer rc.Close()
// defer rc.Close() out, _ := ioutil.ReadAll(rc)
// out, _ := ioutil.ReadAll(rc) g.Assert(string(out)).Equal("echo hi")
// g.Assert(string(out)).Equal("echo hi") })
// })
// g.It("Should update a log", func() {
// g.It("Should update a log", func() { proc := model.Proc{
// job := model.Job{ ID: 1,
// ID: 1, }
// } buf1 := bytes.NewBufferString("echo hi")
// buf1 := bytes.NewBufferString("echo hi") buf2 := bytes.NewBufferString("echo allo?")
// buf2 := bytes.NewBufferString("echo allo?") err1 := s.LogSave(&proc, buf1)
// err1 := s.WriteLog(&job, buf1) err2 := s.LogSave(&proc, buf2)
// err2 := s.WriteLog(&job, buf2) g.Assert(err1 == nil).IsTrue()
// g.Assert(err1 == nil).IsTrue() g.Assert(err2 == nil).IsTrue()
// g.Assert(err2 == nil).IsTrue()
// rc, err := s.LogFind(&proc)
// rc, err := s.ReadLog(&job) g.Assert(err == nil).IsTrue()
// g.Assert(err == nil).IsTrue() defer rc.Close()
// defer rc.Close() out, _ := ioutil.ReadAll(rc)
// out, _ := ioutil.ReadAll(rc) g.Assert(string(out)).Equal("echo allo?")
// g.Assert(string(out)).Equal("echo allo?") })
// })
// })
// }) }
// }

View file

@ -152,6 +152,9 @@ type Store interface {
ProcCreate([]*model.Proc) error ProcCreate([]*model.Proc) error
ProcUpdate(*model.Proc) error ProcUpdate(*model.Proc) error
LogFind(*model.Proc) (io.ReadCloser, error)
LogSave(*model.Proc, io.Reader) error
FileList(*model.Build) ([]*model.File, error) FileList(*model.Build) ([]*model.File, error)
FileFind(*model.Proc, string) (*model.File, error) FileFind(*model.Proc, string) (*model.File, error)
FileRead(*model.Proc, string) (io.ReadCloser, error) FileRead(*model.Proc, string) (io.ReadCloser, error)