Przeglądaj źródła

extract: warning RC for unextracted big extended attributes, followup (#2258)

* Set warning exit code when xattr is too big

* Warnings for more extended attributes errors (ENOTSUP, EACCES)

* Add tests for all xattr warnings
Abdel-Rahman 8 lat temu
rodzic
commit
63b5cbfc99
2 zmienionych plików z 34 dodań i 11 usunięć
  1. 12 6
      src/borg/archive.py
  2. 22 5
      src/borg/testsuite/archiver.py

+ 12 - 6
src/borg/archive.py

@@ -26,7 +26,7 @@ from .constants import *  # NOQA
 from .hashindex import ChunkIndex, ChunkIndexEntry
 from .helpers import Manifest
 from .helpers import Chunk, ChunkIteratorFileWrapper, open_item
-from .helpers import Error, IntegrityError
+from .helpers import Error, IntegrityError, set_ec
 from .helpers import uid2user, user2uid, gid2group, group2gid
 from .helpers import parse_timestamp, to_localtime
 from .helpers import format_time, format_timedelta, format_file_size, file_status, FileSize
@@ -689,13 +689,19 @@ Utilization of max. archive size: {csize_max:.0%}
                 xattr.setxattr(fd or path, k, v, follow_symlinks=False)
             except OSError as e:
                 if e.errno == errno.E2BIG:
+                    # xattr is too big
                     logger.warning('%s: Value or key of extended attribute %s is too big for this filesystem' %
                                    (path, k.decode()))
-                elif e.errno not in (errno.ENOTSUP, errno.EACCES):
-                    # only raise if the errno is not on our ignore list:
-                    # ENOTSUP == xattrs not supported here
-                    # EACCES == permission denied to set this specific xattr
-                    #           (this may happen related to security.* keys)
+                    set_ec(EXIT_WARNING)
+                elif e.errno == errno.ENOTSUP:
+                    # xattrs not supported here
+                    logger.warning('%s: Extended attributes are not supported on this filesystem' % path)
+                    set_ec(EXIT_WARNING)
+                elif e.errno == errno.EACCES:
+                    # permission denied to set this specific xattr (this may happen related to security.* keys)
+                    logger.warning('%s: Permission denied when setting extended attribute %s' % (path, k.decode()))
+                    set_ec(EXIT_WARNING)
+                else:
                     raise
 
     def set_meta(self, key, value):

+ 22 - 5
src/borg/testsuite/archiver.py

@@ -1049,18 +1049,35 @@ class ArchiverTestCase(ArchiverTestCaseBase):
 
     @pytest.mark.skipif(not xattr.XATTR_FAKEROOT, reason='xattr not supported on this system or on this version of'
                                                          'fakeroot')
-    def test_extract_big_xattrs(self):
-        def patched_setxattr(*args, **kwargs):
+    def test_extract_xattrs_errors(self):
+        def patched_setxattr_E2BIG(*args, **kwargs):
             raise OSError(errno.E2BIG, 'E2BIG')
+
+        def patched_setxattr_ENOTSUP(*args, **kwargs):
+            raise OSError(errno.ENOTSUP, 'ENOTSUP')
+
+        def patched_setxattr_EACCES(*args, **kwargs):
+            raise OSError(errno.EACCES, 'EACCES')
+
         self.create_regular_file('file')
         xattr.setxattr('input/file', 'attribute', 'value')
         self.cmd('init', self.repository_location, '-e' 'none')
         self.cmd('create', self.repository_location + '::test', 'input')
         with changedir('output'):
-            with patch.object(xattr, 'setxattr', patched_setxattr):
+            input_abspath = os.path.abspath('input/file')
+            with patch.object(xattr, 'setxattr', patched_setxattr_E2BIG):
+                out = self.cmd('extract', self.repository_location + '::test', exit_code=EXIT_WARNING)
+                assert out == (input_abspath + ': Value or key of extended attribute attribute is too big for this '
+                                               'filesystem\n')
+            os.remove(input_abspath)
+            with patch.object(xattr, 'setxattr', patched_setxattr_ENOTSUP):
+                out = self.cmd('extract', self.repository_location + '::test', exit_code=EXIT_WARNING)
+                assert out == (input_abspath + ': Extended attributes are not supported on this filesystem\n')
+            os.remove(input_abspath)
+            with patch.object(xattr, 'setxattr', patched_setxattr_EACCES):
                 out = self.cmd('extract', self.repository_location + '::test', exit_code=EXIT_WARNING)
-                assert out == (os.path.abspath('input/file') + ': Value or key of extended attribute attribute is too big'
-                                                               'for this filesystem\n')
+                assert out == (input_abspath + ': Permission denied when setting extended attribute attribute\n')
+            assert os.path.isfile(input_abspath)
 
     def test_path_normalization(self):
         self.cmd('init', '--encryption=repokey', self.repository_location)