mirror of https://github.com/docker/buildx.git
build: sublogger to show docker load progress output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
parent
42a0f3d504
commit
03bedfb3c3
|
@ -552,7 +552,9 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
|||
return nil, nil, err
|
||||
}
|
||||
defers = append(defers, cancel)
|
||||
opt.Exports[i].Output = wrapWriteCloser(w)
|
||||
opt.Exports[i].Output = func(_ map[string]string) (io.WriteCloser, error) {
|
||||
return w, nil
|
||||
}
|
||||
}
|
||||
} else if !nodeDriver.Features(ctx)[driver.DockerExporter] {
|
||||
return nil, nil, notSupported(nodeDriver, driver.DockerExporter)
|
||||
|
@ -1607,12 +1609,6 @@ func handleLowercaseDockerfile(dir, p string) string {
|
|||
return p
|
||||
}
|
||||
|
||||
func wrapWriteCloser(wc io.WriteCloser) func(map[string]string) (io.WriteCloser, error) {
|
||||
return func(map[string]string) (io.WriteCloser, error) {
|
||||
return wc, nil
|
||||
}
|
||||
}
|
||||
|
||||
var nodeIdentifierMu sync.Mutex
|
||||
|
||||
func tryNodeIdentifier(configDir string) (out string) {
|
||||
|
|
|
@ -60,8 +60,10 @@ func (c *Client) LoadImage(ctx context.Context, name string, status progress.Wri
|
|||
return
|
||||
}
|
||||
|
||||
prog := progress.WithPrefix(status, "", false)
|
||||
if err := fromReader(prog, "importing to docker", resp.Body); err != nil {
|
||||
status = progress.ResetTime(status)
|
||||
if err := progress.Wrap("importing to docker", status.Write, func(l progress.SubLogger) error {
|
||||
return fromReader(l, resp.Body)
|
||||
}); err != nil {
|
||||
handleErr(err)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,47 +1,76 @@
|
|||
package dockerutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/docker/buildx/util/progress"
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
func fromReader(w progress.Writer, name string, rc io.ReadCloser) error {
|
||||
dgst := digest.FromBytes([]byte(identity.NewID()))
|
||||
tm := time.Now()
|
||||
const minTimeDelta = 2 * time.Second
|
||||
|
||||
vtx := client.Vertex{
|
||||
Digest: dgst,
|
||||
Name: name,
|
||||
Started: &tm,
|
||||
}
|
||||
func fromReader(l progress.SubLogger, rc io.ReadCloser) error {
|
||||
started := map[string]client.VertexStatus{}
|
||||
|
||||
w.Write(&client.SolveStatus{
|
||||
Vertexes: []*client.Vertex{&vtx},
|
||||
})
|
||||
|
||||
err := jsonmessage.DisplayJSONMessagesToStream(rc, streams.NewOut(io.Discard), nil)
|
||||
if err != nil {
|
||||
if jerr, ok := err.(*jsonmessage.JSONError); ok {
|
||||
err = errors.New(jerr.Message)
|
||||
defer func() {
|
||||
for _, st := range started {
|
||||
st := st
|
||||
if st.Completed == nil {
|
||||
now := time.Now()
|
||||
st.Completed = &now
|
||||
l.SetStatus(&st)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
dec := json.NewDecoder(rc)
|
||||
var parsedErr error
|
||||
var jm jsonmessage.JSONMessage
|
||||
for {
|
||||
if err := dec.Decode(&jm); err != nil {
|
||||
if parsedErr != nil {
|
||||
return parsedErr
|
||||
}
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
if jm.Error != nil {
|
||||
parsedErr = jm.Error
|
||||
}
|
||||
if jm.ID == "" || jm.Progress == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
id := "loading layer " + jm.ID
|
||||
st, ok := started[id]
|
||||
if !ok {
|
||||
now := time.Now()
|
||||
st = client.VertexStatus{
|
||||
ID: id,
|
||||
Started: &now,
|
||||
}
|
||||
}
|
||||
timeDelta := time.Now().Sub(st.Timestamp)
|
||||
if timeDelta < minTimeDelta {
|
||||
continue
|
||||
}
|
||||
st.Timestamp = time.Now()
|
||||
if jm.Status == "Loading layer" {
|
||||
st.Current = jm.Progress.Current
|
||||
st.Total = jm.Progress.Total
|
||||
}
|
||||
if jm.Error != nil {
|
||||
now := time.Now()
|
||||
st.Completed = &now
|
||||
}
|
||||
started[id] = st
|
||||
l.SetStatus(&st)
|
||||
}
|
||||
|
||||
tm2 := time.Now()
|
||||
vtx2 := vtx
|
||||
vtx2.Completed = &tm2
|
||||
if err != nil {
|
||||
vtx2.Error = err.Error()
|
||||
}
|
||||
w.Write(&client.SolveStatus{
|
||||
Vertexes: []*client.Vertex{&vtx2},
|
||||
})
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue