def _gotChangeImpl(self, change, _important): """Process the received data and send the queue buildset.""" # Find poller that this change came from. for poller in self.pollers: if not isinstance(poller, gitiles_poller.GitilesPoller): continue if poller.repo_url == change.repository: break else: raise BadJobfile('Received tryjob from unsupported repository %s' % change.repository) # pylint: disable=W0631 file_contents = yield self.loadGitilesChangeFile(poller, change) parsed = {} try: parsed = self.load_job(file_contents) self.validate_job(parsed) self.updateJobDesc(parsed) except BadJobfile as e: self.send_validation_fail_email(parsed.setdefault('name', ''), parsed['email'], str(e)) raise # The sourcestamp/buildsets created will be merge-able. ssid = yield self.master.db.sourcestamps.addSourceStamp( branch=change.branch, revision=change.revision, project=change.project, repository=change.repository, changeids=[change.number]) yield self.create_buildset(ssid, parsed)
def validate_job(self, parsed_job): # A list of field description tuples of the format: # (name, type, required). fields = [ ('name', basestring, True), ('user', basestring, True), ('email', list, True), ('bot', list, True), ('extra_args', list, False), ('version', int, True), ('slaves_request', list, False), ] error_msgs = [] for name, f_type, required in fields: val = parsed_job.get(name) if val is None: if required: error_msgs.append('Option %s missing!' % name) elif not isinstance(val, f_type): error_msgs.append('Option %s of wrong type!' % name) # If we're an 'etc' job, we must have bots defined to execute. for bot in parsed_job['bot']: if bot in self.cbb.configs: continue # Assert that this is a valid 'etc' build. try: self.cbb.ValidateEtcBuild(bot) except ValueError as e: error_msgs.append("Invalid 'etc' build (%s): %s" % (bot, e.message)) if error_msgs: raise BadJobfile('\n'.join(error_msgs))
def gotChange(self, change, important): """Process the received data and send the queue buildset.""" # Implicitly skips over non-files like directories. if len(change.files) != 1: # We only accept changes with 1 diff file. raise BadJobfile('Try job with too many files %s' % (','.join(change.files))) # Find poller that this change came from. for poller in self.pollers: if poller.repourl == change.repository: break else: raise BadJobfile('Received tryjob from unsupported repository %s' % change.repository) # pylint: disable=W0631 wfd = defer.waitForDeferred( get_file_contents(poller, change.branch, change.files[0])) yield wfd parsed = None try: parsed = self.load_job(wfd.getResult()) self.validate_job(parsed) self.updateJobDesc(parsed) except BadJobfile as e: self.send_validation_fail_email(parsed.setdefault('name', ''), parsed['email'], str(e)) raise except Exception as e: print 'EXCEPTION:', e import traceback traceback.print_exc() raise # The sourcestamp/buildsets created will be merge-able. d = self.master.db.sourcestamps.addSourceStamp( branch=change.branch, revision=change.revision, project=change.project, repository=change.repository, changeids=[change.number]) d.addCallback(self.create_buildset, parsed) d.addErrback(log.err, "Failed to queue a try job!")
def translate_v2_to_v3(parsed_job): """Translate tryjob desc from V2 to V3.""" # V3 --remote-patches format is not backwards compatible. if any(a.startswith('--remote-patches') for a in parsed_job['extra_args']): raise BadJobfile( 'Cannot translate --remote-patches from tryjob v.2 to ' 'v.3. Please run repo sync.') parsed_job['version'] = 3
def loadGitilesChangeFile(self, poller, change): if len(change.files) != 1: # We only accept changes with 1 diff file. raise BadJobfile('Try job with too many files %s' % (','.join(change.files))) # Load the contents of the modified file. path = self._GITILES_PATH_TMPL % { 'repo': poller.repo_path, 'revision': change.revision, 'path': change.files[0], } contents_b64 = yield poller.agent.request('GET', path, retry=5, protocol=StringResponse.Get) defer.returnValue(base64.b64decode(contents_b64))
def validate_job(parsed_job): # A list of field description tuples of the format: # (name, type, required). fields = [('name', basestring, True), ('user', basestring, True), ('email', list, True), ('bot', list, True), ('extra_args', list, False), ('version', int, True), ('slaves_request', list, False)] error_msgs = [] for name, f_type, required in fields: val = parsed_job.get(name) if val is None: if required: error_msgs.append('Option %s missing!' % name) elif not isinstance(val, f_type): error_msgs.append('Option %s of wrong type!' % name) if error_msgs: raise BadJobfile('\n'.join(error_msgs))
def load_job(data): try: return json.loads(data) except ValueError as e: raise BadJobfile("Failed to parse job JSON: %s" % (e.message, ))