def GetSyncInstance(self):
        """Syncs the tree using one of the distributed sync logic paths.

    Returns:
      The instance of the sync stage to run.
    """
        # Determine sync class to use.  CQ overrides PFQ bits so should check it
        # first.
        if config_lib.IsCanaryType(self._run.config.build_type):
            sync_stage = self._GetStageInstance(
                sync_stages.ManifestVersionedSyncStage)
            self.completion_stage_class = (
                completion_stages.CanaryCompletionStage)
        elif (config_lib.IsPFQType(self._run.config.build_type)
              or self._run.config.build_type
              in (constants.TOOLCHAIN_TYPE, constants.FULL_TYPE,
                  constants.INCREMENTAL_TYPE)):
            sync_stage = self._GetStageInstance(
                sync_stages.MasterSlaveLKGMSyncStage)
            self.completion_stage_class = (
                completion_stages.MasterSlaveSyncCompletionStage)
        else:
            sync_stage = self._GetStageInstance(
                sync_stages.ManifestVersionedSyncStage)
            self.completion_stage_class = (
                completion_stages.ManifestVersionedSyncCompletionStage)

        self.sync_stage = sync_stage
        return self.sync_stage
Пример #2
0
 def _ShouldGenerateBlameListSinceLKGM(self):
     """Returns True if we should generate the blamelist."""
     # We want to generate the blamelist only for valid pfq types and if we are
     # building on the master branch i.e. revving the build number.
     return (self.incr_type == 'build'
             and config_lib.IsPFQType(self.build_type)
             and self.build_type != constants.CHROME_PFQ_TYPE
             and self.build_type != constants.ANDROID_PFQ_TYPE)
    def PerformStage(self):
        if not self.success:
            self.message = self.GetBuildFailureMessage()

        if not config_lib.IsPFQType(self._run.config.build_type):
            # Update the pass/fail status in the manifest-versions
            # repo. Suite scheduler checks the build status to schedule
            # suites.
            self._run.attrs.manifest_manager.UpdateStatus(
                success_map=GetBuilderSuccessMap(self._run, self.success),
                message=self.message)
Пример #4
0
  def Perform(self):
    """Write and commit *BINHOST.conf files."""
    # Common args we generate for all types of builds.
    generated_args = self._GenerateCommonArgs()
    # Args we specifically add for public/private build types.
    public_args, private_args = [], []
    # Gather public/private (slave) builders.
    public_builders, private_builders = [], []

    # Distributed builders that use manifest-versions to sync with one another
    # share prebuilt logic by passing around versions.
    assert config_lib.IsPFQType(self._prebuilt_type)

    # Public pfqs should upload host preflight prebuilts.
    public_args.append('--sync-host')

    # Update all the binhost conf files.
    generated_args.append('--sync-binhost-conf')

    slave_configs = self._run.site_config.GetSlavesForMaster(
        self._run.config, self._run.options)
    experimental_builders = self._run.attrs.metadata.GetValueWithDefault(
        constants.METADATA_EXPERIMENTAL_BUILDERS, [])
    for slave_config in slave_configs:
      if slave_config in experimental_builders:
        continue
      if slave_config['prebuilts'] == constants.PUBLIC:
        public_builders.append(slave_config['name'])
        public_args.extend(self._AddOptionsForSlave(slave_config))
      elif slave_config['prebuilts'] == constants.PRIVATE:
        private_builders.append(slave_config['name'])
        private_args.extend(self._AddOptionsForSlave(slave_config))

    # Upload the public prebuilts, if any.
    if public_builders:
      UploadPrebuilts(
          category=self._prebuilt_type, chrome_rev=self._chrome_rev,
          private_bucket=False, buildroot=self._build_root, board=None,
          extra_args=generated_args + public_args)

    # Upload the private prebuilts, if any.
    if private_builders:
      UploadPrebuilts(
          category=self._prebuilt_type, chrome_rev=self._chrome_rev,
          private_bucket=True, buildroot=self._build_root, board=None,
          extra_args=generated_args + private_args)

    # If we're the Chrome PFQ master, update our binhost JSON file.
    if self._run.config.build_type == constants.CHROME_PFQ_TYPE:
      commands.UpdateBinhostJson(self._build_root)
    def HandleSuccess(self):
        if self._run.config.master:
            self.sync_stage.pool.SubmitPool(
                reason=constants.STRATEGY_CQ_SUCCESS)
            if config_lib.IsPFQType(self._run.config.build_type):
                super(CommitQueueCompletionStage, self).HandleSuccess()

        manager = self._run.attrs.manifest_manager
        version = manager.current_version
        if version:
            chroot_manager = chroot_lib.ChrootManager(self._build_root)
            chroot_manager.SetChrootVersion(version)

        self._RecordSubmissionMetrics()
 def testChromeRev(self):
     """Verify chrome_rev has an expected value"""
     for build_name, config in self.site_config.items():
         self.assertTrue(
             config['chrome_rev']
             in constants.VALID_CHROME_REVISIONS + [None],
             'Config %s: has unexpected chrome_rev value.' % build_name)
         self.assertFalse(
             config['chrome_rev'] == constants.CHROME_REV_LOCAL,
             'Config %s: has unexpected chrome_rev_local value.' %
             build_name)
         if config['chrome_rev']:
             self.assertTrue(
                 config_lib.IsPFQType(config['build_type']),
                 'Config %s: has chrome_rev but is not a PFQ.' % build_name)
    def HandleSuccess(self):
        """Handle a successful build.

    This function is called whenever the cbuildbot run is successful.
    For the master, this will only be called when all slave builders
    are also successful. This function may be overridden by subclasses.
    """
        # We only promote for the pfq, not chrome pfq.
        # TODO(build): Run this logic in debug mode too.
        if (not self._run.options.debug
                and config_lib.IsPFQType(self._run.config.build_type)
                and self._run.config.master
                and self._run.manifest_branch == 'master'):
            self._run.attrs.manifest_manager.PromoteCandidate()
            if sync_stages.MasterSlaveLKGMSyncStage.external_manager:
                sync_stages.MasterSlaveLKGMSyncStage.external_manager.PromoteCandidate(
                )
Пример #8
0
    def GetSyncInstance(self):
        """Syncs the tree using one of the distributed sync logic paths.

    Returns:
      The instance of the sync stage to run.
    """
        # Determine sync class to use.  CQ overrides PFQ bits so should check it
        # first.
        if self._run.config.pre_cq:
            sync_stage = self._GetStageInstance(sync_stages.PreCQSyncStage,
                                                self.patch_pool.gerrit_patches)
            self.completion_stage_class = completion_stages.PreCQCompletionStage
            self.patch_pool.gerrit_patches = []
        elif config_lib.IsCQType(self._run.config.build_type):
            if self._run.config.do_not_apply_cq_patches:
                sync_stage = self._GetStageInstance(
                    sync_stages.MasterSlaveLKGMSyncStage)
            else:
                sync_stage = self._GetStageInstance(
                    sync_stages.CommitQueueSyncStage)
            self.completion_stage_class = completion_stages.CommitQueueCompletionStage
        elif config_lib.IsPFQType(self._run.config.build_type):
            sync_stage = self._GetStageInstance(
                sync_stages.MasterSlaveLKGMSyncStage)
            self.completion_stage_class = (
                completion_stages.MasterSlaveSyncCompletionStage)
        elif config_lib.IsCanaryType(self._run.config.build_type):
            sync_stage = self._GetStageInstance(
                sync_stages.ManifestVersionedSyncStage)
            self.completion_stage_class = (
                completion_stages.CanaryCompletionStage)
        elif self._run.config.build_type == constants.TOOLCHAIN_TYPE:
            sync_stage = self._GetStageInstance(
                sync_stages.MasterSlaveLKGMSyncStage)
            self.completion_stage_class = (
                completion_stages.MasterSlaveSyncCompletionStage)
        else:
            sync_stage = self._GetStageInstance(
                sync_stages.ManifestVersionedSyncStage)
            self.completion_stage_class = (
                completion_stages.ManifestVersionedSyncCompletionStage)

        self.sync_stage = sync_stage
        return self.sync_stage
Пример #9
0
    def GetSyncInstance(self):
        """Syncs the tree using one of the distributed sync logic paths.

    Returns:
      The instance of the sync stage to run.
    """
        # Determine sync class to use.  CQ overrides PFQ bits so should check it
        # first.
        if self._run.config.pre_cq:
            assert False, 'Pre-CQ no longer supported'
        elif config_lib.IsCQType(self._run.config.build_type):
            assert False, 'Legacy CQ no longer supported'
            if self._run.config.do_not_apply_cq_patches:
                sync_stage = self._GetStageInstance(
                    sync_stages.MasterSlaveLKGMSyncStage)
        elif config_lib.IsCanaryType(self._run.config.build_type):
            sync_stage = self._GetStageInstance(
                sync_stages.ManifestVersionedSyncStage)
            self.completion_stage_class = (
                completion_stages.CanaryCompletionStage)
        elif self._run.config.build_type == constants.CHROME_PFQ_TYPE:
            assert False, 'Chrome PFQ no longer supported'
        elif (config_lib.IsPFQType(self._run.config.build_type)
              or self._run.config.build_type
              in (constants.TOOLCHAIN_TYPE, constants.FULL_TYPE,
                  constants.INCREMENTAL_TYPE, constants.POSTSUBMIT_TYPE)):
            sync_stage = self._GetStageInstance(
                sync_stages.MasterSlaveLKGMSyncStage)
            self.completion_stage_class = (
                completion_stages.MasterSlaveSyncCompletionStage)
        else:
            sync_stage = self._GetStageInstance(
                sync_stages.ManifestVersionedSyncStage)
            self.completion_stage_class = (
                completion_stages.ManifestVersionedSyncCompletionStage)

        self.sync_stage = sync_stage
        return self.sync_stage
Пример #10
0
    def _HandleStageException(self, exc_info):
        """Override and don't set status to FAIL but FORGIVEN instead."""
        exc_type = exc_info[0]

        # If the suite config says HW Tests can only warn, only warn.
        if self.suite_config.warn_only:
            return self._HandleExceptionAsWarning(exc_info)

        if self.suite_config.critical:
            return super(HWTestStage, self)._HandleStageException(exc_info)

        if issubclass(exc_type, failures_lib.TestWarning):
            # HWTest passed with warning. All builders should pass.
            logging.warning('HWTest passed with warning code.')
            return self._HandleExceptionAsWarning(exc_info)
        elif issubclass(exc_type, failures_lib.BoardNotAvailable):
            # Some boards may not have been setup in the lab yet for
            # non-code-checkin configs.
            if not config_lib.IsPFQType(self._run.config.build_type):
                logging.info('HWTest did not run because the board was not '
                             'available in the lab yet')
                return self._HandleExceptionAsSuccess(exc_info)

        return super(HWTestStage, self)._HandleStageException(exc_info)
Пример #11
0
  def GenerateCommonArgs(self):
    """Generate common prebuilt arguments."""
    generated_args = []
    if self._run.options.debug:
      generated_args.extend(['--debug', '--dry-run'])

    profile = self._run.options.profile or self._run.config.profile
    if profile:
      generated_args.extend(['--profile', profile])

    # Generate the version if we are a manifest_version build.
    if self._run.config.manifest_version:
      version = self._run.GetVersion()
    else:
      version = self.prebuilts_version
    if version is not None:
      generated_args.extend(['--set-version', version])

    if self._run.config.git_sync:
      # Git sync should never be set for pfq type builds.
      assert not config_lib.IsPFQType(self._prebuilt_type)
      generated_args.extend(['--git-sync'])

    return generated_args
Пример #12
0
def UploadPrebuilts(category, chrome_rev, private_bucket, buildroot,
                    version=None, **kwargs):
  """Upload Prebuilts for non-dev-installer use cases.

  Args:
    category: Build type. Can be [binary|full|chrome|chroot|paladin].
    chrome_rev: Chrome_rev of type constants.VALID_CHROME_REVISIONS.
    private_bucket: True if we are uploading to a private bucket.
    buildroot: The root directory where the build occurs.
    version: Specific version to set.
    board: Board type that was built on this machine.
    extra_args: Extra args to pass to prebuilts script.
  """
  extra_args = ['--prepend-version', category]
  extra_args.extend(['--upload', 'gs://chromeos-prebuilt'])
  if private_bucket:
    extra_args.extend(['--private', '--binhost-conf-dir',
                       PRIVATE_BINHOST_CONF_DIR])
  else:
    extra_args.extend(['--binhost-conf-dir', PUBLIC_BINHOST_CONF_DIR])

  if version is not None:
    extra_args.extend(['--set-version', version])

  if category == constants.CHROOT_BUILDER_TYPE:
    extra_args.extend(['--sync-host',
                       '--upload-board-tarball'])
    tarball_location = os.path.join(buildroot, 'built-sdk.tar.xz')
    extra_args.extend(['--prepackaged-tarball', tarball_location])

    # Find toolchain overlay tarballs of the form
    # built-sdk-overlay-toolchains-<toolchains_spec>.tar.* and create an upload
    # specification for each of them. The upload path template has the form
    # cros-sdk-overlay-toolchains-<toolchain_spec>-<version>.tar.*.
    toolchain_overlay_paths = GetToolchainSdkPaths(buildroot, is_overlay=True)
    if toolchain_overlay_paths:
      # Only add the upload path arg when processing the first tarball.
      extra_args.extend([
          '--toolchains-overlay-upload-path',
          GetToolchainSdkUploadFormat(
              version, toolchain_overlay_paths[0][1], is_overlay=True)])
      for entry in toolchain_overlay_paths:
        extra_args.extend(['--toolchains-overlay-tarball', '%s:%s' % entry])

    # Find toolchain package tarballs of the form <target>.tar.* and create an
    # upload specificion for each fo them. The upload path template has the
    # form <target>-<version>.tar.*.
    toolchain_paths = GetToolchainSdkPaths(buildroot)
    if toolchain_paths:
      # Only add the path arg when processing the first tarball.  We do
      # this to get access to the tarball suffix dynamically (so it can
      # change and this code will still work).
      extra_args.extend([
          '--toolchain-upload-path',
          GetToolchainSdkUploadFormat(version, toolchain_paths[0][1])])
      for entry in toolchain_paths:
        extra_args.extend(['--toolchain-tarball', '%s:%s' % entry])

  if category == constants.CHROME_PFQ_TYPE:
    assert chrome_rev
    key = '%s_%s' % (chrome_rev, _CHROME_BINHOST)
    extra_args.extend(['--key', key.upper()])
  elif config_lib.IsPFQType(category):
    extra_args.extend(['--key', _PREFLIGHT_BINHOST])
  else:
    assert category in (constants.BUILD_FROM_SOURCE_TYPE,
                        constants.CHROOT_BUILDER_TYPE)
    extra_args.extend(['--key', _FULL_BINHOST])

  if category == constants.CHROME_PFQ_TYPE:
    extra_args += ['--packages=%s' % x
                   for x in ([constants.CHROME_PN] +
                             constants.OTHER_CHROME_PACKAGES)]

  kwargs.setdefault('extra_args', []).extend(extra_args)
  return _UploadPrebuilts(buildroot=buildroot, **kwargs)
Пример #13
0
  def PerformStage(self):
    """Uploads prebuilts for master and slave builders."""
    prebuilt_type = self._prebuilt_type
    board = self._current_board
    binhosts = []

    # Whether we publish public or private prebuilts.
    public = self._run.config.prebuilts == constants.PUBLIC
    # Common args we generate for all types of builds.
    generated_args = self.GenerateCommonArgs()
    # Args we specifically add for public/private build types.
    public_args, private_args = [], []
    # Public / private builders.
    public_builders, private_builders = [], []

    # Distributed builders that use manifest-versions to sync with one another
    # share prebuilt logic by passing around versions.
    if config_lib.IsPFQType(prebuilt_type):
      # Public pfqs should upload host preflight prebuilts.
      if prebuilt_type != constants.CHROME_PFQ_TYPE:
        public_args.append('--sync-host')

      # Deduplicate against previous binhosts.
      binhosts.extend(self._GetPortageEnvVar(_PORTAGE_BINHOST, board).split())
      binhosts.extend(self._GetPortageEnvVar(_PORTAGE_BINHOST, None).split())
      for binhost in filter(None, binhosts):
        generated_args.extend(['--previous-binhost-url', binhost])

      if self._run.config.master and board == self._boards[-1]:
        # The master builder updates all the binhost conf files, and needs to do
        # so only once so as to ensure it doesn't try to update the same file
        # more than once. As multiple boards can be built on the same builder,
        # we arbitrarily decided to update the binhost conf files when we run
        # upload_prebuilts for the last board. The other boards are treated as
        # slave boards.
        generated_args.append('--sync-binhost-conf')
        for c in self._GetSlaveConfigs():
          if c['prebuilts'] == constants.PUBLIC:
            public_builders.append(c['name'])
            public_args.extend(self._AddOptionsForSlave(c, board))
          elif c['prebuilts'] == constants.PRIVATE:
            private_builders.append(c['name'])
            private_args.extend(self._AddOptionsForSlave(c, board))

    common_kwargs = {
        'buildroot': self._build_root,
        'category': prebuilt_type,
        'chrome_rev': self._chrome_rev,
        'version': self.prebuilts_version,
    }

    # Upload the public prebuilts, if any.
    if public_builders or public:
      public_board = board if public else None
      prebuilts.UploadPrebuilts(
          private_bucket=False, board=public_board,
          extra_args=generated_args + public_args,
          **common_kwargs)

    # Upload the private prebuilts, if any.
    if private_builders or not public:
      private_board = board if not public else None
      prebuilts.UploadPrebuilts(
          private_bucket=True, board=private_board,
          extra_args=generated_args + private_args,
          **common_kwargs)
Пример #14
0
def UploadPrebuilts(category,
                    chrome_rev,
                    private_bucket,
                    buildroot,
                    version=None,
                    **kwargs):
    """Upload Prebuilts for non-dev-installer use cases.

  Args:
    category: Build type. Can be [binary|full|chrome|chroot|paladin].
    chrome_rev: Chrome_rev of type constants.VALID_CHROME_REVISIONS.
    private_bucket: True if we are uploading to a private bucket.
    buildroot: The root directory where the build occurs.
    version: Specific version to set.
    board: Board type that was built on this machine.
    extra_args: Extra args to pass to prebuilts script.
  """
    extra_args = ['--prepend-version', category]
    extra_args.extend(['--upload', 'gs://chromeos-prebuilt'])
    if private_bucket:
        extra_args.extend(
            ['--private', '--binhost-conf-dir', _PRIVATE_BINHOST_CONF_DIR])
    else:
        extra_args.extend(['--binhost-conf-dir', _PUBLIC_BINHOST_CONF_DIR])

    if version is not None:
        extra_args.extend(['--set-version', version])

    if category == constants.CHROOT_BUILDER_TYPE:
        extra_args.extend(['--sync-host', '--upload-board-tarball'])
        tarball_location = os.path.join(buildroot, 'built-sdk.tar.xz')
        extra_args.extend(['--prepackaged-tarball', tarball_location])

        # Remaining artifacts get uploaded into <year>/<month>/ subdirs so we don't
        # start dumping even more stuff into the top level. Also, the following
        # code handles any tarball suffix (.tar.*). For each of the artifact types
        # below, we also generate a single upload path template to be filled by the
        # uploading script. This has placeholders for the version (substituted
        # first) and another qualifier (either board or target, substituted second
        # and therefore uses a quoted %% modifier).
        # TODO(garnold) Using a mix of quoted/unquoted template variables is
        # confusing and error-prone, we should get rid of it.
        # TODO(garnold) Be specific about matching file suffixes, like making sure
        # there's nothing past the compression suffix (for example, .tar.xz.log).
        subdir_prefix = os.path.join(*version.split('.')[0:2])

        # Find toolchain overlay tarballs of the form
        # built-sdk-overlay-toolchains-<toolchains_spec>.tar.* and create an upload
        # specification for each of them. The upload path template has the form
        # cros-sdk-overlay-toolchains-<toolchain_spec>-<version>.tar.*.
        toolchains_overlay_prefix = 'built-sdk-overlay-toolchains-'
        for tarball in glob.glob(
                os.path.join(buildroot, constants.DEFAULT_CHROOT_DIR,
                             constants.SDK_OVERLAYS_OUTPUT,
                             toolchains_overlay_prefix + '*.tar.*')):
            tarball_name, tarball_suffix = os.path.basename(tarball).split(
                '.', 1)

            # Only add the upload path arg when processing the first tarball.
            if '--toolchains-overlay-upload-path' not in extra_args:
                subdir = os.path.join(
                    subdir_prefix,
                    'cros-sdk-overlay-toolchains-%%(toolchains)s-%(version)s.'
                    + tarball_suffix)
                extra_args.extend(['--toolchains-overlay-upload-path', subdir])

            toolchains = tarball_name[len(toolchains_overlay_prefix):]
            extra_args.extend([
                '--toolchains-overlay-tarball',
                '%s:%s' % (toolchains, tarball)
            ])

        # Find toolchain package tarballs of the form <target>.tar.* and create an
        # upload specificion for each fo them. The upload path template has the
        # form <target>-<version>.tar.*.
        for tarball in glob.glob(
                os.path.join(buildroot, constants.DEFAULT_CHROOT_DIR,
                             constants.SDK_TOOLCHAINS_OUTPUT, '*.tar.*')):
            tarball_target, tarball_suffix = os.path.basename(tarball).split(
                '.', 1)

            # Only add the path arg when processing the first tarball.  We do
            # this to get access to the tarball suffix dynamically (so it can
            # change and this code will still work).
            if '--toolchain-upload-path' not in extra_args:
                subdir = os.path.join(
                    subdir_prefix, '%%(target)s-%(version)s.' + tarball_suffix)
                extra_args.extend(['--toolchain-upload-path', subdir])

            extra_args.extend(
                ['--toolchain-tarball',
                 '%s:%s' % (tarball_target, tarball)])

    if category == constants.CHROME_PFQ_TYPE:
        assert chrome_rev
        key = '%s_%s' % (chrome_rev, _CHROME_BINHOST)
        extra_args.extend(['--key', key.upper()])
    elif config_lib.IsPFQType(category):
        extra_args.extend(['--key', _PREFLIGHT_BINHOST])
    else:
        assert category in (constants.BUILD_FROM_SOURCE_TYPE,
                            constants.CHROOT_BUILDER_TYPE)
        extra_args.extend(['--key', _FULL_BINHOST])

    if category == constants.CHROME_PFQ_TYPE:
        extra_args += [
            '--packages=%s' % x
            for x in ([constants.CHROME_PN] + constants.OTHER_CHROME_PACKAGES)
        ]

    kwargs.setdefault('extra_args', []).extend(extra_args)
    return _UploadPrebuilts(buildroot=buildroot, **kwargs)
Пример #15
0
    def __init__(self,
                 source_repo,
                 manifest_repo,
                 build_names,
                 build_type,
                 incr_type,
                 force,
                 branch,
                 manifest=constants.DEFAULT_MANIFEST,
                 dry_run=True,
                 lkgm_path_rel=constants.LKGM_MANIFEST,
                 config=None,
                 metadata=None,
                 buildstore=None,
                 buildbucket_client=None):
        """Initialize an LKGM Manager.

    Args:
      source_repo: Repository object for the source code.
      manifest_repo: Manifest repository for manifest versions/buildspecs.
      build_names: Identifiers for the build. Must match config_lib
          entries. If multiple identifiers are provided, the first item in the
          list must be an identifier for the group.
      build_type: Type of build.  Must be a pfq type.
      incr_type: How we should increment this version - build|branch|patch
      force: Create a new manifest even if there are no changes.
      branch: Branch this builder is running on.
      manifest: Manifest to use for checkout. E.g. 'full' or 'buildtools'.
      dry_run: Whether we actually commit changes we make or not.
      master: Whether we are the master builder.
      lkgm_path_rel: Path to the LKGM symlink, relative to manifest dir.
      config: Instance of config_lib.BuildConfig. Config dict of this builder.
      metadata: Instance of metadata_lib.CBuildbotMetadata. Metadata of this
                builder.
      buildstore: BuildStore instance to make DB calls.
      buildbucket_client: Instance of buildbucket_lib.buildbucket_client.
    """
        super(LKGMManager,
              self).__init__(source_repo=source_repo,
                             manifest_repo=manifest_repo,
                             manifest=manifest,
                             build_names=build_names,
                             incr_type=incr_type,
                             force=force,
                             branch=branch,
                             dry_run=dry_run,
                             config=config,
                             metadata=metadata,
                             buildstore=buildstore,
                             buildbucket_client=buildbucket_client)

        self.lkgm_path = os.path.join(self.manifest_dir, lkgm_path_rel)
        self.compare_versions_fn = _LKGMCandidateInfo.VersionCompare
        self.build_type = build_type
        # Chrome PFQ and PFQ's exist at the same time and version separately so they
        # must have separate subdirs in the manifest-versions repository.
        if self.build_type == constants.ANDROID_PFQ_TYPE:
            self.rel_working_dir = self.ANDROID_PFQ_SUBDIR
        elif self.build_type == constants.TOOLCHAIN_TYPE:
            self.rel_working_dir = self.TOOLCHAIN_SUBDIR
        elif self.build_type == constants.FULL_TYPE:
            self.rel_working_dir = self.FULL_SUBDIR
        elif self.build_type == constants.INCREMENTAL_TYPE:
            self.rel_working_dir = self.INCREMENTAL_SUBDIR
        else:
            assert config_lib.IsPFQType(self.build_type)
            self.rel_working_dir = self.LKGM_SUBDIR
Пример #16
0
    def CreateNewCandidate(self,
                           validation_pool=None,
                           android_version=None,
                           chrome_version=None,
                           retries=manifest_version.NUM_RETRIES,
                           build_id=None):
        """Creates, syncs to, and returns the next candidate manifest.

    Args:
      validation_pool: Validation pool to apply to the manifest before
        publishing.
      android_version: The Android version to write in the manifest. Defaults
        to None, in which case no version is written.
      chrome_version: The Chrome version to write in the manifest. Defaults
        to None, in which case no version is written.
      retries: Number of retries for updating the status. Defaults to
        manifest_version.NUM_RETRIES.
      build_id: Optional integer cidb id of the build that is creating
                this candidate.

    Raises:
      GenerateBuildSpecException in case of failure to generate a buildspec
    """
        self.CheckoutSourceCode()

        # Refresh manifest logic from manifest_versions repository to grab the
        # LKGM to generate the blamelist.
        version_info = self.GetCurrentVersionInfo()
        self.RefreshManifestCheckout()
        self.InitializeManifestVariables(version_info)

        has_chump_cls = self.GenerateBlameListSinceLKGM()

        # Throw away CLs that might not be used this run.
        if validation_pool:
            validation_pool.has_chump_cls = has_chump_cls
            validation_pool.FilterChangesForThrottledTree()

            # Apply any manifest CLs (internal or exteral).
            validation_pool.ApplyPoolIntoRepo(
                filter_fn=trybot_patch_pool.ManifestFilter)

            manifest_dir = os.path.join(validation_pool.build_root,
                                        'manifest-internal')

            if not os.path.exists(manifest_dir):
                # Fall back to external manifest directory.
                manifest_dir = os.path.join(validation_pool.build_root,
                                            'manifest')

            # This is only needed if there were internal manifest changes, but we
            # always run it to make sure this logic works.
            self._AdjustRepoCheckoutToLocalManifest(manifest_dir)

        new_manifest = self.CreateManifest()

        # For Android PFQ, add the version of Android to use.
        if android_version:
            self._AddAndroidVersionToManifest(new_manifest, android_version)

        # For Chrome PFQ, add the version of Chrome to use.
        if chrome_version:
            self._AddChromeVersionToManifest(new_manifest, chrome_version)

        # For the Commit Queue, apply the validation pool as part of checkout.
        if validation_pool:
            # If we have nothing that could apply from the validation pool and
            # we're not also a pfq type, we got nothing to do.
            assert self.cros_source.directory == validation_pool.build_root
            if (not validation_pool.ApplyPoolIntoRepo()
                    and not config_lib.IsPFQType(self.build_type)):
                return None

            self._AddPatchesToManifest(new_manifest, validation_pool)

            # Add info about the last known good version to the manifest. This will
            # be used by slaves to calculate what artifacts from old builds are safe
            # to use.
            self._AddLKGMToManifest(new_manifest)

        last_error = None
        for attempt in range(0, retries + 1):
            try:
                # Refresh manifest logic from manifest_versions repository.
                # Note we don't need to do this on our first attempt as we needed to
                # have done it to get the LKGM.
                if attempt != 0:
                    self.RefreshManifestCheckout()
                    self.InitializeManifestVariables(version_info)

                # If we don't have any valid changes to test, make sure the checkout
                # is at least different.
                if ((not validation_pool or not validation_pool.applied)
                        and not self.force and self.HasCheckoutBeenBuilt()):
                    return None

                # Check whether the latest spec available in manifest-versions is
                # newer than our current version number. If so, use it as the base
                # version number. Otherwise, we default to 'rc1'.
                if self.latest:
                    latest = max(self.latest,
                                 version_info.VersionString(),
                                 key=self.compare_versions_fn)
                    version_info = _LKGMCandidateInfo(
                        latest,
                        chrome_branch=version_info.chrome_branch,
                        incr_type=self.incr_type)

                git.CreatePushBranch(manifest_version.PUSH_BRANCH,
                                     self.manifest_dir,
                                     sync=False)
                version = self.GetNextVersion(version_info)
                self.PublishManifest(new_manifest, version, build_id=build_id)
                self.current_version = version
                return self.GetLocalManifest(version)
            except cros_build_lib.RunCommandError as e:
                err_msg = 'Failed to generate LKGM Candidate. error: %s' % e
                logging.error(err_msg)
                last_error = err_msg

        raise manifest_version.GenerateBuildSpecException(last_error)