def RunGit(self, project, cmd, retries=3):
        """Run a git command inside the given project.

    Args:
      project: repo_manifest.Project to run the command in.
      cmd: Command as a list of arguments. Callers should exclude 'git'.
      retries: Maximum number of retries for the git command.
    """
        retry_util.RetryCommand(git.RunGit,
                                retries,
                                self.AbsoluteProjectPath(project),
                                cmd,
                                print_cmd=True,
                                sleep=2,
                                log_retries=True)
Exemple #2
0
def RunSwarmingCommandWithRetries(max_retry, *args, **kwargs):
    """Wrapper for RunSwarmingCommand that will retry a command.

  Args:
    max_retry: See RetryCommand.
    *args: See RetryCommand and RunSwarmingCommand.
    **kwargs: See RetryCommand and RunSwarmingCommand.

  Returns:
    A SwarmingCommandResult object.

  Raises:
    RunCommandError: When the command fails.
  """
    return retry_util.RetryCommand(RunSwarmingCommand, max_retry, *args,
                                   **kwargs)
Exemple #3
0
    def Sync(self,
             local_manifest=None,
             jobs=None,
             all_branches=True,
             network_only=False,
             detach=False):
        """Sync/update the source.  Changes manifest if specified.

    Args:
      local_manifest: If true, checks out source to manifest.  DEFAULT_MANIFEST
        may be used to set it back to the default manifest.
      jobs: May be set to override the default sync parallelism defined by
        the manifest.
      all_branches: If False, a repo sync -c is performed; this saves on
        sync'ing via grabbing only what is needed for the manifest specified
        branch. Defaults to True. TODO(davidjames): Set the default back to
        False once we've fixed http://crbug.com/368722 .
      network_only: If true, perform only the network half of the sync; skip
        the checkout.  Primarily of use to validate a manifest (although
        if the manifest has bad copyfile statements, via skipping checkout
        the broken copyfile tag won't be spotted), or of use when the
        invoking code is fine w/ operating on bare repos, ie .repo/projects/*.
      detach: If true, throw away all local changes, even if on tracking
        branches.
    """
        try:
            # Always re-initialize to the current branch.
            self.Initialize(local_manifest)
            # Fix existing broken mirroring configurations.
            self._EnsureMirroring()

            cmd = [self.repo_cmd, '--time', 'sync']
            if jobs:
                cmd += ['--jobs', str(jobs)]
            if not all_branches or self._depth is not None:
                # Note that this option can break kernel checkouts. crbug.com/464536
                cmd.append('-c')
            # Do the network half of the sync; retry as necessary to get the content.
            try:
                cros_build_lib.RunCommand(cmd + ['-n'], cwd=self.directory)
            except cros_build_lib.RunCommandError:
                if constants.SYNC_RETRIES > 0:
                    # Retry on clean up and repo sync commands,
                    # decrement max_retry for this command
                    logging.warning(
                        'cmd %s failed, clean up repository and retry sync.' %
                        cmd)
                    retry_util.RetryCommand(self._CleanUpAndRunCommand,
                                            constants.SYNC_RETRIES - 1,
                                            cmd + ['-n'],
                                            cwd=self.directory,
                                            local_manifest=local_manifest)
                else:
                    # No need to retry
                    raise

            if network_only:
                return

            if detach:
                cmd.append('--detach')

            # Do the local sync; note that there is a couple of corner cases where
            # the new manifest cannot transition from the old checkout cleanly-
            # primarily involving git submodules.  Thus we intercept, and do
            # a forced wipe, then a retry.
            try:
                cros_build_lib.RunCommand(cmd + ['-l'], cwd=self.directory)
            except cros_build_lib.RunCommandError:
                manifest = git.ManifestCheckout.Cached(self.directory)
                targets = set(project['path'].split('/', 1)[0]
                              for project in manifest.ListCheckouts())
                if not targets:
                    # No directories to wipe, thus nothing we can fix.
                    raise

                cros_build_lib.SudoRunCommand(['rm', '-rf'] + sorted(targets),
                                              cwd=self.directory)

                # Retry the sync now; if it fails, let the exception propagate.
                cros_build_lib.RunCommand(cmd + ['-l'], cwd=self.directory)

            # We do a second run to fix any new repositories created by repo to
            # use relative object pathways.  Note that cros_sdk also triggers the
            # same cleanup- we however kick it erring on the side of caution.
            self._EnsureMirroring(True)
            self._DoCleanup()

        except cros_build_lib.RunCommandError as e:
            err_msg = e.Stringify(error=False, output=False)
            logging.error(err_msg)
            raise SrcCheckOutException(err_msg)
Exemple #4
0
    def Initialize(self,
                   local_manifest=None,
                   manifest_repo_url=None,
                   extra_args=()):
        """Initializes a repository.  Optionally forces a local manifest.

    Args:
      local_manifest: The absolute path to a custom manifest to use.  This will
                      replace .repo/manifest.xml.
      manifest_repo_url: A new value for manifest_repo_url.
      extra_args: Extra args to pass to 'repo init'
    """
        self.AssertNotNested()

        if manifest_repo_url:
            self.manifest_repo_url = manifest_repo_url

        # Do a sanity check on the repo; if it exists and we can't pull a
        # manifest from it, we know it's fairly screwed up and needs a fresh
        # rebuild.
        if os.path.exists(os.path.join(self.directory, '.repo',
                                       'manifest.xml')):
            cmd = [self.repo_cmd, 'manifest']
            try:
                cros_build_lib.run(cmd,
                                   cwd=self.directory,
                                   capture_output=True)
            except cros_build_lib.RunCommandError:
                metrics.Counter(
                    constants.MON_REPO_MANIFEST_FAILURE_COUNT).increment()
                logging.warning('Wiping %r due to `repo manifest` failure',
                                self.directory)
                self._CleanUpRepoManifest(self.directory)
                self._repo_update_needed = False

        # Wipe local_manifest.xml if it exists- it can interfere w/ things in
        # bad ways (duplicate projects, etc); we control this repository, thus
        # we can destroy it.
        osutils.SafeUnlink(os.path.join(self.directory, 'local_manifest.xml'))

        # Force a repo update the first time we initialize an old repo checkout.
        # Don't update if there is nothing to update.
        if self._repo_update_needed:
            if IsARepoRoot(self.directory):
                self._RepoSelfupdate()
            self._repo_update_needed = False

        # Use our own repo, in case android.kernel.org (the default location) is
        # down.
        init_cmd = [
            self.repo_cmd, 'init', '--manifest-url', self.manifest_repo_url
        ]
        if self.repo_url:
            init_cmd.extend(['--repo-url', self.repo_url])
        if self._referenced_repo:
            init_cmd.extend(['--reference', self._referenced_repo])
        if self._manifest:
            init_cmd.extend(['--manifest-name', self._manifest])
        if self._depth is not None:
            init_cmd.extend(['--depth', str(self._depth)])
        init_cmd.extend(extra_args)
        # Handle branch / manifest options.
        if self.branch:
            init_cmd.extend(['--manifest-branch', self.branch])
        if self.repo_branch:
            init_cmd.extend(['--repo-branch', self.repo_branch])
        if self.groups:
            init_cmd.extend(['--groups', self.groups])

        def _StatusCallback(attempt, _):
            if attempt:
                metrics.Counter(constants.MON_REPO_INIT_RETRY_COUNT).increment(
                    fields={'manifest_url': self.manifest_repo_url})

        retry_util.RetryCommand(self._RepoInit,
                                REPO_INIT_RETRY_LIMIT,
                                init_cmd,
                                sleep=DEFAULT_SLEEP_TIME,
                                backoff_factor=2,
                                log_retries=True,
                                status_callback=_StatusCallback)

        if local_manifest and local_manifest != self._manifest:
            self._SwitchToLocalManifest(local_manifest)