mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #31538 from yongtang/31325-service-ls-filter-mode
Support `--filter mode=global|replicated` for `docker service ls`
This commit is contained in:
commit
b36ce6f2f6
6 changed files with 77 additions and 18 deletions
|
@ -7399,6 +7399,7 @@ paths:
|
|||
|
||||
- `id=<service id>`
|
||||
- `label=<service label>`
|
||||
- `mode=["replicated"|"global"]`
|
||||
- `name=<service name>`
|
||||
tags: ["Service"]
|
||||
/services/create:
|
||||
|
|
|
@ -45,22 +45,6 @@ func newListNodesFilters(filter filters.Args) (*swarmapi.ListNodesRequest_Filter
|
|||
return f, nil
|
||||
}
|
||||
|
||||
func newListServicesFilters(filter filters.Args) (*swarmapi.ListServicesRequest_Filters, error) {
|
||||
accepted := map[string]bool{
|
||||
"name": true,
|
||||
"id": true,
|
||||
"label": true,
|
||||
}
|
||||
if err := filter.Validate(accepted); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &swarmapi.ListServicesRequest_Filters{
|
||||
NamePrefixes: filter.Get("name"),
|
||||
IDPrefixes: filter.Get("id"),
|
||||
Labels: runconfigopts.ConvertKVStringsToMap(filter.Get("label")),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func newListTasksFilters(filter filters.Args, transformFunc func(filters.Args) error) (*swarmapi.ListTasksRequest_Filters, error) {
|
||||
accepted := map[string]bool{
|
||||
"name": true,
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/docker/docker/daemon/logger"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||
swarmapi "github.com/docker/swarmkit/api"
|
||||
gogotypes "github.com/gogo/protobuf/types"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -37,10 +38,25 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
|
|||
return nil, c.errNoManager(state)
|
||||
}
|
||||
|
||||
filters, err := newListServicesFilters(options.Filters)
|
||||
if err != nil {
|
||||
// We move the accepted filter check here as "mode" filter
|
||||
// is processed in the daemon, not in SwarmKit. So it might
|
||||
// be good to have accepted file check in the same file as
|
||||
// the filter processing (in the for loop below).
|
||||
accepted := map[string]bool{
|
||||
"name": true,
|
||||
"id": true,
|
||||
"label": true,
|
||||
"mode": true,
|
||||
}
|
||||
if err := options.Filters.Validate(accepted); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filters := &swarmapi.ListServicesRequest_Filters{
|
||||
NamePrefixes: options.Filters.Get("name"),
|
||||
IDPrefixes: options.Filters.Get("id"),
|
||||
Labels: runconfigopts.ConvertKVStringsToMap(options.Filters.Get("label")),
|
||||
}
|
||||
|
||||
ctx, cancel := c.getRequestContext()
|
||||
defer cancel()
|
||||
|
||||
|
@ -54,6 +70,19 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
|
|||
services := []types.Service{}
|
||||
|
||||
for _, service := range r.Services {
|
||||
if options.Filters.Include("mode") {
|
||||
var mode string
|
||||
switch service.Spec.GetMode().(type) {
|
||||
case *swarmapi.ServiceSpec_Global:
|
||||
mode = "global"
|
||||
case *swarmapi.ServiceSpec_Replicated:
|
||||
mode = "replicated"
|
||||
}
|
||||
|
||||
if !options.Filters.ExactMatch("mode", mode) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
services = append(services, convert.ServiceFromGRPC(*service))
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
* `POST /build` now accepts `extrahosts` parameter to specify a host to ip mapping to use during the build.
|
||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept a `rollback` value for `FailureAction`.
|
||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept an optional `RollbackConfig` object which specifies rollback options.
|
||||
* `GET /services` now supports a `mode` filter to filter services based on the service mode (either `global` or `replicated`).
|
||||
|
||||
## v1.27 API changes
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ The currently supported filters are:
|
|||
|
||||
* [id](service_ls.md#id)
|
||||
* [label](service_ls.md#label)
|
||||
* [mode](service_ls.md#mode)
|
||||
* [name](service_ls.md#name)
|
||||
|
||||
#### id
|
||||
|
@ -98,6 +99,18 @@ ID NAME MODE REPLICAS IMAGE
|
|||
74nzcxxjv6fq backend replicated 3/3 redis:3.0.6
|
||||
```
|
||||
|
||||
#### mode
|
||||
|
||||
The `mode` filter matches on the mode (either `replicated` or `global`) of a service.
|
||||
|
||||
The following filter matches only `global` services.
|
||||
|
||||
```bash
|
||||
$ docker service ls --filter mode=global
|
||||
ID NAME MODE REPLICAS IMAGE
|
||||
w7y0v2yrn620 top global 1/1 busybox
|
||||
```
|
||||
|
||||
#### name
|
||||
|
||||
The `name` filter matches on all or part of a service's name.
|
||||
|
|
|
@ -1797,3 +1797,34 @@ func (s *DockerSwarmSuite) TestSwarmStopSignal(c *check.C) {
|
|||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "SIGUSR1")
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestSwarmServiceLsFilterMode(c *check.C) {
|
||||
d := s.AddDaemon(c, true, true)
|
||||
|
||||
out, err := d.Cmd("service", "create", "--name", "top1", "busybox", "top")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||
|
||||
out, err = d.Cmd("service", "create", "--name", "top2", "--mode=global", "busybox", "top")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||
|
||||
// make sure task has been deployed.
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 2)
|
||||
|
||||
out, err = d.Cmd("service", "ls")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "top1")
|
||||
c.Assert(out, checker.Contains, "top2")
|
||||
c.Assert(out, checker.Not(checker.Contains), "localnet")
|
||||
|
||||
out, err = d.Cmd("service", "ls", "--filter", "mode=global")
|
||||
c.Assert(out, checker.Not(checker.Contains), "top1")
|
||||
c.Assert(out, checker.Contains, "top2")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
out, err = d.Cmd("service", "ls", "--filter", "mode=replicated")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "top1")
|
||||
c.Assert(out, checker.Not(checker.Contains), "top2")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue