From 28045f19bf8b0715901faba059632c2db2355a5e Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 1 Jun 2017 17:30:02 -0700 Subject: [PATCH] worker: add stdout/stderr to runc worker Signed-off-by: Tonis Tiigi --- control/control_test.go | 19 +++++++++++++++---- worker/runcworker/worker.go | 35 +++++++++++++++++++++++++++++------ worker/worker.go | 4 +++- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/control/control_test.go b/control/control_test.go index bc1b2225..27c2dbc9 100644 --- a/control/control_test.go +++ b/control/control_test.go @@ -3,6 +3,7 @@ package control import ( + "bytes" "context" "io" "io/ioutil" @@ -107,21 +108,23 @@ func TestControl(t *testing.T) { meta := worker.Meta{ Args: []string{"/bin/sh", "-c", "echo \"foo\" > /bar"}, - // Args: []string{"/bin/sleep", "3"}, - Cwd: "/", + Cwd: "/", } m := make(map[string]cache.Mountable) m["/"] = snap - err = w.Exec(context.TODO(), meta, m) + stderr := bytes.NewBuffer(nil) + + err = w.Exec(context.TODO(), meta, m, nil, &nopCloser{stderr}) assert.Error(t, err) // Read-only root + assert.Contains(t, stderr.String(), "Read-only file system") root, err := cm.New(snap) assert.NoError(t, err) m["/"] = root - err = w.Exec(context.TODO(), meta, m) + err = w.Exec(context.TODO(), meta, m, nil, nil) assert.NoError(t, err) rf, err := root.Freeze() @@ -241,3 +244,11 @@ func (rc *readCounter) Read(p []byte) (n int, err error) { rc.c += int64(n) return } + +type nopCloser struct { + io.Writer +} + +func (n *nopCloser) Close() error { + return nil +} diff --git a/worker/runcworker/worker.go b/worker/runcworker/worker.go index 0536eb88..3d65a968 100644 --- a/worker/runcworker/worker.go +++ b/worker/runcworker/worker.go @@ -4,7 +4,9 @@ import ( "crypto/rand" "encoding/hex" "encoding/json" + "io" "os" + "os/exec" "path/filepath" "syscall" @@ -36,7 +38,7 @@ func New(root string) (worker.Worker, error) { return w, nil } -func (w *runcworker) Exec(ctx context.Context, meta worker.Meta, mounts map[string]cache.Mountable) error { +func (w *runcworker) Exec(ctx context.Context, meta worker.Meta, mounts map[string]cache.Mountable, stdout, stderr io.WriteCloser) error { root, ok := mounts["/"] if !ok { return errors.Errorf("no root mount") @@ -81,12 +83,8 @@ func (w *runcworker) Exec(ctx context.Context, meta worker.Meta, mounts map[stri return err } - io, err := runc.NewSTDIO() - if err != nil { - return err - } status, err := w.runc.Run(ctx, id, bundle, &runc.CreateOpts{ - IO: io, + IO: &forwardIO{stdout: stdout, stderr: stderr}, }) if status != 0 { return errors.Errorf("exit code %d", status) @@ -95,6 +93,31 @@ func (w *runcworker) Exec(ctx context.Context, meta worker.Meta, mounts map[stri return err } +type forwardIO struct { + stdout, stderr io.WriteCloser +} + +func (s *forwardIO) Close() error { + return nil +} + +func (s *forwardIO) Set(cmd *exec.Cmd) { + cmd.Stdout = s.stdout + cmd.Stderr = s.stderr +} + +func (s *forwardIO) Stdin() io.WriteCloser { + return nil +} + +func (s *forwardIO) Stdout() io.ReadCloser { + return nil +} + +func (s *forwardIO) Stderr() io.ReadCloser { + return nil +} + func generateID() string { b := make([]byte, 32) if _, err := rand.Read(b); err != nil { diff --git a/worker/worker.go b/worker/worker.go index 6a0340cb..43b11ff3 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -1,6 +1,8 @@ package worker import ( + "io" + "github.com/tonistiigi/buildkit_poc/cache" "golang.org/x/net/context" ) @@ -16,5 +18,5 @@ type Meta struct { type Worker interface { // TODO: add stdout/err - Exec(ctx context.Context, meta Meta, mounts map[string]cache.Mountable) error + Exec(ctx context.Context, meta Meta, mounts map[string]cache.Mountable, stdout, stderr io.WriteCloser) error }