summaryrefslogtreecommitdiff
path: root/libpod/container_exec.go
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-06-15 11:05:00 +0200
committerPaul Holzinger <pholzing@redhat.com>2021-06-16 16:43:30 +0200
commit666f555aa52b9f82da9d6ca64cf11e4f5e1e78e8 (patch)
tree0175dbf916bdb7d4722890191bb5f523f64b202f /libpod/container_exec.go
parente2f51eeb0693eda026fa509a9decfbdd7e0b74a8 (diff)
downloadpodman-666f555aa52b9f82da9d6ca64cf11e4f5e1e78e8.tar.gz
podman-666f555aa52b9f82da9d6ca64cf11e4f5e1e78e8.tar.bz2
podman-666f555aa52b9f82da9d6ca64cf11e4f5e1e78e8.zip
Fix resize race with podman exec -it
When starting a process with `podman exec -it` the terminal is resized after the process is started. To fix this allow exec start to accept the terminal height and width as parameter and let it resize right before the process is started. Fixes #10560 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'libpod/container_exec.go')
-rw-r--r--libpod/container_exec.go16
1 files changed, 11 insertions, 5 deletions
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index 737bf74ad..5d4bcb422 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -277,9 +277,10 @@ func (c *Container) ExecStart(sessionID string) error {
}
// ExecStartAndAttach starts and attaches to an exec session in a container.
+// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
// TODO: Should we include detach keys in the signature to allow override?
// TODO: How do we handle AttachStdin/AttachStdout/AttachStderr?
-func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams) error {
+func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *define.TerminalSize) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -310,7 +311,7 @@ func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachS
return err
}
- pid, attachChan, err := c.ociRuntime.ExecContainer(c, session.ID(), opts, streams)
+ pid, attachChan, err := c.ociRuntime.ExecContainer(c, session.ID(), opts, streams, newSize)
if err != nil {
return err
}
@@ -373,7 +374,9 @@ func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachS
}
// ExecHTTPStartAndAttach starts and performs an HTTP attach to an exec session.
-func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool) error {
+// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
+func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w http.ResponseWriter,
+ streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, newSize *define.TerminalSize) error {
// TODO: How do we combine streams with the default streams set in the exec session?
// Ensure that we don't leak a goroutine here
@@ -431,7 +434,7 @@ func (c *Container) ExecHTTPStartAndAttach(sessionID string, r *http.Request, w
close(holdConnOpen)
}()
- pid, attachChan, err := c.ociRuntime.ExecContainerHTTP(c, session.ID(), execOpts, r, w, streams, cancel, hijackDone, holdConnOpen)
+ pid, attachChan, err := c.ociRuntime.ExecContainerHTTP(c, session.ID(), execOpts, r, w, streams, cancel, hijackDone, holdConnOpen, newSize)
if err != nil {
session.State = define.ExecStateStopped
session.ExitCode = define.TranslateExecErrorToExitCode(define.ExecErrorCodeGeneric, err)
@@ -719,7 +722,10 @@ func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resi
// API there.
// TODO: Refactor so this is closed here, before we remove the exec
// session.
+ var size *define.TerminalSize
if resize != nil {
+ s := <-resize
+ size = &s
go func() {
logrus.Debugf("Sending resize events to exec session %s", sessionID)
for resizeRequest := range resize {
@@ -737,7 +743,7 @@ func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resi
}()
}
- if err := c.ExecStartAndAttach(sessionID, streams); err != nil {
+ if err := c.ExecStartAndAttach(sessionID, streams, size); err != nil {
return -1, err
}