1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Ignore stat errors on volume rm.

Underlying volume data may have been removed by some other tool.
Ignore and remove the reference in this case.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2015-09-08 22:01:02 -04:00
parent 5f5d73d515
commit 8d27417bfe
3 changed files with 104 additions and 8 deletions

View file

@ -152,7 +152,7 @@ func (daemon *Daemon) VolumeRm(name string) error {
if err == ErrVolumeInUse {
return fmt.Errorf("Conflict: %v", err)
}
return err
return fmt.Errorf("Error while removing volume %s: %v", name, err)
}
return nil
}

View file

@ -126,6 +126,7 @@ func (r *Root) Create(name string, _ map[string]string) (volume.Volume, error) {
func (r *Root) Remove(v volume.Volume) error {
r.m.Lock()
defer r.m.Unlock()
lv, ok := v.(*localVolume)
if !ok {
return errors.New("unknown volume type")
@ -133,18 +134,32 @@ func (r *Root) Remove(v volume.Volume) error {
realPath, err := filepath.EvalSymlinks(lv.path)
if err != nil {
if !os.IsNotExist(err) {
return err
}
if !r.scopedPath(realPath) {
return fmt.Errorf("Unable to remove a directory of out the Docker root: %s", realPath)
realPath = filepath.Dir(lv.path)
}
if err := os.RemoveAll(realPath); err != nil {
if !r.scopedPath(realPath) {
return fmt.Errorf("Unable to remove a directory of out the Docker root %s: %s", r.scope, realPath)
}
if err := removePath(realPath); err != nil {
return err
}
delete(r.volumes, lv.name)
return os.RemoveAll(filepath.Dir(lv.path))
return removePath(filepath.Dir(lv.path))
}
func removePath(path string) error {
if err := os.RemoveAll(path); err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
return nil
}
// Get looks up the volume for the given name and returns it if found
@ -162,7 +177,7 @@ func (r *Root) Get(name string) (volume.Volume, error) {
// 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)) {
if strings.HasPrefix(realPath, filepath.Join(r.scope, volumesPathName)) && realPath != filepath.Join(r.scope, volumesPathName) {
return true
}

View file

@ -0,0 +1,81 @@
package local
import (
"io/ioutil"
"os"
"testing"
)
func TestRemove(t *testing.T) {
rootDir, err := ioutil.TempDir("", "local-volume-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir)
if err != nil {
t.Fatal(err)
}
vol, err := r.Create("testing", nil)
if err != nil {
t.Fatal(err)
}
if err := r.Remove(vol); err != nil {
t.Fatal(err)
}
vol, err = r.Create("testing2", nil)
if err != nil {
t.Fatal(err)
}
if err := os.RemoveAll(vol.Path()); err != nil {
t.Fatal(err)
}
if err := r.Remove(vol); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(vol.Path()); err != nil && !os.IsNotExist(err) {
t.Fatal("volume dir not removed")
}
if len(r.List()) != 0 {
t.Fatal("expected there to be no volumes")
}
}
func TestInitializeWithVolumes(t *testing.T) {
rootDir, err := ioutil.TempDir("", "local-volume-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir)
if err != nil {
t.Fatal(err)
}
vol, err := r.Create("testing", nil)
if err != nil {
t.Fatal(err)
}
r, err = New(rootDir)
if err != nil {
t.Fatal(err)
}
v, err := r.Get(vol.Name())
if err != nil {
t.Fatal(err)
}
if v.Path() != vol.Path() {
t.Fatal("expected to re-initialize root with existing volumes")
}
}