Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

Commit

Permalink
Create a global variable to hold output file
Browse files Browse the repository at this point in the history
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 <ulysses.souza@docker.com>
  • Loading branch information
ulyssessouza committed Nov 27, 2019
1 parent e3a9aed commit d26c9ad
Showing 1 changed file with 28 additions and 7 deletions.
35 changes: 28 additions & 7 deletions internal/commands/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -75,6 +76,30 @@ func Cmd(dockerCli command.Cli) *cobra.Command {
return cmd
}

// FIXME: DO NOT SET THIS VARIABLE DIRECTLY! Use `getOutputFile`
// This global var prevents the file to be garbage collected and by that invalidated
// A an alternative fix for this would be writing the output to a bytes buffer and flushing to stdout.
// The impossibility here is that os.File is not an interface that a buffer can implement.
// Maybe `progress.NewPrinter` should implement an "os.File-like" interface just for its needs.
// See https://github.com/golang/go/issues/14106
var _outputFile *os.File

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 runBuild(dockerCli command.Cli, contextPath string, opt buildOptions) error {
err := checkMinimalEngineVersion(dockerCli)
if err != nil {
Expand Down Expand Up @@ -160,13 +185,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)
Expand Down

0 comments on commit d26c9ad

Please sign in to comment.