1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Add name/driver filter support for volume

This change include filter `name` and `driver`,
and also update related docs to reflect that filters usage.

Closes: #21243

Signed-off-by: Kai Qiang Wu(Kennan) <wkqwu@cn.ibm.com>
This commit is contained in:
Kai Qiang Wu(Kennan) 2016-03-21 07:39:48 +00:00
parent 6748ecb005
commit 8e9305ef94
5 changed files with 113 additions and 23 deletions

View file

@ -18,6 +18,8 @@ import (
var acceptedVolumeFilterTags = map[string]bool{ var acceptedVolumeFilterTags = map[string]bool{
"dangling": true, "dangling": true,
"name": true,
"driver": true,
} }
var acceptedPsFilterTags = map[string]bool{ var acceptedPsFilterTags = map[string]bool{
@ -473,7 +475,6 @@ func (daemon *Daemon) transformContainer(container *container.Container, ctx *li
func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, []string, error) { func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, []string, error) {
var ( var (
volumesOut []*types.Volume volumesOut []*types.Volume
danglingOnly = false
) )
volFilters, err := filters.FromParam(filter) volFilters, err := filters.FromParam(filter)
if err != nil { if err != nil {
@ -484,27 +485,51 @@ func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, []string, error)
return nil, nil, err return nil, nil, err
} }
if volFilters.Include("dangling") {
if volFilters.ExactMatch("dangling", "true") || volFilters.ExactMatch("dangling", "1") {
danglingOnly = true
} else if !volFilters.ExactMatch("dangling", "false") && !volFilters.ExactMatch("dangling", "0") {
return nil, nil, fmt.Errorf("Invalid filter 'dangling=%s'", volFilters.Get("dangling"))
}
}
volumes, warnings, err := daemon.volumes.List() volumes, warnings, err := daemon.volumes.List()
filterVolumes, err := daemon.filterVolumes(volumes, volFilters)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if volFilters.Include("dangling") { for _, v := range filterVolumes {
volumes = daemon.volumes.FilterByUsed(volumes, !danglingOnly)
}
for _, v := range volumes {
volumesOut = append(volumesOut, volumeToAPIType(v)) volumesOut = append(volumesOut, volumeToAPIType(v))
} }
return volumesOut, warnings, nil return volumesOut, warnings, nil
} }
// filterVolumes filters volume list according to user specified filter
// and returns user chosen volumes
func (daemon *Daemon) filterVolumes(vols []volume.Volume, filter filters.Args) ([]volume.Volume, error) {
// if filter is empty, return original volume list
if filter.Len() == 0 {
return vols, nil
}
var retVols []volume.Volume
for _, vol := range vols {
if filter.Include("name") {
if !filter.Match("name", vol.Name()) {
continue
}
}
if filter.Include("driver") {
if !filter.Match("driver", vol.DriverName()) {
continue
}
}
retVols = append(retVols, vol)
}
danglingOnly := false
if filter.Include("dangling") {
if filter.ExactMatch("dangling", "true") || filter.ExactMatch("dangling", "1") {
danglingOnly = true
} else if !filter.ExactMatch("dangling", "false") && !filter.ExactMatch("dangling", "0") {
return nil, fmt.Errorf("Invalid filter 'dangling=%s'", filter.Get("dangling"))
}
retVols = daemon.volumes.FilterByUsed(retVols, !danglingOnly)
}
return retVols, nil
}
func populateImageFilterByParents(ancestorMap map[image.ID]bool, imageID image.ID, getChildren func(image.ID) []image.ID) { func populateImageFilterByParents(ancestorMap map[image.ID]bool, imageID image.ID, getChildren func(image.ID) []image.ID) {
if !ancestorMap[imageID] { if !ancestorMap[imageID] {
for _, id := range getChildren(imageID) { for _, id := range getChildren(imageID) {

View file

@ -134,6 +134,7 @@ This section lists each version from latest to oldest. Each listing includes a
* `POST /containers/create` now allows specifying `nocopy` for named volumes, which disables automatic copying from the container path to the volume. * `POST /containers/create` now allows specifying `nocopy` for named volumes, which disables automatic copying from the container path to the volume.
* `POST /auth` now returns an `IdentityToken` when supported by a registry. * `POST /auth` now returns an `IdentityToken` when supported by a registry.
* `POST /containers/create` with both `Hostname` and `Domainname` fields specified will result in the container's hostname being set to `Hostname`, rather than `Hostname.Domainname`. * `POST /containers/create` with both `Hostname` and `Domainname` fields specified will result in the container's hostname being set to `Hostname`, rather than `Hostname.Domainname`.
* `GET /volumes` now supports more filters, new added filters are `name` and `driver`.
### v1.22 API changes ### v1.22 API changes

View file

@ -2837,7 +2837,10 @@ Status Codes:
Query Parameters: Query Parameters:
- **filters** - JSON encoded value of the filters (a `map[string][]string`) to process on the volumes list. There is one available filter: `dangling=true` - **filters** - JSON encoded value of the filters (a `map[string][]string`) to process on the volumes list. Available filters:
- `name=<volume-name>` Matches all or part of a volume name.
- `dangling=<boolean>` When set to `true` (or `1`), returns all volumes that are "dangling" (not in use by a container). When set to `false` (or `0`), only volumes that are in use by one or more containers are returned.
- `driver=<volume-driver-name>` Matches all or part of a volume driver name.
Status Codes: Status Codes:

View file

@ -14,25 +14,68 @@ parent = "smn_cli"
List volumes List volumes
-f, --filter=[] Provide filter values (i.e. 'dangling=true') -f, --filter=[] Filter output based on these conditions:
- dangling=<boolean> a volume if referenced or not
- driver=<string> a volume's driver name
- name=<string> a volume's name
--help Print usage --help Print usage
-q, --quiet Only display volume names -q, --quiet Only display volume names
Lists all the volumes Docker knows about. You can filter using the `-f` or `--filter` flag. The filtering format is a `key=value` pair. To specify more than one filter, pass multiple flags (for example, `--filter "foo=bar" --filter "bif=baz"`) Lists all the volumes Docker knows about. You can filter using the `-f` or `--filter` flag. Refer to the [filtering](#filtering) section for more information about available filter options.
There is a single supported filter `dangling=value` which takes a boolean of `true` or `false`.
Example output: Example output:
$ docker volume create --name rose $ docker volume create --name rosemary
rose rosemary
$docker volume create --name tyler $docker volume create --name tyler
tyler tyler
$ docker volume ls $ docker volume ls
DRIVER VOLUME NAME DRIVER VOLUME NAME
local rose local rosemary
local tyler local tyler
## Filtering
The filtering flag (`-f` or `--filter`) format is of "key=value". If there is more
than one filter, then pass multiple flags (e.g., `--filter "foo=bar" --filter "bif=baz"`)
The currently supported filters are:
* dangling (boolean - true or false, 0 or 1)
* driver (a volume driver's name)
* name (a volume's name)
### dangling
The `dangling` filter matches on all volumes not referenced by any containers
$ docker run -d -v tyler:/tmpwork busybox
f86a7dd02898067079c99ceacd810149060a70528eff3754d0b0f1a93bd0af18
$ docker volume ls -f dangling=true
DRIVER VOLUME NAME
local rosemary
### driver
The `driver` filter matches on all or part of a volume's driver name.
The following filter matches all volumes with a driver name containing the `local` string.
$ docker volume ls -f driver=local
DRIVER VOLUME NAME
local rosemary
local tyler
### name
The `name` filter matches on all or part of a volume's name.
The following filter matches all volumes with a name containing the `rose` string.
$ docker volume ls -f name=rose
DRIVER VOLUME NAME
local rosemary
## Related information ## Related information
* [volume create](volume_create.md) * [volume create](volume_create.md)

View file

@ -138,6 +138,24 @@ func (s *DockerSuite) TestVolumeCliLsFilterDangling(c *check.C) {
c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output")) c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output")) c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
out, _ = dockerCmd(c, "volume", "ls", "--filter", "name=testisin")
c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("execpeted volume 'testisinuse1' in output"))
c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=invalidDriver")
outArr := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=local")
outArr = strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=loc")
outArr = strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
} }
func (s *DockerSuite) TestVolumeCliLsErrorWithInvalidFilterName(c *check.C) { func (s *DockerSuite) TestVolumeCliLsErrorWithInvalidFilterName(c *check.C) {