mirror of https://github.com/docker/cli.git
Merge pull request #1185 from tiborvass/18.06-cp
[18.06] build: --iidfile support with buildkit
This commit is contained in:
commit
9fbab758a9
|
@ -1,12 +1,15 @@
|
||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -43,6 +46,13 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
|
||||||
return errors.Errorf("buildkit not supported by daemon")
|
return errors.Errorf("buildkit not supported by daemon")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.imageIDFile != "" {
|
||||||
|
// Avoid leaving a stale file if we eventually fail
|
||||||
|
if err := os.Remove(options.imageIDFile); err != nil && !os.IsNotExist(err) {
|
||||||
|
return errors.Wrap(err, "removing image ID file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
remote string
|
remote string
|
||||||
body io.Reader
|
body io.Reader
|
||||||
|
@ -159,6 +169,7 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
|
||||||
return eg.Wait()
|
return eg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint: gocyclo
|
||||||
func doBuild(ctx context.Context, eg *errgroup.Group, dockerCli command.Cli, options buildOptions, buildOptions types.ImageBuildOptions) (finalErr error) {
|
func doBuild(ctx context.Context, eg *errgroup.Group, dockerCli command.Cli, options buildOptions, buildOptions types.ImageBuildOptions) (finalErr error) {
|
||||||
response, err := dockerCli.Client().ImageBuild(context.Background(), nil, buildOptions)
|
response, err := dockerCli.Client().ImageBuild(context.Background(), nil, buildOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -180,9 +191,8 @@ func doBuild(ctx context.Context, eg *errgroup.Group, dockerCli command.Cli, opt
|
||||||
t := newTracer()
|
t := newTracer()
|
||||||
ssArr := []*client.SolveStatus{}
|
ssArr := []*client.SolveStatus{}
|
||||||
|
|
||||||
displayStatus := func(displayCh chan *client.SolveStatus) {
|
displayStatus := func(out *os.File, displayCh chan *client.SolveStatus) {
|
||||||
var c console.Console
|
var c console.Console
|
||||||
out := os.Stderr
|
|
||||||
// TODO: Handle interactive output in non-interactive environment.
|
// TODO: Handle interactive output in non-interactive environment.
|
||||||
consoleOpt := options.console.Value()
|
consoleOpt := options.console.Value()
|
||||||
if cons, err := console.ConsoleFromFile(out); err == nil && (consoleOpt == nil || *consoleOpt) {
|
if cons, err := console.ConsoleFromFile(out); err == nil && (consoleOpt == nil || *consoleOpt) {
|
||||||
|
@ -210,15 +220,31 @@ func doBuild(ctx context.Context, eg *errgroup.Group, dockerCli command.Cli, opt
|
||||||
}
|
}
|
||||||
close(displayCh)
|
close(displayCh)
|
||||||
}()
|
}()
|
||||||
displayStatus(displayCh)
|
displayStatus(os.Stderr, displayCh)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
displayStatus(t.displayCh)
|
displayStatus(os.Stdout, t.displayCh)
|
||||||
}
|
}
|
||||||
defer close(t.displayCh)
|
defer close(t.displayCh)
|
||||||
err = jsonmessage.DisplayJSONMessagesStream(response.Body, os.Stdout, dockerCli.Out().FD(), dockerCli.Out().IsTerminal(), t.write)
|
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
|
imageID := ""
|
||||||
|
writeAux := func(msg jsonmessage.JSONMessage) {
|
||||||
|
if msg.ID == "moby.image.id" {
|
||||||
|
var result types.BuildResult
|
||||||
|
if err := json.Unmarshal(*msg.Aux, &result); err != nil {
|
||||||
|
fmt.Fprintf(dockerCli.Err(), "failed to parse aux message: %v", err)
|
||||||
|
}
|
||||||
|
imageID = result.ID
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.write(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = jsonmessage.DisplayJSONMessagesStream(response.Body, buf, dockerCli.Out().FD(), dockerCli.Out().IsTerminal(), writeAux)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if jerr, ok := err.(*jsonmessage.JSONError); ok {
|
if jerr, ok := err.(*jsonmessage.JSONError); ok {
|
||||||
// If no error code is set, default to 1
|
// If no error code is set, default to 1
|
||||||
|
@ -228,6 +254,26 @@ func doBuild(ctx context.Context, eg *errgroup.Group, dockerCli command.Cli, opt
|
||||||
return cli.StatusError{Status: jerr.Message, StatusCode: jerr.Code}
|
return cli.StatusError{Status: jerr.Message, StatusCode: jerr.Code}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Everything worked so if -q was provided the output from the daemon
|
||||||
|
// should be just the image ID and we'll print that to stdout.
|
||||||
|
//
|
||||||
|
// TODO: we may want to use Aux messages with ID "moby.image.id" regardless of options.quiet (i.e. don't send HTTP param q=1)
|
||||||
|
// instead of assuming that output is image ID if options.quiet.
|
||||||
|
if options.quiet {
|
||||||
|
imageID = buf.String()
|
||||||
|
fmt.Fprint(dockerCli.Out(), imageID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.imageIDFile != "" {
|
||||||
|
if imageID == "" {
|
||||||
|
return errors.Errorf("cannot write %s because server did not provide an image ID", options.imageIDFile)
|
||||||
|
}
|
||||||
|
imageID = strings.TrimSpace(imageID)
|
||||||
|
if err := ioutil.WriteFile(options.imageIDFile, []byte(imageID), 0666); err != nil {
|
||||||
|
return errors.Wrap(err, "cannot write image ID file")
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue