119 lines
3.7 KiB
Diff
119 lines
3.7 KiB
Diff
|
|
From a275947784ed0772b08bbd43114c5cc0a1ba8feb Mon Sep 17 00:00:00 2001
|
||
|
|
From: DCCooper <1866858@gmail.com>
|
||
|
|
Date: Tue, 15 Sep 2020 19:42:14 +0800
|
||
|
|
Subject: [PATCH] bugfix: fix build hang problem when error happened before
|
||
|
|
pipe open
|
||
|
|
|
||
|
|
Signed-off-by: DCCooper <1866858@gmail.com>
|
||
|
|
---
|
||
|
|
builder/builder.go | 2 +-
|
||
|
|
builder/dockerfile/builder.go | 3 ++-
|
||
|
|
cmd/cli/build.go | 4 +++-
|
||
|
|
daemon/build.go | 8 +++++++-
|
||
|
|
daemon/status.go | 6 ++++++
|
||
|
|
5 files changed, 19 insertions(+), 4 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/builder/builder.go b/builder/builder.go
|
||
|
|
index 02c40ea7..1f650a5c 100644
|
||
|
|
--- a/builder/builder.go
|
||
|
|
+++ b/builder/builder.go
|
||
|
|
@@ -29,7 +29,7 @@ import (
|
||
|
|
|
||
|
|
// Builder is an interface for building an image
|
||
|
|
type Builder interface {
|
||
|
|
- Build() (imageID string, err error)
|
||
|
|
+ Build(chan struct{}) (imageID string, err error)
|
||
|
|
StatusChan() <-chan string
|
||
|
|
CleanResources() error
|
||
|
|
OutputPipeWrapper() *exporter.PipeWrapper
|
||
|
|
diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go
|
||
|
|
index 27c688f9..fd0bd695 100644
|
||
|
|
--- a/builder/dockerfile/builder.go
|
||
|
|
+++ b/builder/dockerfile/builder.go
|
||
|
|
@@ -407,7 +407,7 @@ func getFlagsAndArgs(line *parser.Line, allowFlags map[string]bool) (map[string]
|
||
|
|
}
|
||
|
|
|
||
|
|
// Build makes the image
|
||
|
|
-func (b *Builder) Build() (string, error) {
|
||
|
|
+func (b *Builder) Build(syncChan chan struct{}) (string, error) {
|
||
|
|
var (
|
||
|
|
executeTimer = b.cliLog.StartTimer("\nTotal")
|
||
|
|
err error
|
||
|
|
@@ -446,6 +446,7 @@ func (b *Builder) Build() (string, error) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ close(syncChan)
|
||
|
|
// 4. export images
|
||
|
|
if err = b.export(imageID); err != nil {
|
||
|
|
return "", errors.Wrapf(err, "exporting images failed")
|
||
|
|
diff --git a/cmd/cli/build.go b/cmd/cli/build.go
|
||
|
|
index 08c591b5..5c94bedd 100644
|
||
|
|
--- a/cmd/cli/build.go
|
||
|
|
+++ b/cmd/cli/build.go
|
||
|
|
@@ -150,7 +150,9 @@ func buildCommand(c *cobra.Command, args []string) error {
|
||
|
|
logrus.Debugf("Status get failed: %v", err2)
|
||
|
|
cancel()
|
||
|
|
}
|
||
|
|
- return errors.Wrap(err2, "error runStatus")
|
||
|
|
+ // user should not pay attention on runStatus error
|
||
|
|
+ // the errors were already printed to daemon log if any
|
||
|
|
+ return nil
|
||
|
|
})
|
||
|
|
|
||
|
|
return eg.Wait()
|
||
|
|
diff --git a/daemon/build.go b/daemon/build.go
|
||
|
|
index b66a9058..6c5e0acb 100644
|
||
|
|
--- a/daemon/build.go
|
||
|
|
+++ b/daemon/build.go
|
||
|
|
@@ -59,11 +59,12 @@ func (b *Backend) Build(req *pb.BuildRequest, stream pb.Control_BuildServer) err
|
||
|
|
|
||
|
|
pipeWrapper := builder.OutputPipeWrapper()
|
||
|
|
eg, ctx := errgroup.WithContext(ctx)
|
||
|
|
+ syncPipeChan := make(chan struct{})
|
||
|
|
eg.Go(func() error {
|
||
|
|
b.syncBuildStatus(req.BuildID) <- struct{}{}
|
||
|
|
b.closeStatusChan(req.BuildID)
|
||
|
|
var berr error
|
||
|
|
- imageID, berr = builder.Build()
|
||
|
|
+ imageID, berr = builder.Build(syncPipeChan)
|
||
|
|
|
||
|
|
if berr != nil && pipeWrapper != nil {
|
||
|
|
// in case there is error during Build stage, the backend will always waiting for content write into
|
||
|
|
@@ -85,6 +86,11 @@ func (b *Backend) Build(req *pb.BuildRequest, stream pb.Control_BuildServer) err
|
||
|
|
if pipeWrapper == nil {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
+ select {
|
||
|
|
+ case <-syncPipeChan:
|
||
|
|
+ case <-ctx.Done():
|
||
|
|
+ return nil
|
||
|
|
+ }
|
||
|
|
f, perr := exporter.PipeArchiveStream(pipeWrapper)
|
||
|
|
if perr != nil {
|
||
|
|
return perr
|
||
|
|
diff --git a/daemon/status.go b/daemon/status.go
|
||
|
|
index c08a6e77..d8b666ee 100644
|
||
|
|
--- a/daemon/status.go
|
||
|
|
+++ b/daemon/status.go
|
||
|
|
@@ -41,10 +41,16 @@ func (b *Backend) Status(req *pb.StatusRequest, stream pb.Control_StatusServer)
|
||
|
|
|
||
|
|
builder, err := b.daemon.Builder(req.BuildID)
|
||
|
|
if err != nil {
|
||
|
|
+ logrus.WithFields(logrus.Fields{
|
||
|
|
+ "BuildID": req.GetBuildID(),
|
||
|
|
+ }).Error(err)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
for value := range builder.StatusChan() {
|
||
|
|
if err := stream.Send(&pb.StatusResponse{Content: value}); err != nil {
|
||
|
|
+ logrus.WithFields(logrus.Fields{
|
||
|
|
+ "BuildID": req.GetBuildID(),
|
||
|
|
+ }).Error(err)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
--
|
||
|
|
2.19.1
|
||
|
|
|