Move term creation into driver

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-02-21 12:42:37 -08:00
parent 1e74287698
commit 592c2f6f9a
3 changed files with 33 additions and 37 deletions

View File

@ -530,9 +530,6 @@ func (container *Container) Start() (err error) {
} }
populateCommand(container) populateCommand(container)
if err := execdriver.NewTerminal(container.command); err != nil {
return err
}
// Setup logging of stdout and stderr to disk // Setup logging of stdout and stderr to disk
if err := container.runtime.LogToDisk(container.stdout, container.logPath("json"), "stdout"); err != nil { if err := container.runtime.LogToDisk(container.stdout, container.logPath("json"), "stdout"); err != nil {

View File

@ -77,10 +77,8 @@ func (d *driver) Name() string {
} }
func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) { func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
if c.Terminal != nil { if err := execdriver.SetTerminal(c, pipes); err != nil {
if err := c.Terminal.Attach(pipes); err != nil { return -1, err
return -1, err
}
} }
configPath, err := d.generateLXCConfig(c) configPath, err := d.generateLXCConfig(c)
if err != nil { if err != nil {

View File

@ -10,7 +10,6 @@ import (
type Term interface { type Term interface {
io.Closer io.Closer
Resize(height, width int) error Resize(height, width int) error
Attach(pipes *Pipes) error
} }
type Pipes struct { type Pipes struct {
@ -29,15 +28,15 @@ func NewPipes(stdin io.ReadCloser, stdout, stderr io.WriteCloser, useStdin bool)
return p return p
} }
func NewTerminal(command *Command) error { func SetTerminal(command *Command, pipes *Pipes) error {
var ( var (
term Term term Term
err error err error
) )
if command.Tty { if command.Tty {
term, err = NewTtyConsole(command) term, err = NewTtyConsole(command, pipes)
} else { } else {
term, err = NewStdConsole(command) term, err = NewStdConsole(command, pipes)
} }
if err != nil { if err != nil {
return err return err
@ -47,20 +46,22 @@ func NewTerminal(command *Command) error {
} }
type TtyConsole struct { type TtyConsole struct {
command *Command Master *os.File
Master *os.File Slave *os.File
Slave *os.File
} }
func NewTtyConsole(command *Command) (*TtyConsole, error) { func NewTtyConsole(command *Command, pipes *Pipes) (*TtyConsole, error) {
ptyMaster, ptySlave, err := pty.Open() ptyMaster, ptySlave, err := pty.Open()
if err != nil { if err != nil {
return nil, err return nil, err
} }
tty := &TtyConsole{ tty := &TtyConsole{
Master: ptyMaster, Master: ptyMaster,
Slave: ptySlave, Slave: ptySlave,
command: command, }
if err := tty.attach(command, pipes); err != nil {
tty.Close()
return nil, err
} }
return tty, nil return tty, nil
} }
@ -69,11 +70,10 @@ func (t *TtyConsole) Resize(h, w int) error {
return term.SetWinsize(t.Master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)}) return term.SetWinsize(t.Master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
} }
func (t *TtyConsole) Attach(pipes *Pipes) error { func (t *TtyConsole) attach(command *Command, pipes *Pipes) error {
t.command.Stdout = t.Slave command.Stdout = t.Slave
t.command.Stderr = t.Slave command.Stderr = t.Slave
command.Console = t.Slave.Name()
t.command.Console = t.Slave.Name()
go func() { go func() {
defer pipes.Stdout.Close() defer pipes.Stdout.Close()
@ -81,8 +81,8 @@ func (t *TtyConsole) Attach(pipes *Pipes) error {
}() }()
if pipes.Stdin != nil { if pipes.Stdin != nil {
t.command.Stdin = t.Slave command.Stdin = t.Slave
t.command.SysProcAttr.Setctty = true command.SysProcAttr.Setctty = true
go func() { go func() {
defer pipes.Stdin.Close() defer pipes.Stdin.Close()
@ -93,27 +93,28 @@ func (t *TtyConsole) Attach(pipes *Pipes) error {
} }
func (t *TtyConsole) Close() error { func (t *TtyConsole) Close() error {
err := t.Slave.Close() t.Slave.Close()
if merr := t.Master.Close(); err == nil { return t.Master.Close()
err = merr
}
return err
} }
type StdConsole struct { type StdConsole struct {
command *Command
} }
func NewStdConsole(command *Command) (*StdConsole, error) { func NewStdConsole(command *Command, pipes *Pipes) (*StdConsole, error) {
return &StdConsole{command}, nil std := &StdConsole{}
if err := std.attach(command, pipes); err != nil {
return nil, err
}
return std, nil
} }
func (s *StdConsole) Attach(pipes *Pipes) error { func (s *StdConsole) attach(command *Command, pipes *Pipes) error {
s.command.Stdout = pipes.Stdout command.Stdout = pipes.Stdout
s.command.Stderr = pipes.Stderr command.Stderr = pipes.Stderr
if pipes.Stdin != nil { if pipes.Stdin != nil {
stdin, err := s.command.StdinPipe() stdin, err := command.StdinPipe()
if err != nil { if err != nil {
return err return err
} }