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)
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)
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)