mirror of
https://github.com/containers/podman.git
synced 2025-09-09 21:52:21 +08:00
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>
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user