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

Commit

Permalink
Workaround for broken output
Browse files Browse the repository at this point in the history
This avoids calling `os.Newfile` since it seems to break the
file referenced by it.
This workaround expects the `io.Writer` to be also a `*os.File`.
The default case is true since it uses an `os.Stdout` to
construct the `dockerCli`.
If any of this works, it prints a warning and returns `os.Stdout`.

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
  • Loading branch information
ulyssessouza committed Nov 26, 2019
1 parent e3a9aed commit 9de59d4
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions internal/commands/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strconv"
"strings"
"unsafe"

"github.com/deislabs/cnab-go/bundle"
cnab "github.com/deislabs/cnab-go/driver"
Expand All @@ -23,6 +25,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 @@ -136,6 +139,28 @@ func runBuild(dockerCli command.Cli, contextPath string, opt buildOptions) error
return err
}

// FIXME (ulyssessouza): This is a workaround to avoid calling os.NewFile on an already referenced file
// Calling `os.NewFile` with for example `os.Stdout.Fd()` invalidates the descriptor.
func getOutputFile(realOut *streams.Out, quiet bool) (*os.File, error) {
if quiet {
out, err := os.Create(os.DevNull)
if err != nil {
return nil, err
}
return out, nil
}
// Gets the encapsulated `io.Writer` from inside the realOut (default for dockerCli is `os.Stdout`)
// Expects the internal io.Writer to be a `*os.File` and not just an `io.Writer`
f := reflect.ValueOf(realOut).Elem().FieldByName("out")
f = reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem()
out, ok := f.Interface().(*os.File)
if !ok {
fmt.Fprintln(os.Stderr, "WARNING: Could not retrieve the output stream, using stdout instead")
return os.Stdout, nil
}
return out, 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 {
Expand All @@ -161,12 +186,8 @@ 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")
if out, err = getOutputFile(dockerCli.Out(), opt.quiet); err != nil {
return nil, err
}

pw := progress.NewPrinter(ctx, out, opt.progress)
Expand Down

0 comments on commit 9de59d4

Please sign in to comment.