mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #13699 from calavera/volume_backwards
Allow to downgrade local volumes from > 1.7 to 1.6.
This commit is contained in:
commit
55bdb51659
7 changed files with 444 additions and 107 deletions
|
|
@ -6,29 +6,46 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/volume"
|
||||
)
|
||||
|
||||
func New(rootDirectory string) (*Root, error) {
|
||||
// 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
|
||||
// Docker versions.
|
||||
const (
|
||||
VolumeDataPathName = "_data"
|
||||
volumesPathName = "volumes"
|
||||
)
|
||||
|
||||
var oldVfsDir = filepath.Join("vfs", "dir")
|
||||
|
||||
func New(scope string) (*Root, error) {
|
||||
rootDirectory := filepath.Join(scope, volumesPathName)
|
||||
|
||||
if err := os.MkdirAll(rootDirectory, 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := &Root{
|
||||
scope: scope,
|
||||
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),
|
||||
path: r.DataPath(name),
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
|
|
@ -36,10 +53,15 @@ func New(rootDirectory string) (*Root, error) {
|
|||
|
||||
type Root struct {
|
||||
m sync.Mutex
|
||||
scope string
|
||||
path string
|
||||
volumes map[string]*Volume
|
||||
}
|
||||
|
||||
func (r *Root) DataPath(volumeName string) string {
|
||||
return filepath.Join(r.path, volumeName, VolumeDataPathName)
|
||||
}
|
||||
|
||||
func (r *Root) Name() string {
|
||||
return "local"
|
||||
}
|
||||
|
|
@ -47,12 +69,13 @@ func (r *Root) Name() string {
|
|||
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 {
|
||||
path := r.DataPath(name)
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
if os.IsExist(err) {
|
||||
return nil, fmt.Errorf("volume already exists under %s", path)
|
||||
return nil, fmt.Errorf("volume already exists under %s", filepath.Dir(path))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -76,12 +99,40 @@ func (r *Root) Remove(v volume.Volume) error {
|
|||
}
|
||||
lv.release()
|
||||
if lv.usedCount == 0 {
|
||||
realPath, err := filepath.EvalSymlinks(lv.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !r.scopedPath(realPath) {
|
||||
return fmt.Errorf("Unable to remove a directory of out the Docker root: %s", realPath)
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(realPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(r.volumes, lv.name)
|
||||
return os.RemoveAll(lv.path)
|
||||
return os.RemoveAll(filepath.Dir(lv.path))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// scopedPath verifies that the path where the volume is located
|
||||
// is under Docker's root and the valid local paths.
|
||||
func (r *Root) scopedPath(realPath string) bool {
|
||||
// Volumes path for Docker version >= 1.7
|
||||
if strings.HasPrefix(realPath, filepath.Join(r.scope, volumesPathName)) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Volumes path for Docker version < 1.7
|
||||
if strings.HasPrefix(realPath, filepath.Join(r.scope, oldVfsDir)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
m sync.Mutex
|
||||
usedCount int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue