client: save logs to trace file
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-18.09
parent
0a7a2c1da3
commit
3d3190573c
|
@ -73,6 +73,14 @@ func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveS
|
|||
Completed: v.Completed,
|
||||
})
|
||||
}
|
||||
for _, v := range resp.Logs {
|
||||
s.Logs = append(s.Logs, &VertexLog{
|
||||
Vertex: v.Vertex,
|
||||
Stream: int(v.Stream),
|
||||
Data: v.Msg,
|
||||
Timestamp: v.Timestamp,
|
||||
})
|
||||
}
|
||||
if statusChan != nil {
|
||||
statusChan <- &s
|
||||
}
|
||||
|
|
|
@ -2,8 +2,11 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/tonistiigi/buildkit_poc/client"
|
||||
"github.com/tonistiigi/buildkit_poc/util/progress/progressui"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -22,7 +25,17 @@ func build(clicontext *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
traceFile, err := ioutil.TempFile("", "buildctl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer traceFile.Close()
|
||||
traceEnc := json.NewEncoder(traceFile)
|
||||
|
||||
logrus.Infof("tracing logs to %s", traceFile.Name())
|
||||
|
||||
ch := make(chan *client.SolveStatus)
|
||||
displayCh := make(chan *client.SolveStatus)
|
||||
eg, ctx := errgroup.WithContext(context.TODO()) // TODO: define appContext
|
||||
|
||||
eg.Go(func() error {
|
||||
|
@ -30,16 +43,18 @@ func build(clicontext *cli.Context) error {
|
|||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
return progressui.DisplaySolveStatus(ctx, ch)
|
||||
// for s := range ch {
|
||||
// for _, v := range s.Vertexes {
|
||||
// log.Print(spew.Sdump(v))
|
||||
// }
|
||||
// for _, v := range s.Statuses {
|
||||
// log.Print(spew.Sdump(v))
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
defer close(displayCh)
|
||||
for s := range ch {
|
||||
if err := traceEnc.Encode(s); err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
displayCh <- s
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
return progressui.DisplaySolveStatus(ctx, displayCh)
|
||||
})
|
||||
|
||||
return eg.Wait()
|
||||
|
|
|
@ -111,6 +111,14 @@ func (c *Controller) Status(req *controlapi.StatusRequest, stream controlapi.Con
|
|||
Completed: v.Completed,
|
||||
})
|
||||
}
|
||||
for _, v := range ss.Logs {
|
||||
sr.Logs = append(sr.Logs, &controlapi.VertexLog{
|
||||
Vertex: v.Vertex,
|
||||
Stream: int64(v.Stream),
|
||||
Msg: v.Data,
|
||||
Timestamp: v.Timestamp,
|
||||
})
|
||||
}
|
||||
if err := stream.SendMsg(&sr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -122,6 +122,15 @@ func (j *job) pipe(ctx context.Context, ch chan *client.SolveStatus) error {
|
|||
Completed: v.Completed,
|
||||
}
|
||||
ss.Statuses = append(ss.Statuses, vs)
|
||||
case client.VertexLog:
|
||||
vtx, ok := p.Meta("vertex")
|
||||
if !ok {
|
||||
logrus.Warnf("progress %s status without vertex info", p.ID)
|
||||
continue
|
||||
}
|
||||
v.Vertex = vtx.(digest.Digest)
|
||||
v.Timestamp = p.Timestamp
|
||||
ss.Logs = append(ss.Logs, &v)
|
||||
}
|
||||
}
|
||||
select {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package solver
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -10,6 +11,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"github.com/tonistiigi/buildkit_poc/cache"
|
||||
"github.com/tonistiigi/buildkit_poc/client"
|
||||
"github.com/tonistiigi/buildkit_poc/identity"
|
||||
"github.com/tonistiigi/buildkit_poc/solver/pb"
|
||||
"github.com/tonistiigi/buildkit_poc/source"
|
||||
"github.com/tonistiigi/buildkit_poc/util/progress"
|
||||
|
@ -211,7 +213,12 @@ func (g *opVertex) runExecOp(ctx context.Context, cm cache.Manager, w worker.Wor
|
|||
Cwd: op.Exec.Meta.Cwd,
|
||||
}
|
||||
|
||||
if err := w.Exec(ctx, meta, mounts, os.Stderr, os.Stderr); err != nil {
|
||||
stdout := newStreamWriter(ctx, 1)
|
||||
defer stdout.Close()
|
||||
stderr := newStreamWriter(ctx, 2)
|
||||
defer stderr.Close()
|
||||
|
||||
if err := w.Exec(ctx, meta, mounts, stdout, stderr); err != nil {
|
||||
return errors.Wrapf(err, "worker failed running %v", meta.Args)
|
||||
}
|
||||
|
||||
|
@ -253,3 +260,36 @@ func (g *opVertex) name() string {
|
|||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func newStreamWriter(ctx context.Context, stream int) io.WriteCloser {
|
||||
pw, _, _ := progress.FromContext(ctx)
|
||||
return &streamWriter{
|
||||
pw: pw,
|
||||
stream: stream,
|
||||
}
|
||||
}
|
||||
|
||||
type streamWriter struct {
|
||||
pw progress.Writer
|
||||
stream int
|
||||
}
|
||||
|
||||
func (sw *streamWriter) Write(dt []byte) (int, error) {
|
||||
sw.pw.Write(identity.NewID(), client.VertexLog{
|
||||
Stream: sw.stream,
|
||||
Data: append([]byte{}, dt...),
|
||||
})
|
||||
// TODO: remove debug
|
||||
switch sw.stream {
|
||||
case 1:
|
||||
return os.Stdout.Write(dt)
|
||||
case 2:
|
||||
return os.Stderr.Write(dt)
|
||||
default:
|
||||
return 0, errors.Errorf("invalid stream %d", sw.stream)
|
||||
}
|
||||
}
|
||||
|
||||
func (sw *streamWriter) Close() error {
|
||||
return sw.pw.Close()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue