summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--runsc/main.go18
-rw-r--r--runsc/test/image/image_test.go21
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())