diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-06-03 16:07:43 +0200 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-06-04 16:55:48 +0200 |
commit | 1f73374acd3c33d1884e9383205c9f891a3552db (patch) | |
tree | 95ed36dbd4022c772a3be26d2c8205ba9ec6507c /pkg/bindings | |
parent | 52dae693da0df1447b7f5210a4c842d5c5a8a401 (diff) | |
download | podman-1f73374acd3c33d1884e9383205c9f891a3552db.tar.gz podman-1f73374acd3c33d1884e9383205c9f891a3552db.tar.bz2 podman-1f73374acd3c33d1884e9383205c9f891a3552db.zip |
remote: always send resize before the container starts
There is race condition in the remote client attach logic. Because the
resize api call was handled in an extra goroutine the container was
started before the resize call happend. To fix this we have to call
resize in the same goroutine as attach. When the first resize is done
start a goroutine to listen on SIGWINCH in the background and resize
again if the signal is received.
Fixes #9859
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'pkg/bindings')
-rw-r--r-- | pkg/bindings/containers/attach.go | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go index fd8a7011d..adef1e7c8 100644 --- a/pkg/bindings/containers/attach.go +++ b/pkg/bindings/containers/attach.go @@ -138,7 +138,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri winCtx, winCancel := context.WithCancel(ctx) defer winCancel() - go attachHandleResize(ctx, winCtx, winChange, false, nameOrID, file) + attachHandleResize(ctx, winCtx, winChange, false, nameOrID, file) } // If we are attaching around a start, we need to "signal" @@ -327,32 +327,38 @@ func (f *rawFormatter) Format(entry *logrus.Entry) ([]byte, error) { return append(buffer, '\r'), nil } -// This is intended to be run as a goroutine, handling resizing for a container -// or exec session. +// This is intended to not be run as a goroutine, handling resizing for a container +// or exec session. It will call resize once and then starts a goroutine which calls resize on winChange func attachHandleResize(ctx, winCtx context.Context, winChange chan os.Signal, isExec bool, id string, file *os.File) { - // Prime the pump, we need one reset to ensure everything is ready - winChange <- sig.SIGWINCH - for { - select { - case <-winCtx.Done(): - return - case <-winChange: - w, h, err := terminal.GetSize(int(file.Fd())) - if err != nil { - logrus.Warnf("failed to obtain TTY size: %v", err) - } + resize := func() { + w, h, err := terminal.GetSize(int(file.Fd())) + if err != nil { + logrus.Warnf("failed to obtain TTY size: %v", err) + } - var resizeErr error - if isExec { - resizeErr = ResizeExecTTY(ctx, id, new(ResizeExecTTYOptions).WithHeight(h).WithWidth(w)) - } else { - resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w)) - } - if resizeErr != nil { - logrus.Warnf("failed to resize TTY: %v", resizeErr) - } + var resizeErr error + if isExec { + resizeErr = ResizeExecTTY(ctx, id, new(ResizeExecTTYOptions).WithHeight(h).WithWidth(w)) + } else { + resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w)) + } + if resizeErr != nil { + logrus.Warnf("failed to resize TTY: %v", resizeErr) } } + + resize() + + go func() { + for { + select { + case <-winCtx.Done(): + return + case <-winChange: + resize() + } + } + }() } // Configure the given terminal for raw mode @@ -457,7 +463,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar winCtx, winCancel := context.WithCancel(ctx) defer winCancel() - go attachHandleResize(ctx, winCtx, winChange, true, sessionID, terminalFile) + attachHandleResize(ctx, winCtx, winChange, true, sessionID, terminalFile) } if options.GetAttachInput() { |