зеркало из https://github.com/microsoft/docker.git
Merge pull request #1194 from crosbymichael/build-verbose
* Builder: Add verbose output to docker build
This commit is contained in:
Коммит
de563a3ea3
9
api.go
9
api.go
|
@ -774,6 +774,7 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
|
||||||
}
|
}
|
||||||
remoteURL := r.FormValue("remote")
|
remoteURL := r.FormValue("remote")
|
||||||
repoName := r.FormValue("t")
|
repoName := r.FormValue("t")
|
||||||
|
rawSuppressOutput := r.FormValue("q")
|
||||||
tag := ""
|
tag := ""
|
||||||
if strings.Contains(repoName, ":") {
|
if strings.Contains(repoName, ":") {
|
||||||
remoteParts := strings.Split(repoName, ":")
|
remoteParts := strings.Split(repoName, ":")
|
||||||
|
@ -820,7 +821,13 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
|
||||||
}
|
}
|
||||||
context = c
|
context = c
|
||||||
}
|
}
|
||||||
b := NewBuildFile(srv, utils.NewWriteFlusher(w))
|
|
||||||
|
suppressOutput, err := getBoolParam(rawSuppressOutput)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := NewBuildFile(srv, utils.NewWriteFlusher(w), !suppressOutput)
|
||||||
id, err := b.Build(context)
|
id, err := b.Build(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(w, "Error build: %s\n", err)
|
fmt.Fprintf(w, "Error build: %s\n", err)
|
||||||
|
|
39
buildfile.go
39
buildfile.go
|
@ -28,8 +28,8 @@ type buildFile struct {
|
||||||
maintainer string
|
maintainer string
|
||||||
config *Config
|
config *Config
|
||||||
context string
|
context string
|
||||||
|
verbose bool
|
||||||
|
|
||||||
lastContainer *Container
|
|
||||||
tmpContainers map[string]struct{}
|
tmpContainers map[string]struct{}
|
||||||
tmpImages map[string]struct{}
|
tmpImages map[string]struct{}
|
||||||
|
|
||||||
|
@ -254,7 +254,6 @@ func (b *buildFile) CmdAdd(args string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
b.tmpContainers[container.ID] = struct{}{}
|
b.tmpContainers[container.ID] = struct{}{}
|
||||||
b.lastContainer = container
|
|
||||||
|
|
||||||
if err := container.EnsureMounted(); err != nil {
|
if err := container.EnsureMounted(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -290,7 +289,6 @@ func (b *buildFile) run() (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
b.tmpContainers[c.ID] = struct{}{}
|
b.tmpContainers[c.ID] = struct{}{}
|
||||||
b.lastContainer = c
|
|
||||||
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(c.ID))
|
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(c.ID))
|
||||||
|
|
||||||
// override the entry point that may have been picked up from the base image
|
// override the entry point that may have been picked up from the base image
|
||||||
|
@ -303,6 +301,13 @@ func (b *buildFile) run() (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.verbose {
|
||||||
|
err = <-c.Attach(nil, nil, b.out, b.out)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for it to finish
|
// Wait for it to finish
|
||||||
if ret := c.Wait(); ret != 0 {
|
if ret := c.Wait(); ret != 0 {
|
||||||
return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, ret)
|
return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, ret)
|
||||||
|
@ -337,7 +342,6 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
b.tmpContainers[container.ID] = struct{}{}
|
b.tmpContainers[container.ID] = struct{}{}
|
||||||
b.lastContainer = container
|
|
||||||
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
|
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
|
||||||
id = container.ID
|
id = container.ID
|
||||||
if err := container.EnsureMounted(); err != nil {
|
if err := container.EnsureMounted(); err != nil {
|
||||||
|
@ -365,29 +369,6 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *buildFile) Build(context io.Reader) (string, error) {
|
func (b *buildFile) Build(context io.Reader) (string, error) {
|
||||||
defer func() {
|
|
||||||
// If we have an error and a container, the display the logs
|
|
||||||
if b.lastContainer != nil {
|
|
||||||
fmt.Fprintf(b.out, "******** Logs from last container (%s) *******\n", b.lastContainer.ShortID())
|
|
||||||
|
|
||||||
cLog, err := b.lastContainer.ReadLog("stdout")
|
|
||||||
if err != nil {
|
|
||||||
utils.Debugf("Error reading logs (stdout): %s", err)
|
|
||||||
}
|
|
||||||
if _, err := io.Copy(b.out, cLog); err != nil {
|
|
||||||
utils.Debugf("Error streaming logs (stdout): %s", err)
|
|
||||||
}
|
|
||||||
cLog, err = b.lastContainer.ReadLog("stderr")
|
|
||||||
if err != nil {
|
|
||||||
utils.Debugf("Error reading logs (stderr): %s", err)
|
|
||||||
}
|
|
||||||
if _, err := io.Copy(b.out, cLog); err != nil {
|
|
||||||
utils.Debugf("Error streaming logs (stderr): %s", err)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(b.out, "************* End of logs for %s *************\n", b.lastContainer.ShortID())
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// FIXME: @creack any reason for using /tmp instead of ""?
|
// FIXME: @creack any reason for using /tmp instead of ""?
|
||||||
// FIXME: @creack "name" is a terrible variable name
|
// FIXME: @creack "name" is a terrible variable name
|
||||||
name, err := ioutil.TempDir("/tmp", "docker-build")
|
name, err := ioutil.TempDir("/tmp", "docker-build")
|
||||||
|
@ -440,7 +421,6 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
|
||||||
return "", ret.(error)
|
return "", ret.(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.lastContainer = nil
|
|
||||||
fmt.Fprintf(b.out, " ---> %v\n", utils.TruncateID(b.image))
|
fmt.Fprintf(b.out, " ---> %v\n", utils.TruncateID(b.image))
|
||||||
}
|
}
|
||||||
if b.image != "" {
|
if b.image != "" {
|
||||||
|
@ -450,7 +430,7 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
|
||||||
return "", fmt.Errorf("An error occured during the build\n")
|
return "", fmt.Errorf("An error occured during the build\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuildFile(srv *Server, out io.Writer) BuildFile {
|
func NewBuildFile(srv *Server, out io.Writer, verbose bool) BuildFile {
|
||||||
return &buildFile{
|
return &buildFile{
|
||||||
builder: NewBuilder(srv.runtime),
|
builder: NewBuilder(srv.runtime),
|
||||||
runtime: srv.runtime,
|
runtime: srv.runtime,
|
||||||
|
@ -459,5 +439,6 @@ func NewBuildFile(srv *Server, out io.Writer) BuildFile {
|
||||||
out: out,
|
out: out,
|
||||||
tmpContainers: make(map[string]struct{}),
|
tmpContainers: make(map[string]struct{}),
|
||||||
tmpImages: make(map[string]struct{}),
|
tmpImages: make(map[string]struct{}),
|
||||||
|
verbose: verbose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ func TestBuild(t *testing.T) {
|
||||||
pushingPool: make(map[string]struct{}),
|
pushingPool: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
buildfile := NewBuildFile(srv, ioutil.Discard)
|
buildfile := NewBuildFile(srv, ioutil.Discard, false)
|
||||||
if _, err := buildfile.Build(mkTestContext(ctx.dockerfile, ctx.files, t)); err != nil {
|
if _, err := buildfile.Build(mkTestContext(ctx.dockerfile, ctx.files, t)); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ func TestVolume(t *testing.T) {
|
||||||
pushingPool: make(map[string]struct{}),
|
pushingPool: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
buildfile := NewBuildFile(srv, ioutil.Discard)
|
buildfile := NewBuildFile(srv, ioutil.Discard, false)
|
||||||
imgId, err := buildfile.Build(mkTestContext(`
|
imgId, err := buildfile.Build(mkTestContext(`
|
||||||
from %s
|
from %s
|
||||||
VOLUME /test
|
VOLUME /test
|
||||||
|
@ -150,7 +150,7 @@ CMD Hello world
|
||||||
if len(img.Config.Volumes) == 0 {
|
if len(img.Config.Volumes) == 0 {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
for key, _ := range img.Config.Volumes {
|
for key := range img.Config.Volumes {
|
||||||
if key != "/test" {
|
if key != "/test" {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,8 @@ func mkBuildContext(dockerfile string, files [][2]string) (Archive, error) {
|
||||||
func (cli *DockerCli) CmdBuild(args ...string) error {
|
func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
cmd := Subcmd("build", "[OPTIONS] PATH | URL | -", "Build a new container image from the source code at PATH")
|
cmd := Subcmd("build", "[OPTIONS] PATH | URL | -", "Build a new container image from the source code at PATH")
|
||||||
tag := cmd.String("t", "", "Tag to be applied to the resulting image in case of success")
|
tag := cmd.String("t", "", "Tag to be applied to the resulting image in case of success")
|
||||||
|
suppressOutput := cmd.Bool("q", false, "Suppress verbose build output")
|
||||||
|
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -195,6 +197,10 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
// Upload the build context
|
// Upload the build context
|
||||||
v := &url.Values{}
|
v := &url.Values{}
|
||||||
v.Set("t", *tag)
|
v.Set("t", *tag)
|
||||||
|
|
||||||
|
if *suppressOutput {
|
||||||
|
v.Set("q", "1")
|
||||||
|
}
|
||||||
if isRemote {
|
if isRemote {
|
||||||
v.Set("remote", cmd.Arg(0))
|
v.Set("remote", cmd.Arg(0))
|
||||||
}
|
}
|
||||||
|
|
|
@ -921,6 +921,7 @@ Build an image from Dockerfile via stdin
|
||||||
The Content-type header should be set to "application/tar".
|
The Content-type header should be set to "application/tar".
|
||||||
|
|
||||||
:query t: tag to be applied to the resulting image in case of success
|
:query t: tag to be applied to the resulting image in case of success
|
||||||
|
:query q: suppress verbose build output
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 500: server error
|
:statuscode 500: server error
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
Usage: docker build [OPTIONS] PATH | URL | -
|
Usage: docker build [OPTIONS] PATH | URL | -
|
||||||
Build a new container image from the source code at PATH
|
Build a new container image from the source code at PATH
|
||||||
-t="": Tag to be applied to the resulting image in case of success.
|
-t="": Tag to be applied to the resulting image in case of success.
|
||||||
|
-q=false: Suppress verbose build output.
|
||||||
When a single Dockerfile is given as URL, then no context is set. When a git repository is set as URL, the repository is used as context
|
When a single Dockerfile is given as URL, then no context is set. When a git repository is set as URL, the repository is used as context
|
||||||
|
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче