333
336
_mod_bzrdir.BzrDirMetaFormat1._set_repository_format) #.im_func)
339
class RemoteControlStore(config.IniFileStore):
340
"""Control store which attempts to use HPSS calls to retrieve control store.
342
Note that this is specific to bzr-based formats.
345
def __init__(self, bzrdir):
346
super(RemoteControlStore, self).__init__()
348
self._real_store = None
350
def lock_write(self, token=None):
352
return self._real_store.lock_write(token)
356
return self._real_store.unlock()
360
# We need to be able to override the undecorated implementation
361
self.save_without_locking()
363
def save_without_locking(self):
364
super(RemoteControlStore, self).save()
366
def _ensure_real(self):
367
self.bzrdir._ensure_real()
368
if self._real_store is None:
369
self._real_store = config.ControlStore(self.bzrdir)
371
def external_url(self):
372
return self.bzrdir.user_url
374
def _load_content(self):
375
medium = self.bzrdir._client._medium
376
path = self.bzrdir._path_for_remote_call(self.bzrdir._client)
378
response, handler = self.bzrdir._call_expecting_body(
379
'BzrDir.get_config_file', path)
380
except errors.UnknownSmartMethod:
382
return self._real_store._load_content()
383
if len(response) and response[0] != 'ok':
384
raise errors.UnexpectedSmartServerResponse(response)
385
return handler.read_body_bytes()
387
def _save_content(self, content):
388
# FIXME JRV 2011-11-22: Ideally this should use a
389
# HPSS call too, but at the moment it is not possible
390
# to write lock control directories.
392
return self._real_store._save_content(content)
336
395
class RemoteBzrDir(_mod_bzrdir.BzrDir, _RpcHelper):
337
396
"""Control directory on a remote server, accessed via bzr:// or similar."""
1016
1127
for older plugins that don't use e.g. the CommitBuilder
1020
return self._real_repository.commit_write_group()
1130
if self._real_repository:
1132
return self._real_repository.commit_write_group()
1133
if not self.is_in_write_group():
1134
raise errors.BzrError("not in write group")
1135
path = self.bzrdir._path_for_remote_call(self._client)
1136
response = self._call('Repository.commit_write_group', path,
1137
self._lock_token, self._write_group_tokens)
1138
if response != ('ok', ):
1139
raise errors.UnexpectedSmartServerResponse(response)
1140
self._write_group_tokens = None
1022
1142
def resume_write_group(self, tokens):
1024
return self._real_repository.resume_write_group(tokens)
1143
if self._real_repository:
1144
return self._real_repository.resume_write_group(tokens)
1145
path = self.bzrdir._path_for_remote_call(self._client)
1147
response = self._call('Repository.check_write_group', path,
1148
self._lock_token, tokens)
1149
except errors.UnknownSmartMethod:
1151
return self._real_repository.resume_write_group(tokens)
1152
if response != ('ok', ):
1153
raise errors.UnexpectedSmartServerResponse(response)
1154
self._write_group_tokens = tokens
1026
1156
def suspend_write_group(self):
1028
return self._real_repository.suspend_write_group()
1157
if self._real_repository:
1158
return self._real_repository.suspend_write_group()
1159
ret = self._write_group_tokens or []
1160
self._write_group_tokens = None
1030
1163
def get_missing_parent_inventories(self, check_for_missing_texts=True):
1031
1164
self._ensure_real()
2732
class RemoteBranchStore(config.IniFileStore):
2733
"""Branch store which attempts to use HPSS calls to retrieve branch store.
2735
Note that this is specific to bzr-based formats.
2738
def __init__(self, branch):
2739
super(RemoteBranchStore, self).__init__()
2740
self.branch = branch
2742
self._real_store = None
2744
def lock_write(self, token=None):
2745
return self.branch.lock_write(token)
2748
return self.branch.unlock()
2752
# We need to be able to override the undecorated implementation
2753
self.save_without_locking()
2755
def save_without_locking(self):
2756
super(RemoteBranchStore, self).save()
2758
def external_url(self):
2759
return self.branch.user_url
2761
def _load_content(self):
2762
path = self.branch._remote_path()
2764
response, handler = self.branch._call_expecting_body(
2765
'Branch.get_config_file', path)
2766
except errors.UnknownSmartMethod:
2768
return self._real_store._load_content()
2769
if len(response) and response[0] != 'ok':
2770
raise errors.UnexpectedSmartServerResponse(response)
2771
return handler.read_body_bytes()
2773
def _save_content(self, content):
2774
path = self.branch._remote_path()
2776
response, handler = self.branch._call_with_body_bytes_expecting_body(
2777
'Branch.put_config_file', (path,
2778
self.branch._lock_token, self.branch._repo_lock_token),
2780
except errors.UnknownSmartMethod:
2782
return self._real_store._save_content(content)
2783
handler.cancel_read_body()
2784
if response != ('ok', ):
2785
raise errors.UnexpectedSmartServerResponse(response)
2787
def _ensure_real(self):
2788
self.branch._ensure_real()
2789
if self._real_store is None:
2790
self._real_store = config.BranchStore(self.branch)
2526
2793
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
2527
2794
"""Branch stored on a server accessed by HPSS RPC.
3071
3353
return self._lock_count >= 1
3073
3355
@needs_read_lock
3356
def revision_id_to_dotted_revno(self, revision_id):
3357
"""Given a revision id, return its dotted revno.
3359
:return: a tuple like (1,) or (400,1,3).
3362
response = self._call('Branch.revision_id_to_revno',
3363
self._remote_path(), revision_id)
3364
except errors.UnknownSmartMethod:
3366
return self._real_branch.revision_id_to_dotted_revno(revision_id)
3367
if response[0] == 'ok':
3368
return tuple([int(x) for x in response[1:]])
3370
raise errors.UnexpectedSmartServerResponse(response)
3074
3373
def revision_id_to_revno(self, revision_id):
3076
return self._real_branch.revision_id_to_revno(revision_id)
3374
"""Given a revision id on the branch mainline, return its revno.
3379
response = self._call('Branch.revision_id_to_revno',
3380
self._remote_path(), revision_id)
3381
except errors.UnknownSmartMethod:
3383
return self._real_branch.revision_id_to_revno(revision_id)
3384
if response[0] == 'ok':
3385
if len(response) == 2:
3386
return int(response[1])
3387
raise NoSuchRevision(self, revision_id)
3389
raise errors.UnexpectedSmartServerResponse(response)
3078
3391
@needs_write_lock
3079
3392
def set_last_revision_info(self, revno, revision_id):
3352
3669
'Missing key %r in context %r', key_err.args[0], context)
3355
if err.error_verb == 'NoSuchRevision':
3356
raise NoSuchRevision(find('branch'), err.error_args[0])
3357
elif err.error_verb == 'nosuchrevision':
3358
raise NoSuchRevision(find('repository'), err.error_args[0])
3359
elif err.error_verb == 'nobranch':
3360
if len(err.error_args) >= 1:
3361
extra = err.error_args[0]
3364
raise errors.NotBranchError(path=find('bzrdir').root_transport.base,
3366
elif err.error_verb == 'norepository':
3367
raise errors.NoRepositoryPresent(find('bzrdir'))
3368
elif err.error_verb == 'UnlockableTransport':
3369
raise errors.UnlockableTransport(find('bzrdir').root_transport)
3370
elif err.error_verb == 'TokenMismatch':
3371
raise errors.TokenMismatch(find('token'), '(remote token)')
3372
elif err.error_verb == 'Diverged':
3373
raise errors.DivergedBranches(find('branch'), find('other_branch'))
3374
elif err.error_verb == 'NotStacked':
3375
raise errors.NotStacked(branch=find('branch'))
3376
elif err.error_verb == 'PermissionDenied':
3378
if len(err.error_args) >= 2:
3379
extra = err.error_args[1]
3382
raise errors.PermissionDenied(path, extra=extra)
3383
elif err.error_verb == 'ReadError':
3385
raise errors.ReadError(path)
3386
elif err.error_verb == 'NoSuchFile':
3388
raise errors.NoSuchFile(path)
3389
_translate_error_without_context(err)
3392
def _translate_error_without_context(err):
3393
"""Translate any ErrorFromSmartServer values that don't require context"""
3394
if err.error_verb == 'IncompatibleRepositories':
3395
raise errors.IncompatibleRepositories(err.error_args[0],
3396
err.error_args[1], err.error_args[2])
3397
elif err.error_verb == 'LockContention':
3398
raise errors.LockContention('(remote lock)')
3399
elif err.error_verb == 'LockFailed':
3400
raise errors.LockFailed(err.error_args[0], err.error_args[1])
3401
elif err.error_verb == 'TipChangeRejected':
3402
raise errors.TipChangeRejected(err.error_args[0].decode('utf8'))
3403
elif err.error_verb == 'UnstackableBranchFormat':
3404
raise errors.UnstackableBranchFormat(*err.error_args)
3405
elif err.error_verb == 'UnstackableRepositoryFormat':
3406
raise errors.UnstackableRepositoryFormat(*err.error_args)
3407
elif err.error_verb == 'FileExists':
3408
raise errors.FileExists(err.error_args[0])
3409
elif err.error_verb == 'DirectoryNotEmpty':
3410
raise errors.DirectoryNotEmpty(err.error_args[0])
3411
elif err.error_verb == 'ShortReadvError':
3412
args = err.error_args
3413
raise errors.ShortReadvError(
3414
args[0], int(args[1]), int(args[2]), int(args[3]))
3415
elif err.error_verb in ('UnicodeEncodeError', 'UnicodeDecodeError'):
3673
translator = error_translators.get(err.error_verb)
3677
raise translator(err, find, get_path)
3679
translator = no_context_error_translators.get(err.error_verb)
3681
raise errors.UnknownErrorFromSmartServer(err)
3683
raise translator(err)
3686
error_translators.register('NoSuchRevision',
3687
lambda err, find, get_path: NoSuchRevision(
3688
find('branch'), err.error_args[0]))
3689
error_translators.register('nosuchrevision',
3690
lambda err, find, get_path: NoSuchRevision(
3691
find('repository'), err.error_args[0]))
3693
def _translate_nobranch_error(err, find, get_path):
3694
if len(err.error_args) >= 1:
3695
extra = err.error_args[0]
3698
return errors.NotBranchError(path=find('bzrdir').root_transport.base,
3701
error_translators.register('nobranch', _translate_nobranch_error)
3702
error_translators.register('norepository',
3703
lambda err, find, get_path: errors.NoRepositoryPresent(
3705
error_translators.register('UnlockableTransport',
3706
lambda err, find, get_path: errors.UnlockableTransport(
3707
find('bzrdir').root_transport))
3708
error_translators.register('TokenMismatch',
3709
lambda err, find, get_path: errors.TokenMismatch(
3710
find('token'), '(remote token)'))
3711
error_translators.register('Diverged',
3712
lambda err, find, get_path: errors.DivergedBranches(
3713
find('branch'), find('other_branch')))
3714
error_translators.register('NotStacked',
3715
lambda err, find, get_path: errors.NotStacked(branch=find('branch')))
3717
def _translate_PermissionDenied(err, find, get_path):
3719
if len(err.error_args) >= 2:
3720
extra = err.error_args[1]
3723
return errors.PermissionDenied(path, extra=extra)
3725
error_translators.register('PermissionDenied', _translate_PermissionDenied)
3726
error_translators.register('ReadError',
3727
lambda err, find, get_path: errors.ReadError(get_path()))
3728
error_translators.register('NoSuchFile',
3729
lambda err, find, get_path: errors.NoSuchFile(get_path()))
3730
no_context_error_translators.register('IncompatibleRepositories',
3731
lambda err: errors.IncompatibleRepositories(
3732
err.error_args[0], err.error_args[1], err.error_args[2]))
3733
no_context_error_translators.register('LockContention',
3734
lambda err: errors.LockContention('(remote lock)'))
3735
no_context_error_translators.register('LockFailed',
3736
lambda err: errors.LockFailed(err.error_args[0], err.error_args[1]))
3737
no_context_error_translators.register('TipChangeRejected',
3738
lambda err: errors.TipChangeRejected(err.error_args[0].decode('utf8')))
3739
no_context_error_translators.register('UnstackableBranchFormat',
3740
lambda err: errors.UnstackableBranchFormat(*err.error_args))
3741
no_context_error_translators.register('UnstackableRepositoryFormat',
3742
lambda err: errors.UnstackableRepositoryFormat(*err.error_args))
3743
no_context_error_translators.register('FileExists',
3744
lambda err: errors.FileExists(err.error_args[0]))
3745
no_context_error_translators.register('DirectoryNotEmpty',
3746
lambda err: errors.DirectoryNotEmpty(err.error_args[0]))
3748
def _translate_short_readv_error(err):
3749
args = err.error_args
3750
return errors.ShortReadvError(args[0], int(args[1]), int(args[2]),
3753
no_context_error_translators.register('ShortReadvError',
3754
_translate_short_readv_error)
3756
def _translate_unicode_error(err):
3416
3757
encoding = str(err.error_args[0]) # encoding must always be a string
3417
3758
val = err.error_args[1]
3418
3759
start = int(err.error_args[2])
3426
3767
raise UnicodeDecodeError(encoding, val, start, end, reason)
3427
3768
elif err.error_verb == 'UnicodeEncodeError':
3428
3769
raise UnicodeEncodeError(encoding, val, start, end, reason)
3429
elif err.error_verb == 'ReadOnlyError':
3430
raise errors.TransportNotPossible('readonly transport')
3431
elif err.error_verb == 'MemoryError':
3432
raise errors.BzrError("remote server out of memory\n"
3433
"Retry non-remotely, or contact the server admin for details.")
3434
raise errors.UnknownErrorFromSmartServer(err)
3771
no_context_error_translators.register('UnicodeEncodeError',
3772
_translate_unicode_error)
3773
no_context_error_translators.register('UnicodeDecodeError',
3774
_translate_unicode_error)
3775
no_context_error_translators.register('ReadOnlyError',
3776
lambda err: errors.TransportNotPossible('readonly transport'))
3777
no_context_error_translators.register('MemoryError',
3778
lambda err: errors.BzrError("remote server out of memory\n"
3779
"Retry non-remotely, or contact the server admin for details."))
3781
no_context_error_translators.register('BzrCheckError',
3782
lambda err: errors.BzrCheckError(msg=err.error_args[0]))
3784
error_translators.register('UnsuspendableWriteGroup',
3785
lambda err, find, get_path: errors.UnsuspendableWriteGroup(
3786
repository=find('repository')))
3787
error_translators.register('UnresumableWriteGroup',
3788
lambda err, find, get_path: errors.UnresumableWriteGroup(
3789
repository=find('repository'), write_groups=err.error_args[0],
3790
reason=err.error_args[1]))