Merge pull request #15666 from vdemeester/3519-configurable-escape
Implement configurable escape key for attach/exec Upstream-commit: db738dd77f699e93f976441d5fc11ab48a2d6c68 Component: engine
This commit is contained in:
@@ -15,13 +15,14 @@ import (
|
||||
|
||||
// ContainerAttachWithLogsConfig holds the streams to use when connecting to a container to view logs.
|
||||
type ContainerAttachWithLogsConfig struct {
|
||||
Hijacker http.Hijacker
|
||||
Upgrade bool
|
||||
UseStdin bool
|
||||
UseStdout bool
|
||||
UseStderr bool
|
||||
Logs bool
|
||||
Stream bool
|
||||
Hijacker http.Hijacker
|
||||
Upgrade bool
|
||||
UseStdin bool
|
||||
UseStdout bool
|
||||
UseStderr bool
|
||||
Logs bool
|
||||
Stream bool
|
||||
DetachKeys []byte
|
||||
}
|
||||
|
||||
// ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig.
|
||||
@@ -75,7 +76,7 @@ func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerA
|
||||
stderr = errStream
|
||||
}
|
||||
|
||||
if err := daemon.attachWithLogs(container, stdin, stdout, stderr, c.Logs, c.Stream); err != nil {
|
||||
if err := daemon.attachWithLogs(container, stdin, stdout, stderr, c.Logs, c.Stream, c.DetachKeys); err != nil {
|
||||
fmt.Fprintf(outStream, "Error attaching: %s\n", err)
|
||||
}
|
||||
return nil
|
||||
@@ -87,6 +88,7 @@ type ContainerWsAttachWithLogsConfig struct {
|
||||
InStream io.ReadCloser
|
||||
OutStream, ErrStream io.Writer
|
||||
Logs, Stream bool
|
||||
DetachKeys []byte
|
||||
}
|
||||
|
||||
// ContainerWsAttachWithLogs websocket connection
|
||||
@@ -95,10 +97,10 @@ func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *Containe
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return daemon.attachWithLogs(container, c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream)
|
||||
return daemon.attachWithLogs(container, c.InStream, c.OutStream, c.ErrStream, c.Logs, c.Stream, c.DetachKeys)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) attachWithLogs(container *container.Container, stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
|
||||
func (daemon *Daemon) attachWithLogs(container *container.Container, stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool, keys []byte) error {
|
||||
if logs {
|
||||
logDriver, err := daemon.getLogger(container)
|
||||
if err != nil {
|
||||
@@ -144,7 +146,7 @@ func (daemon *Daemon) attachWithLogs(container *container.Container, stdin io.Re
|
||||
}()
|
||||
stdinPipe = r
|
||||
}
|
||||
<-container.Attach(stdinPipe, stdout, stderr)
|
||||
<-container.Attach(stdinPipe, stdout, stderr, keys)
|
||||
// If we are in stdinonce mode, wait for the process to end
|
||||
// otherwise, simply return
|
||||
if container.Config.StdinOnce && !container.Config.Tty {
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
"github.com/docker/docker/pkg/promise"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
)
|
||||
|
||||
func (d *Daemon) registerExecCommand(container *container.Container, config *exec.Config) {
|
||||
@@ -88,6 +89,14 @@ func (d *Daemon) ContainerExecCreate(config *types.ExecConfig) (string, error) {
|
||||
cmd := strslice.New(config.Cmd...)
|
||||
entrypoint, args := d.getEntrypointAndArgs(strslice.New(), cmd)
|
||||
|
||||
keys := []byte{}
|
||||
if config.DetachKeys != "" {
|
||||
keys, err = term.ToBytes(config.DetachKeys)
|
||||
if err != nil {
|
||||
logrus.Warnf("Wrong escape keys provided (%s, error: %s) using default : ctrl-p ctrl-q", config.DetachKeys, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
processConfig := &execdriver.ProcessConfig{
|
||||
CommonProcessConfig: execdriver.CommonProcessConfig{
|
||||
Tty: config.Tty,
|
||||
@@ -103,6 +112,7 @@ func (d *Daemon) ContainerExecCreate(config *types.ExecConfig) (string, error) {
|
||||
execConfig.OpenStderr = config.AttachStderr
|
||||
execConfig.ProcessConfig = processConfig
|
||||
execConfig.ContainerID = container.ID
|
||||
execConfig.DetachKeys = keys
|
||||
|
||||
d.registerExecCommand(container, execConfig)
|
||||
|
||||
@@ -158,7 +168,8 @@ func (d *Daemon) ContainerExecStart(name string, stdin io.ReadCloser, stdout io.
|
||||
ec.NewNopInputPipe()
|
||||
}
|
||||
|
||||
attachErr := container.AttachStreams(ec.StreamConfig, ec.OpenStdin, true, ec.ProcessConfig.Tty, cStdin, cStdout, cStderr)
|
||||
attachErr := container.AttachStreams(ec.StreamConfig, ec.OpenStdin, true, ec.ProcessConfig.Tty, cStdin, cStdout, cStderr, ec.DetachKeys)
|
||||
|
||||
execErr := make(chan error)
|
||||
|
||||
// Note, the ExecConfig data will be removed when the container
|
||||
|
||||
@@ -25,6 +25,7 @@ type Config struct {
|
||||
OpenStdout bool
|
||||
CanRemove bool
|
||||
ContainerID string
|
||||
DetachKeys []byte
|
||||
|
||||
// waitStart will be closed immediately after the exec is really started.
|
||||
waitStart chan struct{}
|
||||
|
||||
Reference in New Issue
Block a user