diff options
-rw-r--r-- | runsc/main.go | 18 | ||||
-rw-r--r-- | runsc/test/image/image_test.go | 21 |
2 files changed, 38 insertions, 1 deletions
diff --git a/runsc/main.go b/runsc/main.go index 2a18c4b9e..16d30f7a0 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -175,14 +175,30 @@ func main() { cmd.Fatalf("invalid log format %q, must be 'json' or 'text'", *logFormat) } + subcommand := flag.CommandLine.Arg(0) if *debugLogFD > -1 { f := os.NewFile(uintptr(*debugLogFD), "debug log file") + + // Quick sanity check to make sure no other commands get passed + // a log fd (they should use log dir instead). + if subcommand != "boot" { + cmd.Fatalf("flag --debug-log-fd should only be passed to 'boot' command, but was passed to %q", subcommand) + } + + // If we are the boot process, then we own our stdio FDs and + // can do what we want with them. Since Docker and Containerd + // both eat boot's stderr, we dup our stderr to the provided + // log FD so that panics will appear in the logs, rather than + // just disappear. + if err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd())); err != nil { + cmd.Fatalf("error dup'ing fd %d to stderr: %v", f.Fd(), err) + } + e = log.MultiEmitter{e, log.GoogleEmitter{&log.Writer{Next: f}}} } else if *debugLogDir != "" { if err := os.MkdirAll(*debugLogDir, 0775); err != nil { cmd.Fatalf("error creating dir %q: %v", *debugLogDir, err) } - subcommand := flag.CommandLine.Arg(0) f, err := specutils.DebugLogFile(*debugLogDir, subcommand) if err != nil { cmd.Fatalf("error opening debug log file in %q: %v", *debugLogDir, err) diff --git a/runsc/test/image/image_test.go b/runsc/test/image/image_test.go index 341bdc1d5..428f05c04 100644 --- a/runsc/test/image/image_test.go +++ b/runsc/test/image/image_test.go @@ -303,6 +303,27 @@ func TestRuby(t *testing.T) { } } +func TestStdio(t *testing.T) { + if err := testutil.Pull("alpine"); err != nil { + t.Fatalf("docker pull failed: %v", err) + } + d := testutil.MakeDocker("stdio-test") + + wantStdout := "hello stdout" + wantStderr := "bonjour stderr" + cmd := fmt.Sprintf("echo %q; echo %q 1>&2;", wantStdout, wantStderr) + if err := d.Run("alpine", "/bin/sh", "-c", cmd); err != nil { + t.Fatalf("docker run failed: %v", err) + } + defer d.CleanUp() + + for _, want := range []string{wantStdout, wantStderr} { + if _, err := d.WaitForOutput(want, 5*time.Second); err != nil { + t.Fatalf("docker didn't get output %q : %v", want, err) + } + } +} + func TestMain(m *testing.M) { testutil.EnsureSupportedDockerVersion() os.Exit(m.Run()) |