Reduce the number of IO constructors

Signed-off-by: Daniel Nephin <dnephin@gmail.com>
This commit is contained in:
Daniel Nephin
2017-12-07 14:09:08 -05:00
parent a901091f7c
commit 7d4337e738
9 changed files with 171 additions and 139 deletions

View File

@@ -15,11 +15,12 @@ import (
"github.com/pkg/errors"
)
// newFIFOSetInTempDir returns a new set of fifos for the task
func newFIFOSetInTempDir(id string) (*FIFOSet, error) {
root := "/run/containerd/fifo"
if err := os.MkdirAll(root, 0700); err != nil {
return nil, err
// NewFIFOSetInDir returns a new FIFOSet with paths in a temporary directory under root
func NewFIFOSetInDir(root, id string, terminal bool) (*FIFOSet, error) {
if root != "" {
if err := os.MkdirAll(root, 0700); err != nil {
return nil, err
}
}
dir, err := ioutil.TempDir(root, "")
if err != nil {
@@ -29,18 +30,15 @@ func newFIFOSetInTempDir(id string) (*FIFOSet, error) {
return os.RemoveAll(dir)
}
return NewFIFOSet(Config{
Stdin: filepath.Join(dir, id+"-stdin"),
Stdout: filepath.Join(dir, id+"-stdout"),
Stderr: filepath.Join(dir, id+"-stderr"),
Stdin: filepath.Join(dir, id+"-stdin"),
Stdout: filepath.Join(dir, id+"-stdout"),
Stderr: filepath.Join(dir, id+"-stderr"),
Terminal: terminal,
}, closer), nil
}
func copyIO(fifos *FIFOSet, ioset *ioSet) (*cio, error) {
var (
ctx, cancel = context.WithCancel(context.Background())
wg = &sync.WaitGroup{}
)
func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) {
var ctx, cancel = context.WithCancel(context.Background())
pipes, err := openFifos(ctx, fifos)
if err != nil {
cancel()
@@ -49,14 +47,15 @@ func copyIO(fifos *FIFOSet, ioset *ioSet) (*cio, error) {
if fifos.Stdin != "" {
go func() {
io.Copy(pipes.Stdin, ioset.in)
io.Copy(pipes.Stdin, ioset.Stdin)
pipes.Stdin.Close()
}()
}
var wg = &sync.WaitGroup{}
wg.Add(1)
go func() {
io.Copy(ioset.out, pipes.Stdout)
io.Copy(ioset.Stdout, pipes.Stdout)
pipes.Stdout.Close()
wg.Done()
}()
@@ -64,12 +63,13 @@ func copyIO(fifos *FIFOSet, ioset *ioSet) (*cio, error) {
if !fifos.Terminal {
wg.Add(1)
go func() {
io.Copy(ioset.err, pipes.Stderr)
io.Copy(ioset.Stderr, pipes.Stderr)
pipes.Stderr.Close()
wg.Done()
}()
}
return &cio{
config: fifos.Config,
wg: wg,
closers: append(pipes.closers(), fifos),
cancel: cancel,
@@ -78,41 +78,38 @@ func copyIO(fifos *FIFOSet, ioset *ioSet) (*cio, error) {
func openFifos(ctx context.Context, fifos *FIFOSet) (pipes, error) {
var err error
f := new(pipes)
defer func() {
if err != nil {
fifos.Close()
}
}()
var f pipes
if fifos.Stdin != "" {
if f.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
return pipes{}, errors.Wrapf(err, "failed to open stdin fifo")
return f, errors.Wrapf(err, "failed to open stdin fifo")
}
}
if f.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
f.Stdin.Close()
return pipes{}, errors.Wrapf(err, "failed to open stdout fifo")
if fifos.Stdout != "" {
if f.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
f.Stdin.Close()
return f, errors.Wrapf(err, "failed to open stdout fifo")
}
}
if f.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
f.Stdin.Close()
f.Stdout.Close()
return pipes{}, errors.Wrapf(err, "failed to open stderr fifo")
if fifos.Stderr != "" {
if f.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil {
f.Stdin.Close()
f.Stdout.Close()
return f, errors.Wrapf(err, "failed to open stderr fifo")
}
}
return pipes{}, nil
return f, nil
}
// NewDirectIO returns an IO implementation that exposes the IO streams as io.ReadCloser
// and io.WriteCloser. FIFOs are created in /run/containerd/fifo.
func NewDirectIO(ctx context.Context, terminal bool) (*DirectIO, error) {
fifos, err := newFIFOSetInTempDir("")
if err != nil {
return nil, err
}
fifos.Terminal = terminal
ctx, cancel := context.WithCancel(context.Background())
// and io.WriteCloser.
func NewDirectIO(ctx context.Context, fifos *FIFOSet) (*DirectIO, error) {
ctx, cancel := context.WithCancel(ctx)
pipes, err := openFifos(ctx, fifos)
return &DirectIO{
pipes: pipes,
@@ -124,10 +121,6 @@ func NewDirectIO(ctx context.Context, terminal bool) (*DirectIO, error) {
}, err
}
// DirectIO allows task IO to be handled externally by the caller
type DirectIO struct {
pipes
cio
func (p *pipes) closers() []io.Closer {
return []io.Closer{p.Stdin, p.Stdout, p.Stderr}
}
var _ IO = &DirectIO{}