예제 #1
0
    def ConstructDashboardURL(self, stage=None):
        """Return the dashboard URL

    This is the direct link to buildbot logs as seen in build.chromium.org

    Args:
      stage: Link to a specific |stage|, otherwise the general buildbot log

    Returns:
      The fully formed URL
    """
        return tree_status.ConstructDashboardURL(self.GetBuildbotUrl(),
                                                 self.GetBuilderName(),
                                                 self.options.buildnumber,
                                                 stage=stage)
예제 #2
0
    def PerformStage(self):
        if not self._run.config.master:
            logging.info('This stage is only meaningful for master builds. '
                         'Doing nothing.')
            return

        build_id, db = self._run.GetCIDBHandle()

        if not db:
            logging.info('No cidb connection for this build. '
                         'Doing nothing.')
            return

        slave_failures = db.GetSlaveFailures(build_id)
        failures_by_build = cros_build_lib.GroupByKey(slave_failures,
                                                      'build_id')
        for build_id, build_failures in sorted(failures_by_build.items()):
            failures_by_stage = cros_build_lib.GroupByKey(
                build_failures, 'build_stage_id')
            # Surface a link to each slave stage that failed, in stage_id sorted
            # order.
            for stage_id in sorted(failures_by_stage):
                failure = failures_by_stage[stage_id][0]
                # Ignore failures that did not cause their enclosing stage to fail.
                # Ignore slave builds that are still inflight, because some stage logs
                # might not have been printed to buildbot yet.
                # TODO(akeshet) revisit this approach, if we seem to be suppressing
                # useful information as a result of it.
                if (failure['stage_status'] != constants.BUILDER_STATUS_FAILED
                        or failure['build_status']
                        == constants.BUILDER_STATUS_INFLIGHT):
                    continue
                waterfall_url = constants.WATERFALL_TO_DASHBOARD[
                    failure['waterfall']]
                slave_stage_url = tree_status.ConstructDashboardURL(
                    waterfall_url, failure['builder_name'],
                    failure['build_number'], failure['stage_name'])
                logging.PrintBuildbotLink(
                    '%s %s' % (failure['build_config'], failure['stage_name']),
                    slave_stage_url)
예제 #3
0
    def PerformStage(self):
        if self._run.config['doc']:
            logging.PrintBuildbotLink('Builder documentation',
                                      self._run.config['doc'])

        WriteBasicMetadata(self._run)
        WriteTagMetadata(self._run)

        # This is a heuristic value for |important|, since patches that get applied
        # later in the build might change the config. We write it now anyway,
        # because in case the build fails before Sync, it is better to have this
        # heuristic value than None. In BuildReexectuionFinishedStage, we re-write
        # the definitive value.
        self._run.attrs.metadata.UpdateWithDict(
            {'important': self._run.config['important']})

        d = self._run.attrs.metadata.GetDict()

        # BuildStartStage should only run once per build. But just in case it
        # is somehow running a second time, we do not want to insert an additional
        # database entry. Detect if a database entry has been inserted already
        # and if so quit the stage.
        if 'build_id' in d:
            logging.info('Already have build_id %s, not inserting an entry.',
                         d['build_id'])
            return

        graphite.StatsFactory.GetInstance().Counter('build_started').increment(
            self._run.config['name'] or 'NO_CONFIG')

        # Note: In other build stages we use self._run.GetCIDBHandle to fetch
        # a cidb handle. However, since we don't yet have a build_id, we can't
        # do that here.
        if cidb.CIDBConnectionFactory.IsCIDBSetup():
            db_type = cidb.CIDBConnectionFactory.GetCIDBConnectionType()
            db = cidb.CIDBConnectionFactory.GetCIDBConnectionForBuilder()
            if db:
                waterfall = d['buildbot-master-name']
                assert waterfall in constants.CIDB_KNOWN_WATERFALLS
                build_id = db.InsertBuild(
                    builder_name=d['builder-name'],
                    waterfall=waterfall,
                    build_number=d['build-number'],
                    build_config=d['bot-config'],
                    bot_hostname=d['bot-hostname'],
                    master_build_id=d['master_build_id'],
                    timeout_seconds=self._GetBuildTimeoutSeconds(),
                    important=d['important'],
                    buildbucket_id=self._run.options.buildbucket_id)
                self._run.attrs.metadata.UpdateWithDict({
                    'build_id': build_id,
                    'db_type': db_type
                })
                logging.info(
                    'Inserted build_id %s into cidb database type %s.',
                    build_id, db_type)
                logging.PrintBuildbotStepText('database: %s, build_id: %s' %
                                              (db_type, build_id))

                master_build_id = d['master_build_id']
                if master_build_id is not None:
                    master_build_status = db.GetBuildStatus(master_build_id)
                    master_waterfall_url = constants.WATERFALL_TO_DASHBOARD[
                        master_build_status['waterfall']]

                    master_url = tree_status.ConstructDashboardURL(
                        master_waterfall_url,
                        master_build_status['builder_name'],
                        master_build_status['build_number'])
                    logging.PrintBuildbotLink('Link to master build',
                                              master_url)