Bladeren bron

Merge pull request #1194 from crosbymichael/build-verbose

* Builder: Add verbose output to docker build
Guillaume J. Charmes 12 jaren geleden
bovenliggende
commit
de563a3ea3
6 gewijzigde bestanden met toevoegingen van 29 en 33 verwijderingen
  1. 8 1
      api.go
  2. 10 29
      buildfile.go
  3. 3 3
      buildfile_test.go
  4. 6 0
      commands.go
  5. 1 0
      docs/sources/api/docker_remote_api_v1.3.rst
  6. 1 0
      docs/sources/commandline/command/build.rst

+ 8 - 1
api.go

@@ -774,6 +774,7 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
 	}
 	remoteURL := r.FormValue("remote")
 	repoName := r.FormValue("t")
+	rawSuppressOutput := r.FormValue("q")
 	tag := ""
 	if strings.Contains(repoName, ":") {
 		remoteParts := strings.Split(repoName, ":")
@@ -820,7 +821,13 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
 		}
 		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)
 	if err != nil {
 		fmt.Fprintf(w, "Error build: %s\n", err)

+ 10 - 29
buildfile.go

@@ -28,8 +28,8 @@ type buildFile struct {
 	maintainer string
 	config     *Config
 	context    string
+	verbose    bool
 
-	lastContainer *Container
 	tmpContainers map[string]struct{}
 	tmpImages     map[string]struct{}
 
@@ -254,7 +254,6 @@ func (b *buildFile) CmdAdd(args string) error {
 		return err
 	}
 	b.tmpContainers[container.ID] = struct{}{}
-	b.lastContainer = container
 
 	if err := container.EnsureMounted(); err != nil {
 		return err
@@ -290,7 +289,6 @@ func (b *buildFile) run() (string, error) {
 		return "", err
 	}
 	b.tmpContainers[c.ID] = struct{}{}
-	b.lastContainer = c
 	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
@@ -303,6 +301,13 @@ func (b *buildFile) run() (string, error) {
 		return "", err
 	}
 
+	if b.verbose {
+		err = <-c.Attach(nil, nil, b.out, b.out)
+		if err != nil {
+			return "", err
+		}
+	}
+
 	// Wait for it to finish
 	if ret := c.Wait(); ret != 0 {
 		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
 		}
 		b.tmpContainers[container.ID] = struct{}{}
-		b.lastContainer = container
 		fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
 		id = container.ID
 		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) {
-	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 "name" is a terrible variable name
 	name, err := ioutil.TempDir("/tmp", "docker-build")
@@ -440,7 +421,6 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
 			return "", ret.(error)
 		}
 
-		b.lastContainer = nil
 		fmt.Fprintf(b.out, " ---> %v\n", utils.TruncateID(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")
 }
 
-func NewBuildFile(srv *Server, out io.Writer) BuildFile {
+func NewBuildFile(srv *Server, out io.Writer, verbose bool) BuildFile {
 	return &buildFile{
 		builder:       NewBuilder(srv.runtime),
 		runtime:       srv.runtime,
@@ -459,5 +439,6 @@ func NewBuildFile(srv *Server, out io.Writer) BuildFile {
 		out:           out,
 		tmpContainers: make(map[string]struct{}),
 		tmpImages:     make(map[string]struct{}),
+		verbose:       verbose,
 	}
 }

+ 3 - 3
buildfile_test.go

@@ -114,7 +114,7 @@ func TestBuild(t *testing.T) {
 			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 {
 			t.Fatal(err)
 		}
@@ -134,7 +134,7 @@ func TestVolume(t *testing.T) {
 		pushingPool: make(map[string]struct{}),
 	}
 
-	buildfile := NewBuildFile(srv, ioutil.Discard)
+	buildfile := NewBuildFile(srv, ioutil.Discard, false)
 	imgId, err := buildfile.Build(mkTestContext(`
 from %s
 VOLUME /test
@@ -150,7 +150,7 @@ CMD Hello world
 	if len(img.Config.Volumes) == 0 {
 		t.Fail()
 	}
-	for key, _ := range img.Config.Volumes {
+	for key := range img.Config.Volumes {
 		if key != "/test" {
 			t.Fail()
 		}

+ 6 - 0
commands.go

@@ -158,6 +158,8 @@ func mkBuildContext(dockerfile string, files [][2]string) (Archive, 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")
 	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 {
 		return nil
 	}
@@ -195,6 +197,10 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 	// Upload the build context
 	v := &url.Values{}
 	v.Set("t", *tag)
+
+	if *suppressOutput {
+		v.Set("q", "1")
+	}
 	if isRemote {
 		v.Set("remote", cmd.Arg(0))
 	}

+ 1 - 0
docs/sources/api/docker_remote_api_v1.3.rst

@@ -921,6 +921,7 @@ Build an image from Dockerfile via stdin
         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 q: suppress verbose build output
 	:statuscode 200: no error
         :statuscode 500: server error
 

+ 1 - 0
docs/sources/commandline/command/build.rst

@@ -11,6 +11,7 @@
     Usage: docker build [OPTIONS] PATH | URL | -
     Build a new container image from the source code at PATH
       -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