-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
relates to:
- There was a problem entering the container #3231
- Flaky test: TestInitTtySizeErrors() (on macOS "latest") #3441
- There was a problem entering the container moby/moby#42707
The TestInitTtySizeErrors test is failing frequently (see #3441), and it looks like it's not just a flaky test, but a bug / regression in the CLI:
--- FAIL: TestInitTtySizeErrors (0.16s)
tty_test.go:29: assertion failed:
--- expectedError
+++ →
@@ -1,2 +1 @@
-failed to resize tty, using default size
We had issues in this area before;
- Docker Exec does not resize terminal moby/moby#35407
- initial windows size of docker exec -it is too small #1492
- fixes 1492: tty initial size error #1529
- Strange terminal behaviour inside docker moby/moby#33794
- various other issues
Previous "fixes" implemented a retry loop to try resizing the terminal if it didn't work the first time (there's some race between the container being created and it being receptacle for resizing), so the existing code continues to be a "best effort";
cli/cli/command/container/run.go
Lines 189 to 193 in b68db38
| if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && dockerCli.Out().IsTerminal() { | |
| if err := MonitorTtySize(ctx, dockerCli, createResponse.ID, false); err != nil { | |
| fmt.Fprintln(stderr, "Error monitoring TTY size:", err) | |
| } | |
| } |
Reproduction steps
The issue can be reproduced with this script (which just starts a lot of containers in a loop); I haven't counted the success/failure ratio, but it's failing very frequently:
#!/bin/bash
A=0
while true; do
for a in $(seq 1 15); do
com.docker.cli run --rm -t alpine echo $A/$a &
done
wait
date
A=$((A+1))
echo $A
doneCoincidentally, when using a Windows machine, the CLI sets the initial size when creating the container.
cli/cli/command/container/run.go
Lines 122 to 127 in b68db38
| // Telling the Windows daemon the initial size of the tty during start makes | |
| // a far better user experience rather than relying on subsequent resizes | |
| // to cause things to catch up. | |
| if runtime.GOOS == "windows" { | |
| hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCli.Out().GetTtySize() | |
| } |
The code above looks wrong though;
- it checks for the operating system on the CLI side, but does not take into account that the daemon could be either a Linux or a Windows daemon
- which could be either an "omission" (initial size supported on both Linux and Windows daemons)
- or (if Linux daemons do not support this) result in Linux container shells never getting the right size when started from a Windows CLI.
- or "redundant" (initial size already connect, but after this, doing a resize to the same size again)
What's needed?
- Investigate what's missing (if anything) to set the correct terminal size when running (
docker run), attaching (docker attach) and exec-ing (docker exec) a container - If setting the initial size is not supported on a Linux daemon, why not?
- ISTR containerd did not support setting the initial size in all of these cases (is this just something that's not "punched through" in the containerd API, or is more needed?)
If it's possible to set the initial size, we should prefer that over "resizing", although resizing would still be needed if the terminal from which the container was started is resized. Of course, we also need to take into account whether the daemon (and containerd) supports setting the initial size (which may depend on the API version).