-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
cmd/docker: split handling exit-code to a separate utility #5229
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5229 +/- ##
==========================================
+ Coverage 61.47% 61.49% +0.01%
==========================================
Files 298 298
Lines 20815 20811 -4
==========================================
Hits 12797 12797
+ Misses 7106 7102 -4
Partials 912 912 |
AH! I broke something probably; I was indeed thinking if the === FAIL: e2e/cli-plugins TestPluginSocketCommunication/detached/the_plugin_does_not_get_signalled (1.00s)
socket_test.go:194: context cancelled
Status: , Code: 2
socket_test.go:199: assertion failed:
--- ←
+++ →
@@ -1,3 +1,2 @@
context cancelled
-Status: , Code: 2 Slightly wondering now if the test should be checking for the cli/e2e/cli-plugins/socket_test.go Lines 193 to 199 in 5aae44b
|
79e22e5
to
1c78142
Compare
Wait; what's this? Do we have 2 separate spellings of
This happened when I changed the test to use assert.Check(t, is.Equal(strings.TrimSpace(string(out)), context.Canceled.Error())) |
Ha! We do! cli/e2e/cli-plugins/plugins/presocket/main.go Lines 64 to 69 in 5aae44b
|
941724b
to
822447b
Compare
And... after my initial confusion around
Before my patch, such errors would be silently discarded; Lines 52 to 54 in 5aae44b
It's odd that we're constructing our own output, instead of Lines 31 to 33 in 5aae44b
We can probably borrow similar logic / output as used by Go's func (p *ProcessState) String() string {
if p == nil {
return "<nil>"
}
status := p.Sys().(syscall.WaitStatus)
res := ""
switch {
case status.Exited():
code := status.ExitStatus()
if runtime.GOOS == "windows" && uint(code) >= 1<<16 { // windows uses large hex numbers
res = "exit status " + itoa.Uitox(uint(code))
} else { // unix systems use small decimal integers
res = "exit status " + itoa.Itoa(code) // unix
}
case status.Signaled():
res = "signal: " + status.Signal().String()
case status.Stopped():
res = "stop signal: " + status.StopSignal().String()
if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
res += " (trap " + itoa.Itoa(status.TrapCause()) + ")"
}
case status.Continued():
res = "continued"
}
if status.CoreDump() {
res += " (core dumped)"
}
return res
} |
d8efa58
to
c031b2a
Compare
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
To keep some linters happier, and my IDE to be less noisy. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This confused me fore a bit, because I thought the test was checking for an actual `context.Canceled` error (which is spelled "context canceled" with a single "l". But then I found that this was a string that's printed as part of a test-utility, just looking very similar but with the British spelling ("cancelled"). Let's change this to a message that's unique for the test, also to make it more grep'able. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also remove a debug-log, as the output would already be shown if the test would fail. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Verify that we get the expected exit-code, not just the message. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The logic in this function is confusing; let's start make it obvious where the error that is returned is produced, Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This allows dockerMain() to return an error "as usual", and puts the responsibility for turning that into an appropriate exit-code in main() (which also sets the exit-code when terminating). We could consider putting this utility in the cli package and exporting it if would be useful for doing a similar handling in plugins. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
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.
Thankyou! Yeah, this had been a bit of a mess for a while 😅
It still is messy, but "baby steps"; at least #5231 helped making these if err := doSomething(); err != nil {
if errdefs.IsInvalidParameter(err) {
return cli.StatusErr(err, 123)
}
return err
} But we need to have a good look at that; basically, the status should probably ONLY be set if the error MUST be considered final / terminal; once you set the exit-code, that's it? Every caller handling that error must not ignore the error, and make it trickle up so that the CLI terminates with the given status. We need to look at that consideration if that works (but we could still end up having different classes, basically equivalent to the |
if err := RunPlugin(dockerCli, plugin, meta); err != nil { | ||
if sterr, ok := err.(cli.StatusError); ok { | ||
if sterr.Status != "" { | ||
fmt.Fprintln(dockerCli.Err(), sterr.Status) | ||
} | ||
var stErr cli.StatusError | ||
if errors.As(err, &stErr) { |
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 should probably extract the code in the plugin-code as well (so maybe export the handling), but will look at that in follow-up(s)
Some "regression" after this PR:
Before:
Notice that after this PR cc @thaJeztah |
Good one; I think it's worth having a ticket for that @vvoland so that we can look into what the intent was there; do we want it to have a non-zero exit status (if so; why don't we have an error message to go with it?) or did some (context) error trickle through and therefore we set a 130 exit status? And maybe there's cases we DO want to have just the exit status with no message? 🤔 |
In the "before" case; was the exit status 0? (echo $?) |
This allows dockerMain() to return an error "as usual", and puts the responsibility for turning that into an appropriate exit-code in main() (which also sets the exit-code when terminating).
We could consider putting this utility in the cli package and exporting it if would be useful for doing a similar handling in plugins.
- A picture of a cute animal (not mandatory but encouraged)