mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
81fa9feb0c
Signed by all authors: Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com> Signed-off-by: David Calavera <david.calavera@gmail.com> Signed-off-by: Jeff Lindsay <progrium@gmail.com> Signed-off-by: Alexander Morozov <lk4d4@docker.com> Signed-off-by: Luke Marsden <luke@clusterhq.com> Signed-off-by: David Calavera <david.calavera@gmail.com>
126 lines
2.1 KiB
Go
126 lines
2.1 KiB
Go
package local
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"github.com/docker/docker/volume"
|
|
)
|
|
|
|
func New(rootDirectory string) (*Root, error) {
|
|
if err := os.MkdirAll(rootDirectory, 0700); err != nil {
|
|
return nil, err
|
|
}
|
|
r := &Root{
|
|
path: rootDirectory,
|
|
volumes: make(map[string]*Volume),
|
|
}
|
|
dirs, err := ioutil.ReadDir(rootDirectory)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, d := range dirs {
|
|
name := filepath.Base(d.Name())
|
|
r.volumes[name] = &Volume{
|
|
driverName: r.Name(),
|
|
name: name,
|
|
path: filepath.Join(rootDirectory, name),
|
|
}
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
type Root struct {
|
|
m sync.Mutex
|
|
path string
|
|
volumes map[string]*Volume
|
|
}
|
|
|
|
func (r *Root) Name() string {
|
|
return "local"
|
|
}
|
|
|
|
func (r *Root) Create(name string) (volume.Volume, error) {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
v, exists := r.volumes[name]
|
|
if !exists {
|
|
path := filepath.Join(r.path, name)
|
|
if err := os.Mkdir(path, 0755); err != nil {
|
|
if os.IsExist(err) {
|
|
return nil, fmt.Errorf("volume already exists under %s", path)
|
|
}
|
|
return nil, err
|
|
}
|
|
v = &Volume{
|
|
driverName: r.Name(),
|
|
name: name,
|
|
path: path,
|
|
}
|
|
r.volumes[name] = v
|
|
}
|
|
v.use()
|
|
return v, nil
|
|
}
|
|
|
|
func (r *Root) Remove(v volume.Volume) error {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
lv, ok := v.(*Volume)
|
|
if !ok {
|
|
return errors.New("unknown volume type")
|
|
}
|
|
lv.release()
|
|
if lv.usedCount == 0 {
|
|
delete(r.volumes, lv.name)
|
|
return os.RemoveAll(lv.path)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type Volume struct {
|
|
m sync.Mutex
|
|
usedCount int
|
|
// unique name of the volume
|
|
name string
|
|
// path is the path on the host where the data lives
|
|
path string
|
|
// driverName is the name of the driver that created the volume.
|
|
driverName string
|
|
}
|
|
|
|
func (v *Volume) Name() string {
|
|
return v.name
|
|
}
|
|
|
|
func (v *Volume) DriverName() string {
|
|
return v.driverName
|
|
}
|
|
|
|
func (v *Volume) Path() string {
|
|
return v.path
|
|
}
|
|
|
|
func (v *Volume) Mount() (string, error) {
|
|
return v.path, nil
|
|
}
|
|
|
|
func (v *Volume) Unmount() error {
|
|
return nil
|
|
}
|
|
|
|
func (v *Volume) use() {
|
|
v.m.Lock()
|
|
v.usedCount++
|
|
v.m.Unlock()
|
|
}
|
|
|
|
func (v *Volume) release() {
|
|
v.m.Lock()
|
|
v.usedCount--
|
|
v.m.Unlock()
|
|
}
|