You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cmd/create: Don't block user interaction while fetching the image size
It takes 'skopeo inspect' a few seconds to fetch the image size from the
remote registry, and while that happens the user can't interact with the
image download prompt:
$ toolbox create
Image required to create toolbox container.
<wait for a few seconds>
Download registry.fedoraproject.org/fedora-toolbox:39 (359.8MB)? [y/N]:
This feels awkward because it's not clear to the user what's going on
during those few seconds. Moreover, while knowing the image size can be
convenient at times, for example when disk space and network bandwidth
are limited, it's not always important.
It will be better if 'skopeo inspect' ran in the background, while
waiting for the user to respond to the image download prompt, and once
the image size has been fetched, the image download prompt can be
updated to include it.
So, initially:
$ toolbox create
Image required to create toolbox container.
Download registry.fedoraproject.org/fedora-toolbox:39 ( ... MB)? [y/N]:
... and then once the size is available:
$ toolbox create
Image required to create toolbox container.
Download registry.fedoraproject.org/fedora-toolbox:39 (359.8MB)? [y/N]:
If skopeo(1) is missing or too old, then the prompt can continue without
the size, as it did before:
$ toolbox create
Image required to create toolbox container.
Download registry.fedoraproject.org/fedora-toolbox:39 [y/N]:
The placeholder for the missing image size (ie., ' ... MB') was chosen
to have seven characters, so that it matches the most common sizes. The
human-readable representation of the image size is capped at four valid
numbers [1]. Unless it's a perfect round number like 1KB or 1.2MB, it
will likely use all four numbers and the decimal point, which is five
characters. Then two more for the unit, because it's very unlikely that
there will be an image that's less than 1KB in size and will be shown in
bytes with a B. That makes it seven characters in total.
Updating the image download prompt with the results of 'skopeo inspect'
is vulnerable to races. At the same time as the terminal's cursor is
being moved to the beginning of the current line to overwrite the
earlier prompt with the new one, the user can keep typing and keep
moving the cursor forward. This competition over the cursor can lead to
awkward outcomes.
For example, the prompt can overwrite the characters typed in by the
user, leaving characters in the terminal's input buffer waiting for the
user to hit ENTER, even though they are not visible on the screen.
Another example is that hitting BACKSPACE can end up deleting parts of
the prompt, instead of stopping at the edge.
This is solved by putting the terminal device into non-canonical mode
input and disabling the echoing of input characters, while the prompt is
being updated. This prevents input from moving the terminal's cursor
forward, and from accumulating in the terminal's input buffer even if
it might not be visible. Any input during this interim period is
discarded and replaced by '...', and a fresh new prompt is shown in the
following line.
In practice, this race shouldn't be too common. It can only happen if
the user is typing right when the prompt is being updated, which is
unlikely because it's only supposed to be a short 'yes' or 'no' input.
The use of the context.Cause and context.WithCancelCause functions [2]
requires Go >= 1.20. Bumping the Go version in src/go.mod then requires
a 'go mod tidy'. Otherwise, it leads to:
$ meson compile -C builddir --verbose
...
/home/rishi/devel/containers/git/toolbox/src/go-build-wrapper
/home/rishi/devel/containers/git/toolbox/src
/home/rishi/devel/containers/git/toolbox/builddir src/toolbox
0.0.99.4 cc /lib64/ld-linux-x86-64.so.2 false
go: updates to go.mod needed; to update it:
go mod tidy
ninja: build stopped: subcommand failed.
[1] https://pkg.go.dev/github.com/docker/go-units#HumanSize
[2] https://pkg.go.dev/context#752#1263
0 commit comments