logs: adjust handling around partial log messages

In libpod/logs.LogLine.Write(), don't write a newline to stdout/stderr
when the log message is only part of a line.

In libpod.ConmonOCIRuntime.HTTPAttach(), don't send a newline over the
HTTP connection when the log message is only part of a line.

In pkg/api/handlers/compat.LogsFromContainer(), don't send a newline
over the HTTP connection when the log message is only part of a line,
and don't make doing so conditional on whether or not the client used
the docker or podman endpoint.

In pkg/domain/infra/tunnel.ContainerEngine.ContainerLogs(), don't add
our own newline to log messages, since they already come through from
the server when they need to.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2021-08-19 18:24:47 -04:00
parent b20a547059
commit 21f396de6f
4 changed files with 18 additions and 10 deletions

View File

@ -251,11 +251,19 @@ func (l *LogLine) Write(stdout io.Writer, stderr io.Writer, logOpts *LogOptions)
switch l.Device { switch l.Device {
case "stdout": case "stdout":
if stdout != nil { if stdout != nil {
fmt.Fprintln(stdout, l.String(logOpts)) if l.Partial() {
fmt.Fprint(stdout, l.String(logOpts))
} else {
fmt.Fprintln(stdout, l.String(logOpts))
}
} }
case "stderr": case "stderr":
if stderr != nil { if stderr != nil {
fmt.Fprintln(stderr, l.String(logOpts)) if l.Partial() {
fmt.Fprint(stderr, l.String(logOpts))
} else {
fmt.Fprintln(stderr, l.String(logOpts))
}
} }
default: default:
// Warn the user if the device type does not match. Most likely the file is corrupted. // Warn the user if the device type does not match. Most likely the file is corrupted.

View File

@ -625,9 +625,11 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
if err != nil { if err != nil {
break break
} }
_, err = httpBuf.Write([]byte("\n")) if !logLine.Partial() {
if err != nil { _, err = httpBuf.Write([]byte("\n"))
break if err != nil {
break
}
} }
err = httpBuf.Flush() err = httpBuf.Flush()
if err != nil { if err != nil {

View File

@ -152,9 +152,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
} }
frame.WriteString(line.Msg) frame.WriteString(line.Msg)
// Log lines in the compat layer require adding EOL if !line.Partial() {
// https://github.com/containers/podman/issues/8058
if !utils.IsLibpodRequest(r) {
frame.WriteString("\n") frame.WriteString("\n")
} }

View File

@ -404,11 +404,11 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string,
return err return err
case line := <-stdoutCh: case line := <-stdoutCh:
if opts.StdoutWriter != nil { if opts.StdoutWriter != nil {
_, _ = io.WriteString(opts.StdoutWriter, line+"\n") _, _ = io.WriteString(opts.StdoutWriter, line)
} }
case line := <-stderrCh: case line := <-stderrCh:
if opts.StderrWriter != nil { if opts.StderrWriter != nil {
_, _ = io.WriteString(opts.StderrWriter, line+"\n") _, _ = io.WriteString(opts.StderrWriter, line)
} }
} }
} }