Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"sync/atomic"

"github.com/containerd/console"
"github.com/docker/buildx/build"
Expand Down Expand Up @@ -368,15 +370,22 @@ func runControllerBuild(ctx context.Context, dockerCli command.Cli, opts *contro
var retErr error
var resp *client.SolveResponse
f := ioset.NewSingleForwarder()
f.SetReader(dockerCli.In())
pr, pw := io.Pipe()
f.SetWriter(pw, func() io.WriteCloser {
pw.Close() // propagate EOF
logrus.Debug("propagating stdin close")
return nil
})
isForwardStarted := false
prReader := &readCloserWithCallback{
rc: pr,
onRead: func() {
f.SetWriter(pw, func() io.WriteCloser {
pw.Close() // propagate EOF
logrus.Debug("propagating stdin close")
return nil
})
f.SetReader(dockerCli.In())
isForwardStarted = true
},
}

ref, resp, err = c.Build(ctx, *opts, pr, printer)
ref, resp, err = c.Build(ctx, *opts, prReader, printer)
if err != nil {
var be *controllererrors.BuildError
if errors.As(err, &be) {
Expand All @@ -391,7 +400,7 @@ func runControllerBuild(ctx context.Context, dockerCli command.Cli, opts *contro
if err := pw.Close(); err != nil {
logrus.Debug("failed to close stdin pipe writer")
}
if err := pr.Close(); err != nil {
if err := prReader.Close(); err != nil {
logrus.Debug("failed to close stdin pipe reader")
}

Expand All @@ -401,6 +410,9 @@ func runControllerBuild(ctx context.Context, dockerCli command.Cli, opts *contro
logrus.Warnf("failed to print error information: %v", err)
}

if !isForwardStarted {
f.SetReader(dockerCli.In())
}
pr2, pw2 := io.Pipe()
f.SetWriter(pw2, func() io.WriteCloser {
pw2.Close() // propagate EOF
Expand Down Expand Up @@ -967,3 +979,22 @@ func recordVersionInfo(mp metric.MeterProvider, command string) {
),
)
}

type readCloserWithCallback struct {
rc io.ReadCloser
onRead func()
closed atomic.Bool
onReadOnce sync.Once
}

func (r *readCloserWithCallback) Read(p []byte) (int, error) {
if !r.closed.Load() && r.onRead != nil {
r.onReadOnce.Do(r.onRead)
}
return r.rc.Read(p)
}

func (r *readCloserWithCallback) Close() error {
r.closed.Store(true)
return r.rc.Close()
}