|
@@ -41,6 +41,13 @@ var (
|
|
ErrContainerStartTimeout = errors.New("The container failed to start due to timed out.")
|
|
ErrContainerStartTimeout = errors.New("The container failed to start due to timed out.")
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+type StdConfig struct {
|
|
|
|
+ stdout *broadcastwriter.BroadcastWriter
|
|
|
|
+ stderr *broadcastwriter.BroadcastWriter
|
|
|
|
+ stdin io.ReadCloser
|
|
|
|
+ stdinPipe io.WriteCloser
|
|
|
|
+}
|
|
|
|
+
|
|
type Container struct {
|
|
type Container struct {
|
|
*State
|
|
*State
|
|
root string // Path to the "home" of the container, including metadata.
|
|
root string // Path to the "home" of the container, including metadata.
|
|
@@ -66,10 +73,7 @@ type Container struct {
|
|
ExecDriver string
|
|
ExecDriver string
|
|
|
|
|
|
command *execdriver.Command
|
|
command *execdriver.Command
|
|
- stdout *broadcastwriter.BroadcastWriter
|
|
|
|
- stderr *broadcastwriter.BroadcastWriter
|
|
|
|
- stdin io.ReadCloser
|
|
|
|
- stdinPipe io.WriteCloser
|
|
|
|
|
|
+ StdConfig StdConfig
|
|
|
|
|
|
daemon *Daemon
|
|
daemon *Daemon
|
|
MountLabel, ProcessLabel string
|
|
MountLabel, ProcessLabel string
|
|
@@ -247,26 +251,31 @@ func populateCommand(c *Container, env []string) error {
|
|
CpuShares: c.Config.CpuShares,
|
|
CpuShares: c.Config.CpuShares,
|
|
Cpuset: c.Config.Cpuset,
|
|
Cpuset: c.Config.Cpuset,
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ processConfig := execdriver.ProcessConfig{
|
|
|
|
+ Privileged: c.hostConfig.Privileged,
|
|
|
|
+ Entrypoint: c.Path,
|
|
|
|
+ Arguments: c.Args,
|
|
|
|
+ Tty: c.Config.Tty,
|
|
|
|
+ User: c.Config.User,
|
|
|
|
+ }
|
|
|
|
+ processConfig.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
|
|
|
|
+ processConfig.Env = env
|
|
c.command = &execdriver.Command{
|
|
c.command = &execdriver.Command{
|
|
ID: c.ID,
|
|
ID: c.ID,
|
|
- Privileged: c.hostConfig.Privileged,
|
|
|
|
Rootfs: c.RootfsPath(),
|
|
Rootfs: c.RootfsPath(),
|
|
InitPath: "/.dockerinit",
|
|
InitPath: "/.dockerinit",
|
|
- Entrypoint: c.Path,
|
|
|
|
- Arguments: c.Args,
|
|
|
|
WorkingDir: c.Config.WorkingDir,
|
|
WorkingDir: c.Config.WorkingDir,
|
|
Network: en,
|
|
Network: en,
|
|
- Tty: c.Config.Tty,
|
|
|
|
- User: c.Config.User,
|
|
|
|
Config: context,
|
|
Config: context,
|
|
Resources: resources,
|
|
Resources: resources,
|
|
AllowedDevices: allowedDevices,
|
|
AllowedDevices: allowedDevices,
|
|
AutoCreatedDevices: autoCreatedDevices,
|
|
AutoCreatedDevices: autoCreatedDevices,
|
|
CapAdd: c.hostConfig.CapAdd,
|
|
CapAdd: c.hostConfig.CapAdd,
|
|
CapDrop: c.hostConfig.CapDrop,
|
|
CapDrop: c.hostConfig.CapDrop,
|
|
|
|
+ ProcessConfig: processConfig,
|
|
}
|
|
}
|
|
- c.command.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
|
|
|
|
- c.command.Env = env
|
|
|
|
|
|
+
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -329,7 +338,7 @@ func (container *Container) Run() error {
|
|
}
|
|
}
|
|
|
|
|
|
func (container *Container) Output() (output []byte, err error) {
|
|
func (container *Container) Output() (output []byte, err error) {
|
|
- pipe, err := container.StdoutPipe()
|
|
|
|
|
|
+ pipe, err := container.StdConfig.StdoutPipe()
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
@@ -342,7 +351,7 @@ func (container *Container) Output() (output []byte, err error) {
|
|
return output, err
|
|
return output, err
|
|
}
|
|
}
|
|
|
|
|
|
-// Container.StdinPipe returns a WriteCloser which can be used to feed data
|
|
|
|
|
|
+// StdConfig.StdinPipe returns a WriteCloser which can be used to feed data
|
|
// to the standard input of the container's active process.
|
|
// to the standard input of the container's active process.
|
|
// Container.StdoutPipe and Container.StderrPipe each return a ReadCloser
|
|
// Container.StdoutPipe and Container.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
|
|
@@ -350,31 +359,31 @@ func (container *Container) Output() (output []byte, err error) {
|
|
// 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".
|
|
|
|
|
|
-func (container *Container) StdinPipe() (io.WriteCloser, error) {
|
|
|
|
- return container.stdinPipe, nil
|
|
|
|
|
|
+func (stdConfig *StdConfig) StdinPipe() (io.WriteCloser, error) {
|
|
|
|
+ return stdConfig.stdinPipe, nil
|
|
}
|
|
}
|
|
|
|
|
|
-func (container *Container) StdoutPipe() (io.ReadCloser, error) {
|
|
|
|
|
|
+func (stdConfig *StdConfig) StdoutPipe() (io.ReadCloser, error) {
|
|
reader, writer := io.Pipe()
|
|
reader, writer := io.Pipe()
|
|
- container.stdout.AddWriter(writer, "")
|
|
|
|
|
|
+ stdConfig.stdout.AddWriter(writer, "")
|
|
return utils.NewBufReader(reader), nil
|
|
return utils.NewBufReader(reader), nil
|
|
}
|
|
}
|
|
|
|
|
|
-func (container *Container) StderrPipe() (io.ReadCloser, error) {
|
|
|
|
|
|
+func (stdConfig *StdConfig) StderrPipe() (io.ReadCloser, error) {
|
|
reader, writer := io.Pipe()
|
|
reader, writer := io.Pipe()
|
|
- container.stderr.AddWriter(writer, "")
|
|
|
|
|
|
+ stdConfig.stderr.AddWriter(writer, "")
|
|
return utils.NewBufReader(reader), nil
|
|
return utils.NewBufReader(reader), nil
|
|
}
|
|
}
|
|
|
|
|
|
func (container *Container) StdoutLogPipe() io.ReadCloser {
|
|
func (container *Container) StdoutLogPipe() io.ReadCloser {
|
|
reader, writer := io.Pipe()
|
|
reader, writer := io.Pipe()
|
|
- container.stdout.AddWriter(writer, "stdout")
|
|
|
|
|
|
+ container.StdConfig.stdout.AddWriter(writer, "stdout")
|
|
return utils.NewBufReader(reader)
|
|
return utils.NewBufReader(reader)
|
|
}
|
|
}
|
|
|
|
|
|
func (container *Container) StderrLogPipe() io.ReadCloser {
|
|
func (container *Container) StderrLogPipe() io.ReadCloser {
|
|
reader, writer := io.Pipe()
|
|
reader, writer := io.Pipe()
|
|
- container.stderr.AddWriter(writer, "stderr")
|
|
|
|
|
|
+ container.StdConfig.stderr.AddWriter(writer, "stderr")
|
|
return utils.NewBufReader(reader)
|
|
return utils.NewBufReader(reader)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -631,7 +640,7 @@ func (container *Container) Restart(seconds int) error {
|
|
}
|
|
}
|
|
|
|
|
|
func (container *Container) Resize(h, w int) error {
|
|
func (container *Container) Resize(h, w int) error {
|
|
- return container.command.Terminal.Resize(h, w)
|
|
|
|
|
|
+ return container.command.ProcessConfig.Terminal.Resize(h, w)
|
|
}
|
|
}
|
|
|
|
|
|
func (container *Container) ExportRw() (archive.Archive, error) {
|
|
func (container *Container) ExportRw() (archive.Archive, error) {
|
|
@@ -815,7 +824,7 @@ func (container *Container) Exposes(p nat.Port) bool {
|
|
}
|
|
}
|
|
|
|
|
|
func (container *Container) GetPtyMaster() (*os.File, error) {
|
|
func (container *Container) GetPtyMaster() (*os.File, error) {
|
|
- ttyConsole, ok := container.command.Terminal.(execdriver.TtyTerminal)
|
|
|
|
|
|
+ ttyConsole, ok := container.command.ProcessConfig.Terminal.(execdriver.TtyTerminal)
|
|
if !ok {
|
|
if !ok {
|
|
return nil, ErrNoTTY
|
|
return nil, ErrNoTTY
|
|
}
|
|
}
|
|
@@ -1083,11 +1092,11 @@ func (container *Container) startLoggingToDisk() error {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- if err := container.daemon.LogToDisk(container.stdout, pth, "stdout"); err != nil {
|
|
|
|
|
|
+ if err := container.daemon.LogToDisk(container.StdConfig.stdout, pth, "stdout"); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- if err := container.daemon.LogToDisk(container.stderr, pth, "stderr"); err != nil {
|
|
|
|
|
|
+ if err := container.daemon.LogToDisk(container.StdConfig.stderr, pth, "stderr"); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|