mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
commit
9cfc223cc0
5 changed files with 57 additions and 17 deletions
|
@ -64,6 +64,9 @@ packages=(
|
||||||
registry
|
registry
|
||||||
runconfig
|
runconfig
|
||||||
utils
|
utils
|
||||||
|
volume
|
||||||
|
volume/local
|
||||||
|
volume/drivers
|
||||||
)
|
)
|
||||||
|
|
||||||
errors=()
|
errors=()
|
||||||
|
|
|
@ -4,11 +4,13 @@ package volumedrivers
|
||||||
|
|
||||||
import "github.com/docker/docker/volume"
|
import "github.com/docker/docker/volume"
|
||||||
|
|
||||||
|
// NewVolumeDriver returns a driver has the given name mapped on the given client.
|
||||||
func NewVolumeDriver(name string, c client) volume.Driver {
|
func NewVolumeDriver(name string, c client) volume.Driver {
|
||||||
proxy := &volumeDriverProxy{c}
|
proxy := &volumeDriverProxy{c}
|
||||||
return &volumeDriverAdapter{name, proxy}
|
return &volumeDriverAdapter{name, proxy}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VolumeDriver defines the available functions that volume plugins must implement.
|
||||||
type VolumeDriver interface {
|
type VolumeDriver interface {
|
||||||
// Create a volume with the given name
|
// Create a volume with the given name
|
||||||
Create(name string) (err error)
|
Create(name string) (err error)
|
||||||
|
|
|
@ -18,6 +18,8 @@ type driverExtpoint struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register associates the given driver to the given name, checking if
|
||||||
|
// the name is already associated
|
||||||
func Register(extension volume.Driver, name string) bool {
|
func Register(extension volume.Driver, name string) bool {
|
||||||
drivers.Lock()
|
drivers.Lock()
|
||||||
defer drivers.Unlock()
|
defer drivers.Unlock()
|
||||||
|
@ -32,6 +34,7 @@ func Register(extension volume.Driver, name string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unregister dissociates the name from it's driver, if the association exists.
|
||||||
func Unregister(name string) bool {
|
func Unregister(name string) bool {
|
||||||
drivers.Lock()
|
drivers.Lock()
|
||||||
defer drivers.Unlock()
|
defer drivers.Unlock()
|
||||||
|
@ -43,6 +46,9 @@ func Unregister(name string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lookup returns the driver associated with the given name. If a
|
||||||
|
// driver with the given name has not been registered it checks if
|
||||||
|
// there is a VolumeDriver plugin available with the given name.
|
||||||
func Lookup(name string) (volume.Driver, error) {
|
func Lookup(name string) (volume.Driver, error) {
|
||||||
drivers.Lock()
|
drivers.Lock()
|
||||||
defer drivers.Unlock()
|
defer drivers.Unlock()
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// Package local provides the default implementation for volumes. It
|
||||||
|
// is used to mount data volume containers and directories local to
|
||||||
|
// the host server.
|
||||||
package local
|
package local
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -13,7 +16,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// VolumeDataPathName is the name of the directory where the volume data is stored.
|
// VolumeDataPathName is the name of the directory where the volume data is stored.
|
||||||
// It uses a very distintive name to avoid colissions migrating data between
|
// It uses a very distintive name to avoid collisions migrating data between
|
||||||
// Docker versions.
|
// Docker versions.
|
||||||
const (
|
const (
|
||||||
VolumeDataPathName = "_data"
|
VolumeDataPathName = "_data"
|
||||||
|
@ -22,6 +25,9 @@ const (
|
||||||
|
|
||||||
var oldVfsDir = filepath.Join("vfs", "dir")
|
var oldVfsDir = filepath.Join("vfs", "dir")
|
||||||
|
|
||||||
|
// New instantiates a new Root instance with the provided scope. Scope
|
||||||
|
// is the base path that the Root instance uses to store its
|
||||||
|
// volumes. The base path is created here if it does not exist.
|
||||||
func New(scope string) (*Root, error) {
|
func New(scope string) (*Root, error) {
|
||||||
rootDirectory := filepath.Join(scope, volumesPathName)
|
rootDirectory := filepath.Join(scope, volumesPathName)
|
||||||
|
|
||||||
|
@ -32,7 +38,7 @@ func New(scope string) (*Root, error) {
|
||||||
r := &Root{
|
r := &Root{
|
||||||
scope: scope,
|
scope: scope,
|
||||||
path: rootDirectory,
|
path: rootDirectory,
|
||||||
volumes: make(map[string]*Volume),
|
volumes: make(map[string]*localVolume),
|
||||||
}
|
}
|
||||||
|
|
||||||
dirs, err := ioutil.ReadDir(rootDirectory)
|
dirs, err := ioutil.ReadDir(rootDirectory)
|
||||||
|
@ -42,7 +48,7 @@ func New(scope string) (*Root, error) {
|
||||||
|
|
||||||
for _, d := range dirs {
|
for _, d := range dirs {
|
||||||
name := filepath.Base(d.Name())
|
name := filepath.Base(d.Name())
|
||||||
r.volumes[name] = &Volume{
|
r.volumes[name] = &localVolume{
|
||||||
driverName: r.Name(),
|
driverName: r.Name(),
|
||||||
name: name,
|
name: name,
|
||||||
path: r.DataPath(name),
|
path: r.DataPath(name),
|
||||||
|
@ -51,21 +57,29 @@ func New(scope string) (*Root, error) {
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Root implements the Driver interface for the volume package and
|
||||||
|
// manages the creation/removal of volumes. It uses only standard vfs
|
||||||
|
// commands to create/remove dirs within its provided scope.
|
||||||
type Root struct {
|
type Root struct {
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
scope string
|
scope string
|
||||||
path string
|
path string
|
||||||
volumes map[string]*Volume
|
volumes map[string]*localVolume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataPath returns the constructed path of this volume.
|
||||||
func (r *Root) DataPath(volumeName string) string {
|
func (r *Root) DataPath(volumeName string) string {
|
||||||
return filepath.Join(r.path, volumeName, VolumeDataPathName)
|
return filepath.Join(r.path, volumeName, VolumeDataPathName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the name of Root, defined in the volume package in the DefaultDriverName constant.
|
||||||
func (r *Root) Name() string {
|
func (r *Root) Name() string {
|
||||||
return "local"
|
return volume.DefaultDriverName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create creates a new volume.Volume with the provided name, creating
|
||||||
|
// the underlying directory tree required for this volume in the
|
||||||
|
// process.
|
||||||
func (r *Root) Create(name string) (volume.Volume, error) {
|
func (r *Root) Create(name string) (volume.Volume, error) {
|
||||||
r.m.Lock()
|
r.m.Lock()
|
||||||
defer r.m.Unlock()
|
defer r.m.Unlock()
|
||||||
|
@ -79,7 +93,7 @@ func (r *Root) Create(name string) (volume.Volume, error) {
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
v = &Volume{
|
v = &localVolume{
|
||||||
driverName: r.Name(),
|
driverName: r.Name(),
|
||||||
name: name,
|
name: name,
|
||||||
path: path,
|
path: path,
|
||||||
|
@ -90,10 +104,14 @@ func (r *Root) Create(name string) (volume.Volume, error) {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove removes the specified volume and all underlying data. If the
|
||||||
|
// given volume does not belong to this driver and an error is
|
||||||
|
// returned. The volume is reference counted, if all references are
|
||||||
|
// not released then the volume is not removed.
|
||||||
func (r *Root) Remove(v volume.Volume) error {
|
func (r *Root) Remove(v volume.Volume) error {
|
||||||
r.m.Lock()
|
r.m.Lock()
|
||||||
defer r.m.Unlock()
|
defer r.m.Unlock()
|
||||||
lv, ok := v.(*Volume)
|
lv, ok := v.(*localVolume)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("unknown volume type")
|
return errors.New("unknown volume type")
|
||||||
}
|
}
|
||||||
|
@ -133,7 +151,9 @@ func (r *Root) scopedPath(realPath string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type Volume struct {
|
// localVolume implements the Volume interface from the volume package and
|
||||||
|
// represents the volumes created by Root.
|
||||||
|
type localVolume struct {
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
usedCount int
|
usedCount int
|
||||||
// unique name of the volume
|
// unique name of the volume
|
||||||
|
@ -144,33 +164,38 @@ type Volume struct {
|
||||||
driverName string
|
driverName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) Name() string {
|
// Name returns the name of the given Volume.
|
||||||
|
func (v *localVolume) Name() string {
|
||||||
return v.name
|
return v.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) DriverName() string {
|
// DriverName returns the driver that created the given Volume.
|
||||||
|
func (v *localVolume) DriverName() string {
|
||||||
return v.driverName
|
return v.driverName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) Path() string {
|
// Path returns the data location.
|
||||||
|
func (v *localVolume) Path() string {
|
||||||
return v.path
|
return v.path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) Mount() (string, error) {
|
// Mount implements the localVolume interface, returning the data location.
|
||||||
|
func (v *localVolume) Mount() (string, error) {
|
||||||
return v.path, nil
|
return v.path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) Unmount() error {
|
// Umount is for satisfying the localVolume interface and does not do anything in this driver.
|
||||||
|
func (v *localVolume) Unmount() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) use() {
|
func (v *localVolume) use() {
|
||||||
v.m.Lock()
|
v.m.Lock()
|
||||||
v.usedCount++
|
v.usedCount++
|
||||||
v.m.Unlock()
|
v.m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volume) release() {
|
func (v *localVolume) release() {
|
||||||
v.m.Lock()
|
v.m.Lock()
|
||||||
v.usedCount--
|
v.usedCount--
|
||||||
v.m.Unlock()
|
v.m.Unlock()
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package volume
|
package volume
|
||||||
|
|
||||||
const DefaultDriverName = "local"
|
// DefaultDriverName is the driver name used for the driver
|
||||||
|
// implemented in the local package.
|
||||||
|
const DefaultDriverName string = "local"
|
||||||
|
|
||||||
|
// Driver is for creating and removing volumes.
|
||||||
type Driver interface {
|
type Driver interface {
|
||||||
// Name returns the name of the volume driver.
|
// Name returns the name of the volume driver.
|
||||||
Name() string
|
Name() string
|
||||||
|
@ -11,6 +14,7 @@ type Driver interface {
|
||||||
Remove(Volume) error
|
Remove(Volume) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Volume is a place to store data. It is backed by a specific driver, and can be mounted.
|
||||||
type Volume interface {
|
type Volume interface {
|
||||||
// Name returns the name of the volume
|
// Name returns the name of the volume
|
||||||
Name() string
|
Name() string
|
||||||
|
@ -51,7 +55,7 @@ func ValidateMountMode(mode string) (bool, bool) {
|
||||||
return roModes[mode] || rwModes[mode], rwModes[mode]
|
return roModes[mode] || rwModes[mode], rwModes[mode]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadOnly tells you if a mode string is a valid read-only mode or not.
|
// ReadWrite tells you if a mode string is a valid read-only mode or not.
|
||||||
func ReadWrite(mode string) bool {
|
func ReadWrite(mode string) bool {
|
||||||
return rwModes[mode]
|
return rwModes[mode]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue