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,
|
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 {
|
if statusChan != nil {
|
||||||
statusChan <- &s
|
statusChan <- &s
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/tonistiigi/buildkit_poc/client"
|
"github.com/tonistiigi/buildkit_poc/client"
|
||||||
"github.com/tonistiigi/buildkit_poc/util/progress/progressui"
|
"github.com/tonistiigi/buildkit_poc/util/progress/progressui"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
@ -22,7 +25,17 @@ func build(clicontext *cli.Context) error {
|
||||||
return err
|
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)
|
ch := make(chan *client.SolveStatus)
|
||||||
|
displayCh := make(chan *client.SolveStatus)
|
||||||
eg, ctx := errgroup.WithContext(context.TODO()) // TODO: define appContext
|
eg, ctx := errgroup.WithContext(context.TODO()) // TODO: define appContext
|
||||||
|
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
|
@ -30,16 +43,18 @@ func build(clicontext *cli.Context) error {
|
||||||
})
|
})
|
||||||
|
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
return progressui.DisplaySolveStatus(ctx, ch)
|
defer close(displayCh)
|
||||||
// for s := range ch {
|
for s := range ch {
|
||||||
// for _, v := range s.Vertexes {
|
if err := traceEnc.Encode(s); err != nil {
|
||||||
// log.Print(spew.Sdump(v))
|
logrus.Error(err)
|
||||||
// }
|
}
|
||||||
// for _, v := range s.Statuses {
|
displayCh <- s
|
||||||
// log.Print(spew.Sdump(v))
|
}
|
||||||
// }
|
return nil
|
||||||
// }
|
})
|
||||||
// return nil
|
|
||||||
|
eg.Go(func() error {
|
||||||
|
return progressui.DisplaySolveStatus(ctx, displayCh)
|
||||||
})
|
})
|
||||||
|
|
||||||
return eg.Wait()
|
return eg.Wait()
|
||||||
|
|
|
@ -111,6 +111,14 @@ func (c *Controller) Status(req *controlapi.StatusRequest, stream controlapi.Con
|
||||||
Completed: v.Completed,
|
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 {
|
if err := stream.SendMsg(&sr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,15 @@ func (j *job) pipe(ctx context.Context, ch chan *client.SolveStatus) error {
|
||||||
Completed: v.Completed,
|
Completed: v.Completed,
|
||||||
}
|
}
|
||||||
ss.Statuses = append(ss.Statuses, vs)
|
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 {
|
select {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package solver
|
package solver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -10,6 +11,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tonistiigi/buildkit_poc/cache"
|
"github.com/tonistiigi/buildkit_poc/cache"
|
||||||
"github.com/tonistiigi/buildkit_poc/client"
|
"github.com/tonistiigi/buildkit_poc/client"
|
||||||
|
"github.com/tonistiigi/buildkit_poc/identity"
|
||||||
"github.com/tonistiigi/buildkit_poc/solver/pb"
|
"github.com/tonistiigi/buildkit_poc/solver/pb"
|
||||||
"github.com/tonistiigi/buildkit_poc/source"
|
"github.com/tonistiigi/buildkit_poc/source"
|
||||||
"github.com/tonistiigi/buildkit_poc/util/progress"
|
"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,
|
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)
|
return errors.Wrapf(err, "worker failed running %v", meta.Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,3 +260,36 @@ func (g *opVertex) name() string {
|
||||||
return "unknown"
|
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