mirror of https://github.com/docker/cli.git
Fix prefix-matching for service ps
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>
This commit is contained in:
parent
6c59636498
commit
6279612443
|
@ -69,29 +69,43 @@ func runPS(dockerCli command.Cli, options psOptions) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, service := range options.services {
|
var errs []string
|
||||||
serviceCount := 0
|
serviceCount := 0
|
||||||
// Lookup by ID/Prefix
|
loop:
|
||||||
for _, serviceEntry := range serviceByIDList {
|
// Match services by 1. Full ID, 2. Full name, 3. ID prefix. An error is returned if the ID-prefix match is ambiguous
|
||||||
if strings.HasPrefix(serviceEntry.ID, service) {
|
for _, service := range options.services {
|
||||||
filter.Add("service", serviceEntry.ID)
|
for _, s := range serviceByIDList {
|
||||||
|
if s.ID == service {
|
||||||
|
filter.Add("service", s.ID)
|
||||||
serviceCount++
|
serviceCount++
|
||||||
|
continue loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, s := range serviceByNameList {
|
||||||
// Lookup by Name/Prefix
|
if s.Spec.Annotations.Name == service {
|
||||||
for _, serviceEntry := range serviceByNameList {
|
filter.Add("service", s.ID)
|
||||||
if strings.HasPrefix(serviceEntry.Spec.Annotations.Name, service) {
|
|
||||||
filter.Add("service", serviceEntry.ID)
|
|
||||||
serviceCount++
|
serviceCount++
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found := false
|
||||||
|
for _, s := range serviceByIDList {
|
||||||
|
if strings.HasPrefix(s.ID, service) {
|
||||||
|
if found {
|
||||||
|
return errors.New("multiple services found with provided prefix: " + service)
|
||||||
|
}
|
||||||
|
filter.Add("service", s.ID)
|
||||||
|
serviceCount++
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
errs = append(errs, "no such service: "+service)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If nothing has been found, return immediately.
|
|
||||||
if serviceCount == 0 {
|
if serviceCount == 0 {
|
||||||
return errors.Errorf("no such services: %s", service)
|
return errors.New(strings.Join(errs, "\n"))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if filter.Include("node") {
|
if filter.Include("node") {
|
||||||
nodeFilters := filter.Get("node")
|
nodeFilters := filter.Get("node")
|
||||||
for _, nodeFilter := range nodeFilters {
|
for _, nodeFilter := range nodeFilters {
|
||||||
|
@ -117,6 +131,11 @@ func runPS(dockerCli command.Cli, options psOptions) error {
|
||||||
format = formatter.TableFormatKey
|
format = formatter.TableFormatKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format); err != nil {
|
||||||
return task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format)
|
return err
|
||||||
|
}
|
||||||
|
if len(errs) != 0 {
|
||||||
|
return errors.New(strings.Join(errs, "\n"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue