From 8475f864b9fc2c10aee7b48abb224e43f5d563dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Va=C5=A1ek?= Date: Fri, 20 Dec 2024 13:59:12 +0100 Subject: [PATCH] Fix deadlock (#2630) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix deadlock Signed-off-by: Matej Vašek * Rework digest detection Signed-off-by: Matej Vašek --------- Signed-off-by: Matej Vašek --- hack/update-builder.go | 62 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/hack/update-builder.go b/hack/update-builder.go index 259e87c21..0b3ca6999 100644 --- a/hack/update-builder.go +++ b/hack/update-builder.go @@ -189,43 +189,45 @@ func buildBuilderImage(ctx context.Context, variant, arch string) (string, error }(rc) pr, pw := io.Pipe() - digestCh := make(chan string) + r := io.TeeReader(rc, pw) + go func() { - var ( - jm jsonmessage.JSONMessage - dec = json.NewDecoder(pr) - err error - ) - for { - err = dec.Decode(&jm) - if err != nil { - if errors.Is(err, io.EOF) { - break - } - panic(err) - } - if jm.Error != nil { - continue - } + fd := os.Stdout.Fd() + isTerminal := term.IsTerminal(int(os.Stdout.Fd())) + e := jsonmessage.DisplayJSONMessagesStream(pr, os.Stderr, fd, isTerminal, nil) + _ = pr.CloseWithError(e) + }() - re := regexp.MustCompile(`\sdigest: (?Psha256:[a-zA-Z0-9]+)\s`) - matches := re.FindStringSubmatch(jm.Status) - if len(matches) == 2 { - digestCh <- matches[1] + var ( + digest string + jm jsonmessage.JSONMessage + dec = json.NewDecoder(r) + re = regexp.MustCompile(`\sdigest: (?Psha256:[a-zA-Z0-9]+)\s`) + ) + for { + err = dec.Decode(&jm) + if err != nil { + if errors.Is(err, io.EOF) { + break } + return "", err + } + if jm.Error != nil { + continue } - }() - r := io.TeeReader(rc, pw) - fd := os.Stdout.Fd() - isTerminal := term.IsTerminal(int(os.Stdout.Fd())) - err = jsonmessage.DisplayJSONMessagesStream(r, os.Stderr, fd, isTerminal, nil) - _ = pw.Close() - if err != nil { - return "", err + matches := re.FindStringSubmatch(jm.Status) + if len(matches) == 2 { + digest = matches[1] + _, _ = io.Copy(io.Discard, r) + break + } } - return <-digestCh, nil + if digest == "" { + return "", fmt.Errorf("digest not found") + } + return digest, nil } var d string