def setUp(self):
     TestCaseWithRepository.setUp(self)
     # make_bzrdir relies on this being a relative filesystem path.
     self._source_branch_path = 'source-branch'
     SafeBranchOpener.install_hook()
     self.worker = self.makePullerWorker(
         self.get_url(self._source_branch_path), self.get_url('dest-path'))
示例#2
0
 def _doImport(self):
     self._logger.info("Starting job.")
     saved_factory = bzrlib.ui.ui_factory
     opener = SafeBranchOpener(self._opener_policy, self.probers)
     bzrlib.ui.ui_factory = LoggingUIFactory(logger=self._logger)
     try:
         self._logger.info(
             "Getting exising bzr branch from central store.")
         bazaar_branch = self.getBazaarBranch()
         try:
             remote_branch = opener.open(self.source_details.url)
         except TooManyRedirections:
             self._logger.info("Too many redirections.")
             return CodeImportWorkerExitCode.FAILURE_INVALID
         except NotBranchError:
             self._logger.info("No branch found at remote location.")
             return CodeImportWorkerExitCode.FAILURE_INVALID
         except BadUrl as e:
             self._logger.info("Invalid URL: %s" % e)
             return CodeImportWorkerExitCode.FAILURE_FORBIDDEN
         except ConnectionError as e:
             self._logger.info("Unable to open remote branch: %s" % e)
             return CodeImportWorkerExitCode.FAILURE_INVALID
         try:
             remote_branch_tip = remote_branch.last_revision()
             inter_branch = InterBranch.get(remote_branch, bazaar_branch)
             self._logger.info("Importing branch.")
             revision_limit = self.getRevisionLimit()
             inter_branch.fetch(limit=revision_limit)
             if bazaar_branch.repository.has_revision(remote_branch_tip):
                 pull_result = inter_branch.pull(overwrite=True)
                 if pull_result.old_revid != pull_result.new_revid:
                     result = CodeImportWorkerExitCode.SUCCESS
                 else:
                     result = CodeImportWorkerExitCode.SUCCESS_NOCHANGE
             else:
                 result = CodeImportWorkerExitCode.SUCCESS_PARTIAL
         except Exception as e:
             if e.__class__ in self.unsupported_feature_exceptions:
                 self._logger.info(
                     "Unable to import branch because of limitations in "
                     "Bazaar.")
                 self._logger.info(str(e))
                 return (
                     CodeImportWorkerExitCode.FAILURE_UNSUPPORTED_FEATURE)
             elif e.__class__ in self.invalid_branch_exceptions:
                 self._logger.info("Branch invalid: %s", str(e))
                 return CodeImportWorkerExitCode.FAILURE_INVALID
             elif e.__class__ in self.broken_remote_exceptions:
                 self._logger.info("Remote branch broken: %s", str(e))
                 return CodeImportWorkerExitCode.FAILURE_REMOTE_BROKEN
             else:
                 raise
         self._logger.info("Pushing local import branch to central store.")
         self.pushBazaarBranch(bazaar_branch)
         self._logger.info("Job complete.")
         return result
     finally:
         bzrlib.ui.ui_factory = saved_factory
 def setUp(self):
     TestCaseWithRepository.setUp(self)
     # make_bzrdir relies on this being a relative filesystem path.
     self._source_branch_path = 'source-branch'
     SafeBranchOpener.install_hook()
     self.worker = self.makePullerWorker(
         self.get_url(self._source_branch_path),
         self.get_url('dest-path'))
 def setUp(self):
     super(BzrSyncTestCase, self).setUp()
     SafeBranchOpener.install_hook()
     self.disable_directory_isolation()
     self.useBzrBranches(direct_database=True)
     self.makeFixtures()
     switch_dbuser("branchscanner")
     # Catch both constraints and permissions for the db user.
     self.addCleanup(Store.of(self.db_branch).flush)
示例#5
0
 def setUp(self):
     super(BzrSyncTestCase, self).setUp()
     SafeBranchOpener.install_hook()
     self.disable_directory_isolation()
     self.useBzrBranches(direct_database=True)
     self.makeFixtures()
     switch_dbuser("branchscanner")
     # Catch both constraints and permissions for the db user.
     self.addCleanup(Store.of(self.db_branch).flush)
示例#6
0
    def __init__(self, policy, protocol=None, log=None):
        """Construct a branch opener with 'policy'.

        :param policy: A `BranchOpenPolicy` that tells us what URLs are valid
            and similar things.
        :param log: A callable which can be called with a format string and
            arguments to log messages in the scheduler, or None, in which case
            log messages are discarded.
        """
        self.policy = policy
        self.protocol = protocol
        self.opener = SafeBranchOpener(policy)
        if log is not None:
            self.log = log
        else:
            self.log = lambda *args: None
 def setUp(self):
     super(TestSafeBranchOpenerCheckAndFollowBranchReference, self).setUp()
     SafeBranchOpener.install_hook()
 def setUp(self):
     super(TestSafeOpen, self).setUp()
     SafeBranchOpener.install_hook()
示例#9
0
class BranchMirrorer(object):
    """A `BranchMirrorer` safely makes mirrors of branches.

    A `BranchMirrorer` has a `BranchOpenPolicy` to tell it which URLs are safe
    to accesss and whether or not to follow branch references.

    The mirrorer knows how to follow branch references, create new mirrors,
    update existing mirrors, determine stacked-on branches and the like.

    Public methods are `open` and `mirror`.
    """

    def __init__(self, policy, protocol=None, log=None):
        """Construct a branch opener with 'policy'.

        :param policy: A `BranchOpenPolicy` that tells us what URLs are valid
            and similar things.
        :param log: A callable which can be called with a format string and
            arguments to log messages in the scheduler, or None, in which case
            log messages are discarded.
        """
        self.policy = policy
        self.protocol = protocol
        self.opener = SafeBranchOpener(policy)
        if log is not None:
            self.log = log
        else:
            self.log = lambda *args: None

    def createDestinationBranch(self, source_branch, destination_url):
        """Create a destination branch for 'source_branch'.

        Creates a branch at 'destination_url' that is a mirror of
        'source_branch'. Any content already at 'destination_url' will be
        deleted.

        :param source_branch: The Bazaar branch that will be mirrored.
        :param destination_url: The place to make the destination branch. This
            URL must point to a writable location.
        :return: The destination branch.
        """
        return self.opener.runWithTransformFallbackLocationHookInstalled(
            self.policy.createDestinationBranch, source_branch,
            destination_url)

    def openDestinationBranch(self, source_branch, destination_url):
        """Open or create the destination branch at 'destination_url'.

        :param source_branch: The Bazaar branch that will be mirrored.
        :param destination_url: The place to make the destination branch. This
            URL must point to a writable location.
        :return: The opened or created branch.
        """
        try:
            branch = Branch.open(destination_url)
        except (errors.NotBranchError, errors.IncompatibleRepositories):
            # Make a new branch in the same format as the source branch.
            return self.createDestinationBranch(
                source_branch, destination_url)
        # Check that destination branch is in the same format as the source.
        if identical_formats(source_branch, branch):
            return branch
        self.log('Formats differ.')
        return self.createDestinationBranch(source_branch, destination_url)

    def updateBranch(self, source_branch, dest_branch):
        """Bring 'dest_branch' up-to-date with 'source_branch'.

        This method pulls 'source_branch' into 'dest_branch' and sets the
        stacked-on URL of 'dest_branch' to match 'source_branch'.

        This method assumes that 'source_branch' and 'dest_branch' both have
        the same format.
        """
        stacked_on_url = self.policy.getStackedOnURLForDestinationBranch(
            source_branch, dest_branch.base)
        try:
            dest_branch.set_stacked_on_url(stacked_on_url)
        except (errors.UnstackableRepositoryFormat,
                errors.UnstackableBranchFormat,
                errors.IncompatibleRepositories):
            stacked_on_url = None
        if stacked_on_url is None:
            # We use stacked_on_url == '' to mean "no stacked on location"
            # because XML-RPC doesn't support None.
            stacked_on_url = ''
        dest_branch.pull(source_branch, overwrite=True)
        return stacked_on_url

    def mirror(self, source_branch, destination_url):
        """Mirror 'source_branch' to 'destination_url'."""
        branch = self.openDestinationBranch(source_branch, destination_url)
        revid_before = branch.last_revision()
        # If the branch is locked, try to break it. Our special UI factory
        # will allow the breaking of locks that look like they were left
        # over from previous puller worker runs. We will block on other
        # locks and fail if they are not broken before the timeout expires
        # (currently 5 minutes).
        if branch.get_physical_lock_status():
            branch.break_lock()
        stacked_on_url = self.updateBranch(source_branch, branch)
        return branch, revid_before, stacked_on_url

    def open(self, url):
        return self.opener.open(url)
 def setUp(self):
     super(TestSafeBranchOpenerCheckAndFollowBranchReference, self).setUp()
     SafeBranchOpener.install_hook()
 def setUp(self):
     super(TestSafeOpen, self).setUp()
     SafeBranchOpener.install_hook()
 def makeBranchOpener(self, allowed_urls, probers=None):
     policy = WhitelistPolicy(True, allowed_urls, True)
     return SafeBranchOpener(policy, probers)