Merge pull request #8686 from Luap99/logs-stderr

podman logs honor stderr correctly
This commit is contained in:
OpenShift Merge Robot
2020-12-11 10:38:17 -05:00
committed by GitHub
8 changed files with 58 additions and 14 deletions

View File

@ -122,6 +122,7 @@ func logs(_ *cobra.Command, args []string) error {
}
logsOptions.Since = since
}
logsOptions.Writer = os.Stdout
logsOptions.StdoutWriter = os.Stdout
logsOptions.StderrWriter = os.Stderr
return registry.ContainerEngine().ContainerLogs(registry.GetContext(), args, logsOptions.ContainerLogsOptions)
}

View File

@ -210,3 +210,19 @@ func NewLogLine(line string) (*LogLine, error) {
func (l *LogLine) Partial() bool {
return l.ParseLogType == PartialLogType
}
func (l *LogLine) Write(stdout io.Writer, stderr io.Writer, logOpts *LogOptions) {
switch l.Device {
case "stdout":
if stdout != nil {
fmt.Fprintln(stdout, l.String(logOpts))
}
case "stderr":
if stderr != nil {
fmt.Fprintln(stderr, l.String(logOpts))
}
default:
// Warn the user if the device type does not match. Most likely the file is corrupted.
logrus.Warnf("unknown Device type '%s' in log file from Container %s", l.Device, l.CID)
}
}

View File

@ -227,8 +227,10 @@ type ContainerLogsOptions struct {
Tail int64
// Show timestamps in the logs.
Timestamps bool
// Write the logs to Writer.
Writer io.Writer
// Write the stdout to this Writer.
StdoutWriter io.Writer
// Write the stderr to this Writer.
StderrWriter io.Writer
}
// ExecOptions describes the cli values to exec into

View File

@ -925,7 +925,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
}
func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error {
if options.Writer == nil {
if options.StdoutWriter == nil && options.StderrWriter == nil {
return errors.New("no io.Writer set for container logs")
}
@ -963,7 +963,7 @@ func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []strin
}()
for line := range logChannel {
fmt.Fprintln(options.Writer, line.String(logOpts))
line.Write(options.StdoutWriter, options.StderrWriter, logOpts)
}
return nil

View File

@ -360,11 +360,12 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG
func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string, options entities.ContainerLogsOptions) error {
since := options.Since.Format(time.RFC3339)
tail := strconv.FormatInt(options.Tail, 10)
stdout := options.Writer != nil
stdout := options.StdoutWriter != nil
stderr := options.StderrWriter != nil
opts := containers.LogOptions{
Follow: &options.Follow,
Since: &since,
Stderr: &stdout,
Stderr: &stderr,
Stdout: &stdout,
Tail: &tail,
Timestamps: &options.Timestamps,
@ -372,10 +373,11 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string,
}
var err error
outCh := make(chan string)
stdoutCh := make(chan string)
stderrCh := make(chan string)
ctx, cancel := context.WithCancel(context.Background())
go func() {
err = containers.Logs(ic.ClientCxt, nameOrIDs[0], opts, outCh, outCh)
err = containers.Logs(ic.ClientCxt, nameOrIDs[0], opts, stdoutCh, stderrCh)
cancel()
}()
@ -383,8 +385,14 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string,
select {
case <-ctx.Done():
return err
case line := <-outCh:
_, _ = io.WriteString(options.Writer, line+"\n")
case line := <-stdoutCh:
if options.StdoutWriter != nil {
_, _ = io.WriteString(options.StdoutWriter, line+"\n")
}
case line := <-stderrCh:
if options.StderrWriter != nil {
_, _ = io.WriteString(options.StderrWriter, line+"\n")
}
}
}
}

View File

@ -355,4 +355,21 @@ var _ = Describe("Podman logs", func() {
Expect(outlines[0]).To(Equal("1\r"))
Expect(outlines[1]).To(Equal("2\r"))
})
It("podman logs test stdout and stderr", func() {
cname := "log-test"
logc := podmanTest.Podman([]string{"run", "--name", cname, ALPINE, "sh", "-c", "echo stdout; echo stderr >&2"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
wait := podmanTest.Podman([]string{"wait", cname})
wait.WaitWithDefaultTimeout()
Expect(wait).To(Exit(0))
results := podmanTest.Podman([]string{"logs", cname})
results.WaitWithDefaultTimeout()
Expect(results).To(Exit(0))
Expect(results.OutputToString()).To(Equal("stdout"))
Expect(results.ErrorToString()).To(Equal("stderr"))
})
})

View File

@ -1072,7 +1072,7 @@ var _ = Describe("Podman play kube", func() {
logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)})
logs.WaitWithDefaultTimeout()
Expect(logs.ExitCode()).To(Equal(0))
Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted"))
Expect(logs.ErrorToString()).To(ContainSubstring("Operation not permitted"))
})
It("podman play kube seccomp pod level", func() {
@ -1099,7 +1099,7 @@ var _ = Describe("Podman play kube", func() {
logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)})
logs.WaitWithDefaultTimeout()
Expect(logs.ExitCode()).To(Equal(0))
Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted"))
Expect(logs.ErrorToString()).To(ContainSubstring("Operation not permitted"))
})
It("podman play kube with pull policy of never should be 125", func() {

View File

@ -239,7 +239,7 @@ var _ = Describe("Toolbox-specific testing", func() {
session = podmanTest.Podman([]string{"logs", "test"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring(expectedOutput))
Expect(session.ErrorToString()).To(ContainSubstring(expectedOutput))
})
It("podman create --userns=keep-id + podman exec - adding group with groupadd", func() {