mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Allow volume drivers to provide a Status
field
The `Status` field is a `map[string]interface{}` which allows the driver to pass back low-level details about the underlying volume. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
parent
6472a6d9e5
commit
36a1c56cf5
9 changed files with 62 additions and 4 deletions
|
@ -206,6 +206,7 @@ func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
|
|||
}
|
||||
apiV := volumeToAPIType(v)
|
||||
apiV.Mountpoint = v.Path()
|
||||
apiV.Status = v.Status()
|
||||
return apiV, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,21 @@ external storage systems, such as Amazon EBS, and enable data volumes to persist
|
|||
beyond the lifetime of a single Engine host. See the [plugin
|
||||
documentation](plugins.md) for more information.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 1.12.0
|
||||
|
||||
- Add `Status` field to `VolumeDriver.Get` response ([#21006](https://github.com/docker/docker/pull/21006#))
|
||||
|
||||
### 1.10.0
|
||||
|
||||
- Add `VolumeDriver.Get` which gets the details about the volume ([#16534](https://github.com/docker/docker/pull/16534))
|
||||
- Add `VolumeDriver.List` which lists all volumes owned by the driver ([#16534](https://github.com/docker/docker/pull/16534))
|
||||
|
||||
### 1.8.0
|
||||
|
||||
- Initial support for volume driver plugins ([#14659](https://github.com/docker/docker/pull/14659))
|
||||
|
||||
## Command-line changes
|
||||
|
||||
A volume plugin makes use of the `-v`and `--volume-driver` flag on the `docker run` command. The `-v` flag accepts a volume name and the `--volume-driver` flag a driver type, for example:
|
||||
|
@ -183,6 +198,7 @@ Get the volume info.
|
|||
"Volume": {
|
||||
"Name": "volume_name",
|
||||
"Mountpoint": "/path/to/directory/on/host",
|
||||
"Status": {}
|
||||
},
|
||||
"Err": ""
|
||||
}
|
||||
|
|
|
@ -2792,7 +2792,8 @@ Create a volume
|
|||
{
|
||||
"Name": "tardis",
|
||||
"Driver": "local",
|
||||
"Mountpoint": "/var/lib/docker/volumes/tardis"
|
||||
"Mountpoint": "/var/lib/docker/volumes/tardis",
|
||||
"Status": null
|
||||
}
|
||||
|
||||
Status Codes:
|
||||
|
|
|
@ -32,7 +32,8 @@ Example output:
|
|||
{
|
||||
"Name": "85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d",
|
||||
"Driver": "local",
|
||||
"Mountpoint": "/var/lib/docker/volumes/85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d/_data"
|
||||
"Mountpoint": "/var/lib/docker/volumes/85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d/_data",
|
||||
"Status": null
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -44,4 +45,4 @@ Example output:
|
|||
* [volume create](volume_create.md)
|
||||
* [volume ls](volume_ls.md)
|
||||
* [volume rm](volume_rm.md)
|
||||
* [Understand Data Volumes](../../userguide/containers/dockervolumes.md)
|
||||
* [Understand Data Volumes](../../userguide/containers/dockervolumes.md)
|
||||
|
|
|
@ -72,6 +72,7 @@ func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) {
|
|||
Name string
|
||||
Mountpoint string
|
||||
Ninja bool // hack used to trigger an null volume return on `Get`
|
||||
Status map[string]interface{}
|
||||
}
|
||||
var volList []vol
|
||||
|
||||
|
@ -110,7 +111,8 @@ func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) {
|
|||
return
|
||||
}
|
||||
_, isNinja := pr.Opts["ninja"]
|
||||
volList = append(volList, vol{Name: pr.Name, Ninja: isNinja})
|
||||
status := map[string]interface{}{"Hello": "world"}
|
||||
volList = append(volList, vol{Name: pr.Name, Ninja: isNinja, Status: status})
|
||||
send(w, nil)
|
||||
})
|
||||
|
||||
|
@ -140,6 +142,7 @@ func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) {
|
|||
send(w, map[string]vol{})
|
||||
return
|
||||
}
|
||||
|
||||
v.Mountpoint = hostVolumePath(pr.Name)
|
||||
send(w, map[string]vol{"Volume": v})
|
||||
return
|
||||
|
@ -419,6 +422,19 @@ func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverGet(c *check.C) {
|
|||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(s.ec.gets, check.Equals, 1)
|
||||
c.Assert(out, checker.Contains, "No such volume")
|
||||
|
||||
dockerCmd(c, "volume", "create", "--name", "test", "-d", "test-external-volume-driver")
|
||||
out, _ = dockerCmd(c, "volume", "inspect", "test")
|
||||
|
||||
type vol struct {
|
||||
Status map[string]string
|
||||
}
|
||||
var st []vol
|
||||
|
||||
c.Assert(json.Unmarshal([]byte(out), &st), checker.IsNil)
|
||||
c.Assert(st, checker.HasLen, 1)
|
||||
c.Assert(st[0].Status, checker.HasLen, 1, check.Commentf("%v", st[0]))
|
||||
c.Assert(st[0].Status["Hello"], checker.Equals, "world", check.Commentf("%v", st[0].Status))
|
||||
}
|
||||
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverWithDaemnRestart(c *check.C) {
|
|
@ -64,6 +64,7 @@ func (a *volumeDriverAdapter) Get(name string) (volume.Volume, error) {
|
|||
name: v.Name,
|
||||
driverName: a.Name(),
|
||||
eMount: v.Mountpoint,
|
||||
status: v.Status,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -72,11 +73,13 @@ type volumeAdapter struct {
|
|||
name string
|
||||
driverName string
|
||||
eMount string // ephemeral host volume path
|
||||
status map[string]interface{}
|
||||
}
|
||||
|
||||
type proxyVolume struct {
|
||||
Name string
|
||||
Mountpoint string
|
||||
Status map[string]interface{}
|
||||
}
|
||||
|
||||
func (a *volumeAdapter) Name() string {
|
||||
|
@ -111,3 +114,11 @@ func (a *volumeAdapter) Unmount() error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *volumeAdapter) Status() map[string]interface{} {
|
||||
out := make(map[string]interface{}, len(a.status))
|
||||
for k, v := range a.status {
|
||||
out[k] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -328,3 +328,7 @@ func validateOpts(opts map[string]string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *localVolume) Status() map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ func (NoopVolume) Mount() (string, error) { return "noop", nil }
|
|||
// Unmount unmounts the volume from the container
|
||||
func (NoopVolume) Unmount() error { return nil }
|
||||
|
||||
// Status proivdes low-level details about the volume
|
||||
func (NoopVolume) Status() map[string]interface{} { return nil }
|
||||
|
||||
// FakeVolume is a fake volume with a random name
|
||||
type FakeVolume struct {
|
||||
name string
|
||||
|
@ -50,6 +53,9 @@ func (FakeVolume) Mount() (string, error) { return "fake", nil }
|
|||
// Unmount unmounts the volume from the container
|
||||
func (FakeVolume) Unmount() error { return nil }
|
||||
|
||||
// Status proivdes low-level details about the volume
|
||||
func (FakeVolume) Status() map[string]interface{} { return nil }
|
||||
|
||||
// FakeDriver is a driver that generates fake volumes
|
||||
type FakeDriver struct {
|
||||
name string
|
||||
|
|
|
@ -41,6 +41,8 @@ type Volume interface {
|
|||
Mount() (string, error)
|
||||
// Unmount unmounts the volume when it is no longer in use.
|
||||
Unmount() error
|
||||
// Status returns low-level status information about a volume
|
||||
Status() map[string]interface{}
|
||||
}
|
||||
|
||||
// MountPoint is the intersection point between a volume and a container. It
|
||||
|
|
Loading…
Add table
Reference in a new issue