Skip to content
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

Merged
merged 3 commits into from
Jun 13, 2017

Conversation

thaJeztah
Copy link
Member

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

This PR carries the CLI changes of moby/moby#32800

@thaJeztah
Copy link
Member Author

ping @aaronlehmann @vdemeester PTAL

@dnephin
Copy link
Contributor

dnephin commented May 11, 2017

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>
@thaJeztah
Copy link
Member Author

Rebased, not sure if I should pick the changes from #61, due to the changes still being discussed there

@thaJeztah thaJeztah mentioned this pull request May 31, 2017
23 tasks
@dnephin
Copy link
Contributor

dnephin commented Jun 1, 2017

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-io
Copy link

codecov-io commented Jun 1, 2017

Codecov Report

Merging #72 into master will increase coverage by 0.25%.
The diff coverage is 66.66%.

@@            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>
@thaJeztah
Copy link
Member Author

Thanks @dnephin I was quite busy, and didn't find a moment into applying just that commit ❤️

@dnephin
Copy link
Contributor

dnephin commented Jun 1, 2017

No problem!

I'm working on a unit test for this, since there aren't any yet.

@dnephin
Copy link
Contributor

dnephin commented Jun 1, 2017

Added another commit with unit tests. Build is green

@vdemeester vdemeester requested review from vdemeester, dnephin and aaronlehmann and removed request for dnephin June 1, 2017 17:13
Copy link
Collaborator

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👼

expected.Add("service", "abababab")
expected.Add("service", "cccccccc")
expected.Add("node", "somenode")
assert.Equal(t, expected, actual)
Copy link
Contributor

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.

Copy link
Contributor

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)
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

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?

Copy link
Contributor

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"))
Copy link
Contributor

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.

Copy link
Contributor

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.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
@aaronlehmann
Copy link
Contributor

aaronlehmann commented Jun 2, 2017 via email

@dnephin
Copy link
Contributor

dnephin commented Jun 7, 2017

Technically I think we could. I think this behaviour is designed to match what we do for other commands.

@thaJeztah thaJeztah mentioned this pull request Jun 7, 2017
40 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants