Open nicks opened 1 year ago
(as a side note, i was able to reproduce the same behavior with both the Cloud Integration cli and the vanilla com.docker.cli
one)
I just ran into a docker buildx imagetools inspect
hanging, and had to triple-signal to kill the CLI;
docker buildx imagetools inspect nginx
^C^CERRO[0113] got 3 SIGTERM/SIGINTs, forcing shutdown
I went looking for the "SIGTERM/SIGINTs, forcing shutdown", error, and it looks like that is implemented in the "appcontext" utility in BuildKit; https://github.com/docker/cli/blob/dc2eb3bf7c835ff820e0a38de123a846b9e887e9/vendor/github.com/moby/buildkit/util/appcontext/appcontext.go#L33-L43
Originally, that code was pulled into the CLI for BuildKit builds only; https://github.com/docker/cli/commit/656fe85c740110eb726771264ba5b3f29430e97c
So, I guess the intention was for the CLI to forward signals to the plugin, and wait for the plugin to shutdown, but providing a "force stop" of the CLI (itself?) in situations where the plugin refused to shut down. I would expect in that case for the plugin to be force-killed though (and not kept running).
It's possible some "unrelated" change broke that signal forwarding, or maybe it never was there, because plugins were of course added later, and it's possible that existing code only considered forwarding signals to a container (if attached), but not to processes running locally (i.e., "plugins").
Hey folks, coming over from docker/compose#10898. I think that when the CLI receives a signal which is customarily used to ask processes to gracefully terminate, the CLI should oblige; but it's been pointed out that if the CLI were to forward signals to its children (which would be the easiest solution), then plugins would receive two signals in cases where the signal is sent to the entire process group (such as when pressing Ctrl+C in the terminal) - which would break the existing and, as I understand it, desirable behaviour of plugins (shutdown gracefully on first signal, shutdown fast on second).
So, trying to come up with another solution which would achieve the desired behaviour without breaking existing functionality, I had another idea: if plugins were to terminate gracefully when their standard input is closed, then the CLI could use that to signal to the plugin that it should politely bow out. That is, the CLI's signal handler would basically be (in pseudo-code) something like:
def signal_handler($signal):
uninstall signal_handler
close plugin's STDIN
wait for plugin to terminate
send $signal to self
What do you think? I'm not an expert on POSIX, but as far as I understand, this is how one should cleanly react to a signal - uninstall the signal handler, perform any necessary shutdown and cleanup operations, and then self-kill using the same signal so that the appropriate termination signal is registered by the kernel (or something like that, the details are murky). Obviously the same probably wouldn't work on Windows; I don't have the faintest idea of how things work there.
@thaJeztah We are using a lot of tools from inside of the containers when running locally and, since switching from Docker Compose 1, this has became a real pain.
Is there a way to prioritise this fix please? I'm happy to sponsor this work to have this resolved. Thank you
fyi @jahudka @AlexSkrypnyk the above issue is fixed w/ the latest CLI and Compose releases, which should also get shipped in Desktop soon.
Description
Docker plugins have some really odd behavior when the main process gets a SIGTERM signal:
Reproduce
Example code: https://github.com/nicks/docker-sleep/blob/31f7ba2ffd0d48f7c1ba99ef4def3bd1c2429bcb/main.go#L1
1) Install my sample plugin,
docker sleep
2) Run
docker sleep
3) In a separate terminal, run
kill
3 times on the maindocker
processExpected behavior
The ideal behavior would be for the main
docker
cli process to forward the SIGTERM to the plugin, then exit when the plugin exits. But I think other behaviors are arguable?It seems bizarre that it ignores the first signal, swallows it without telling the plugin, then dies on the third signal.
the error message is also incorrect - it doesn't shutdown anything, it just leaves the subprocess running in the background
docker version
docker info
Additional Info
related issue: https://github.com/docker/cli/issues/4332
related pr: https://github.com/docker/cli/pull/2799
cc @neersighted (this came from a slack convo i'm having with them)