mirror of https://github.com/docker/docs.git
Merge pull request #19513 from crosbymichael/tty-restore
Move tty set and restore to caller
This commit is contained in:
commit
4a9523adc9
|
@ -75,6 +75,12 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
|
if in != nil && c.Config.Tty {
|
||||||
|
if err := cli.setRawTerminal(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cli.restoreTerminal(in)
|
||||||
|
}
|
||||||
|
|
||||||
if err := cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp); err != nil {
|
if err := cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -44,6 +44,8 @@ type DockerCli struct {
|
||||||
isTerminalOut bool
|
isTerminalOut bool
|
||||||
// client is the http client that performs all API operations
|
// client is the http client that performs all API operations
|
||||||
client client.APIClient
|
client client.APIClient
|
||||||
|
// state holds the terminal state
|
||||||
|
state *term.State
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize calls the init function that will setup the configuration for the client
|
// Initialize calls the init function that will setup the configuration for the client
|
||||||
|
@ -79,6 +81,27 @@ func (cli *DockerCli) ImagesFormat() string {
|
||||||
return cli.configFile.ImagesFormat
|
return cli.configFile.ImagesFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *DockerCli) setRawTerminal() error {
|
||||||
|
if cli.isTerminalIn && os.Getenv("NORAW") == "" {
|
||||||
|
state, err := term.SetRawTerminal(cli.inFd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cli.state = state
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *DockerCli) restoreTerminal(in io.Closer) error {
|
||||||
|
if cli.state != nil {
|
||||||
|
term.RestoreTerminal(cli.inFd, cli.state)
|
||||||
|
}
|
||||||
|
if in != nil {
|
||||||
|
return in.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
|
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
|
||||||
// The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
|
// The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
|
||||||
// is set the client scheme will be set to https.
|
// is set the client scheme will be set to https.
|
||||||
|
|
|
@ -87,6 +87,12 @@ func (cli *DockerCli) CmdExec(args ...string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
|
if in != nil && execConfig.Tty {
|
||||||
|
if err := cli.setRawTerminal(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cli.restoreTerminal(in)
|
||||||
|
}
|
||||||
errCh = promise.Go(func() error {
|
errCh = promise.Go(func() error {
|
||||||
return cli.holdHijackedConnection(execConfig.Tty, in, out, stderr, resp)
|
return cli.holdHijackedConnection(execConfig.Tty, in, out, stderr, resp)
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,41 +2,19 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
"github.com/docker/docker/pkg/term"
|
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cli *DockerCli) holdHijackedConnection(setRawTerminal bool, inputStream io.ReadCloser, outputStream, errorStream io.Writer, resp types.HijackedResponse) error {
|
func (cli *DockerCli) holdHijackedConnection(tty bool, inputStream io.ReadCloser, outputStream, errorStream io.Writer, resp types.HijackedResponse) error {
|
||||||
var (
|
var err error
|
||||||
err error
|
|
||||||
oldState *term.State
|
|
||||||
)
|
|
||||||
if inputStream != nil && setRawTerminal && cli.isTerminalIn && os.Getenv("NORAW") == "" {
|
|
||||||
oldState, err = term.SetRawTerminal(cli.inFd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer term.RestoreTerminal(cli.inFd, oldState)
|
|
||||||
}
|
|
||||||
|
|
||||||
receiveStdout := make(chan error, 1)
|
receiveStdout := make(chan error, 1)
|
||||||
if outputStream != nil || errorStream != nil {
|
if outputStream != nil || errorStream != nil {
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
|
||||||
if inputStream != nil {
|
|
||||||
if setRawTerminal && cli.isTerminalIn {
|
|
||||||
term.RestoreTerminal(cli.inFd, oldState)
|
|
||||||
}
|
|
||||||
inputStream.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// When TTY is ON, use regular copy
|
// When TTY is ON, use regular copy
|
||||||
if setRawTerminal && outputStream != nil {
|
if tty && outputStream != nil {
|
||||||
_, err = io.Copy(outputStream, resp.Reader)
|
_, err = io.Copy(outputStream, resp.Reader)
|
||||||
} else {
|
} else {
|
||||||
_, err = stdcopy.StdCopy(outputStream, errorStream, resp.Reader)
|
_, err = stdcopy.StdCopy(outputStream, errorStream, resp.Reader)
|
||||||
|
|
|
@ -207,6 +207,12 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if in != nil && config.Tty {
|
||||||
|
if err := cli.setRawTerminal(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cli.restoreTerminal(in)
|
||||||
|
}
|
||||||
errCh = promise.Go(func() error {
|
errCh = promise.Go(func() error {
|
||||||
return cli.holdHijackedConnection(config.Tty, in, out, stderr, resp)
|
return cli.holdHijackedConnection(config.Tty, in, out, stderr, resp)
|
||||||
})
|
})
|
||||||
|
|
|
@ -96,6 +96,12 @@ func (cli *DockerCli) CmdStart(args ...string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
|
if in != nil && c.Config.Tty {
|
||||||
|
if err := cli.setRawTerminal(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cli.restoreTerminal(in)
|
||||||
|
}
|
||||||
|
|
||||||
cErr := promise.Go(func() error {
|
cErr := promise.Go(func() error {
|
||||||
return cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp)
|
return cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp)
|
||||||
|
|
Loading…
Reference in New Issue