diff --git a/borg/archiver.py b/borg/archiver.py index 3c921e962..bfd56bf0b 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -68,8 +68,8 @@ def with_repository(fake=False, create=False, lock=True, exclusive=False, manife if argument(args, fake): return method(self, args, repository=None, **kwargs) elif location.proto == 'ssh': - repository = RemoteRepository(location, create=create, lock_wait=self.lock_wait, lock=lock, - append_only=append_only, args=args) + repository = RemoteRepository(location, create=create, exclusive=argument(args, exclusive), + lock_wait=self.lock_wait, lock=lock, append_only=append_only, args=args) else: repository = Repository(location.path, create=create, exclusive=argument(args, exclusive), lock_wait=self.lock_wait, lock=lock, diff --git a/borg/remote.py b/borg/remote.py index daaa021cf..8d1bf95ea 100644 --- a/borg/remote.py +++ b/borg/remote.py @@ -114,7 +114,7 @@ class RepositoryServer: # pragma: no cover def negotiate(self, versions): return RPC_PROTOCOL_VERSION - def open(self, path, create=False, lock_wait=None, lock=True, append_only=False): + def open(self, path, create=False, lock_wait=None, lock=True, exclusive=False, append_only=False): path = os.fsdecode(path) if path.startswith('/~'): path = path[1:] @@ -125,7 +125,9 @@ class RepositoryServer: # pragma: no cover break else: raise PathNotAllowed(path) - self.repository = Repository(path, create, lock_wait=lock_wait, lock=lock, append_only=self.append_only or append_only) + self.repository = Repository(path, create, lock_wait=lock_wait, lock=lock, + append_only=self.append_only or append_only, + exclusive=exclusive) self.repository.__enter__() # clean exit handled by serve() method return self.repository.id @@ -141,7 +143,7 @@ class RemoteRepository: class NoAppendOnlyOnServer(Error): """Server does not support --append-only.""" - def __init__(self, location, create=False, lock_wait=None, lock=True, append_only=False, args=None): + def __init__(self, location, create=False, exclusive=False, lock_wait=None, lock=True, append_only=False, args=None): self.location = self._location = location self.preload_ids = [] self.msgid = 0 @@ -178,16 +180,13 @@ class RemoteRepository: raise ConnectionClosedWithHint('Is borg working on the server?') from None if version != RPC_PROTOCOL_VERSION: raise Exception('Server insisted on using unsupported protocol version %d' % version) - # Because of protocol versions, only send append_only if necessary - if append_only: - try: - self.id = self.call('open', self.location.path, create, lock_wait, lock, append_only) - except self.RPCError as err: - if err.remote_type == 'TypeError': - raise self.NoAppendOnlyOnServer() from err - else: - raise - else: + try: + self.id = self.call('open', self.location.path, create, lock_wait, lock, exclusive, append_only) + except self.RPCError as err: + if err.remote_type != 'TypeError': + raise + if append_only: + raise self.NoAppendOnlyOnServer() self.id = self.call('open', self.location.path, create, lock_wait, lock) except Exception: self.close() diff --git a/borg/testsuite/repository.py b/borg/testsuite/repository.py index a012f514a..bc08e097f 100644 --- a/borg/testsuite/repository.py +++ b/borg/testsuite/repository.py @@ -386,7 +386,8 @@ class RepositoryCheckTestCase(RepositoryTestCaseBase): class RemoteRepositoryTestCase(RepositoryTestCase): def open(self, create=False): - return RemoteRepository(Location('__testsuite__:' + os.path.join(self.tmppath, 'repository')), create=create) + return RemoteRepository(Location('__testsuite__:' + os.path.join(self.tmppath, 'repository')), + exclusive=True, create=create) def test_invalid_rpc(self): self.assert_raises(InvalidRPCMethod, lambda: self.repository.call('__init__', None)) @@ -415,7 +416,8 @@ class RemoteRepositoryTestCase(RepositoryTestCase): class RemoteRepositoryCheckTestCase(RepositoryCheckTestCase): def open(self, create=False): - return RemoteRepository(Location('__testsuite__:' + os.path.join(self.tmppath, 'repository')), create=create) + return RemoteRepository(Location('__testsuite__:' + os.path.join(self.tmppath, 'repository')), + exclusive=True, create=create) def test_crash_before_compact(self): # skip this test, we can't mock-patch a Repository class in another process!