Fix flake on failed podman-remote build : try 2

This time we are checking if the function actually succeeded,
otherwise we will report an error.

Also if we did not get the id, report unexpected failure.

[NO TESTS NEEDED] Still no good way to test this, but manually.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2021-04-14 15:55:09 -04:00
parent 9f36efda37
commit 855a5a89dd
2 changed files with 20 additions and 6 deletions

View File

@ -464,15 +464,16 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
var ( var (
imageID string imageID string
failed bool success bool
) )
runCtx, cancel := context.WithCancel(context.Background()) runCtx, cancel := context.WithCancel(context.Background())
go func() { go func() {
defer cancel() defer cancel()
imageID, _, err = runtime.Build(r.Context(), buildOptions, query.Dockerfile) imageID, _, err = runtime.Build(r.Context(), buildOptions, query.Dockerfile)
if err != nil { if err == nil {
failed = true success = true
} else {
stderr.Write([]byte(err.Error() + "\n")) stderr.Write([]byte(err.Error() + "\n"))
} }
}() }()
@ -534,7 +535,8 @@ loop:
} }
flush() flush()
case <-runCtx.Done(): case <-runCtx.Done():
if !failed { flush()
if success {
if !utils.IsLibpodRequest(r) { if !utils.IsLibpodRequest(r) {
m.Stream = fmt.Sprintf("Successfully built %12.12s\n", imageID) m.Stream = fmt.Sprintf("Successfully built %12.12s\n", imageID)
if err := enc.Encode(m); err != nil { if err := enc.Encode(m); err != nil {

View File

@ -340,6 +340,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
re := regexp.MustCompile(`[0-9a-f]{12}`) re := regexp.MustCompile(`[0-9a-f]{12}`)
var id string var id string
var mErr error
for { for {
var s struct { var s struct {
Stream string `json:"stream,omitempty"` Stream string `json:"stream,omitempty"`
@ -347,11 +348,21 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
} }
if err := dec.Decode(&s); err != nil { if err := dec.Decode(&s); err != nil {
if errors.Is(err, io.EOF) { if errors.Is(err, io.EOF) {
return &entities.BuildReport{ID: id}, nil if mErr == nil && id == "" {
mErr = errors.New("stream dropped, unexpected failure")
}
break
} }
s.Error = err.Error() + "\n" s.Error = err.Error() + "\n"
} }
select {
case <-response.Request.Context().Done():
return &entities.BuildReport{ID: id}, mErr
default:
// non-blocking select
}
switch { switch {
case s.Stream != "": case s.Stream != "":
stdout.Write([]byte(s.Stream)) stdout.Write([]byte(s.Stream))
@ -359,11 +370,12 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
id = strings.TrimSuffix(s.Stream, "\n") id = strings.TrimSuffix(s.Stream, "\n")
} }
case s.Error != "": case s.Error != "":
return nil, errors.New(s.Error) mErr = errors.New(s.Error)
default: default:
return &entities.BuildReport{ID: id}, errors.New("failed to parse build results stream, unexpected input") return &entities.BuildReport{ID: id}, errors.New("failed to parse build results stream, unexpected input")
} }
} }
return &entities.BuildReport{ID: id}, mErr
} }
func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {