mirror of
https://github.com/containers/podman.git
synced 2025-07-04 18:27:33 +08:00
fix podman top missing output flake
Sometimes there is no output displayed from the podman top command but no error is shown either. Looking at the code I think the issue here is that we do not wait for the output reader to end as it runs in a different goroutine. Thus the last lines of output might be missing. The fix is simply to wait for said goroutine to finish before returning. While at it also fix the missing scanner error check and return the read errors back to the caller. [NO NEW TESTS NEEDED] It is a flake. Fixes #19504 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
@ -297,19 +297,24 @@ func (c *Container) execPS(psArgs []string) ([]string, bool, error) {
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
defer wPipe.Close()
|
||||
defer rPipe.Close()
|
||||
|
||||
outErrChan := make(chan error)
|
||||
stdout := []string{}
|
||||
go func() {
|
||||
defer close(outErrChan)
|
||||
scanner := bufio.NewScanner(rPipe)
|
||||
for scanner.Scan() {
|
||||
stdout = append(stdout, scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
outErrChan <- err
|
||||
}
|
||||
}()
|
||||
|
||||
psPath, err := exec.LookPath("ps")
|
||||
if err != nil {
|
||||
wPipe.Close()
|
||||
return nil, true, err
|
||||
}
|
||||
args := append([]string{podmanTopCommand, strconv.Itoa(c.state.PID), psPath}, psArgs...)
|
||||
@ -326,6 +331,7 @@ func (c *Container) execPS(psArgs []string) ([]string, bool, error) {
|
||||
|
||||
retryContainerExec := true
|
||||
err = cmd.Run()
|
||||
wPipe.Close()
|
||||
if err != nil {
|
||||
exitError := &exec.ExitError{}
|
||||
if errors.As(err, &exitError) {
|
||||
@ -342,6 +348,10 @@ func (c *Container) execPS(psArgs []string) ([]string, bool, error) {
|
||||
err = fmt.Errorf("could not reexec podman-top command: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := <-outErrChan; err != nil {
|
||||
return nil, retryContainerExec, fmt.Errorf("failed to read ps stdout: %w", err)
|
||||
}
|
||||
return stdout, retryContainerExec, err
|
||||
}
|
||||
|
||||
@ -352,7 +362,6 @@ func (c *Container) execPSinContainer(args []string) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer wPipe.Close()
|
||||
defer rPipe.Close()
|
||||
|
||||
var errBuf bytes.Buffer
|
||||
@ -362,18 +371,24 @@ func (c *Container) execPSinContainer(args []string) ([]string, error) {
|
||||
streams.AttachOutput = true
|
||||
streams.AttachError = true
|
||||
|
||||
outErrChan := make(chan error)
|
||||
stdout := []string{}
|
||||
go func() {
|
||||
defer close(outErrChan)
|
||||
scanner := bufio.NewScanner(rPipe)
|
||||
for scanner.Scan() {
|
||||
stdout = append(stdout, scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
outErrChan <- err
|
||||
}
|
||||
}()
|
||||
|
||||
cmd := append([]string{"ps"}, args...)
|
||||
config := new(ExecConfig)
|
||||
config.Command = cmd
|
||||
ec, err := c.Exec(config, streams, nil)
|
||||
wPipe.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if ec != 0 {
|
||||
@ -386,5 +401,8 @@ func (c *Container) execPSinContainer(args []string) ([]string, error) {
|
||||
logrus.Debugf(errBuf.String())
|
||||
}
|
||||
|
||||
if err := <-outErrChan; err != nil {
|
||||
return nil, fmt.Errorf("failed to read ps stdout: %w", err)
|
||||
}
|
||||
return stdout, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user