mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-24 10:07:21 +02:00
use separate log table
This commit is contained in:
parent
ec88661d9e
commit
0daee76aa8
@ -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("/builds", server.GetBuilds)
|
||||
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.GET("/secrets", session.MustPush, server.GetSecrets)
|
||||
|
@ -77,7 +77,8 @@ func GetBuildLogs(c *gin.Context) {
|
||||
// parse the build number and job sequence number from
|
||||
// the repquest parameter.
|
||||
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)
|
||||
if err != nil {
|
||||
@ -85,13 +86,13 @@ func GetBuildLogs(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
proc, err := store.FromContext(c).ProcFind(build, seq)
|
||||
proc, err := store.FromContext(c).ProcChild(build, ppid, name)
|
||||
if err != nil {
|
||||
c.AbortWithError(404, err)
|
||||
return
|
||||
}
|
||||
|
||||
rc, err := store.FromContext(c).FileRead(proc, "logs.json")
|
||||
rc, err := store.FromContext(c).LogFind(proc)
|
||||
if err != nil {
|
||||
c.AbortWithError(404, err)
|
||||
return
|
||||
|
@ -111,15 +111,21 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error {
|
||||
return err
|
||||
}
|
||||
|
||||
proc, err := s.store.ProcLoad(procID)
|
||||
pproc, err := s.store.ProcLoad(procID)
|
||||
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
|
||||
}
|
||||
|
||||
build, err := s.store.GetBuild(proc.BuildID)
|
||||
build, err := s.store.GetBuild(pproc.BuildID)
|
||||
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
|
||||
}
|
||||
|
||||
@ -133,6 +139,10 @@ func (s *RPC) Update(c context.Context, id string, state rpc.State) error {
|
||||
proc.Stopped = state.Finished
|
||||
proc.ExitCode = state.ExitCode
|
||||
proc.Error = state.Error
|
||||
proc.State = model.StatusSuccess
|
||||
if state.ExitCode != 0 || state.Error != "" {
|
||||
proc.State = model.StatusFailure
|
||||
}
|
||||
} else {
|
||||
proc.Started = state.Started
|
||||
proc.State = model.StatusRunning
|
||||
@ -165,12 +175,31 @@ func (s *RPC) Upload(c context.Context, id string, file *rpc.File) error {
|
||||
return err
|
||||
}
|
||||
|
||||
proc, err := s.store.ProcLoad(procID)
|
||||
pproc, err := s.store.ProcLoad(procID)
|
||||
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
|
||||
}
|
||||
|
||||
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{
|
||||
BuildID: proc.BuildID,
|
||||
ProcID: proc.ID,
|
||||
@ -261,19 +290,13 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
||||
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.Error = state.Error
|
||||
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 {
|
||||
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
|
||||
procs, _ := s.store.ProcList(build)
|
||||
for _, p := range procs {
|
||||
if !proc.Running() && p.PPID == proc.PID {
|
||||
if p.Running() && p.PPID == proc.PID {
|
||||
p.State = model.StatusSkipped
|
||||
if p.Started != 0 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
if !proc.Running() && p.PPID == 0 {
|
||||
if !p.Running() && p.PPID == 0 {
|
||||
done = true
|
||||
if p.Failing() {
|
||||
status = model.StatusFailure
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
if done {
|
||||
|
@ -1,37 +1,42 @@
|
||||
package datastore
|
||||
|
||||
//
|
||||
// import (
|
||||
// "bytes"
|
||||
// "io"
|
||||
// "io/ioutil"
|
||||
//
|
||||
// "github.com/drone/drone/model"
|
||||
// "github.com/russross/meddler"
|
||||
// )
|
||||
//
|
||||
// func (db *datastore) ReadLog(job *model.Job) (io.ReadCloser, error) {
|
||||
// var log = new(model.Log)
|
||||
// var err = meddler.QueryRow(db, log, rebind(logQuery), job.ID)
|
||||
// var buf = bytes.NewBuffer(log.Data)
|
||||
// return ioutil.NopCloser(buf), err
|
||||
// }
|
||||
//
|
||||
// func (db *datastore) WriteLog(job *model.Job, r io.Reader) error {
|
||||
// var log = new(model.Log)
|
||||
// var err = meddler.QueryRow(db, log, rebind(logQuery), job.ID)
|
||||
// if err != nil {
|
||||
// log = &model.Log{JobID: job.ID}
|
||||
// }
|
||||
// log.Data, _ = ioutil.ReadAll(r)
|
||||
// return meddler.Save(db, logTable, log)
|
||||
// }
|
||||
//
|
||||
// const logTable = "logs"
|
||||
//
|
||||
// const logQuery = `
|
||||
// SELECT *
|
||||
// FROM logs
|
||||
// WHERE log_job_id=?
|
||||
// LIMIT 1
|
||||
// `
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
func (db *datastore) LogFind(proc *model.Proc) (io.ReadCloser, error) {
|
||||
var log = new(logData)
|
||||
var err = meddler.QueryRow(db, log, rebind(logQuery), proc.ID)
|
||||
var buf = bytes.NewBuffer(log.Data)
|
||||
return ioutil.NopCloser(buf), err
|
||||
}
|
||||
|
||||
func (db *datastore) LogSave(proc *model.Proc, r io.Reader) error {
|
||||
var log = new(logData)
|
||||
var err = meddler.QueryRow(db, log, rebind(logQuery), proc.ID)
|
||||
if err != nil {
|
||||
log = &logData{ProcID: proc.ID}
|
||||
}
|
||||
log.Data, _ = ioutil.ReadAll(r)
|
||||
return meddler.Save(db, logTable, log)
|
||||
}
|
||||
|
||||
type logData struct {
|
||||
ID int64 `meddler:"log_id,pk"`
|
||||
ProcID int64 `meddler:"log_job_id"`
|
||||
Data []byte `meddler:"log_data"`
|
||||
}
|
||||
|
||||
const logTable = "logs"
|
||||
|
||||
const logQuery = `
|
||||
SELECT *
|
||||
FROM logs
|
||||
WHERE log_job_id=?
|
||||
LIMIT 1
|
||||
`
|
||||
|
@ -1,61 +1,60 @@
|
||||
package datastore
|
||||
|
||||
//
|
||||
// import (
|
||||
// "bytes"
|
||||
// "io/ioutil"
|
||||
// "testing"
|
||||
//
|
||||
// "github.com/drone/drone/model"
|
||||
// "github.com/franela/goblin"
|
||||
// )
|
||||
//
|
||||
// func TestLogs(t *testing.T) {
|
||||
// db := openTest()
|
||||
// defer db.Close()
|
||||
//
|
||||
// s := From(db)
|
||||
// g := goblin.Goblin(t)
|
||||
// g.Describe("Logs", func() {
|
||||
//
|
||||
// // before each test be sure to purge the package
|
||||
// // table data from the database.
|
||||
// g.BeforeEach(func() {
|
||||
// db.Exec("DELETE FROM logs")
|
||||
// })
|
||||
//
|
||||
// g.It("Should create a log", func() {
|
||||
// job := model.Job{
|
||||
// ID: 1,
|
||||
// }
|
||||
// buf := bytes.NewBufferString("echo hi")
|
||||
// err := s.WriteLog(&job, buf)
|
||||
// g.Assert(err == nil).IsTrue()
|
||||
//
|
||||
// rc, err := s.ReadLog(&job)
|
||||
// g.Assert(err == nil).IsTrue()
|
||||
// defer rc.Close()
|
||||
// out, _ := ioutil.ReadAll(rc)
|
||||
// g.Assert(string(out)).Equal("echo hi")
|
||||
// })
|
||||
//
|
||||
// g.It("Should update a log", func() {
|
||||
// job := model.Job{
|
||||
// ID: 1,
|
||||
// }
|
||||
// buf1 := bytes.NewBufferString("echo hi")
|
||||
// buf2 := bytes.NewBufferString("echo allo?")
|
||||
// err1 := s.WriteLog(&job, buf1)
|
||||
// err2 := s.WriteLog(&job, buf2)
|
||||
// g.Assert(err1 == nil).IsTrue()
|
||||
// g.Assert(err2 == nil).IsTrue()
|
||||
//
|
||||
// rc, err := s.ReadLog(&job)
|
||||
// g.Assert(err == nil).IsTrue()
|
||||
// defer rc.Close()
|
||||
// out, _ := ioutil.ReadAll(rc)
|
||||
// g.Assert(string(out)).Equal("echo allo?")
|
||||
// })
|
||||
//
|
||||
// })
|
||||
// }
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func TestLogs(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Logs", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM logs")
|
||||
})
|
||||
|
||||
g.It("Should create a log", func() {
|
||||
proc := model.Proc{
|
||||
ID: 1,
|
||||
}
|
||||
buf := bytes.NewBufferString("echo hi")
|
||||
err := s.LogSave(&proc, buf)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
rc, err := s.LogFind(&proc)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
defer rc.Close()
|
||||
out, _ := ioutil.ReadAll(rc)
|
||||
g.Assert(string(out)).Equal("echo hi")
|
||||
})
|
||||
|
||||
g.It("Should update a log", func() {
|
||||
proc := model.Proc{
|
||||
ID: 1,
|
||||
}
|
||||
buf1 := bytes.NewBufferString("echo hi")
|
||||
buf2 := bytes.NewBufferString("echo allo?")
|
||||
err1 := s.LogSave(&proc, buf1)
|
||||
err2 := s.LogSave(&proc, buf2)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
|
||||
rc, err := s.LogFind(&proc)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
defer rc.Close()
|
||||
out, _ := ioutil.ReadAll(rc)
|
||||
g.Assert(string(out)).Equal("echo allo?")
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
@ -152,6 +152,9 @@ type Store interface {
|
||||
ProcCreate([]*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)
|
||||
FileFind(*model.Proc, string) (*model.File, error)
|
||||
FileRead(*model.Proc, string) (io.ReadCloser, error)
|
||||
|
Loading…
Reference in New Issue
Block a user