Skip to content

Commit ab84c4d

Browse files
Try to prevent data race
1 parent 76685de commit ab84c4d

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

pkg/dockerimage/push.go

+46-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"os"
88
"strings"
9+
"sync"
910
)
1011

1112
const (
@@ -14,16 +15,37 @@ const (
1415
remoteDigestPrefix = "latest: digest: sha256:"
1516
)
1617

18+
var (
19+
DigestOutputError = digestOutputError{
20+
errors.New("no digest in output found"),
21+
}
22+
)
23+
24+
type digestOutputError struct {
25+
error
26+
}
27+
28+
func (err digestOutputError) Is(other error) bool {
29+
_, ok := other.(digestOutputError)
30+
return ok
31+
}
32+
1733
// Push calls docker and pushes a tag.
1834
// Returns the remote digest for the pushed image.
1935
func PushWithWriters(tag string, out io.Writer, errOut io.Writer) (string, error) {
2036
r, w := io.Pipe()
2137
defer r.Close()
2238
defer w.Close()
2339

24-
digest := make(chan string)
25-
defer close(digest)
40+
digest := make(chan string, 1)
41+
errs := make(chan error, 1)
42+
errG := sync.WaitGroup{}
43+
44+
errG.Add(1)
2645
go func() {
46+
defer close(digest)
47+
defer errG.Done()
48+
2749
scanner := bufio.NewScanner(r)
2850
for scanner.Scan() {
2951
if !strings.HasPrefix(scanner.Text(), remoteDigestPrefix) {
@@ -33,18 +55,32 @@ func PushWithWriters(tag string, out io.Writer, errOut io.Writer) (string, error
3355
digest <- scanner.Text()[len(remoteDigestPrefix) : len(remoteDigestPrefix)+64]
3456
return
3557
}
58+
errs <- DigestOutputError
3659
}()
37-
err := executeDockerCommandWithWriters(io.MultiWriter(out, w), errOut, "push", tag)
38-
if err != nil {
39-
return "", err
40-
}
4160

42-
select {
43-
case d := <-digest:
61+
errG.Add(1)
62+
go func() {
63+
defer errG.Done()
64+
65+
errs <- executeDockerCommandWithWriters(io.MultiWriter(out, w), errOut, "push", tag)
66+
}()
67+
68+
go func() {
69+
defer close(errs)
70+
71+
errG.Wait()
72+
}()
73+
74+
d, ok := <-digest
75+
if ok {
4476
return d, nil
45-
default:
46-
return "", errors.New("no digest in output found")
4777
}
78+
for err := range errs {
79+
if err != nil {
80+
return "", err
81+
}
82+
}
83+
panic("should have resulted in error before")
4884
}
4985

5086
// Push calls docker and pushes a tag.

0 commit comments

Comments
 (0)