From df09d31e8d1906dd96b0f8862f017a4e2ee1e2d0 Mon Sep 17 00:00:00 2001 From: Ulysses Souza Date: Tue, 26 Nov 2019 17:14:55 +0100 Subject: [PATCH] Create a global variable to hold output file With a function scoped `os.File`, next time the GC passes the instance is collected, calling the finalizer and triggering the invalidation of the FD, that cannot be used anymore. Signed-off-by: Ulysses Souza --- internal/commands/build/build.go | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/internal/commands/build/build.go b/internal/commands/build/build.go index ac2fd7429..462069b84 100644 --- a/internal/commands/build/build.go +++ b/internal/commands/build/build.go @@ -23,6 +23,7 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" compose "github.com/docker/cli/cli/compose/types" + "github.com/docker/cli/cli/streams" "github.com/docker/cnab-to-oci/remotes" "github.com/docker/distribution/reference" "github.com/moby/buildkit/client" @@ -49,6 +50,8 @@ type buildOptions struct { const buildExample = `- $ docker app build . - $ docker app build --file myapp.dockerapp --tag myrepo/myapp:1.0.0 .` +var outputFile *os.File + func Cmd(dockerCli command.Cli) *cobra.Command { var opts buildOptions cmd := &cobra.Command{ @@ -136,6 +139,22 @@ func runBuild(dockerCli command.Cli, contextPath string, opt buildOptions) error return err } +func getOutputFile(realOut *streams.Out, quiet bool) (*os.File, error) { + if outputFile != nil { + return outputFile, nil + } + if quiet { + var err error + outputFile, err = os.Create(os.DevNull) + if err != nil { + return nil, err + } + return outputFile, nil + } + outputFile = os.NewFile(realOut.FD(), os.Stdout.Name()) + return outputFile, nil +} + func buildImageUsingBuildx(app *types.App, contextPath string, opt buildOptions, dockerCli command.Cli) (*bundle.Bundle, error) { buildopts, pulledServices, err := parseCompose(app, contextPath, opt) if err != nil { @@ -160,13 +179,9 @@ func buildImageUsingBuildx(app *types.App, contextPath string, opt buildOptions, }, } - var out *os.File - if opt.quiet { - if out, err = os.Create(os.DevNull); err != nil { - return nil, err - } - } else { - out = os.NewFile(dockerCli.Out().FD(), "/dev/stdout") + out, err := getOutputFile(dockerCli.Out(), opt.quiet) + if err != nil { + return nil, err } pw := progress.NewPrinter(ctx, out, opt.progress)