Merge pull request #16162 from cpuguy83/16071_fix_lstat_errors
Ignore stat errors on volume rm.
This commit is contained in:
commit
d333849459
3 changed files with 104 additions and 8 deletions
|
@ -155,7 +155,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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
return err
|
||||
}
|
||||
if !r.scopedPath(realPath) {
|
||||
return fmt.Errorf("Unable to remove a directory of out the Docker root: %s", realPath)
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
|
81
volume/local/local_test.go
Normal file
81
volume/local/local_test.go
Normal 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")
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue