Skip to content

Commit cdf3c96

Browse files
fix(k8s): prevent goroutine leak and deadlock in pod watcher (#3883)
* fix(k8s): prevent goroutine leak and deadlock in pod watcher Signed-off-by: vishwas-droid <vishwasbajaj.global@gmail.com> * Update persistent_volumes.go * Update persistent_volumes.go * Update persistent_volumes.go * Update persistent_volumes.go --------- Signed-off-by: vishwas-droid <vishwasbajaj.global@gmail.com>
1 parent e687d36 commit cdf3c96

1 file changed

Lines changed: 40 additions & 11 deletions

File tree

pkg/k8s/persistent_volumes.go

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,18 +188,33 @@ func runWithVolumeMounted(ctx context.Context, podImage string, podCommand []str
188188
return fmt.Errorf("cannot set up the watcher: %w", err)
189189
}
190190
defer watcher.Stop()
191+
191192
termCh := make(chan corev1.ContainerStateTerminated, 1)
193+
errCh := make(chan error, 1)
194+
192195
go func() {
193-
for event := range watcher.ResultChan() {
194-
p, ok := event.Object.(*corev1.Pod)
195-
if !ok {
196-
continue
197-
}
198-
if len(p.Status.ContainerStatuses) > 0 {
199-
termState := event.Object.(*corev1.Pod).Status.ContainerStatuses[0].State.Terminated
200-
if termState != nil {
201-
termCh <- *termState
202-
break
196+
for {
197+
select {
198+
case <-localCtx.Done():
199+
return
200+
201+
case event, ok := <-watcher.ResultChan():
202+
if !ok {
203+
errCh <- errors.New("kubernetes pod watch channel closed unexpectedly")
204+
return
205+
}
206+
207+
p, ok := event.Object.(*corev1.Pod)
208+
if !ok {
209+
continue
210+
}
211+
212+
if len(p.Status.ContainerStatuses) > 0 {
213+
termState := p.Status.ContainerStatuses[0].State.Terminated
214+
if termState != nil {
215+
termCh <- *termState
216+
return
217+
}
203218
}
204219
}
205220
}
@@ -211,7 +226,21 @@ func runWithVolumeMounted(ctx context.Context, podImage string, podCommand []str
211226
return fmt.Errorf("cannot attach stdio to the pod: %w", err)
212227
}
213228

214-
termState := <-termCh
229+
var termState corev1.ContainerStateTerminated
230+
231+
select {
232+
case termState = <-termCh:
233+
234+
case watchErr := <-errCh:
235+
if watchErr == nil {
236+
return errors.New("pod execution failed during watch")
237+
}
238+
return fmt.Errorf("pod execution failed during watch: %w", watchErr)
239+
240+
case <-ctx.Done():
241+
return ctx.Err()
242+
}
243+
215244
if termState.ExitCode != 0 {
216245
cmdOut := strings.Trim(outBuff.String(), "\n")
217246
err = fmt.Errorf("the command failed: exitcode=%d, out=%q", termState.ExitCode, cmdOut)

0 commit comments

Comments
 (0)