Don't create pty slave in the daemon for native driver
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: crosbymichael)
This commit is contained in:
parent
9fc6058aa1
commit
1501c342d8
4 changed files with 22 additions and 86 deletions
|
@ -95,6 +95,11 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
|
|||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
if err := execdriver.SetTerminal(c, pipes); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
d.Lock()
|
||||
d.activeContainers[c.ID] = &activeContainer{
|
||||
container: container,
|
||||
|
@ -106,6 +111,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
|
|||
dataPath = filepath.Join(d.root, c.ID)
|
||||
args = append([]string{c.Entrypoint}, c.Arguments...)
|
||||
)
|
||||
|
||||
if err := d.createContainerRoot(c.ID); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
@ -115,9 +121,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
|
|||
return -1, err
|
||||
}
|
||||
|
||||
term := getTerminal(c, pipes)
|
||||
|
||||
return namespaces.Exec(container, term, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd {
|
||||
return namespaces.Exec(container, c.Stdin, c.Stdout, c.Stderr, c.Console, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd {
|
||||
// we need to join the rootfs because namespaces will setup the rootfs and chroot
|
||||
initPath := filepath.Join(c.Rootfs, c.InitPath)
|
||||
|
||||
|
@ -201,11 +205,13 @@ func (d *driver) Terminate(p *execdriver.Command) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if state.InitStartTime == currentStartTime {
|
||||
err = syscall.Kill(p.Process.Pid, 9)
|
||||
syscall.Wait4(p.Process.Pid, nil, 0, nil)
|
||||
}
|
||||
d.removeContainerRoot(p.ID)
|
||||
|
||||
return err
|
||||
|
||||
}
|
||||
|
@ -266,18 +272,3 @@ func getEnv(key string, env []string) string {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getTerminal(c *execdriver.Command, pipes *execdriver.Pipes) namespaces.Terminal {
|
||||
var term namespaces.Terminal
|
||||
if c.Tty {
|
||||
term = &dockerTtyTerm{
|
||||
pipes: pipes,
|
||||
}
|
||||
} else {
|
||||
term = &dockerStdTerm{
|
||||
pipes: pipes,
|
||||
}
|
||||
}
|
||||
c.Terminal = term
|
||||
return term
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
These types are wrappers around the libcontainer Terminal interface so that
|
||||
we can resuse the docker implementations where possible.
|
||||
*/
|
||||
package native
|
||||
|
||||
import (
|
||||
"github.com/dotcloud/docker/daemon/execdriver"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
type dockerStdTerm struct {
|
||||
execdriver.StdConsole
|
||||
pipes *execdriver.Pipes
|
||||
}
|
||||
|
||||
func (d *dockerStdTerm) Attach(cmd *exec.Cmd) error {
|
||||
return d.AttachPipes(cmd, d.pipes)
|
||||
}
|
||||
|
||||
func (d *dockerStdTerm) SetMaster(master *os.File) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
type dockerTtyTerm struct {
|
||||
execdriver.TtyConsole
|
||||
pipes *execdriver.Pipes
|
||||
}
|
||||
|
||||
func (t *dockerTtyTerm) Attach(cmd *exec.Cmd) error {
|
||||
go io.Copy(t.pipes.Stdout, t.MasterPty)
|
||||
if t.pipes.Stdin != nil {
|
||||
go io.Copy(t.MasterPty, t.pipes.Stdin)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *dockerTtyTerm) SetMaster(master *os.File) {
|
||||
t.MasterPty = master
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
package execdriver
|
||||
|
||||
import (
|
||||
"github.com/dotcloud/docker/pkg/term"
|
||||
"github.com/kr/pty"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/dotcloud/docker/pkg/system"
|
||||
"github.com/dotcloud/docker/pkg/term"
|
||||
)
|
||||
|
||||
func SetTerminal(command *Command, pipes *Pipes) error {
|
||||
|
@ -13,37 +14,42 @@ func SetTerminal(command *Command, pipes *Pipes) error {
|
|||
term Terminal
|
||||
err error
|
||||
)
|
||||
|
||||
if command.Tty {
|
||||
term, err = NewTtyConsole(command, pipes)
|
||||
} else {
|
||||
term, err = NewStdConsole(command, pipes)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
command.Terminal = term
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type TtyConsole struct {
|
||||
MasterPty *os.File
|
||||
SlavePty *os.File
|
||||
}
|
||||
|
||||
func NewTtyConsole(command *Command, pipes *Pipes) (*TtyConsole, error) {
|
||||
ptyMaster, ptySlave, err := pty.Open()
|
||||
ptyMaster, console, err := system.CreateMasterAndConsole()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tty := &TtyConsole{
|
||||
MasterPty: ptyMaster,
|
||||
SlavePty: ptySlave,
|
||||
}
|
||||
|
||||
if err := tty.AttachPipes(&command.Cmd, pipes); err != nil {
|
||||
tty.Close()
|
||||
return nil, err
|
||||
}
|
||||
command.Console = tty.SlavePty.Name()
|
||||
command.Console = console
|
||||
|
||||
return tty, nil
|
||||
}
|
||||
|
||||
|
@ -56,9 +62,6 @@ func (t *TtyConsole) Resize(h, w int) error {
|
|||
}
|
||||
|
||||
func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *Pipes) error {
|
||||
command.Stdout = t.SlavePty
|
||||
command.Stderr = t.SlavePty
|
||||
|
||||
go func() {
|
||||
if wb, ok := pipes.Stdout.(interface {
|
||||
CloseWriters() error
|
||||
|
@ -69,19 +72,16 @@ func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *Pipes) error {
|
|||
}()
|
||||
|
||||
if pipes.Stdin != nil {
|
||||
command.Stdin = t.SlavePty
|
||||
command.SysProcAttr.Setctty = true
|
||||
|
||||
go func() {
|
||||
defer pipes.Stdin.Close()
|
||||
io.Copy(t.MasterPty, pipes.Stdin)
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TtyConsole) Close() error {
|
||||
t.SlavePty.Close()
|
||||
return t.MasterPty.Close()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// +build linux,cgo
|
||||
|
||||
package system
|
||||
|
||||
/*
|
||||
#include <unistd.h>
|
||||
int get_hz(void) { return sysconf(_SC_CLK_TCK); }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func GetClockTicks() int {
|
||||
return int(C.get_hz())
|
||||
}
|
Loading…
Reference in a new issue