Commit e42c999e by rfkelly0

SimulateXAttr: ensure xattrs are deleted when deleting a file/directory

parent 776c7082
...@@ -85,7 +85,45 @@ class XAttrTestCases: ...@@ -85,7 +85,45 @@ class XAttrTestCases:
self.assertEquals(self.fs.getxattr("stuff2/a.txt","myattr"),"myvalue") self.assertEquals(self.fs.getxattr("stuff2/a.txt","myattr"),"myvalue")
self.assertEquals(self.fs.getxattr("stuff2/a.txt","testattr"),"testvalue") self.assertEquals(self.fs.getxattr("stuff2/a.txt","testattr"),"testvalue")
self.assertEquals(self.fs.getxattr("stuff2","dirattr"),"a directory") self.assertEquals(self.fs.getxattr("stuff2","dirattr"),"a directory")
def test_remove_file(self):
# Check that xattrs aren't preserved after a file is removed
self.fs.createfile("myfile")
self.assertEquals(self.fs.listxattrs("myfile"),[])
self.fs.setxattr("myfile","testattr","testvalue")
self.assertEquals(self.fs.listxattrs("myfile"),["testattr"])
self.fs.remove("myfile")
self.assertRaises(ResourceNotFoundError,self.fs.listxattrs,"myfile")
self.fs.createfile("myfile")
self.assertEquals(self.fs.listxattrs("myfile"),[])
self.fs.setxattr("myfile","testattr2","testvalue2")
self.assertEquals(self.fs.listxattrs("myfile"),["testattr2"])
self.assertEquals(self.fs.getxattr("myfile","testattr2"),"testvalue2")
# Check that removing a file without xattrs still works
self.fs.createfile("myfile2")
self.fs.remove("myfile2")
def test_remove_dir(self):
# Check that xattrs aren't preserved after a dir is removed
self.fs.makedir("mydir")
self.assertEquals(self.fs.listxattrs("mydir"),[])
self.fs.setxattr("mydir","testattr","testvalue")
self.assertEquals(self.fs.listxattrs("mydir"),["testattr"])
self.fs.removedir("mydir")
self.assertRaises(ResourceNotFoundError,self.fs.listxattrs,"mydir")
self.fs.makedir("mydir")
self.assertEquals(self.fs.listxattrs("mydir"),[])
self.fs.setxattr("mydir","testattr2","testvalue2")
self.assertEquals(self.fs.listxattrs("mydir"),["testattr2"])
self.assertEquals(self.fs.getxattr("mydir","testattr2"),"testvalue2")
# Check that removing a dir without xattrs still works
self.fs.makedir("mydir2")
self.fs.removedir("mydir2")
# Check that forcibly removing a dir with xattrs still works
self.fs.makedir("mydir3")
self.fs.createfile("mydir3/testfile")
self.fs.removedir("mydir3",force=True)
self.assertFalse(self.fs.exists("mydir3"))
from fs.xattrs import ensure_xattrs from fs.xattrs import ensure_xattrs
......
...@@ -23,6 +23,7 @@ function 'ensure_xattrs'. This will interrogate an FS object to determine ...@@ -23,6 +23,7 @@ function 'ensure_xattrs'. This will interrogate an FS object to determine
if it has native xattr support, and return a wrapped version if it does not. if it has native xattr support, and return a wrapped version if it does not.
""" """
import sys
try: try:
import cPickle as pickle import cPickle as pickle
except ImportError: except ImportError:
...@@ -64,9 +65,11 @@ class SimulateXAttr(WrapFS): ...@@ -64,9 +65,11 @@ class SimulateXAttr(WrapFS):
directory itself. directory itself.
""" """
def _get_attr_path(self, path): def _get_attr_path(self, path, isdir=None):
"""Get the path of the file containing xattrs for the given path.""" """Get the path of the file containing xattrs for the given path."""
if self.wrapped_fs.isdir(path): if isdir is None:
isdir = self.wrapped_fs.isdir(path)
if isdir:
attr_path = pathjoin(path, '.xattrs') attr_path = pathjoin(path, '.xattrs')
else: else:
dir_path, file_name = pathsplit(path) dir_path, file_name = pathsplit(path)
...@@ -144,6 +147,33 @@ class SimulateXAttr(WrapFS): ...@@ -144,6 +147,33 @@ class SimulateXAttr(WrapFS):
entries = self.wrapped_fs.listdir(path,**kwds) entries = self.wrapped_fs.listdir(path,**kwds)
return [e for e in entries if not self._is_attr_path(e)] return [e for e in entries if not self._is_attr_path(e)]
def remove(self,path):
"""Remove .xattr when removing a file."""
attr_file = self._get_attr_path(path,isdir=False)
self.wrapped_fs.remove(path)
try:
self.wrapped_fs.remove(attr_file)
except ResourceNotFoundError:
pass
def removedir(self,path,recursive=False,force=False):
"""Remove .xattr when removing a directory."""
try:
self.wrapped_fs.removedir(path,recursive=recursive,force=force)
except DirectoryNotEmptyError:
# The xattr file could block the underlying removedir().
# Remove it, but be prepared to restore it on error.
if self.listdir(path) != []:
raise
attr_file = self._get_attr_path(path,isdir=True)
attr_file_contents = self.wrapped_fs.getcontents(attr_file)
self.wrapped_fs.remove(attr_file)
try:
self.wrapped_fs.removedir(path,recursive=recursive)
except FSError:
self.wrapped_fs.createfile(attr_file,attr_file_contents)
raise
def copy(self,src,dst,**kwds): def copy(self,src,dst,**kwds):
"""Ensure xattrs are copied when copying a file.""" """Ensure xattrs are copied when copying a file."""
self.wrapped_fs.copy(self._encode(src),self._encode(dst),**kwds) self.wrapped_fs.copy(self._encode(src),self._encode(dst),**kwds)
...@@ -163,4 +193,5 @@ class SimulateXAttr(WrapFS): ...@@ -163,4 +193,5 @@ class SimulateXAttr(WrapFS):
self.wrapped_fs.move(s_attr_file,d_attr_file,overwrite=True) self.wrapped_fs.move(s_attr_file,d_attr_file,overwrite=True)
except ResourceNotFoundError: except ResourceNotFoundError:
pass pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment