pkg/bindings/containers: do not ignore ErrUnexpectedEOF

Do not ignore ErrUnexpectedEOF from DemuxHeader(), if we fail to parse
the header there must have been a clear protocal error between client
and server which should be reported and not silently ignored. I wonder
ig this might explain why we have missing remote exec/attach output
without any error, it is possible we are eating some internal errors due
this.

Commit ba8eba83ef added the ErrUnexpectedEOF check but without any
explanation why that would be needed. The tests from that commit pass
without it locally but not in CI. With some debugging best I found the
issue is actually a test bug. The channel is not consumed until it is
closed which means the main test exists before the log reading goroutine
is done. And if the main test exists the first step it does is to kill
the podman service which then can trigger the ErrUnexpectedEOF server on
the still open http connection and thus the test case failed there.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2025-07-09 18:10:40 +02:00
parent ffec133766
commit a360b29626
3 changed files with 8 additions and 3 deletions

View File

@ -219,7 +219,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri
// Read multiplexed channels and write to appropriate stream
fd, l, err := DemuxHeader(socket, buffer)
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
if errors.Is(err, io.EOF) {
return nil
}
return err
@ -540,7 +540,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
// Read multiplexed channels and write to appropriate stream
fd, l, err := DemuxHeader(socket, buffer)
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
if errors.Is(err, io.EOF) {
return nil
}
return err

View File

@ -44,7 +44,7 @@ func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan,
for {
fd, l, err := DemuxHeader(response.Body, buffer)
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
if errors.Is(err, io.EOF) {
return nil
}
return err

View File

@ -383,6 +383,11 @@ var _ = Describe("Podman containers ", func() {
o = strings.TrimSpace(o)
_, err = time.Parse(time.RFC1123Z, o)
Expect(err).ShouldNot(HaveOccurred())
// drain the line channel and make sure there are no more log lines
for l := range stdoutChan {
Fail("container logs returned more than one line: " + l)
}
})
It("podman top", func() {