Don't provide IO when it's not set
This makes sure that runc does not get any valid IO for the pipe. Some builds and other containers will be stuck if they inspect stdin expecially and its a pipe but not connected to any user input. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
55
vendor/github.com/containerd/go-runc/io.go
generated
vendored
55
vendor/github.com/containerd/go-runc/io.go
generated
vendored
@@ -34,6 +34,24 @@ type StartCloser interface {
|
||||
CloseAfterStart() error
|
||||
}
|
||||
|
||||
// IOOpt sets I/O creation options
|
||||
type IOOpt func(*IOOption)
|
||||
|
||||
// IOOption holds I/O creation options
|
||||
type IOOption struct {
|
||||
OpenStdin bool
|
||||
OpenStdout bool
|
||||
OpenStderr bool
|
||||
}
|
||||
|
||||
func defaultIOOption() *IOOption {
|
||||
return &IOOption{
|
||||
OpenStdin: true,
|
||||
OpenStdout: true,
|
||||
OpenStderr: true,
|
||||
}
|
||||
}
|
||||
|
||||
func newPipe() (*pipe, error) {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
@@ -65,14 +83,23 @@ type pipeIO struct {
|
||||
}
|
||||
|
||||
func (i *pipeIO) Stdin() io.WriteCloser {
|
||||
if i.in == nil {
|
||||
return nil
|
||||
}
|
||||
return i.in.w
|
||||
}
|
||||
|
||||
func (i *pipeIO) Stdout() io.ReadCloser {
|
||||
if i.out == nil {
|
||||
return nil
|
||||
}
|
||||
return i.out.r
|
||||
}
|
||||
|
||||
func (i *pipeIO) Stderr() io.ReadCloser {
|
||||
if i.err == nil {
|
||||
return nil
|
||||
}
|
||||
return i.err.r
|
||||
}
|
||||
|
||||
@@ -83,28 +110,38 @@ func (i *pipeIO) Close() error {
|
||||
i.out,
|
||||
i.err,
|
||||
} {
|
||||
if cerr := v.Close(); err == nil {
|
||||
err = cerr
|
||||
if v != nil {
|
||||
if cerr := v.Close(); err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *pipeIO) CloseAfterStart() error {
|
||||
for _, f := range []*os.File{
|
||||
i.out.w,
|
||||
i.err.w,
|
||||
for _, f := range []*pipe{
|
||||
i.out,
|
||||
i.err,
|
||||
} {
|
||||
f.Close()
|
||||
if f != nil {
|
||||
f.w.Close()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set sets the io to the exec.Cmd
|
||||
func (i *pipeIO) Set(cmd *exec.Cmd) {
|
||||
cmd.Stdin = i.in.r
|
||||
cmd.Stdout = i.out.w
|
||||
cmd.Stderr = i.err.w
|
||||
if i.in != nil {
|
||||
cmd.Stdin = i.in.r
|
||||
}
|
||||
if i.out != nil {
|
||||
cmd.Stdout = i.out.w
|
||||
}
|
||||
if i.err != nil {
|
||||
cmd.Stderr = i.err.w
|
||||
}
|
||||
}
|
||||
|
||||
func NewSTDIO() (IO, error) {
|
||||
|
||||
59
vendor/github.com/containerd/go-runc/io_unix.go
generated
vendored
59
vendor/github.com/containerd/go-runc/io_unix.go
generated
vendored
@@ -24,8 +24,15 @@ import (
|
||||
)
|
||||
|
||||
// NewPipeIO creates pipe pairs to be used with runc
|
||||
func NewPipeIO(uid, gid int) (i IO, err error) {
|
||||
var pipes []*pipe
|
||||
func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
|
||||
option := defaultIOOption()
|
||||
for _, o := range opts {
|
||||
o(option)
|
||||
}
|
||||
var (
|
||||
pipes []*pipe
|
||||
stdin, stdout, stderr *pipe
|
||||
)
|
||||
// cleanup in case of an error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@@ -34,33 +41,33 @@ func NewPipeIO(uid, gid int) (i IO, err error) {
|
||||
}
|
||||
}
|
||||
}()
|
||||
stdin, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if option.OpenStdin {
|
||||
if stdin, err = newPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stdin)
|
||||
if err = unix.Fchown(int(stdin.r.Fd()), uid, gid); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to chown stdin")
|
||||
}
|
||||
}
|
||||
pipes = append(pipes, stdin)
|
||||
if err = unix.Fchown(int(stdin.r.Fd()), uid, gid); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to chown stdin")
|
||||
if option.OpenStdout {
|
||||
if stdout, err = newPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stdout)
|
||||
if err = unix.Fchown(int(stdout.w.Fd()), uid, gid); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to chown stdout")
|
||||
}
|
||||
}
|
||||
|
||||
stdout, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if option.OpenStderr {
|
||||
if stderr, err = newPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stderr)
|
||||
if err = unix.Fchown(int(stderr.w.Fd()), uid, gid); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to chown stderr")
|
||||
}
|
||||
}
|
||||
pipes = append(pipes, stdout)
|
||||
if err = unix.Fchown(int(stdout.w.Fd()), uid, gid); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to chown stdout")
|
||||
}
|
||||
|
||||
stderr, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stderr)
|
||||
if err = unix.Fchown(int(stderr.w.Fd()), uid, gid); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to chown stderr")
|
||||
}
|
||||
|
||||
return &pipeIO{
|
||||
in: stdin,
|
||||
out: stdout,
|
||||
|
||||
41
vendor/github.com/containerd/go-runc/io_windows.go
generated
vendored
41
vendor/github.com/containerd/go-runc/io_windows.go
generated
vendored
@@ -19,8 +19,15 @@
|
||||
package runc
|
||||
|
||||
// NewPipeIO creates pipe pairs to be used with runc
|
||||
func NewPipeIO() (i IO, err error) {
|
||||
var pipes []*pipe
|
||||
func NewPipeIO(opts ...IOOpt) (i IO, err error) {
|
||||
option := defaultIOOption()
|
||||
for _, o := range opts {
|
||||
o(option)
|
||||
}
|
||||
var (
|
||||
pipes []*pipe
|
||||
stdin, stdout, stderr *pipe
|
||||
)
|
||||
// cleanup in case of an error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@@ -29,24 +36,24 @@ func NewPipeIO() (i IO, err error) {
|
||||
}
|
||||
}
|
||||
}()
|
||||
stdin, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if option.OpenStdin {
|
||||
if stdin, err = newPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stdin)
|
||||
}
|
||||
pipes = append(pipes, stdin)
|
||||
|
||||
stdout, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if option.OpenStdout {
|
||||
if stdout, err = newPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stdout)
|
||||
}
|
||||
pipes = append(pipes, stdout)
|
||||
|
||||
stderr, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if option.OpenStderr {
|
||||
if stderr, err = newPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pipes = append(pipes, stderr)
|
||||
}
|
||||
pipes = append(pipes, stderr)
|
||||
|
||||
return &pipeIO{
|
||||
in: stdin,
|
||||
out: stdout,
|
||||
|
||||
3
vendor/github.com/containerd/go-runc/runc.go
generated
vendored
3
vendor/github.com/containerd/go-runc/runc.go
generated
vendored
@@ -608,9 +608,8 @@ func parseVersion(data []byte) (Version, error) {
|
||||
var v Version
|
||||
parts := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||
if len(parts) != 3 {
|
||||
return v, ErrParseRuncVersion
|
||||
return v, nil
|
||||
}
|
||||
|
||||
for i, p := range []struct {
|
||||
dest *string
|
||||
split string
|
||||
|
||||
Reference in New Issue
Block a user