Procházet zdrojové kódy

check_can_create_repository: deal with PermissionErrors, see #7016

borg init calls this. If there is a PermissionError, it is
usually fs permission issue at path or its parent directory.

Don't give a traceback, but rather an error msg and a specific exit code.
Thomas Waldmann před 1 rokem
rodič
revize
45815554ce
3 změnil soubory, kde provedl 21 přidání a 2 odebrání
  1. 2 0
      docs/internals/frontends.rst
  2. 2 0
      src/borg/remote.py
  3. 17 2
      src/borg/repository.py

+ 2 - 0
docs/internals/frontends.rst

@@ -612,6 +612,8 @@ Errors
         There is already something at {}.
     Repository.StorageQuotaExceeded rc: 20 traceback: no
         The storage quota ({}) has been exceeded ({}). Try deleting some archives.
+    Repository.PathPermissionDenied rc: 21 traceback: no
+        Permission denied to {}.
 
     MandatoryFeatureUnsupported rc: 25 traceback: no
         Unsupported repository feature(s) {}. A newer version of borg is required to access this repository.

+ 2 - 0
src/borg/remote.py

@@ -780,6 +780,8 @@ class RemoteRepository:
                 raise IntegrityError(args[0])
             elif error == "PathNotAllowed":
                 raise PathNotAllowed(args[0])
+            elif error == "PathPermissionDenied":
+                raise Repository.PathPermissionDenied(args[0])
             elif error == "ParentPathDoesNotExist":
                 raise Repository.ParentPathDoesNotExist(args[0])
             elif error == "ObjectNotFound":

+ 17 - 2
src/borg/repository.py

@@ -188,6 +188,11 @@ class Repository:
 
         exit_mcode = 20
 
+    class PathPermissionDenied(Error):
+        """Permission denied to {}."""
+
+        exit_mcode = 21
+
     def __init__(
         self,
         path,
@@ -299,13 +304,23 @@ class Repository:
             st = os.stat(path)
         except FileNotFoundError:
             pass  # nothing there!
+        except PermissionError:
+            raise self.PathPermissionDenied(path) from None
         else:
             # there is something already there!
             if self.is_repository(path):
                 raise self.AlreadyExists(path)
-            if not stat.S_ISDIR(st.st_mode) or os.listdir(path):
+            if not stat.S_ISDIR(st.st_mode):
                 raise self.PathAlreadyExists(path)
-            # an empty directory is acceptable for us.
+            try:
+                files = os.listdir(path)
+            except PermissionError:
+                raise self.PathPermissionDenied(path) from None
+            else:
+                if files:  # a dir, but not empty
+                    raise self.PathAlreadyExists(path)
+                else:  # an empty directory is acceptable for us.
+                    pass
 
         while True:
             # Check all parent directories for Borg's repository README