worker: add stdout/stderr to runc worker
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-18.09
parent
08134677cd
commit
28045f19bf
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue