Skip to content

Commit 7c486bb

Browse files
authored
fix: prevent git progress writer race reading stageNumber (#309)
1 parent 3f054f6 commit 7c486bb

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

envbuilder.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ func Run(ctx context.Context, opts options.Options) error {
116116
newColor(color.FgCyan).Sprintf(cloneOpts.Path),
117117
)
118118

119-
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNumber, line) })
119+
stageNum := stageNumber
120+
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNum, line) })
120121
defer w.Close()
121122
cloneOpts.Progress = w
122123

@@ -132,6 +133,8 @@ func Run(ctx context.Context, opts options.Options) error {
132133
opts.Logger(log.LevelError, "Falling back to the default image...")
133134
}
134135

136+
_ = w.Close()
137+
135138
// Always clone the repo in remote repo build mode into a location that
136139
// we control that isn't affected by the users changes.
137140
if opts.RemoteRepoBuildMode {
@@ -146,7 +149,8 @@ func Run(ctx context.Context, opts options.Options) error {
146149
newColor(color.FgCyan).Sprintf(cloneOpts.Path),
147150
)
148151

149-
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNumber, line) })
152+
stageNum := stageNumber
153+
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNum, line) })
150154
defer w.Close()
151155
cloneOpts.Progress = w
152156

@@ -158,6 +162,8 @@ func Run(ctx context.Context, opts options.Options) error {
158162
opts.Logger(log.LevelError, "Failed to clone repository for remote repo mode: %s", fallbackErr.Error())
159163
opts.Logger(log.LevelError, "Falling back to the default image...")
160164
}
165+
166+
_ = w.Close()
161167
}
162168
}
163169

@@ -893,7 +899,8 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
893899
newColor(color.FgCyan).Sprintf(cloneOpts.Path),
894900
)
895901

896-
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNumber, line) })
902+
stageNum := stageNumber
903+
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNum, line) })
897904
defer w.Close()
898905
cloneOpts.Progress = w
899906

@@ -908,6 +915,8 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
908915
opts.Logger(log.LevelError, "Failed to clone repository: %s", fallbackErr.Error())
909916
opts.Logger(log.LevelError, "Falling back to the default image...")
910917
}
918+
919+
_ = w.Close()
911920
} else {
912921
cloneOpts, err := git.CloneOptionsFromOptions(opts)
913922
if err != nil {
@@ -920,7 +929,8 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
920929
newColor(color.FgCyan).Sprintf(cloneOpts.Path),
921930
)
922931

923-
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNumber, line) })
932+
stageNum := stageNumber
933+
w := git.ProgressWriter(func(line string) { opts.Logger(log.LevelInfo, "#%d: %s", stageNum, line) })
924934
defer w.Close()
925935
cloneOpts.Progress = w
926936

@@ -932,6 +942,8 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
932942
opts.Logger(log.LevelError, "Failed to clone repository for remote repo mode: %s", fallbackErr.Error())
933943
opts.Logger(log.LevelError, "Falling back to the default image...")
934944
}
945+
946+
_ = w.Close()
935947
}
936948
}
937949

git/git.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,14 @@ func CloneOptionsFromOptions(options options.Options) (CloneRepoOptions, error)
317317

318318
type progressWriter struct {
319319
io.WriteCloser
320-
r io.ReadCloser
320+
r io.ReadCloser
321+
done chan struct{}
321322
}
322323

323324
func (w *progressWriter) Close() error {
324-
err := w.r.Close()
325-
err2 := w.WriteCloser.Close()
325+
err := w.WriteCloser.Close()
326+
<-w.done
327+
err2 := w.r.Close()
326328
if err != nil {
327329
return err
328330
}
@@ -331,7 +333,9 @@ func (w *progressWriter) Close() error {
331333

332334
func ProgressWriter(write func(line string)) io.WriteCloser {
333335
reader, writer := io.Pipe()
336+
done := make(chan struct{})
334337
go func() {
338+
defer close(done)
335339
data := make([]byte, 4096)
336340
for {
337341
read, err := reader.Read(data)
@@ -351,5 +355,6 @@ func ProgressWriter(write func(line string)) io.WriteCloser {
351355
return &progressWriter{
352356
WriteCloser: writer,
353357
r: reader,
358+
done: done,
354359
}
355360
}

0 commit comments

Comments
 (0)