Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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))
Ejemplo n.º 3
0
    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!")
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    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))
Ejemplo n.º 6
0
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))
Ejemplo n.º 7
0
 def load_job(data):
     try:
         return json.loads(data)
     except ValueError as e:
         raise BadJobfile("Failed to parse job JSON: %s" % (e.message, ))