-
Notifications
You must be signed in to change notification settings - Fork 2k
plugins: run plugin with new process group ID #4769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0891316
to
c719dfb
Compare
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #4769 +/- ##
==========================================
- Coverage 59.68% 59.60% -0.08%
==========================================
Files 287 288 +1
Lines 24865 24785 -80
==========================================
- Hits 14841 14774 -67
+ Misses 9138 9125 -13
Partials 886 886 |
See docker/cli#4599 and docker/cli#4769. When running through the CLI, signal handling + the "3 SIGINTS = exit" behavior is handled by the CLI, and the CLI will signal buildx through the plugin socket to cancel it's context. To deal with the standalone case, this commit introduces `cobrautil.HandleContextCancellation` which checks if the context being executed is already cancellable/plugin is running through the CLI and sets up signal handling if necessary. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
See docker/cli#4599 and docker/cli#4769. When running through the CLI, signal handling + the "3 SIGINTS = exit" behavior is handled by the CLI, and the CLI will signal buildx through the plugin socket to cancel it's context. To deal with the standalone case, this commit introduces `cobrautil.HandleContextCancellation` which checks if the context being executed is already cancellable/plugin is running through the CLI and sets up signal handling if necessary. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code changes look good afaics; left some comments / suggestions 😅
|
||
func configureOSSpecificCommand(cmd *exec.Cmd) { | ||
cmd.SysProcAttr = &syscall.SysProcAttr{ | ||
Setpgid: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping this was abstracted in the syscall
package (and that to be the reason to use syscall
instead of golang.org/x/sys
), but looks like it's not 😢 (otherwise we could've dropped the abstraction)
Well.. it is what it is 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth adding a comment why we're doing this (writing down the intent; it looks like you already have a good description in the commit message)? Or do you think it's clear from the code alone?
(A good way to judge: would you understand (without looking in history) 1 Year from now when looking at the code?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm too used to having to do dig through many years old commits to understand code that I don't even notice anymore 😞 I'll add some more comments!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I'm pretty sure we'd be able to trace it back if needed. I started to pay more attention to these things (sorry for being the victim of that), for all those times I had to spend "too much time" finding back the reason.
Having a comment also can help deciding making changes ("oh! thanks for the description; this is soooooo last year and really no longer needed. I can confidently remove this part").
That's funny, I usually do this because almost every time I'm doing Github archaeology, if I have to find the commit I want to go to the PR to get additional context. However, the noise and accessibility outside of Github are good arguments, and Github makes it pretty easy now to find the PR a commit came from, so I'll start doing what you're suggesting! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks excellent to me, especially with the addition of explicit signal-forwarding. Like @thaJeztah, my only suggestion is that we add comments explaining why we set the pgid/why we forward the signal in some cases, but not all.
Yup; I'm good with merging after the commit message is updated and a comment added 👍 (thought I'd wait for you to look at that) |
Changes were made in 1554ac3 to provide a mechanism for the CLI to notify running plugin processes that they should exit, in order to improve the general CLI/plugin UX. The current implementation boils down to: 1. The CLI creates a socket 2. The CLI executes the plugin 3. The plugin connects to the socket 4. (When) the CLI receives a termination signal, it uses the socket to notify the plugin that it should exit 5. The plugin's gets notified via the socket, and cancels it's `cmd.Context`, which then gets handled appropriately This change works in most cases and fixes the issue it sets out to solve (see: docker/compose#11292) however, in the case where the user has a TTY attached and the plugin is not already handling received signals, steps 4+ changes: 4. (When) the CLI receives a termination signal, before it can use the socket to notify the plugin that it should exit, the plugin process also receives a signal due to sharing the pgid with the CLI Since we now have a proper "job control" mechanism, we can simplify the scenarios by executing the plugins with their own process group id, thereby removing the "double notification" issue and making it so that plugins can handle the same whether attached to a TTY or not. In order to make this change "plugin-binary" backwards-compatible, in the case that a plugin does not connect to the socket, the CLI passes the signal to the plugin process. Co-authored-by: Bjorn Neergaard <bjorn.neergaard@docker.com> Signed-off-by: Laura Brehm <laurabrehm@hey.com> Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
c719dfb
to
ef5e5fa
Compare
I've carried this with the requested comments and commit message change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Looks like this introduced a regression with buildx running with |
See docker/cli#4599 and docker/cli#4769. Since we switched to using the cobra command context instead of `appcontext`, we need to set up the signal handling that was being provided by `appcontext`, as well as configuring the context with the OTEL tracing utilities also used by `appcontext`. This commit introduces `cobrautil.ConfigureContext` which implements the pre-existing signal handling logic from `appcontext` and cancels the command's context when a signal is received, as well as doing the relevant OTEL config. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
See docker/cli#4599 and docker/cli#4769. Since we switched to using the cobra command context instead of `appcontext`, we need to set up the signal handling that was being provided by `appcontext`, as well as configuring the context with the OTEL tracing utilities also used by `appcontext`. This commit introduces `cobrautil.ConfigureContext` which implements the pre-existing signal handling logic from `appcontext` and cancels the command's context when a signal is received, as well as doing the relevant OTEL config. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
See docker/cli#4599 and docker/cli#4769. Since we switched to using the cobra command context instead of `appcontext`, we need to set up the signal handling that was being provided by `appcontext`, as well as configuring the context with the OTEL tracing utilities also used by `appcontext`. This commit introduces `cobrautil.ConfigureContext` which implements the pre-existing signal handling logic from `appcontext` and cancels the command's context when a signal is received, as well as doing the relevant OTEL config. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
Changes were made in #4599 to provide a mechanism for the CLI to notify running plugin processes that they should exit, in order to improve the general CLI/plugin UX. The current implementation boils down to:
cmd.Context
, which then gets handled appropriatelyThis change works in most cases and fixes the issue it sets out to solve (see: docker/compose#11292) however, in the case where the user has a TTY attached and the plugin is not already handling received signals, steps 4+ changes:
4. (When) the CLI receives a termination signal, before it can use the socket to notify the plugin that it should exit, the plugin process also receives a signal due to sharing the pgid with the CLI
Since we now have a proper "job control" mechanism, we can simplify the scenarios by executing the plugins with their own process group id, thereby removing the "double notification" issue and making it so that plugins can handle the same whether attached to a TTY or not.
In order to make this change "plugin-binary" backwards-compatible, in the case that a plugin does not connect to the socket, the CLI passes the signal to the plugin process.
- What I did
Execute plugins with their own process group id. If a(n older) plugin does not connect to the CLI socket, pass received signals onto the plugin process, so as to preserve compatibility with older plugin binaries.
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)