summaryrefslogtreecommitdiff
path: root/pkg
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 /pkg
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 'pkg')
-rw-r--r--pkg/api/handlers/compat/exec.go10
-rw-r--r--pkg/api/handlers/compat/resize.go2
-rw-r--r--pkg/api/handlers/types.go6
-rw-r--r--pkg/api/server/register_exec.go10
-rw-r--r--pkg/bindings/containers/attach.go24
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go4
6 files changed, 42 insertions, 14 deletions
diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go
index 1b7b884e0..77e62c112 100644
--- a/pkg/api/handlers/compat/exec.go
+++ b/pkg/api/handlers/compat/exec.go
@@ -178,8 +178,16 @@ func ExecStartHandler(w http.ResponseWriter, r *http.Request) {
logrus.Error(errors.Wrapf(e, "error attaching to container %s exec session %s", sessionCtr.ID(), sessionID))
}
+ var size *define.TerminalSize
+ if bodyParams.Tty && (bodyParams.Height > 0 || bodyParams.Width > 0) {
+ size = &define.TerminalSize{
+ Height: bodyParams.Height,
+ Width: bodyParams.Width,
+ }
+ }
+
hijackChan := make(chan bool, 1)
- err = sessionCtr.ExecHTTPStartAndAttach(sessionID, r, w, nil, nil, nil, hijackChan)
+ err = sessionCtr.ExecHTTPStartAndAttach(sessionID, r, w, nil, nil, nil, hijackChan, size)
if <-hijackChan {
// If connection was Hijacked, we have to signal it's being closed
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index f65e313fc..844fb74c4 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -73,7 +73,7 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
return
}
if err := ctnr.ExecResize(name, sz); err != nil {
- if errors.Cause(err) != define.ErrCtrStateInvalid || !query.IgnoreNotRunning {
+ if errors.Cause(err) != define.ErrExecSessionStateInvalid || !query.IgnoreNotRunning {
utils.InternalServerError(w, errors.Wrapf(err, "cannot resize session"))
return
}
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index f94c9a1f5..ee157cb56 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -157,8 +157,10 @@ type ExecCreateResponse struct {
}
type ExecStartConfig struct {
- Detach bool `json:"Detach"`
- Tty bool `json:"Tty"`
+ Detach bool `json:"Detach"`
+ Tty bool `json:"Tty"`
+ Height uint16 `json:"h"`
+ Width uint16 `json:"w"`
}
func ImageToImageSummary(l *libimage.Image) (*entities.ImageSummary, error) {
diff --git a/pkg/api/server/register_exec.go b/pkg/api/server/register_exec.go
index 3716ef6a2..e353d714c 100644
--- a/pkg/api/server/register_exec.go
+++ b/pkg/api/server/register_exec.go
@@ -269,10 +269,16 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error {
// properties:
// Detach:
// type: boolean
- // description: Detach from the command. Not presently supported.
+ // description: Detach from the command.
// Tty:
// type: boolean
- // description: Allocate a pseudo-TTY. Presently ignored.
+ // description: Allocate a pseudo-TTY.
+ // h:
+ // type: integer
+ // description: Height of the TTY session in characters. Tty must be set to true to use it.
+ // w:
+ // type: integer
+ // description: Width of the TTY session in characters. Tty must be set to true to use it.
// produces:
// - application/json
// responses:
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index adef1e7c8..cc12c8ab7 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -343,7 +343,7 @@ func attachHandleResize(ctx, winCtx context.Context, winChange chan os.Signal, i
resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w))
}
if resizeErr != nil {
- logrus.Warnf("failed to resize TTY: %v", resizeErr)
+ logrus.Infof("failed to resize TTY: %v", resizeErr)
}
}
@@ -408,6 +408,17 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
// If we are in TTY mode, we need to set raw mode for the terminal.
// TODO: Share all of this with Attach() for containers.
needTTY := terminalFile != nil && terminal.IsTerminal(int(terminalFile.Fd())) && isTerm
+
+ body := struct {
+ Detach bool `json:"Detach"`
+ TTY bool `json:"Tty"`
+ Height uint16 `json:"h"`
+ Width uint16 `json:"w"`
+ }{
+ Detach: false,
+ TTY: needTTY,
+ }
+
if needTTY {
state, err := setRawTerminal(terminalFile)
if err != nil {
@@ -419,13 +430,14 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
}
logrus.SetFormatter(&logrus.TextFormatter{})
}()
+ w, h, err := terminal.GetSize(int(terminalFile.Fd()))
+ if err != nil {
+ logrus.Warnf("failed to obtain TTY size: %v", err)
+ }
+ body.Width = uint16(w)
+ body.Height = uint16(h)
}
- body := struct {
- Detach bool `json:"Detach"`
- }{
- Detach: false,
- }
bodyJSON, err := json.Marshal(body)
if err != nil {
return err
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
index ab71f8f6f..09c0f802d 100644
--- a/pkg/domain/infra/abi/terminal/terminal_linux.go
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -15,12 +15,13 @@ import (
// ExecAttachCtr execs and attaches to a container
func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) {
- resize := make(chan define.TerminalSize)
+ var resize chan define.TerminalSize
haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
if haveTerminal && execConfig.Terminal {
+ resize = make(chan define.TerminalSize)
cancel, oldTermState, err := handleTerminalAttach(ctx, resize)
if err != nil {
return -1, err
@@ -32,7 +33,6 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
}
}()
}
-
return ctr.Exec(execConfig, streams, resize)
}