build: fix output handling with buildkit (quiet option, redirects)

With this patch the following become true even with buildkit enabled:
1. `docker build -q .` only outputs the created image's sha256 ID.
2. `docker build -q .` outputs as if no `-q` was specified, if error occurred
3. `docker build . &> out` outputs JSON (instead of TTY characters)

Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
Tibor Vass 2018-05-24 22:02:13 +00:00
parent 82f0e1e5d8
commit 640cbb8d2f
1 changed files with 47 additions and 10 deletions

View File

@ -150,7 +150,7 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
})
}
eg.Go(func() error {
eg.Go(func() (finalErr error) {
defer func() { // make sure the Status ends cleanly on build errors
s.Close()
}()
@ -209,16 +209,53 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
})
t := newTracer()
var auxCb func(jsonmessage.JSONMessage)
if c, err := console.ConsoleFromFile(os.Stderr); err == nil {
// not using shared context to not disrupt display but let is finish reporting errors
auxCb = t.write
eg.Go(func() error {
return progressui.DisplaySolveStatus(context.TODO(), c, t.displayCh)
})
defer close(t.displayCh)
ssArr := []*client.SolveStatus{}
displayStatus := func(displayCh chan *client.SolveStatus) {
if c, err := console.ConsoleFromFile(os.Stderr); err == nil {
// not using shared context to not disrupt display but let is finish reporting errors
eg.Go(func() error {
return progressui.DisplaySolveStatus(context.TODO(), c, displayCh)
})
} else {
// read from t.displayCh and send json to Stderr
eg.Go(func() error {
enc := json.NewEncoder(os.Stderr)
for ss := range displayCh {
if err := enc.Encode(ss); err != nil {
return err
}
}
return nil
})
}
}
err = jsonmessage.DisplayJSONMessagesStream(response.Body, os.Stdout, dockerCli.Out().FD(), dockerCli.Out().IsTerminal(), auxCb)
if options.quiet {
eg.Go(func() error {
// TODO: make sure t.displayCh closes
for ss := range t.displayCh {
ssArr = append(ssArr, ss)
}
<-done
// TODO: verify that finalErr is indeed set when error occurs
if finalErr != nil {
displayCh := make(chan *client.SolveStatus)
go func() {
for _, ss := range ssArr {
displayCh <- ss
}
close(displayCh)
}()
displayStatus(displayCh)
}
return nil
})
} else {
displayStatus(t.displayCh)
}
defer close(t.displayCh)
err = jsonmessage.DisplayJSONMessagesStream(response.Body, os.Stdout, dockerCli.Out().FD(), dockerCli.Out().IsTerminal(), t.write)
if err != nil {
if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1