Add --append-only to borg init

This commit is contained in:
Lee Bousfield 2016-07-22 13:58:53 -04:00
parent e32dcc4c8a
commit 88a4989c57
3 changed files with 28 additions and 9 deletions

View File

@ -64,13 +64,16 @@ def with_repository(fake=False, create=False, lock=True, exclusive=False, manife
@functools.wraps(method)
def wrapper(self, args, **kwargs):
location = args.location # note: 'location' must be always present in args
append_only = getattr(args, 'append_only', False)
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, args=args)
repository = RemoteRepository(location, create=create, 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)
lock_wait=self.lock_wait, lock=lock,
append_only=append_only)
with repository:
if manifest or cache:
kwargs['manifest'], kwargs['key'] = Manifest.load(repository)
@ -947,6 +950,8 @@ class Archiver:
subparser.add_argument('-e', '--encryption', dest='encryption',
choices=('none', 'keyfile', 'repokey'), default='repokey',
help='select encryption key mode (default: "%(default)s")')
subparser.add_argument('-a', '--append-only', dest='append_only', action='store_true',
help='create an append-only mode repository')
check_epilog = textwrap.dedent("""
The check command verifies the consistency of a repository and the corresponding archives.

View File

@ -113,7 +113,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):
def open(self, path, create=False, lock_wait=None, lock=True, append_only=False):
path = os.fsdecode(path)
if path.startswith('/~'):
path = path[1:]
@ -124,7 +124,7 @@ 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)
self.repository = Repository(path, create, lock_wait=lock_wait, lock=lock, append_only=self.append_only or append_only)
self.repository.__enter__() # clean exit handled by serve() method
return self.repository.id
@ -133,10 +133,14 @@ class RemoteRepository:
extra_test_args = []
class RPCError(Exception):
def __init__(self, name):
def __init__(self, name, remote_type):
self.name = name
self.remote_type = remote_type
def __init__(self, location, create=False, lock_wait=None, lock=True, args=None):
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):
self.location = self._location = location
self.preload_ids = []
self.msgid = 0
@ -172,7 +176,17 @@ class RemoteRepository:
if version != RPC_PROTOCOL_VERSION:
raise Exception('Server insisted on using unsupported protocol version %d' % version)
try:
self.id = self.call('open', self.location.path, create, lock_wait, lock)
# 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:
self.id = self.call('open', self.location.path, create, lock_wait, lock)
except Exception:
self.close()
raise
@ -264,7 +278,7 @@ class RemoteRepository:
elif error == b'InvalidRPCMethod':
raise InvalidRPCMethod(*res)
else:
raise self.RPCError(res.decode('utf-8'))
raise self.RPCError(res.decode('utf-8'), error.decode('utf-8'))
calls = list(calls)
waiting_for = []

View File

@ -108,7 +108,7 @@ class Repository:
config.set('repository', 'version', '1')
config.set('repository', 'segments_per_dir', str(self.DEFAULT_SEGMENTS_PER_DIR))
config.set('repository', 'max_segment_size', str(self.DEFAULT_MAX_SEGMENT_SIZE))
config.set('repository', 'append_only', '0')
config.set('repository', 'append_only', str(int(self.append_only)))
config.set('repository', 'id', hexlify(os.urandom(32)).decode('ascii'))
self.save_config(path, config)