diff --git a/daemon/build.go b/daemon/build.go index ba666b7989b908e92a92ebd48b3e430e6c9ba442..acd689b62102c31ede47a04acc4fbe7b0d1280b5 100644 --- a/daemon/build.go +++ b/daemon/build.go @@ -51,21 +51,16 @@ func (b *Backend) Build(req *pb.BuildRequest, stream pb.Control_BuildServer) (er }() var ( - f *os.File - length int - imageID string - pipeFile string - eg *errgroup.Group - errC = make(chan error, 1) + f *os.File + length int + imageID string + eg *errgroup.Group + errC = make(chan error, 1) ) pipeWrapper := builder.OutputPipeWrapper() eg, ctx = errgroup.WithContext(ctx) eg.Go(func() error { - if pipeWrapper != nil { - pipeFile = pipeWrapper.PipeFile - defer pipeWrapper.Close() - } b.syncBuildStatus(req.BuildID) <- struct{}{} imageID, err = builder.Build() @@ -73,8 +68,9 @@ func (b *Backend) Build(req *pb.BuildRequest, stream pb.Control_BuildServer) (er // the pipeFile, which will cause frontend hangs forever. // so if the output type is archive(pipeFile is not empty string) and any error occurred, we write the error // message into the pipe to make the goroutine move on instead of hangs. - if err != nil && pipeFile != "" { - if perr := ioutil.WriteFile(pipeFile, []byte(err.Error()), constant.DefaultRootFileMode); perr != nil { + if err != nil && pipeWrapper.PipeFile != "" { + pipeWrapper.Close() + if perr := ioutil.WriteFile(pipeWrapper.PipeFile, []byte(err.Error()), constant.DefaultRootFileMode); perr != nil { logrus.WithField(util.LogKeySessionID, req.BuildID).Warnf("Write error [%v] in to pipe file failed: %v", err, perr) } } @@ -100,10 +96,10 @@ func (b *Backend) Build(req *pb.BuildRequest, stream pb.Control_BuildServer) (er buf := make([]byte, constant.BufferSize, constant.BufferSize) for { length, err = reader.Read(buf) - if length == 0 && pipeWrapper.Done { + if err == io.EOF || pipeWrapper.Done { break } - if err != nil && err != io.EOF { + if err != nil { return err } if err = stream.Send(&pb.BuildResponse{ diff --git a/daemon/save.go b/daemon/save.go index 618a4694a8d3eb8dc45e107b6cdc605083ccae2f..8d54bf53fd67ea3d6b38d369506771f0869314bf 100644 --- a/daemon/save.go +++ b/daemon/save.go @@ -77,7 +77,6 @@ func (b *Backend) Save(req *pb.SaveRequest, stream pb.Control_SaveServer) (err e eg.Go(func() error { defer func() { - pipeWrapper.Close() cliLogger.CloseContent() }() output := fmt.Sprintf("%s:%s", exportType, pipeWrapper.PipeFile) @@ -88,6 +87,7 @@ func (b *Backend) Save(req *pb.SaveRequest, stream pb.Control_SaveServer) (err e } if err = exporter.Export(imageID, output, exOpts, store); err != nil { + pipeWrapper.Close() logrus.Errorf("Save image %s failed: %v", imageID, err) return err } @@ -110,7 +110,7 @@ func (b *Backend) Save(req *pb.SaveRequest, stream pb.Control_SaveServer) (err e buf := make([]byte, constant.BufferSize, constant.BufferSize) for { length, err = reader.Read(buf) - if err == io.EOF { + if err == io.EOF || pipeWrapper.Done { break } if err != nil { diff --git a/exporter/common.go b/exporter/common.go index e2e083bee0e9b311f6b9cb348787caf79a32fc81..4b334712cb9a1ad90df734d2f62f17742548f512 100644 --- a/exporter/common.go +++ b/exporter/common.go @@ -177,7 +177,6 @@ func newPolicyContext(sc *types.SystemContext) (*signature.PolicyContext, error) type PipeWrapper struct { PipeFile string Done bool - Err error } // Close set the done flag for this pip