Merge pull request #430 from crosbymichael/pipes
Move STDIO initialization to libcontainer.Process
This commit is contained in:
commit
11f8fdca33
|
@ -5,6 +5,7 @@ import (
|
|||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type processOperations interface {
|
||||
|
@ -78,6 +79,54 @@ func (p Process) Signal(sig os.Signal) error {
|
|||
return p.ops.signal(sig)
|
||||
}
|
||||
|
||||
// IO holds the process's STDIO
|
||||
type IO struct {
|
||||
Stdin io.WriteCloser
|
||||
Stdout io.ReadCloser
|
||||
Stderr io.ReadCloser
|
||||
}
|
||||
|
||||
// InitializeIO creates pipes for use with the process's STDIO
|
||||
// and returns the opposite side for each
|
||||
func (p *Process) InitializeIO(rootuid int) (i *IO, err error) {
|
||||
var fds []uintptr
|
||||
i = &IO{}
|
||||
// cleanup in case of an error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
for _, fd := range fds {
|
||||
syscall.Close(int(fd))
|
||||
}
|
||||
}
|
||||
}()
|
||||
// STDIN
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fds = append(fds, r.Fd(), w.Fd())
|
||||
p.Stdin, i.Stdin = r, w
|
||||
// STDOUT
|
||||
if r, w, err = os.Pipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fds = append(fds, r.Fd(), w.Fd())
|
||||
p.Stdout, i.Stdout = w, r
|
||||
// STDERR
|
||||
if r, w, err = os.Pipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fds = append(fds, r.Fd(), w.Fd())
|
||||
p.Stderr, i.Stderr = w, r
|
||||
// change ownership of the pipes incase we are in a user namespace
|
||||
for _, fd := range fds {
|
||||
if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// NewConsole creates new console for process and returns it
|
||||
func (p *Process) NewConsole(rootuid int) (Console, error) {
|
||||
console, err := NewConsole(rootuid, rootuid)
|
||||
|
|
|
@ -126,11 +126,7 @@ func restoreContainer(context *cli.Context, spec *specs.LinuxSpec, config *confi
|
|||
}
|
||||
}
|
||||
}()
|
||||
process := &libcontainer.Process{
|
||||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
process := &libcontainer.Process{}
|
||||
tty, err := newTty(spec.Process.Terminal, process, rootuid)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
|
|
2
start.go
2
start.go
|
@ -110,12 +110,10 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec, rspec *specs.Li
|
|||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
for i := SD_LISTEN_FDS_START; i < (listenFdsInt + SD_LISTEN_FDS_START); i++ {
|
||||
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), ""))
|
||||
}
|
||||
}
|
||||
|
||||
tty, err := newTty(spec.Process.Terminal, process, rootuid)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
|
|
42
tty.go
42
tty.go
|
@ -6,7 +6,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/term"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
|
@ -25,38 +24,20 @@ func newTty(create bool, p *libcontainer.Process, rootuid int) (*tty, error) {
|
|||
// setup standard pipes so that the TTY of the calling runc process
|
||||
// is not inherited by the container.
|
||||
func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) {
|
||||
var (
|
||||
t = &tty{}
|
||||
fds []int
|
||||
)
|
||||
r, w, err := os.Pipe()
|
||||
i, err := p.InitializeIO(rootuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
||||
go io.Copy(w, os.Stdin)
|
||||
t.closers = append(t.closers, w)
|
||||
p.Stdin = r
|
||||
if r, w, err = os.Pipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
||||
go io.Copy(os.Stdout, r)
|
||||
p.Stdout = w
|
||||
t.closers = append(t.closers, r)
|
||||
if r, w, err = os.Pipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
||||
go io.Copy(os.Stderr, r)
|
||||
p.Stderr = w
|
||||
t.closers = append(t.closers, r)
|
||||
// change the ownership of the pipe fds incase we are in a user namespace.
|
||||
for _, fd := range fds {
|
||||
if err := syscall.Fchown(fd, rootuid, rootuid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := &tty{
|
||||
closers: []io.Closer{
|
||||
i.Stdin,
|
||||
i.Stdout,
|
||||
i.Stderr,
|
||||
},
|
||||
}
|
||||
go io.Copy(i.Stdin, os.Stdin)
|
||||
go io.Copy(os.Stdout, i.Stdout)
|
||||
go io.Copy(os.Stderr, i.Stderr)
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
@ -78,9 +59,6 @@ func createTty(p *libcontainer.Process, rootuid int) (*tty, error) {
|
|||
console,
|
||||
},
|
||||
}
|
||||
p.Stderr = nil
|
||||
p.Stdout = nil
|
||||
p.Stdin = nil
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
|
7
utils.go
7
utils.go
|
@ -161,10 +161,7 @@ func newProcess(p specs.Process) *libcontainer.Process {
|
|||
Args: p.Args,
|
||||
Env: p.Env,
|
||||
// TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
|
||||
User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
|
||||
Cwd: p.Cwd,
|
||||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
|
||||
Cwd: p.Cwd,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue