Change the quiet flag behavior in the build command

Right now, the quiet (-q, --quiet) flag ignores the output
generated from within the container.

However, it ought to be quiet in a way that all kind
of diagnostic output should be ignored, unless the build
process fails.

This patch makes the quiet flag behave in the following way:
 1. If the build process succeeds, stdout contains the image ID
    and stderr is empty.
 2. If the build process fails, stdout is empty and stderr
    has the error message and the diagnostic output of that process.

If the quiet flag is not set, then everything goes to stdout
and error messages, if there are any, go to stderr.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Upstream-commit: 60b4db7eb17f4eb509be4a4968364ada2075d60c
Component: engine
This commit is contained in:
Boaz Shuster
2015-10-28 02:29:21 +02:00
committed by ripcurld00d
parent fc63a9d65d
commit 1c5df6581b
8 changed files with 201 additions and 45 deletions

View File

@ -1,6 +1,7 @@
package build
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
@ -72,6 +73,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
authConfigs = map[string]types.AuthConfig{}
authConfigsEncoded = r.Header.Get("X-Registry-Config")
buildConfig = &dockerfile.Config{}
notVerboseBuffer = bytes.NewBuffer(nil)
)
if authConfigsEncoded != "" {
@ -90,6 +92,9 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
defer output.Close()
sf := streamformatter.NewJSONStreamFormatter()
errf := func(err error) error {
if !buildConfig.Verbose && notVerboseBuffer.Len() > 0 {
output.Write(notVerboseBuffer.Bytes())
}
// Do not write the error in the http output if it's still empty.
// This prevents from writing a 200(OK) when there is an internal error.
if !output.Flushed() {
@ -170,6 +175,9 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
// Look at code in DetectContextFromRemoteURL for more information.
createProgressReader := func(in io.ReadCloser) io.ReadCloser {
progressOutput := sf.NewProgressOutput(output, true)
if !buildConfig.Verbose {
progressOutput = sf.NewProgressOutput(notVerboseBuffer, true)
}
return progress.NewProgressReader(in, progressOutput, r.ContentLength, "Downloading context", remoteURL)
}
@ -199,6 +207,9 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
AuthConfigs: authConfigs,
Archiver: defaultArchiver,
}
if !buildConfig.Verbose {
docker.OutOld = notVerboseBuffer
}
b, err := dockerfile.NewBuilder(buildConfig, docker, builder.DockerIgnoreContext{ModifiableContext: context}, nil)
if err != nil {
@ -206,6 +217,10 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
}
b.Stdout = &streamformatter.StdoutFormatter{Writer: output, StreamFormatter: sf}
b.Stderr = &streamformatter.StderrFormatter{Writer: output, StreamFormatter: sf}
if !buildConfig.Verbose {
b.Stdout = &streamformatter.StdoutFormatter{Writer: notVerboseBuffer, StreamFormatter: sf}
b.Stderr = &streamformatter.StderrFormatter{Writer: notVerboseBuffer, StreamFormatter: sf}
}
if closeNotifier, ok := w.(http.CloseNotifier); ok {
finished := make(chan struct{})
@ -235,5 +250,12 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
}
}
// 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.
if !buildConfig.Verbose {
stdout := &streamformatter.StdoutFormatter{Writer: output, StreamFormatter: sf}
fmt.Fprintf(stdout, "%s\n", string(imgID))
}
return nil
}