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

Add mounts to docker ps.

- Allow to filter containers by volume with `--filter volume=name` and `filter volume=/dest`.
- Show their names in the list with the custom format `{{ .Mounts }}`.

Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
David Calavera 2016-02-03 17:46:01 -05:00
parent 64785ff146
commit bd4fb00fb6
7 changed files with 142 additions and 7 deletions

View file

@ -31,6 +31,7 @@ const (
repositoryHeader = "REPOSITORY"
tagHeader = "TAG"
digestHeader = "DIGEST"
mountsHeader = "MOUNTS"
)
type containerContext struct {
@ -142,6 +143,20 @@ func (c *containerContext) Label(name string) string {
return c.c.Labels[name]
}
func (c *containerContext) Mounts() string {
c.addHeader(mountsHeader)
var mounts []string
for _, m := range c.c.Mounts {
name := m.Name
if c.trunc {
name = stringutils.Truncate(name, 15)
}
mounts = append(mounts, name)
}
return strings.Join(mounts, ",")
}
type imageContext struct {
baseSubContext
trunc bool

View file

@ -9,6 +9,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/volume"
"github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/filters"
networktypes "github.com/docker/engine-api/types/network"
@ -306,6 +307,27 @@ func includeContainerInList(container *container.Container, ctx *listContext) it
return excludeContainer
}
if ctx.filters.Include("volume") {
volumesByName := make(map[string]*volume.MountPoint)
for _, m := range container.MountPoints {
volumesByName[m.Name] = m
}
volumeExist := fmt.Errorf("volume mounted in container")
err := ctx.filters.WalkValues("volume", func(value string) error {
if _, exist := container.MountPoints[value]; exist {
return volumeExist
}
if _, exist := volumesByName[value]; exist {
return volumeExist
}
return nil
})
if err != volumeExist {
return excludeContainer
}
}
if ctx.ancestorFilter {
if len(ctx.images) == 0 {
return excludeContainer
@ -419,6 +441,7 @@ func (daemon *Daemon) transformContainer(container *container.Container, ctx *li
newC.SizeRootFs = sizeRootFs
}
newC.Labels = container.Config.Labels
newC.Mounts = addMountPoints(container)
return newC, nil
}

View file

@ -116,6 +116,7 @@ This section lists each version from latest to oldest. Each listing includes a
[Docker Remote API v1.23](docker_remote_api_v1.23.md) documentation
* `GET /containers/json` returns the state of the container, one of `created`, `restarting`, `running`, `paused`, `exited` or `dead`.
* `GET /containers/json` returns the mount points for the container.
* `GET /networks/(name)` now returns an `Internal` field showing whether the network is internal or not.

View file

@ -73,7 +73,18 @@ List containers
"MacAddress": "02:42:ac:11:00:02"
}
}
}
},
"Mounts": [
{
"Name": "fac362...80535",
"Source": "/data",
"Destination": "/data",
"Driver": "local",
"Mode": "ro,Z",
"RW": false,
"Propagation": ""
}
]
},
{
"Id": "9cd87474be90",
@ -102,8 +113,8 @@ List containers
"MacAddress": "02:42:ac:11:00:08"
}
}
}
},
"Mounts": []
},
{
"Id": "3176a2479c92",
@ -132,8 +143,8 @@ List containers
"MacAddress": "02:42:ac:11:00:06"
}
}
}
},
"Mounts": []
},
{
"Id": "4cb07b47f9fb",
@ -162,8 +173,8 @@ List containers
"MacAddress": "02:42:ac:11:00:05"
}
}
}
},
"Mounts": []
}
]
@ -184,6 +195,10 @@ Query Parameters:
- `status=`(`created`|`restarting`|`running`|`paused`|`exited`|`dead`)
- `label=key` or `label="key=value"` of a container label
- `isolation=`(`default`|`process`|`hyperv`) (Windows daemon only)
- `ancestor`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
- `before`=(`<container id>` or `<container name>`)
- `since`=(`<container id>` or `<container name>`)
- `volume`=(`<volume name>` or `<mount point destination>`)
Status Codes:

View file

@ -60,6 +60,7 @@ The currently supported filters are:
* before (container's id or name) - filters containers created before given id or name
* since (container's id or name) - filters containers created since given id or name
* isolation (default|process|hyperv) (Windows daemon only)
* volume (volume name or mount point) - filters containers that mount volumes.
#### Label
@ -193,6 +194,18 @@ with the same containers as in `before` filter:
9c3527ed70ce busybox "top" 10 minutes ago Up 10 minutes desperate_dubinsky
4aace5031105 busybox "top" 10 minutes ago Up 10 minutes focused_hamilton
#### Volume
The `volume` filter shows only containers that mount a specific volume or have a volume mounted in a specific path:
$ docker ps --filter volume=remote-volume --format "table {{.ID}}\t{{.Mounts}}"
CONTAINER ID MOUNTS
9c3527ed70ce remote-volume
$ docker ps --filter volume=/data --format "table {{.ID}}\t{{.Mounts}}"
CONTAINER ID MOUNTS
9c3527ed70ce remote-volume
## Formatting
@ -213,6 +226,7 @@ Placeholder | Description
`.Names` | Container names.
`.Labels` | All labels assigned to the container.
`.Label` | Value of a specific label for this container. For example `{{.Label "com.docker.swarm.cpu"}}`
`.Mounts` | Names of the volumes mounted in this container.
When using the `--format` option, the `ps` command will either output the data exactly as the template
declares or, when using the `table` directive, will include column headers as well.

View file

@ -734,3 +734,56 @@ func (s *DockerSuite) TestPsNotShowPortsOfStoppedContainer(c *check.C) {
fields = strings.Fields(lines[1])
c.Assert(fields[len(fields)-2], checker.Not(checker.Equals), expected, check.Commentf("Should not got %v", expected))
}
func (s *DockerSuite) TestPsShowMounts(c *check.C) {
prefix, slash := getPrefixAndSlashFromDaemonPlatform()
mp := prefix + slash + "test"
dockerCmd(c, "volume", "create", "--name", "ps-volume-test")
runSleepingContainer(c, "--name=volume-test-1", "--volume", "ps-volume-test:"+mp)
c.Assert(waitRun("volume-test-1"), checker.IsNil)
runSleepingContainer(c, "--name=volume-test-2", "--volume", mp)
c.Assert(waitRun("volume-test-2"), checker.IsNil)
out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}")
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
c.Assert(lines, checker.HasLen, 2)
fields := strings.Fields(lines[0])
c.Assert(fields, checker.HasLen, 2)
annonymounsVolumeID := fields[1]
fields = strings.Fields(lines[1])
c.Assert(fields[1], checker.Equals, "ps-volume-test")
// filter by volume name
out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=ps-volume-test")
lines = strings.Split(strings.TrimSpace(string(out)), "\n")
c.Assert(lines, checker.HasLen, 1)
fields = strings.Fields(lines[0])
c.Assert(fields[1], checker.Equals, "ps-volume-test")
// empty results filtering by unknown volume
out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=this-volume-should-not-exist")
c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0)
// filter by mount destination
out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+mp)
lines = strings.Split(strings.TrimSpace(string(out)), "\n")
c.Assert(lines, checker.HasLen, 2)
fields = strings.Fields(lines[0])
c.Assert(fields[1], checker.Equals, annonymounsVolumeID)
fields = strings.Fields(lines[1])
c.Assert(fields[1], checker.Equals, "ps-volume-test")
// empty results filtering by unknown mount point
out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+prefix+slash+"this-path-was-never-mounted")
c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0)
}

View file

@ -35,6 +35,7 @@ the running containers.
- before=(<container-name>|<container-id>)
- since=(<container-name>|<container-id>)
- ancestor=(<image-name>[:tag]|<image-id>|<image@digest>) - containers created from an image or a descendant.
- volume=(<volume-name>|<mount-point-destination>)
**--format**="*TEMPLATE*"
Pretty-print containers using a Go template.
@ -50,6 +51,7 @@ the running containers.
.Names - Container names.
.Labels - All labels assigned to the container.
.Label - Value of a specific label for this container. For example `{{.Label "com.docker.swarm.cpu"}}`
.Mounts - Names of the volumes mounted in this container.
**--help**
Print usage statement
@ -118,6 +120,18 @@ the running containers.
c1d3b0166030 debian
41d50ecd2f57 fedora
# Display containers with `remote-volume` mounted
$ docker ps --filter volume=remote-volume --format "table {{.ID}}\t{{.Mounts}}"
CONTAINER ID MOUNTS
9c3527ed70ce remote-volume
# Display containers with a volume mounted in `/data`
$ docker ps --filter volume=/data --format "table {{.ID}}\t{{.Mounts}}"
CONTAINER ID MOUNTS
9c3527ed70ce remote-volume
# HISTORY
April 2014, Originally compiled by William Henry (whenry at redhat dot com)
based on docker.com source material and internal work.