mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Promote volume drivers from experimental to master.
Remove volume stubs and use the experimental path as the only path. Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
parent
fc2f90fc63
commit
c4d45b6a29
13 changed files with 107 additions and 193 deletions
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/docker/volume/drivers"
|
||||
"github.com/docker/docker/volume/local"
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
)
|
||||
|
@ -333,3 +334,18 @@ func removeVolume(v volume.Volume) error {
|
|||
}
|
||||
return vd.Remove(v)
|
||||
}
|
||||
|
||||
func getVolumeDriver(name string) (volume.Driver, error) {
|
||||
if name == "" {
|
||||
name = volume.DefaultDriverName
|
||||
}
|
||||
return volumedrivers.Lookup(name)
|
||||
}
|
||||
|
||||
func parseVolumeSource(spec string) (string, string, error) {
|
||||
if !filepath.IsAbs(spec) {
|
||||
return spec, "", nil
|
||||
}
|
||||
|
||||
return "", spec, nil
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// +build experimental
|
||||
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/docker/volume/drivers"
|
||||
)
|
||||
|
||||
func getVolumeDriver(name string) (volume.Driver, error) {
|
||||
if name == "" {
|
||||
name = volume.DefaultDriverName
|
||||
}
|
||||
return volumedrivers.Lookup(name)
|
||||
}
|
||||
|
||||
func parseVolumeSource(spec string) (string, string, error) {
|
||||
if !filepath.IsAbs(spec) {
|
||||
return spec, "", nil
|
||||
}
|
||||
|
||||
return "", spec, nil
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// +build !experimental
|
||||
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/docker/volume/drivers"
|
||||
)
|
||||
|
||||
func getVolumeDriver(_ string) (volume.Driver, error) {
|
||||
return volumedrivers.Lookup(volume.DefaultDriverName)
|
||||
}
|
||||
|
||||
func parseVolumeSource(spec string) (string, string, error) {
|
||||
if !filepath.IsAbs(spec) {
|
||||
return "", "", fmt.Errorf("cannot bind mount volume: %s volume paths must be absolute.", spec)
|
||||
}
|
||||
|
||||
return "", spec, nil
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
// +build !experimental
|
||||
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/docker/volume/drivers"
|
||||
"github.com/docker/docker/volume/local"
|
||||
)
|
||||
|
||||
func TestGetVolumeDefaultDriver(t *testing.T) {
|
||||
tmp, err := ioutil.TempDir("", "volume-test-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
l, err := local.New(tmp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
volumedrivers.Register(l, volume.DefaultDriverName)
|
||||
d, err := getVolumeDriver("missing")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if d.Name() != volume.DefaultDriverName {
|
||||
t.Fatalf("Expected local driver, was %s\n", d.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseBindMount(t *testing.T) {
|
||||
cases := []struct {
|
||||
bind string
|
||||
expDest string
|
||||
expSource string
|
||||
expName string
|
||||
mountLabel string
|
||||
expRW bool
|
||||
fail bool
|
||||
}{
|
||||
{"/tmp:/tmp", "/tmp", "/tmp", "", "", true, false},
|
||||
{"/tmp:/tmp:ro", "/tmp", "/tmp", "", "", false, false},
|
||||
{"/tmp:/tmp:rw", "/tmp", "/tmp", "", "", true, false},
|
||||
{"/tmp:/tmp:foo", "/tmp", "/tmp", "", "", false, true},
|
||||
{"name:/tmp", "", "", "", "", false, true},
|
||||
{"local/name:/tmp:rw", "", "", "", "", true, true},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
conf := &runconfig.Config{}
|
||||
m, err := parseBindMount(c.bind, c.mountLabel, conf)
|
||||
if c.fail {
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error, was nil, for spec %s\n", c.bind)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Destination != c.expDest {
|
||||
t.Fatalf("Expected destination %s, was %s, for spec %s\n", c.expDest, m.Destination, c.bind)
|
||||
}
|
||||
|
||||
if m.Source != c.expSource {
|
||||
t.Fatalf("Expected source %s, was %s, for spec %s\n", c.expSource, m.Source, c.bind)
|
||||
}
|
||||
|
||||
if m.Name != c.expName {
|
||||
t.Fatalf("Expected name %s, was %s for spec %s\n", c.expName, m.Name, c.bind)
|
||||
}
|
||||
|
||||
if m.RW != c.expRW {
|
||||
t.Fatalf("Expected RW %v, was %v for spec %s\n", c.expRW, m.RW, c.bind)
|
||||
}
|
||||
}
|
||||
}
|
22
docs/extend/index.md
Normal file
22
docs/extend/index.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!--[metadata]>
|
||||
+++
|
||||
title = "Extend Docker"
|
||||
description = "How to extend Docker with plugins"
|
||||
keywords = ["extend, plugins, docker, documentation, developer"]
|
||||
[menu.main]
|
||||
identifier = "mn_extend"
|
||||
name = "Extend Docker"
|
||||
weight = 6
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
|
||||
## Extending Docker
|
||||
|
||||
Currently, you can extend Docker by adding a plugin. This section contains the following topics:
|
||||
|
||||
* [Understand Docker plugins](plugins.md)
|
||||
* [Write a volume plugin](plugins_volumes.md)
|
||||
* [Docker plugin API](plugin_api.md)
|
||||
|
||||
|
|
@ -1,13 +1,22 @@
|
|||
# Experimental: Docker Plugin API
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Plugins API"
|
||||
description = "How to write Docker plugins extensions "
|
||||
keywords = ["API, Usage, plugins, documentation, developer"]
|
||||
[menu.main]
|
||||
parent = "mn_extend"
|
||||
weight=1
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Docker Plugin API
|
||||
|
||||
Docker plugins are out-of-process extensions which add capabilities to the
|
||||
Docker Engine.
|
||||
|
||||
This page is intended for people who want to develop their own Docker plugin.
|
||||
If you just want to learn about or use Docker plugins, look
|
||||
[here](/experimental/plugins.md).
|
||||
|
||||
This is an experimental feature. For information on installing and using experimental features, see [the experimental feature overview](README.md).
|
||||
[here](plugins.md).
|
||||
|
||||
## What plugins are
|
||||
|
||||
|
@ -77,10 +86,6 @@ manage startup and shutdown order.
|
|||
When upgrading a plugin, you should first stop the Docker daemon, upgrade the
|
||||
plugin, then start Docker again.
|
||||
|
||||
If a plugin is packaged as a container, this may cause issues. Plugins as
|
||||
containers are currently considered experimental due to these shutdown/startup
|
||||
ordering issues. These issues are mitigated by plugin retries (see below).
|
||||
|
||||
## Plugin activation
|
||||
|
||||
When a plugin is first referred to -- either by a user referring to it by name
|
|
@ -1,14 +1,23 @@
|
|||
# Experimental: Extend Docker with a plugin
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Extending Docker with plugins"
|
||||
description = "How to add additional functionality to Docker with plugins extensions"
|
||||
keywords = ["Examples, Usage, plugins, docker, documentation, user guide"]
|
||||
[menu.main]
|
||||
parent = "mn_extend"
|
||||
weight=-1
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Understand Docker plugins
|
||||
|
||||
You can extend the capabilities of the Docker Engine by loading third-party
|
||||
plugins.
|
||||
|
||||
This is an experimental feature. For information on installing and using experimental features, see [the experimental feature overview](README.md).
|
||||
plugins.
|
||||
|
||||
## Types of plugins
|
||||
|
||||
Plugins extend Docker's functionality. They come in specific types. For
|
||||
example, a [volume plugin](/experimental/plugins_volume.md) might enable Docker
|
||||
example, a [volume plugin](plugins_volume.md) might enable Docker
|
||||
volumes to persist across multiple Docker hosts.
|
||||
|
||||
Currently Docker supports volume and network driver plugins. In the future it
|
||||
|
@ -27,12 +36,13 @@ The following plugins exist:
|
|||
databases and other stateful containers and move them around across a cluster
|
||||
of machines.
|
||||
|
||||
* The [Weave plugin](https://github.com/weaveworks/docker-plugin) is a network
|
||||
driver plugin which provides a virtual, multi-host network for containers.
|
||||
* The [GlusterFS plugin](https://github.com/calavera/docker-volume-glusterfs) is
|
||||
another volume plugin that provides multi-host volumes management for Docker
|
||||
using GlusterFS.
|
||||
|
||||
* The [Calico plugin](https://github.com/metaswitch/calico-docker) is a network
|
||||
driver plugin which provides a multi-host network for containers with routes
|
||||
distributed by BGP.
|
||||
* The [Keywhiz plugin](https://github.com/calavera/docker-volume-keywhiz) is
|
||||
a plugin that provides credentials and secret management using Keywhiz as
|
||||
a central repository.
|
||||
|
||||
## Troubleshooting a plugin
|
||||
|
||||
|
@ -42,11 +52,4 @@ of the plugin for help. The Docker team may not be able to assist you.
|
|||
## Writing a plugin
|
||||
|
||||
If you are interested in writing a plugin for Docker, or seeing how they work
|
||||
under the hood, see the [docker plugins reference](/experimental/plugin_api.md).
|
||||
|
||||
# Related GitHub PRs and issues
|
||||
|
||||
- [#13222](https://github.com/docker/docker/pull/13222) Plugins plumbing
|
||||
|
||||
Send us feedback and comments on [#13419](https://github.com/docker/docker/issues/13419),
|
||||
or on the usual Google Groups (docker-user, docker-dev) and IRC channels.
|
||||
under the hood, see the [docker plugins reference](plugin_api.md).
|
|
@ -1,34 +1,38 @@
|
|||
# Experimental: Docker volume plugins
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Volume plugins"
|
||||
description = "How to manage data with external volume plugins"
|
||||
keywords = ["Examples, Usage, volume, docker, data, volumes, plugin, api"]
|
||||
[menu.main]
|
||||
parent = "mn_extend"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Write a volume plugin
|
||||
|
||||
Docker volume plugins enable Docker deployments to be integrated with external
|
||||
storage systems, such as Amazon EBS, and enable data volumes to persist beyond
|
||||
the lifetime of a single Docker host. See the [plugin documentation](/experimental/plugins.md)
|
||||
the lifetime of a single Docker host. See the [plugin documentation](plugins.md)
|
||||
for more information.
|
||||
|
||||
This is an experimental feature. For information on installing and using experimental features, see [the experimental feature overview](README.md).
|
||||
|
||||
# Command-line changes
|
||||
|
||||
This experimental feature introduces two changes to the `docker run` command:
|
||||
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:
|
||||
|
||||
- The `--volume-driver` flag is introduced.
|
||||
- The `-v` syntax is changed to accept a volume name a first component.
|
||||
$ docker run -ti -v volumename:/data --volume-driver=flocker busybox sh
|
||||
|
||||
Example:
|
||||
This command passes the `volumename` through to the volume plugin as a
|
||||
user-given name for the volume. The `volumename` must not begin with a `/`.
|
||||
|
||||
$ docker run -ti -v volumename:/data --volume-driver=flocker busybox sh
|
||||
By having the user specify a `volumename`, a plugin can associate the volume
|
||||
with an external volume beyond the lifetime of a single container or container
|
||||
host. This can be used, for example, to move a stateful container from one
|
||||
server to another.
|
||||
|
||||
By specifying a volume name in conjunction with a volume driver, volume plugins
|
||||
such as [Flocker](https://clusterhq.com/docker-plugin/), once installed, can be
|
||||
used to manage volumes external to a single host, such as those on EBS. In this
|
||||
example, "volumename" is passed through to the volume plugin as a user-given
|
||||
name for the volume which allows the plugin to associate it with an external
|
||||
volume beyond the lifetime of a single container or container host. This can be
|
||||
used, for example, to move a stateful container from one server to another.
|
||||
By specifying a `volumedriver` in conjunction with a `volumename`, users can use plugins such as [Flocker](https://clusterhq.com/docker-plugin/) to manage volumes external to a single host, such as those on EBS.
|
||||
|
||||
The `volumename` must not begin with a `/`.
|
||||
|
||||
# API changes
|
||||
# Create a VolumeDriver
|
||||
|
||||
The container creation endpoint (`/containers/create`) accepts a `VolumeDriver`
|
||||
field of type `string` allowing to specify the name of the driver. It's default
|
||||
|
@ -152,9 +156,3 @@ this point.
|
|||
|
||||
Respond with a string error if an error occurred.
|
||||
|
||||
# Related GitHub PRs and issues
|
||||
|
||||
- [#13161](https://github.com/docker/docker/pull/13161) Volume refactor and external volume plugins
|
||||
|
||||
Send us feedback and comments on [#13420](https://github.com/docker/docker/issues/13420),
|
||||
or on the usual Google Groups (docker-user, docker-dev) and IRC channels.
|
|
@ -18,7 +18,7 @@ commands. For example,
|
|||
|
||||
docker network create -d weave mynet
|
||||
|
||||
Some network driver plugins are listed in [plugins.md](plugins.md)
|
||||
Some network driver plugins are listed in [plugins.md](/docs/extend/plugins.md)
|
||||
|
||||
The network thus created is owned by the plugin, so subsequent commands
|
||||
referring to that network will also be run through the plugin.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// +build experimental
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
|
|
@ -26,15 +26,16 @@ var (
|
|||
|
||||
// validateNM is the set of fields passed to validateNetMode()
|
||||
type validateNM struct {
|
||||
netMode NetworkMode
|
||||
flHostname *string
|
||||
flLinks opts.ListOpts
|
||||
flDns opts.ListOpts
|
||||
flExtraHosts opts.ListOpts
|
||||
flMacAddress *string
|
||||
flPublish opts.ListOpts
|
||||
flPublishAll *bool
|
||||
flExpose opts.ListOpts
|
||||
netMode NetworkMode
|
||||
flHostname *string
|
||||
flLinks opts.ListOpts
|
||||
flDns opts.ListOpts
|
||||
flExtraHosts opts.ListOpts
|
||||
flMacAddress *string
|
||||
flPublish opts.ListOpts
|
||||
flPublishAll *bool
|
||||
flExpose opts.ListOpts
|
||||
flVolumeDriver string
|
||||
}
|
||||
|
||||
func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
|
||||
|
@ -94,6 +95,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
|||
flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only")
|
||||
flLoggingDriver = cmd.String([]string{"-log-driver"}, "", "Logging driver for container")
|
||||
flCgroupParent = cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
|
||||
flVolumeDriver = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container")
|
||||
)
|
||||
|
||||
cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR")
|
||||
|
@ -332,6 +334,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
|||
Entrypoint: entrypoint,
|
||||
WorkingDir: *flWorkingDir,
|
||||
Labels: convertKVStringsToMap(labels),
|
||||
VolumeDriver: *flVolumeDriver,
|
||||
}
|
||||
|
||||
hostConfig := &HostConfig{
|
||||
|
|
|
@ -10,12 +10,10 @@ type experimentalFlags struct {
|
|||
|
||||
func attachExperimentalFlags(cmd *flag.FlagSet) *experimentalFlags {
|
||||
flags := make(map[string]interface{})
|
||||
flags["volume-driver"] = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container")
|
||||
flags["publish-service"] = cmd.String([]string{"-publish-service"}, "", "Publish this container as a service")
|
||||
return &experimentalFlags{flags: flags}
|
||||
}
|
||||
|
||||
func applyExperimentalFlags(exp *experimentalFlags, config *Config, hostConfig *HostConfig) {
|
||||
config.VolumeDriver = *(exp.flags["volume-driver"]).(*string)
|
||||
config.PublishService = *(exp.flags["publish-service"]).(*string)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue