Move STDIO initialization to libcontainer.Process
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
0267ad05b0
commit
29b139f702
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
type processOperations interface {
|
type processOperations interface {
|
||||||
|
@ -78,6 +79,54 @@ func (p Process) Signal(sig os.Signal) error {
|
||||||
return p.ops.signal(sig)
|
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
|
// NewConsole creates new console for process and returns it
|
||||||
func (p *Process) NewConsole(rootuid int) (Console, error) {
|
func (p *Process) NewConsole(rootuid int) (Console, error) {
|
||||||
console, err := NewConsole(rootuid, rootuid)
|
console, err := NewConsole(rootuid, rootuid)
|
||||||
|
|
|
@ -126,11 +126,7 @@ func restoreContainer(context *cli.Context, spec *specs.LinuxSpec, config *confi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
process := &libcontainer.Process{
|
process := &libcontainer.Process{}
|
||||||
Stdin: os.Stdin,
|
|
||||||
Stdout: os.Stdout,
|
|
||||||
Stderr: os.Stderr,
|
|
||||||
}
|
|
||||||
tty, err := newTty(spec.Process.Terminal, process, rootuid)
|
tty, err := newTty(spec.Process.Terminal, process, rootuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
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 {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := SD_LISTEN_FDS_START; i < (listenFdsInt + SD_LISTEN_FDS_START); i++ {
|
for i := SD_LISTEN_FDS_START; i < (listenFdsInt + SD_LISTEN_FDS_START); i++ {
|
||||||
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), ""))
|
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tty, err := newTty(spec.Process.Terminal, process, rootuid)
|
tty, err := newTty(spec.Process.Terminal, process, rootuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
|
|
42
tty.go
42
tty.go
|
@ -6,7 +6,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"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
|
// setup standard pipes so that the TTY of the calling runc process
|
||||||
// is not inherited by the container.
|
// is not inherited by the container.
|
||||||
func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) {
|
func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) {
|
||||||
var (
|
i, err := p.InitializeIO(rootuid)
|
||||||
t = &tty{}
|
|
||||||
fds []int
|
|
||||||
)
|
|
||||||
r, w, err := os.Pipe()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
t := &tty{
|
||||||
go io.Copy(w, os.Stdin)
|
closers: []io.Closer{
|
||||||
t.closers = append(t.closers, w)
|
i.Stdin,
|
||||||
p.Stdin = r
|
i.Stdout,
|
||||||
if r, w, err = os.Pipe(); err != nil {
|
i.Stderr,
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
go io.Copy(i.Stdin, os.Stdin)
|
||||||
|
go io.Copy(os.Stdout, i.Stdout)
|
||||||
|
go io.Copy(os.Stderr, i.Stderr)
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +59,6 @@ func createTty(p *libcontainer.Process, rootuid int) (*tty, error) {
|
||||||
console,
|
console,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
p.Stderr = nil
|
|
||||||
p.Stdout = nil
|
|
||||||
p.Stdin = nil
|
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
utils.go
3
utils.go
|
@ -163,8 +163,5 @@ func newProcess(p specs.Process) *libcontainer.Process {
|
||||||
// TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
|
// 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),
|
User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
|
||||||
Cwd: p.Cwd,
|
Cwd: p.Cwd,
|
||||||
Stdin: os.Stdin,
|
|
||||||
Stdout: os.Stdout,
|
|
||||||
Stderr: os.Stderr,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue