예제 #1
0
    def _GetSHA1ForProject(manifest, project):
        """Get the latest SHA1 for a given project from Gerrit.

    This function looks up the remote and branch for a given project in the
    manifest, and uses this to lookup the SHA1 from Gerrit. This only makes
    sense for unpinned manifests.

    Args:
      manifest: git.ManifestCheckout object.
      project: Project to look up.

    Raises:
      Exception if the manifest is pinned.
    """
        helper = gerrit.GerritHelper.FromManifestProject(manifest, project)
        manifest_branch = manifest.GetAttributeForProject(project, 'revision')
        branch = git.StripRefsHeads(manifest_branch)
        return helper.GetLatestSHA1ForBranch(project, branch)
예제 #2
0
  def _Submit(self, workdir, testjob, dryrun):
    """Internal submission function.  See Submit() for arg description."""
    # TODO(rcui): convert to shallow clone when that's available.
    current_time = str(int(time.time()))

    ref_base = os.path.join('refs/tryjobs', self.user_email, current_time)
    for patch in self.local_patches:
      # Isolate the name; if it's a tag or a remote, let through.
      # Else if it's a branch, get the full branch name minus refs/heads.
      local_branch = git.StripRefsHeads(patch.ref, False)
      ref_final = os.path.join(ref_base, local_branch, patch.sha1)

      checkout = patch.GetCheckout(self.manifest)
      checkout.AssertPushable()
      print('Uploading patch %s' % patch)
      patch.Upload(checkout['push_url'], ref_final, dryrun=dryrun)

      # TODO(rcui): Pass in the remote instead of tag. http://crosbug.com/33937.
      tag = constants.EXTERNAL_PATCH_TAG
      if checkout['remote'] == site_config.params.INTERNAL_REMOTE:
        tag = constants.INTERNAL_PATCH_TAG

      self.extra_args.append('--remote-patches=%s:%s:%s:%s:%s'
                             % (patch.project, local_branch, ref_final,
                                patch.tracking_branch, tag))

    self._VerifyForBuildbot()
    repository.UpdateGitRepo(workdir, self.repo_url)
    version_path = os.path.join(workdir,
                                self.TRYJOB_FORMAT_FILE)
    with open(version_path, 'r') as f:
      try:
        val = int(f.read().strip())
      except ValueError:
        raise ChromiteUpgradeNeeded()
      if val > self.TRYJOB_FORMAT_VERSION:
        raise ChromiteUpgradeNeeded(val)

    if self.use_buildbucket:
      self._PostConfigsToBuildBucket(testjob, dryrun)
    else:
      self._PushConfig(workdir, testjob, dryrun, current_time)
예제 #3
0
def PushLocalPatches(site_config, local_patches, user_email, dryrun=False):
    """Push local changes to a remote ref, and generate args to send.

  Args:
    site_config: config_lib.SiteConfig containing all config info.
    local_patches: patch_pool.local_patches from verified patch_pool.
    user_email: Unique id for user submitting this tryjob.
    dryrun: Is this a dryrun? If so, don't really push.

  Returns:
    List of strings to pass to builder to include these patches.
  """
    manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT)

    current_time = str(int(time.time()))
    ref_base = os.path.join('refs/tryjobs', user_email, current_time)

    extra_args = []
    for patch in local_patches:
        # Isolate the name; if it's a tag or a remote, let through.
        # Else if it's a branch, get the full branch name minus refs/heads.
        local_branch = git.StripRefsHeads(patch.ref, False)
        ref_final = os.path.join(ref_base, local_branch, patch.sha1)

        checkout = patch.GetCheckout(manifest)
        checkout.AssertPushable()
        print('Uploading patch %s' % patch)
        patch.Upload(checkout['push_url'], ref_final, dryrun=dryrun)

        # TODO(rcui): Pass in the remote instead of tag. http://crosbug.com/33937.
        tag = constants.EXTERNAL_PATCH_TAG
        if checkout['remote'] == site_config.params.INTERNAL_REMOTE:
            tag = constants.INTERNAL_PATCH_TAG

        extra_args.append('--remote-patches=%s:%s:%s:%s:%s' %
                          (patch.project, local_branch, ref_final,
                           patch.tracking_branch, tag))

    return extra_args
예제 #4
0
def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)
    repo_dir = git.FindRepoDir(os.getcwd())
    if not repo_dir:
        parser.error("This script must be invoked from within a repository "
                     "checkout.")

    options.git_config = os.path.join(repo_dir, 'manifests.git', 'config')
    options.local_manifest_path = os.path.join(repo_dir, 'local_manifest.xml')

    manifest_sym_path = os.path.join(repo_dir, 'manifest.xml')
    if os.path.basename(os.readlink(manifest_sym_path)) == 'minilayout.xml':
        _AssertNotMiniLayout()

    # For now, we only support the add command.
    assert options.command == 'add'
    if options.workon:
        if options.path is not None:
            parser.error('Adding workon projects do not set project.')
    else:
        if options.remote is None:
            parser.error('Adding non-workon projects requires a remote.')
        if options.path is None:
            parser.error('Adding non-workon projects requires a path.')
    name = options.project
    path = options.path
    revision = options.revision
    if revision is not None:
        if (not git.IsRefsTags(revision) and not git.IsSHA1(revision)):
            revision = git.StripRefsHeads(revision, False)

    main_manifest = git.ManifestCheckout(os.getcwd())
    main_element = main_manifest.FindCheckouts(name)
    if path is not None:
        main_element_from_path = main_manifest.FindCheckoutFromPath(
            path, strict=False)
        if main_element_from_path is not None:
            main_element.append(main_element_from_path)

    local_manifest = LocalManifest.FromPath(options.local_manifest_path)

    if options.workon:
        if not main_element:
            parser.error('No project named %r in the default manifest.' % name)
        _AddProjectsToManifestGroups(
            options, [checkout['name'] for checkout in main_element])

    elif main_element:
        if options.remote is not None:
            # Likely this project wasn't meant to be remote, so workon main element
            print(
                "Project already exists in manifest. Using that as workon project."
            )
            _AddProjectsToManifestGroups(
                options, [checkout['name'] for checkout in main_element])
        else:
            # Conflict will occur; complain.
            parser.error(
                "Requested project name=%r path=%r will conflict with "
                "your current manifest %s" %
                (name, path, main_manifest.manifest_path))

    elif local_manifest.GetProject(name, path=path) is not None:
        parser.error("Requested project name=%r path=%r conflicts with "
                     "your local_manifest.xml" % (name, path))

    else:
        element = local_manifest.AddNonWorkonProject(name=name,
                                                     path=path,
                                                     remote=options.remote,
                                                     revision=revision)
        _AddProjectsToManifestGroups(options, [element.attrib['name']])

        with open(options.local_manifest_path, 'w') as f:
            f.write(local_manifest.ToString())
    return 0
예제 #5
0
  def _Submit(self, testjob, dryrun):
    """Internal submission function.  See Submit() for arg description."""
    # TODO(rcui): convert to shallow clone when that's available.
    current_time = str(int(time.time()))

    ref_base = os.path.join('refs/tryjobs', self.user, current_time)
    for patch in self.local_patches:
      # Isolate the name; if it's a tag or a remote, let through.
      # Else if it's a branch, get the full branch name minus refs/heads.
      local_branch = git.StripRefsHeads(patch.ref, False)
      ref_final = os.path.join(ref_base, local_branch, patch.sha1)

      self.manifest.AssertProjectIsPushable(patch.project)
      data = self.manifest.projects[patch.project]
      print 'Uploading patch %s' % patch
      patch.Upload(data['push_url'], ref_final, dryrun=dryrun)

      # TODO(rcui): Pass in the remote instead of tag. http://crosbug.com/33937.
      tag = constants.EXTERNAL_PATCH_TAG
      if data['remote'] == constants.INTERNAL_REMOTE:
        tag = constants.INTERNAL_PATCH_TAG

      self.extra_args.append('--remote-patches=%s:%s:%s:%s:%s'
                             % (patch.project, local_branch, ref_final,
                                patch.tracking_branch, tag))

    self._VerifyForBuildbot()
    repository.CloneGitRepo(self.tryjob_repo, self.ssh_url)
    version_path = os.path.join(self.tryjob_repo,
                                self.TRYJOB_FORMAT_FILE)
    with open(version_path, 'r') as f:
      try:
        val = int(f.read().strip())
      except ValueError:
        raise ChromiteUpgradeNeeded()
      if val > self.TRYJOB_FORMAT_VERSION:
        raise ChromiteUpgradeNeeded(val)
    push_branch = manifest_version.PUSH_BRANCH

    remote_branch = ('origin', 'refs/remotes/origin/test') if testjob else None
    git.CreatePushBranch(push_branch, self.tryjob_repo, sync=False,
                         remote_push_branch=remote_branch)

    file_name = '%s.%s' % (self.user,
                           current_time)
    user_dir = os.path.join(self.tryjob_repo, self.user)
    if not os.path.isdir(user_dir):
      os.mkdir(user_dir)

    fullpath = os.path.join(user_dir, file_name)
    with open(fullpath, 'w+') as job_desc_file:
      json.dump(self.values, job_desc_file)

    cros_build_lib.RunCommand(['git', 'add', fullpath], cwd=self.tryjob_repo)
    extra_env = {
      # The committer field makes sure the creds match what the remote
      # gerrit instance expects while the author field allows lookup
      # on the console to work.  http://crosbug.com/27939
      'GIT_COMMITTER_EMAIL' : self.user_email,
      'GIT_AUTHOR_EMAIL'    : self.user_email,
    }
    cros_build_lib.RunCommand(['git', 'commit', '-m', self.description],
                              cwd=self.tryjob_repo, extra_env=extra_env)

    try:
      git.PushWithRetry(
          push_branch, self.tryjob_repo, retries=3, dryrun=dryrun)
    except cros_build_lib.RunCommandError:
      cros_build_lib.Error(
          'Failed to submit tryjob.  This could be due to too many '
          'submission requests by users.  Please try again.')
      raise
예제 #6
0
def main(argv):
    parser = optparse.OptionParser(usage='usage: %prog add [options] <name> '
                                   '<--workon | <path> --remote <remote> >')
    parser.add_option('-w',
                      '--workon',
                      action='store_true',
                      dest='workon',
                      default=False,
                      help='Is this a workon package?')
    parser.add_option('-r', '--remote', dest='remote', default=None)
    parser.add_option('-v',
                      '--revision',
                      dest='revision',
                      default=None,
                      help="Use to override the manifest defined default "
                      "revision used for a given project.")
    parser.add_option('--upgrade-minilayout',
                      default=False,
                      action='store_true',
                      help="Upgrade a minilayout checkout into a full.xml "
                      "checkout utilizing manifest groups.")
    (options, args) = parser.parse_args(argv)

    repo_dir = git.FindRepoDir(os.getcwd())
    if not repo_dir:
        parser.error("This script must be invoked from within a repository "
                     "checkout.")

    options.git_config = os.path.join(repo_dir, 'manifests.git', 'config')
    options.repo_dir = repo_dir
    options.local_manifest_path = os.path.join(repo_dir, 'local_manifest.xml')
    # This constant is used only when we're doing an upgrade away from
    # minilayout.xml to default.xml.
    options.default_manifest_path = os.path.join(repo_dir, 'manifests',
                                                 'default.xml')
    options.manifest_sym_path = os.path.join(repo_dir, 'manifest.xml')

    active_manifest = os.path.basename(os.readlink(options.manifest_sym_path))
    upgrade_required = active_manifest == 'minilayout.xml'

    if options.upgrade_minilayout:
        if args:
            parser.error("--upgrade-minilayout takes no arguments.")
        if not upgrade_required:
            print "This repository checkout isn't using minilayout.xml; nothing to do"
        else:
            _UpgradeMinilayout(options)
        return 0
    elif upgrade_required:
        logging.warn(
            "Your repository checkout is using the old minilayout.xml workflow; "
            "auto-upgrading it.")
        cros_build_lib.RunCommand([sys.argv[0], '--upgrade-minilayout'],
                                  cwd=os.getcwd(),
                                  print_cmd=False)

    if not args:
        parser.error("No command specified.")
    elif args[0] != 'add':
        parser.error("Only supported subcommand is add right now.")
    elif options.workon:
        if len(args) != 2:
            parser.error(
                "Argument count is wrong for --workon; must be add <project>")
        name, path = args[1], None
    else:
        if options.remote is None:
            parser.error('Adding non-workon projects requires a remote.')
        elif len(args) != 3:
            parser.error("Argument count is wrong for non-workon mode; "
                         "must be add <project> <path> --remote <remote-arg>")
        name, path = args[1:]

    revision = options.revision
    if revision is not None:
        if (not git.IsRefsTags(revision) and not git.IsSHA1(revision)):
            revision = git.StripRefsHeads(revision, False)

    main_manifest = Manifest.FromPath(options.manifest_sym_path,
                                      empty_if_missing=False)
    local_manifest = Manifest.FromPath(options.local_manifest_path)

    main_element = main_manifest.GetProject(name, path=path)

    if options.workon:
        if main_element is None:
            parser.error('No project named %r in the default manifest.' % name)
        _AddProjectsToManifestGroups(options, main_element.attrib['name'])

    elif main_element is not None:
        if options.remote is not None:
            # Likely this project wasn't meant to be remote, so workon main element
            print "Project already exists in manifest. Using that as workon project."
            _AddProjectsToManifestGroups(options, main_element.attrib['name'])
        else:
            # Conflict will occur; complain.
            parser.error(
                "Requested project name=%r path=%r will conflict with "
                "your current manifest %s" % (name, path, active_manifest))

    elif local_manifest.GetProject(name, path=path) is not None:
        parser.error("Requested project name=%r path=%r conflicts with "
                     "your local_manifest.xml" % (name, path))

    else:
        element = local_manifest.AddNonWorkonProject(name=name,
                                                     path=path,
                                                     remote=options.remote,
                                                     revision=revision)
        _AddProjectsToManifestGroups(options, element.attrib['name'])

        with open(options.local_manifest_path, 'w') as f:
            f.write(local_manifest.ToString())
    return 0
예제 #7
0
def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)

    repo_dir = git.FindRepoDir(os.getcwd())
    if not repo_dir:
        parser.error("This script must be invoked from within a repository "
                     "checkout.")

    options.git_config = os.path.join(repo_dir, 'manifests.git', 'config')
    options.repo_dir = repo_dir
    options.local_manifest_path = os.path.join(repo_dir, 'local_manifest.xml')
    # This constant is used only when we're doing an upgrade away from
    # minilayout.xml to default.xml.
    options.default_manifest_path = os.path.join(repo_dir, 'manifests',
                                                 'default.xml')
    options.manifest_sym_path = os.path.join(repo_dir, 'manifest.xml')

    active_manifest = os.path.basename(os.readlink(options.manifest_sym_path))
    upgrade_required = active_manifest == 'minilayout.xml'

    if options.command == 'upgrade-minilayout':
        if not upgrade_required:
            print("This repository checkout isn't using minilayout.xml; "
                  "nothing to do")
        else:
            _UpgradeMinilayout(options)
        return 0
    elif upgrade_required:
        logging.warning(
            "Your repository checkout is using the old minilayout.xml workflow; "
            "auto-upgrading it.")
        main(['upgrade-minilayout'])

    # For now, we only support the add command.
    assert options.command == 'add'
    if options.workon:
        if options.path is not None:
            parser.error('Adding workon projects do not set project.')
    else:
        if options.remote is None:
            parser.error('Adding non-workon projects requires a remote.')
        if options.path is None:
            parser.error('Adding non-workon projects requires a path.')
    name = options.project
    path = options.path

    revision = options.revision
    if revision is not None:
        if (not git.IsRefsTags(revision) and not git.IsSHA1(revision)):
            revision = git.StripRefsHeads(revision, False)

    main_manifest = Manifest.FromPath(options.manifest_sym_path,
                                      empty_if_missing=False)
    local_manifest = Manifest.FromPath(options.local_manifest_path)

    main_element = main_manifest.GetProject(name, path=path)

    if options.workon:
        if main_element is None:
            parser.error('No project named %r in the default manifest.' % name)
        _AddProjectsToManifestGroups(options, main_element.attrib['name'])

    elif main_element is not None:
        if options.remote is not None:
            # Likely this project wasn't meant to be remote, so workon main element
            print(
                "Project already exists in manifest. Using that as workon project."
            )
            _AddProjectsToManifestGroups(options, main_element.attrib['name'])
        else:
            # Conflict will occur; complain.
            parser.error(
                "Requested project name=%r path=%r will conflict with "
                "your current manifest %s" % (name, path, active_manifest))

    elif local_manifest.GetProject(name, path=path) is not None:
        parser.error("Requested project name=%r path=%r conflicts with "
                     "your local_manifest.xml" % (name, path))

    else:
        element = local_manifest.AddNonWorkonProject(name=name,
                                                     path=path,
                                                     remote=options.remote,
                                                     revision=revision)
        _AddProjectsToManifestGroups(options, element.attrib['name'])

        with open(options.local_manifest_path, 'w') as f:
            f.write(local_manifest.ToString())
    return 0