|
@@ -1,4 +1,4 @@
|
|
-package runconfig
|
|
|
|
|
|
+package stream
|
|
|
|
|
|
import (
|
|
import (
|
|
"fmt"
|
|
"fmt"
|
|
@@ -14,16 +14,16 @@ import (
|
|
"github.com/docker/docker/pkg/pools"
|
|
"github.com/docker/docker/pkg/pools"
|
|
)
|
|
)
|
|
|
|
|
|
-// StreamConfig holds information about I/O streams managed together.
|
|
|
|
|
|
+// Config holds information about I/O streams managed together.
|
|
//
|
|
//
|
|
-// streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
|
|
|
|
|
|
+// config.StdinPipe returns a WriteCloser which can be used to feed data
|
|
// to the standard input of the streamConfig's active process.
|
|
// to the standard input of the streamConfig's active process.
|
|
-// streamConfig.StdoutPipe and streamConfig.StderrPipe each return a ReadCloser
|
|
|
|
|
|
+// config.StdoutPipe and streamConfig.StderrPipe each return a ReadCloser
|
|
// which can be used to retrieve the standard output (and error) generated
|
|
// which can be used to retrieve the standard output (and error) generated
|
|
// by the container's active process. The output (and error) are actually
|
|
// by the container's active process. The output (and error) are actually
|
|
// copied and delivered to all StdoutPipe and StderrPipe consumers, using
|
|
// copied and delivered to all StdoutPipe and StderrPipe consumers, using
|
|
// a kind of "broadcaster".
|
|
// a kind of "broadcaster".
|
|
-type StreamConfig struct {
|
|
|
|
|
|
+type Config struct {
|
|
sync.WaitGroup
|
|
sync.WaitGroup
|
|
stdout *broadcaster.Unbuffered
|
|
stdout *broadcaster.Unbuffered
|
|
stderr *broadcaster.Unbuffered
|
|
stderr *broadcaster.Unbuffered
|
|
@@ -31,76 +31,76 @@ type StreamConfig struct {
|
|
stdinPipe io.WriteCloser
|
|
stdinPipe io.WriteCloser
|
|
}
|
|
}
|
|
|
|
|
|
-// NewStreamConfig creates a stream config and initializes
|
|
|
|
|
|
+// NewConfig creates a stream config and initializes
|
|
// the standard err and standard out to new unbuffered broadcasters.
|
|
// the standard err and standard out to new unbuffered broadcasters.
|
|
-func NewStreamConfig() *StreamConfig {
|
|
|
|
- return &StreamConfig{
|
|
|
|
|
|
+func NewConfig() *Config {
|
|
|
|
+ return &Config{
|
|
stderr: new(broadcaster.Unbuffered),
|
|
stderr: new(broadcaster.Unbuffered),
|
|
stdout: new(broadcaster.Unbuffered),
|
|
stdout: new(broadcaster.Unbuffered),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Stdout returns the standard output in the configuration.
|
|
// Stdout returns the standard output in the configuration.
|
|
-func (streamConfig *StreamConfig) Stdout() *broadcaster.Unbuffered {
|
|
|
|
- return streamConfig.stdout
|
|
|
|
|
|
+func (c *Config) Stdout() *broadcaster.Unbuffered {
|
|
|
|
+ return c.stdout
|
|
}
|
|
}
|
|
|
|
|
|
// Stderr returns the standard error in the configuration.
|
|
// Stderr returns the standard error in the configuration.
|
|
-func (streamConfig *StreamConfig) Stderr() *broadcaster.Unbuffered {
|
|
|
|
- return streamConfig.stderr
|
|
|
|
|
|
+func (c *Config) Stderr() *broadcaster.Unbuffered {
|
|
|
|
+ return c.stderr
|
|
}
|
|
}
|
|
|
|
|
|
// Stdin returns the standard input in the configuration.
|
|
// Stdin returns the standard input in the configuration.
|
|
-func (streamConfig *StreamConfig) Stdin() io.ReadCloser {
|
|
|
|
- return streamConfig.stdin
|
|
|
|
|
|
+func (c *Config) Stdin() io.ReadCloser {
|
|
|
|
+ return c.stdin
|
|
}
|
|
}
|
|
|
|
|
|
// StdinPipe returns an input writer pipe as an io.WriteCloser.
|
|
// StdinPipe returns an input writer pipe as an io.WriteCloser.
|
|
-func (streamConfig *StreamConfig) StdinPipe() io.WriteCloser {
|
|
|
|
- return streamConfig.stdinPipe
|
|
|
|
|
|
+func (c *Config) StdinPipe() io.WriteCloser {
|
|
|
|
+ return c.stdinPipe
|
|
}
|
|
}
|
|
|
|
|
|
// StdoutPipe creates a new io.ReadCloser with an empty bytes pipe.
|
|
// StdoutPipe creates a new io.ReadCloser with an empty bytes pipe.
|
|
// It adds this new out pipe to the Stdout broadcaster.
|
|
// It adds this new out pipe to the Stdout broadcaster.
|
|
-func (streamConfig *StreamConfig) StdoutPipe() io.ReadCloser {
|
|
|
|
|
|
+func (c *Config) StdoutPipe() io.ReadCloser {
|
|
bytesPipe := ioutils.NewBytesPipe()
|
|
bytesPipe := ioutils.NewBytesPipe()
|
|
- streamConfig.stdout.Add(bytesPipe)
|
|
|
|
|
|
+ c.stdout.Add(bytesPipe)
|
|
return bytesPipe
|
|
return bytesPipe
|
|
}
|
|
}
|
|
|
|
|
|
// StderrPipe creates a new io.ReadCloser with an empty bytes pipe.
|
|
// StderrPipe creates a new io.ReadCloser with an empty bytes pipe.
|
|
// It adds this new err pipe to the Stderr broadcaster.
|
|
// It adds this new err pipe to the Stderr broadcaster.
|
|
-func (streamConfig *StreamConfig) StderrPipe() io.ReadCloser {
|
|
|
|
|
|
+func (c *Config) StderrPipe() io.ReadCloser {
|
|
bytesPipe := ioutils.NewBytesPipe()
|
|
bytesPipe := ioutils.NewBytesPipe()
|
|
- streamConfig.stderr.Add(bytesPipe)
|
|
|
|
|
|
+ c.stderr.Add(bytesPipe)
|
|
return bytesPipe
|
|
return bytesPipe
|
|
}
|
|
}
|
|
|
|
|
|
// NewInputPipes creates new pipes for both standard inputs, Stdin and StdinPipe.
|
|
// NewInputPipes creates new pipes for both standard inputs, Stdin and StdinPipe.
|
|
-func (streamConfig *StreamConfig) NewInputPipes() {
|
|
|
|
- streamConfig.stdin, streamConfig.stdinPipe = io.Pipe()
|
|
|
|
|
|
+func (c *Config) NewInputPipes() {
|
|
|
|
+ c.stdin, c.stdinPipe = io.Pipe()
|
|
}
|
|
}
|
|
|
|
|
|
// NewNopInputPipe creates a new input pipe that will silently drop all messages in the input.
|
|
// NewNopInputPipe creates a new input pipe that will silently drop all messages in the input.
|
|
-func (streamConfig *StreamConfig) NewNopInputPipe() {
|
|
|
|
- streamConfig.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard)
|
|
|
|
|
|
+func (c *Config) NewNopInputPipe() {
|
|
|
|
+ c.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard)
|
|
}
|
|
}
|
|
|
|
|
|
// CloseStreams ensures that the configured streams are properly closed.
|
|
// CloseStreams ensures that the configured streams are properly closed.
|
|
-func (streamConfig *StreamConfig) CloseStreams() error {
|
|
|
|
|
|
+func (c *Config) CloseStreams() error {
|
|
var errors []string
|
|
var errors []string
|
|
|
|
|
|
- if streamConfig.stdin != nil {
|
|
|
|
- if err := streamConfig.stdin.Close(); err != nil {
|
|
|
|
|
|
+ if c.stdin != nil {
|
|
|
|
+ if err := c.stdin.Close(); err != nil {
|
|
errors = append(errors, fmt.Sprintf("error close stdin: %s", err))
|
|
errors = append(errors, fmt.Sprintf("error close stdin: %s", err))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if err := streamConfig.stdout.Clean(); err != nil {
|
|
|
|
|
|
+ if err := c.stdout.Clean(); err != nil {
|
|
errors = append(errors, fmt.Sprintf("error close stdout: %s", err))
|
|
errors = append(errors, fmt.Sprintf("error close stdout: %s", err))
|
|
}
|
|
}
|
|
|
|
|
|
- if err := streamConfig.stderr.Clean(); err != nil {
|
|
|
|
|
|
+ if err := c.stderr.Clean(); err != nil {
|
|
errors = append(errors, fmt.Sprintf("error close stderr: %s", err))
|
|
errors = append(errors, fmt.Sprintf("error close stderr: %s", err))
|
|
}
|
|
}
|
|
|
|
|
|
@@ -112,25 +112,25 @@ func (streamConfig *StreamConfig) CloseStreams() error {
|
|
}
|
|
}
|
|
|
|
|
|
// CopyToPipe connects streamconfig with a libcontainerd.IOPipe
|
|
// CopyToPipe connects streamconfig with a libcontainerd.IOPipe
|
|
-func (streamConfig *StreamConfig) CopyToPipe(iop libcontainerd.IOPipe) {
|
|
|
|
|
|
+func (c *Config) CopyToPipe(iop libcontainerd.IOPipe) {
|
|
copyFunc := func(w io.Writer, r io.Reader) {
|
|
copyFunc := func(w io.Writer, r io.Reader) {
|
|
- streamConfig.Add(1)
|
|
|
|
|
|
+ c.Add(1)
|
|
go func() {
|
|
go func() {
|
|
if _, err := pools.Copy(w, r); err != nil {
|
|
if _, err := pools.Copy(w, r); err != nil {
|
|
logrus.Errorf("stream copy error: %+v", err)
|
|
logrus.Errorf("stream copy error: %+v", err)
|
|
}
|
|
}
|
|
- streamConfig.Done()
|
|
|
|
|
|
+ c.Done()
|
|
}()
|
|
}()
|
|
}
|
|
}
|
|
|
|
|
|
if iop.Stdout != nil {
|
|
if iop.Stdout != nil {
|
|
- copyFunc(streamConfig.Stdout(), iop.Stdout)
|
|
|
|
|
|
+ copyFunc(c.Stdout(), iop.Stdout)
|
|
}
|
|
}
|
|
if iop.Stderr != nil {
|
|
if iop.Stderr != nil {
|
|
- copyFunc(streamConfig.Stderr(), iop.Stderr)
|
|
|
|
|
|
+ copyFunc(c.Stderr(), iop.Stderr)
|
|
}
|
|
}
|
|
|
|
|
|
- if stdin := streamConfig.Stdin(); stdin != nil {
|
|
|
|
|
|
+ if stdin := c.Stdin(); stdin != nil {
|
|
if iop.Stdin != nil {
|
|
if iop.Stdin != nil {
|
|
go func() {
|
|
go func() {
|
|
pools.Copy(iop.Stdin, stdin)
|
|
pools.Copy(iop.Stdin, stdin)
|