def _PutConfigToBuildBucket(self, buildbucket_client, dryrun): """Put the tryjob request to buildbucket. Args: buildbucket_client: The buildbucket client instance. dryrun: bool controlling dryrun behavior. Returns: ScheduledBuild describing the scheduled build. Raises: RemoteRequestFailure. """ request_body = self._GetRequestBody() content = buildbucket_client.PutBuildRequest(json.dumps(request_body), dryrun) if buildbucket_lib.GetNestedAttr(content, ['error']): raise RemoteRequestFailure( 'buildbucket error.\nReason: %s\n Message: %s' % (buildbucket_lib.GetErrorReason(content), buildbucket_lib.GetErrorMessage(content))) buildbucket_id = buildbucket_lib.GetBuildId(content) url = uri_lib.ConstructMiloBuildUri(buildbucket_id) created_ts = buildbucket_lib.GetBuildCreated_ts(content) result = ScheduledBuild(self.bucket, buildbucket_id, self.build_config, url, created_ts) logging.info(self.BUILDBUCKET_PUT_RESP_FORMAT, result._asdict()) return result
def ConstructDashboardURL(self, stage=None): """Return the dashboard URL This is the direct link to logdog logs if given a stage, or the link to the legoland build page for the build. Args: stage: Link to a specific |stage|, otherwise the general buildbot log Returns: The fully formed URL """ if stage: return uri_lib.ConstructLogDogUri(self.options.buildnumber, stage) else: return uri_lib.ConstructMiloBuildUri(self.options.buildbucket_id)
def PerformStage(self): if not self._run.config.master: logging.info('This stage is only meaningful for master builds. ' 'Doing nothing.') return if not self.buildstore.AreClientsReady(): logging.info('No buildstore connection for this build. ' 'Doing nothing.') return child_failures = self.buildstore.GetBuildsFailures( self.GetScheduledSlaveBuildbucketIds()) for failure in child_failures: if (failure.stage_status != constants.BUILDER_STATUS_FAILED or failure.build_status == constants.BUILDER_STATUS_INFLIGHT): continue slave_stage_url = uri_lib.ConstructMiloBuildUri( failure.buildbucket_id) 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) # 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 BuildReexecutionFinishedStage, 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 # 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 self.buildstore.AreClientsReady(): db_type = cidb.CIDBConnectionFactory.GetCIDBConnectionType() try: build_id = self.buildstore.InsertBuild( builder_name=d['builder-name'], 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, branch=self._run.manifest_branch) except Exception as e: logging.error( 'Error: %s\n If the buildbucket_id to insert is ' 'duplicated to the buildbucket_id of an old build and ' 'the old build was canceled because of a waterfall ' 'master restart, please ignore this error. Else, ' 'the error needs more investigation. More context: ' 'crbug.com/679974 and crbug.com/685889', e) raise e 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 = self.buildstore.GetBuildStatuses( build_ids=[master_build_id])[0] if master_build_status['buildbucket_id']: master_url = uri_lib.ConstructMiloBuildUri( master_build_status['buildbucket_id']) else: master_url = uri_lib.ConstructDashboardUri( master_build_status['waterfall'], master_build_status['builder_name'], master_build_status['build_number']) logging.PrintBuildbotLink('Link to master build', master_url) # Set annealing snapshot revision build property for Findit integration. if self._run.options.cbb_snapshot_revision: logging.PrintKitchenSetBuildProperty( 'GOT_REVISION', self._run.options.cbb_snapshot_revision) # Write the tag metadata last so that a build_id is available. WriteTagMetadata(self._run)
def testConstructMiloBuildURL(self): """Tests generating Legoland build URIs.""" actual = uri_lib.ConstructMiloBuildUri('bbid') expected = 'https://ci.chromium.org/b/bbid' self.assertEqual(actual, expected)