mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-04-26 21:44:44 +00:00
use separate log table
This commit is contained in:
parent
ec88661d9e
commit
0daee76aa8
7 changed files with 147 additions and 124 deletions
|
@ -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"`
|
|
||||||
// }
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
`
|
||||||
|
|
|
@ -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?")
|
})
|
||||||
// })
|
|
||||||
//
|
})
|
||||||
// })
|
}
|
||||||
// }
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue