pkg/bindings/images.Build(): fix a race condition in error reporting

In nTar(), don't return the error value when the goroutine that's
populating the error value can continue running long after nTar()
returns.  Instead, wrap the Close() method of the pipe that we're
returning in a function that collects those errors, along with any error
we get from closing the pipe, and returns them from Close() wrapper.

In Build(), if the Close() method returns an error, at least log it.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai
2021-03-15 12:03:22 -04:00
parent 604459b404
commit e8918ff10b

View File

@ -20,6 +20,7 @@ import (
"github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/storage/pkg/fileutils" "github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/ioutils"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
@ -252,7 +253,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
logrus.Errorf("cannot tar container entries %v error: %v", entries, err) logrus.Errorf("cannot tar container entries %v error: %v", entries, err)
return nil, err return nil, err
} }
defer tarfile.Close() defer func() {
if err := tarfile.Close(); err != nil {
logrus.Errorf("%v\n", err)
}
}()
containerFile, err := filepath.Abs(entries[0]) containerFile, err := filepath.Abs(entries[0])
if err != nil { if err != nil {
@ -340,7 +345,7 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
gw := gzip.NewWriter(pw) gw := gzip.NewWriter(pw)
tw := tar.NewWriter(gw) tw := tar.NewWriter(gw)
var merr error var merr *multierror.Error
go func() { go func() {
defer pw.Close() defer pw.Close()
defer gw.Close() defer gw.Close()
@ -421,7 +426,14 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
merr = multierror.Append(merr, err) merr = multierror.Append(merr, err)
} }
}() }()
return pr, merr rc := ioutils.NewReadCloserWrapper(pr, func() error {
if merr != nil {
merr = multierror.Append(merr, pr.Close())
return merr.ErrorOrNil()
}
return pr.Close()
})
return rc, nil
} }
func parseDockerignore(root string) ([]string, error) { func parseDockerignore(root string) ([]string, error) {