-
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
Fix prefix-matching for service ps #72
Conversation
ping @aaronlehmann @vdemeester PTAL |
I have a fix for the complexity failure in #61. If you're interested in applying those changes first (just the service/ps.go diff), then these changes on top, I think it should fix the build. |
The docker CLI matches objects either by ID _prefix_ or a full name match, but not partial name matches. The correct order of resolution is; - Full ID match (a name should not be able to mask an ID) - Full name - ID-prefix This patch changes the way services are matched. Also change to use the first matching service, if there's a full match (by ID or Name) instead of continue looking for other possible matches. Error handling changed; - Do not error early if multiple services were requested and one or more services were not found. Print the services that were not found after printing those that _were_ found instead - Print an error if ID-prefix matching is ambiguous Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
d564621
to
6279612
Compare
Rebased, not sure if I should pick the changes from #61, due to the changes still being discussed there |
This doesn't need to be blocked on #61 . I'll prepare a commit with just the relevant fix for this failure and push it to this branch tomorrow. |
Codecov Report
@@ Coverage Diff @@
## master #72 +/- ##
=========================================
+ Coverage 44.95% 45.2% +0.25%
=========================================
Files 169 169
Lines 11381 11399 +18
=========================================
+ Hits 5116 5153 +37
+ Misses 5972 5947 -25
- Partials 293 299 +6 |
Signed-off-by: Daniel Nephin <dnephin@docker.com>
0284d81
to
b5baffd
Compare
Thanks @dnephin I was quite busy, and didn't find a moment into applying just that commit ❤️ |
No problem! I'm working on a unit test for this, since there aren't any yet. |
Added another commit with unit tests. Build is green |
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 👼
cli/command/service/ps_test.go
Outdated
expected.Add("service", "abababab") | ||
expected.Add("service", "cccccccc") | ||
expected.Add("node", "somenode") | ||
assert.Equal(t, expected, actual) |
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.
Can we also test prefix matches? Specifically:
- An unambiguous ID prefix should match
- An ambiguous ID prefix should lead to an error or warning
- A name prefix should never match.
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've added the additional test cases
for _, s := range serviceByIDList { | ||
if strings.HasPrefix(s.ID, service) { | ||
if found { | ||
return filter, nil, errors.New("multiple services found with provided prefix: " + service) |
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.
Just noticed it's a bit odd that that an ambiguous prefix causes service ps
to fail with an error, but a nonexistent service causes ps
to proceed for the other services and show a warning later. Shouldn't these cases be treated similarly?
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.
For non-existing services, I think we follow what we do for other commands. For example, cases like;
docker stop $(docker ps -aq)
Where we don't want the command to fail on the first "not found", however if ambiguous results would be accepted, such a command could easily lead to multiple objects being affected.
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.
Sorry, I don't understand. Are you saying we should fail the whole command on an ambiguous prefix but not a nonexistent service? Why is an ambiguous prefix different from not finding the service?
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.
Yes, I think that's the correct behaviour. It matches what we do for other commands.
We don't want to immediately fail on "not found" because there is other work we can do. But in the case of an ambiguous prefix the work is undefined, so we can't really do anything but error.
} | ||
} | ||
|
||
if serviceCount == 0 { | ||
return filter, nil, errors.New(strings.Join(notfound, "\n")) |
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.
Wondering if it would make sense to just return an empty set of filters here, and have the caller detect that and format the error message. Or we could always return a formatted warning string here. But I think duplicating the errors.New(strings.Join(notfound, "\n"))
code in both places is not ideal.
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.
Either way this has to happen twice, because the other case doesn't return an error until after printing the results.
Also the filters wont necessarily be empty because the user can set other filters (node filters for one, not sure about others).
I can make it a function if you feel that improves the code.
13d1121
to
3718833
Compare
Signed-off-by: Daniel Nephin <dnephin@docker.com>
We don't want to immediately fail on "not found" because there is other work we can do. But in the case of an ambiguous prefix the work is undefined, so we can't really do anything but error.
Why can't we do the work for the other values provided on the command line? Sorry if I seem difficult; I'm just trying to understand the distinction.
|
Technically I think we could. I think this behaviour is designed to match what we do for other commands. |
The docker CLI matches objects either by ID prefix
or a full name match, but not partial name matches.
The correct order of resolution is;
This patch changes the way services are matched.
Also change to use the first matching service, if there's a
full match (by ID or Name) instead of continue looking for
other possible matches.
Error handling changed;
and one or more services were not found. Print the
services that were not found after printing those that
were found instead
This PR carries the CLI changes of moby/moby#32800