| Index: master/skia_master_scripts/monkeypatches.py
|
| diff --git a/master/skia_master_scripts/monkeypatches.py b/master/skia_master_scripts/monkeypatches.py
|
| deleted file mode 100644
|
| index 4d4a473f9c38c049e67168908571bdb3566b81ba..0000000000000000000000000000000000000000
|
| --- a/master/skia_master_scripts/monkeypatches.py
|
| +++ /dev/null
|
| @@ -1,585 +0,0 @@
|
| -# Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -
|
| -""" Monkeypatches to override upstream code. """
|
| -
|
| -
|
| -from buildbot.changes.gitpoller import GitPoller
|
| -from buildbot.process.properties import Properties
|
| -from buildbot.schedulers.trysched import BadJobfile
|
| -from buildbot.status.builder import EXCEPTION, FAILURE
|
| -from buildbot.status.web import base as webstatus_base
|
| -from buildbot.status.web.status_json import BuilderJsonResource
|
| -from buildbot.status.web.status_json import BuildersJsonResource
|
| -from buildbot.status.web.status_json import ChangeSourcesJsonResource
|
| -from buildbot.status.web.status_json import JsonResource
|
| -from buildbot.status.web.status_json import JsonStatusResource
|
| -from buildbot.status.web.status_json import MetricsJsonResource
|
| -from buildbot.status.web.status_json import ProjectJsonResource
|
| -from buildbot.status.web.status_json import SlavesJsonResource
|
| -from master import build_utils
|
| -from master import chromium_notifier
|
| -from master import gatekeeper
|
| -from master import try_job_base
|
| -from master import try_job_rietveld
|
| -from master import try_job_svn
|
| -from master.try_job_base import text_to_dict
|
| -from twisted.internet import defer
|
| -from twisted.python import log
|
| -from twisted.web import server
|
| -from webstatus import builder_statuses
|
| -
|
| -import builder_name_schema
|
| -import config_private
|
| -import json
|
| -import master_revision
|
| -import re
|
| -import slave_hosts_cfg
|
| -import slaves_cfg
|
| -import skia_vars
|
| -import utils
|
| -
|
| -
|
| -# The following users are allowed to run trybots even though they do not have
|
| -# accounts in google.com or chromium.org
|
| -TRYBOTS_REQUESTER_WHITELIST = [
|
| - 'henrik.smiding@intel.com',
|
| - 'kkinnunen@nvidia.com',
|
| - 'cdalton@nvidia.com',
|
| - 'ravimist@gmail.com'
|
| -]
|
| -
|
| -
|
| -################################################################################
|
| -############################# Trybot Monkeypatches #############################
|
| -################################################################################
|
| -
|
| -
|
| -@defer.deferredGenerator
|
| -def SubmitTryJobChanges(self, changes):
|
| - """ Override of SVNPoller.submit_changes:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/master/try_job_svn.py?view=markup
|
| -
|
| - We modify it so that the patch file url is added to the build properties.
|
| - This allows the slave to download the patch directly rather than receiving
|
| - it from the master.
|
| - """
|
| - for chdict in changes:
|
| - # pylint: disable=E1101
|
| - parsed = self.parent.parse_options(text_to_dict(chdict['comments']))
|
| -
|
| - # 'fix' revision.
|
| - # LKGR must be known before creating the change object.
|
| - wfd = defer.waitForDeferred(self.parent.get_lkgr(parsed))
|
| - yield wfd
|
| - wfd.getResult()
|
| -
|
| - wfd = defer.waitForDeferred(self.master.addChange(
|
| - author=','.join(parsed['email']),
|
| - revision=parsed['revision'],
|
| - comments='',
|
| - properties={'patch_file_url': chdict['repository'] + '/' + \
|
| - chdict['files'][0]}))
|
| - yield wfd
|
| - change = wfd.getResult()
|
| -
|
| - self.parent.addChangeInner(chdict['files'], parsed, change.number)
|
| -
|
| -try_job_svn.SVNPoller.submit_changes = SubmitTryJobChanges
|
| -
|
| -
|
| -def TryJobCreateBuildset(self, ssid, parsed_job):
|
| - """ Override of TryJobBase.create_buildset:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/master/try_job_base.py?view=markup
|
| -
|
| - We modify it to verify that the requested builders are in the builder pool for
|
| - this try scheduler. This prevents try requests from running on builders which
|
| - are not registered as trybots. This apparently isn't a problem for Chromium
|
| - since they use a separate try master.
|
| - """
|
| - log.msg('Creating try job(s) %s' % ssid)
|
| - result = None
|
| - for builder in parsed_job['bot']:
|
| - if builder in self.pools[self.name]:
|
| - result = self.addBuildsetForSourceStamp(ssid=ssid,
|
| - reason=parsed_job['name'],
|
| - external_idstring=parsed_job['name'],
|
| - builderNames=[builder],
|
| - properties=self.get_props(builder, parsed_job))
|
| - else:
|
| - log.msg('Scheduler: %s rejecting try job for builder: %s not in %s' % (
|
| - self.name,
|
| - builder,
|
| - self.pools[self.name]))
|
| - log.msg('Returning buildset: %s' % result)
|
| - return result
|
| -
|
| -try_job_base.TryJobBase.create_buildset = TryJobCreateBuildset
|
| -
|
| -
|
| -def HtmlResourceRender(self, request):
|
| - """ Override of buildbot.status.web.base.HtmlResource.render:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/third_party/buildbot_8_4p1/buildbot/status/web/base.py?view=markup
|
| -
|
| - We modify it to pass additional variables on to the web status pages, and
|
| - remove the "if False" section.
|
| - """
|
| - # tell the WebStatus about the HTTPChannel that got opened, so they
|
| - # can close it if we get reconfigured and the WebStatus goes away.
|
| - # They keep a weakref to this, since chances are good that it will be
|
| - # closed by the browser or by us before we get reconfigured. See
|
| - # ticket #102 for details.
|
| - if hasattr(request, "channel"):
|
| - # web.distrib.Request has no .channel
|
| - request.site.buildbot_service.registerChannel(request.channel)
|
| -
|
| - ctx = self.getContext(request)
|
| -
|
| - ############################## Added by borenet ##############################
|
| - status = self.getStatus(request)
|
| - all_builders = status.getBuilderNames()
|
| - all_full_category_names = set()
|
| - all_categories = set()
|
| - all_subcategories = set()
|
| - subcategories_by_category = {}
|
| - for builder_name in all_builders:
|
| - category_full = status.getBuilder(builder_name).category or 'default'
|
| - all_full_category_names.add(category_full)
|
| - category_split = category_full.split('|')
|
| - category = category_split[0]
|
| - subcategory = category_split[1] if len(category_split) > 1 else 'default'
|
| - all_categories.add(category)
|
| - all_subcategories.add(subcategory)
|
| - if not subcategories_by_category.get(category):
|
| - subcategories_by_category[category] = []
|
| - if not subcategory in subcategories_by_category[category]:
|
| - subcategories_by_category[category].append(subcategory)
|
| -
|
| - ctx['tree_status_baseurl'] = \
|
| - skia_vars.GetGlobalVariable('tree_status_baseurl')
|
| -
|
| - ctx['all_full_category_names'] = sorted(list(all_full_category_names))
|
| - ctx['all_categories'] = sorted(list(all_categories))
|
| - ctx['all_subcategories'] = sorted(list(all_subcategories))
|
| - ctx['subcategories_by_category'] = subcategories_by_category
|
| - ctx['default_refresh'] = \
|
| - skia_vars.GetGlobalVariable('default_webstatus_refresh')
|
| - ctx['skia_repo'] = config_private.SKIA_GIT_URL
|
| -
|
| - active_master = config_private.Master.get_active_master()
|
| - ctx['internal_port'] = active_master.master_port
|
| - ctx['external_port'] = active_master.master_port_alt
|
| - ctx['title_url'] = config_private.Master.Skia.project_url
|
| - ctx['slave_hosts_cfg'] = slave_hosts_cfg.SLAVE_HOSTS
|
| - ctx['slaves_cfg'] = slaves_cfg.SLAVES
|
| -
|
| - ctx['active_master_name'] = active_master.project_name
|
| - ctx['master_revision'] = utils.get_current_revision()
|
| - ctx['master_running_revision'] = active_master.running_revision
|
| - ctx['master_launch_datetime'] = active_master.launch_datetime
|
| - ctx['is_internal_view'] = request.host.port == ctx['internal_port']
|
| - ctx['masters'] = []
|
| - for master in config_private.Master.valid_masters:
|
| - ctx['masters'].append({
|
| - 'name': master.project_name,
|
| - 'host': master.master_host,
|
| - 'internal_port': master.master_port,
|
| - 'external_port': master.master_port_alt,
|
| - })
|
| - ##############################################################################
|
| -
|
| - d = defer.maybeDeferred(lambda : self.content(request, ctx))
|
| - def handle(data):
|
| - if isinstance(data, unicode):
|
| - data = data.encode("utf-8")
|
| - request.setHeader("content-type", self.contentType)
|
| - if request.method == "HEAD":
|
| - request.setHeader("content-length", len(data))
|
| - return ''
|
| - return data
|
| - d.addCallback(handle)
|
| - def ok(data):
|
| - request.write(data)
|
| - request.finish()
|
| - def fail(f):
|
| - request.processingFailed(f)
|
| - return None # processingFailed will log this for us
|
| - d.addCallbacks(ok, fail)
|
| - return server.NOT_DONE_YET
|
| -
|
| -webstatus_base.HtmlResource.render = HtmlResourceRender
|
| -
|
| -
|
| -class TryBuildersJsonResource(JsonResource):
|
| - """ Clone of buildbot.status.web.status_json.BuildersJsonResource:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/third_party/buildbot_8_4p1/buildbot/status/web/status_json.py?view=markup
|
| -
|
| - We add filtering to display only the try builders.
|
| - """
|
| - help = """List of all the try builders defined on a master."""
|
| - pageTitle = 'Builders'
|
| -
|
| - def __init__(self, status, include_only_cq_trybots=False):
|
| - JsonResource.__init__(self, status)
|
| - for builder_name in self.status.getBuilderNames():
|
| - if builder_name_schema.IsTrybot(builder_name) and (
|
| - not include_only_cq_trybots or builder_name in slaves_cfg.CQ_TRYBOTS):
|
| - self.putChild(builder_name,
|
| - BuilderJsonResource(status,
|
| - status.getBuilder(builder_name)))
|
| -
|
| -
|
| -class CQRequiredStepsJsonResource(JsonResource):
|
| - help = 'List the steps which cannot fail on the commit queue.'
|
| - pageTitle = 'CQ Required Steps'
|
| -
|
| - def asDict(self, request):
|
| - return {'cq_required_steps':
|
| - skia_vars.GetGlobalVariable('cq_required_steps')}
|
| -
|
| -
|
| -def JsonStatusResourceInit(self, status):
|
| - """ Override of buildbot.status.web.status_json.JsonStatusResource.__init__:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/third_party/buildbot_8_4p1/buildbot/status/web/status_json.py?view=markup
|
| -
|
| - We add trybots, cqtrybots, cq_required_steps (details below).
|
| - """
|
| - JsonResource.__init__(self, status)
|
| - self.level = 1
|
| - self.putChild('builders', BuildersJsonResource(status))
|
| - self.putChild('change_sources', ChangeSourcesJsonResource(status))
|
| - self.putChild('project', ProjectJsonResource(status))
|
| - self.putChild('slaves', SlavesJsonResource(status))
|
| - self.putChild('metrics', MetricsJsonResource(status))
|
| -
|
| - ############################## Added by borenet ##############################
|
| - # Added to address: https://code.google.com/p/skia/issues/detail?id=1134
|
| - self.putChild('trybots', TryBuildersJsonResource(status))
|
| - ##############################################################################
|
| - ############################## Added by rmistry ##############################
|
| - # Added to have a place to get the list of trybots run by the CQ.
|
| - self.putChild('cqtrybots',
|
| - TryBuildersJsonResource(status, include_only_cq_trybots=True))
|
| - ##############################################################################
|
| - ############################## Added by borenet ##############################
|
| - # Added to have a place to get the list of steps which cannot fail on the CQ.
|
| - self.putChild('cq_required_steps', CQRequiredStepsJsonResource(status))
|
| - ##############################################################################
|
| -
|
| - ############################## Added by borenet ##############################
|
| - # Added to have a way to determine which code revision the master is running.
|
| - self.putChild('master_revision',
|
| - master_revision.MasterCheckedOutRevisionJsonResource(status))
|
| - running_rev = config_private.Master.get_active_master().running_revision
|
| - self.putChild('master_running_revision',
|
| - master_revision.MasterRunningRevisionJsonResource(
|
| - status=status, running_revision=running_rev))
|
| -
|
| - # This page gives the result of the most recent build for each builder.
|
| - self.putChild('builder_statuses',
|
| - builder_statuses.BuilderStatusesJsonResource(status))
|
| - ##############################################################################
|
| -
|
| - # This needs to be called before the first HelpResource().body call.
|
| - self.hackExamples()
|
| -
|
| -JsonStatusResource.__init__ = JsonStatusResourceInit
|
| -
|
| -
|
| -@defer.deferredGenerator
|
| -def TryJobRietveldSubmitJobs(self, jobs):
|
| - """ Override of master.try_job_rietveld.TryJobRietveld.SubmitJobs:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/master/try_job_rietveld.py?view=markup
|
| -
|
| - We modify it to include "baseurl" as a build property.
|
| - """
|
| - log.msg('TryJobRietveld.SubmitJobs: %s' % json.dumps(jobs, indent=2))
|
| - for job in jobs:
|
| - try:
|
| - # Gate the try job on the user that requested the job, not the one that
|
| - # authored the CL.
|
| - # pylint: disable=W0212
|
| - ########################## Added by rmistry ##########################
|
| - if (job.get('requester') and not job['requester'].endswith('@google.com')
|
| - and not job['requester'].endswith('@chromium.org')
|
| - and not job['requester'] in TRYBOTS_REQUESTER_WHITELIST):
|
| - # Reject the job only if the requester has an email not ending in
|
| - # google.com or chromium.org
|
| - raise BadJobfile(
|
| - 'TryJobRietveld rejecting job from %s' % job['requester'])
|
| - ######################################################################
|
| - ########################## Added by borenet ##########################
|
| - if not (job.get('baseurl') and
|
| - config_private.Master.Skia.project_name.lower() in
|
| - job['baseurl']):
|
| - raise BadJobfile('TryJobRietveld rejecting job with unknown baseurl: %s'
|
| - % job.get('baseurl'))
|
| - ######################################################################
|
| - if job['email'] != job['requester']:
|
| - # Note the fact the try job was requested by someone else in the
|
| - # 'reason'.
|
| - job['reason'] = job.get('reason') or ''
|
| - if job['reason']:
|
| - job['reason'] += '; '
|
| - job['reason'] += "This CL was triggered by %s" % job['requester']
|
| -
|
| - options = {
|
| - 'bot': {job['builder']: job['tests']},
|
| - 'email': [job['email']],
|
| - 'project': [self._project],
|
| - 'try_job_key': job['key'],
|
| - }
|
| - # Transform some properties as is expected by parse_options().
|
| - for key in (
|
| - ########################## Added by borenet ##########################
|
| - 'baseurl',
|
| - ######################################################################
|
| - 'name', 'user', 'root', 'reason', 'clobber', 'patchset',
|
| - 'issue', 'requester', 'revision'):
|
| - options[key] = [job[key]]
|
| -
|
| - # Now cleanup the job dictionary and submit it.
|
| - cleaned_job = self.parse_options(options)
|
| -
|
| - wfd = defer.waitForDeferred(self.get_lkgr(cleaned_job))
|
| - yield wfd
|
| - wfd.getResult()
|
| -
|
| - wfd = defer.waitForDeferred(self.master.addChange(
|
| - author=','.join(cleaned_job['email']),
|
| - # TODO(maruel): Get patchset properties to get the list of files.
|
| - # files=[],
|
| - revision=cleaned_job['revision'],
|
| - comments=''))
|
| - yield wfd
|
| - changeids = [wfd.getResult().number]
|
| -
|
| - wfd = defer.waitForDeferred(self.SubmitJob(cleaned_job, changeids))
|
| - yield wfd
|
| - wfd.getResult()
|
| - except BadJobfile, e:
|
| - # We need to mark it as failed otherwise it'll stay in the pending
|
| - # state. Simulate a buildFinished event on the build.
|
| - if not job.get('key'):
|
| - log.err(
|
| - 'Got %s for issue %s but not key, not updating Rietveld' %
|
| - (e, job.get('issue')))
|
| - continue
|
| - log.err(
|
| - 'Got %s for issue %s, updating Rietveld' % (e, job.get('issue')))
|
| - for service in self.master.services:
|
| - if service.__class__.__name__ == 'TryServerHttpStatusPush':
|
| - # pylint: disable=W0212,W0612
|
| - build = {
|
| - 'properties': [
|
| - ('buildername', job.get('builder'), None),
|
| - ('buildnumber', -1, None),
|
| - ('issue', job['issue'], None),
|
| - ('patchset', job['patchset'], None),
|
| - ('project', self._project, None),
|
| - ('revision', '', None),
|
| - ('slavename', '', None),
|
| - ('try_job_key', job['key'], None),
|
| - ],
|
| - 'reason': job.get('reason', ''),
|
| - # Use EXCEPTION until SKIPPED results in a non-green try job
|
| - # results on Rietveld.
|
| - 'results': EXCEPTION,
|
| - }
|
| - ########################## Added by rmistry #########################
|
| - # Do not update Rietveld to mark the try job request as failed.
|
| - # See https://code.google.com/p/chromium/issues/detail?id=224014 for
|
| - # more context.
|
| - # service.push('buildFinished', build=build)
|
| - #####################################################################
|
| - break
|
| -
|
| -try_job_rietveld.TryJobRietveld.SubmitJobs = TryJobRietveldSubmitJobs
|
| -
|
| -
|
| -def TryJobBaseGetProps(self, builder, options):
|
| - """ Override of try_job_base.TryJobBase.get_props:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/master/try_job_base.py?view=markup
|
| -
|
| - We modify it to add "baseurl".
|
| - """
|
| - keys = (
|
| -############################### Added by borenet ###############################
|
| - 'baseurl',
|
| -################################################################################
|
| - 'clobber',
|
| - 'issue',
|
| - 'patchset',
|
| - 'requester',
|
| - 'rietveld',
|
| - 'root',
|
| - 'try_job_key',
|
| - )
|
| - # All these settings have no meaning when False or not set, so don't set
|
| - # them in that case.
|
| - properties = dict((i, options[i]) for i in keys if options.get(i))
|
| - properties['testfilter'] = options['bot'].get(builder, None)
|
| - # pylint: disable=W0212
|
| - props = Properties()
|
| - props.updateFromProperties(self.properties)
|
| - props.update(properties, self._PROPERTY_SOURCE)
|
| - return props
|
| -
|
| -try_job_base.TryJobBase.get_props = TryJobBaseGetProps
|
| -
|
| -
|
| -def TryJobRietveldConstructor(
|
| - self, name, pools, properties=None, last_good_urls=None,
|
| - code_review_sites=None, project=None):
|
| - try_job_base.TryJobBase.__init__(self, name, pools, properties,
|
| - last_good_urls, code_review_sites)
|
| - # pylint: disable=W0212
|
| - endpoint = self._GetRietveldEndPointForProject(code_review_sites, project)
|
| -############################### Added by rmistry ###############################
|
| - # rmistry: Adding '&master=tryserver.skia' to the endpoint to help filter the
|
| - # number of pending try patchsets returned. More details are in
|
| - # https://code.google.com/p/skia/issues/detail?id=2659
|
| - endpoint += '&master=tryserver.skia'
|
| - # rmistry: Increased the polling time from 10 seconds to 1 min because 10
|
| - # seconds is too short for us. The RietveldPoller stops working if the time is
|
| - # too short.
|
| - # pylint: disable=W0212
|
| - self._poller = try_job_rietveld._RietveldPoller(endpoint, interval=60)
|
| -################################################################################
|
| - # pylint: disable=W0212
|
| - self._valid_users = try_job_rietveld._ValidUserPoller(interval=12 * 60 * 60)
|
| - self._project = project
|
| - log.msg('TryJobRietveld created, get_pending_endpoint=%s '
|
| - 'project=%s' % (endpoint, project))
|
| -
|
| -try_job_rietveld.TryJobRietveld.__init__ = TryJobRietveldConstructor
|
| -
|
| -
|
| -class SkiaGateKeeper(gatekeeper.GateKeeper):
|
| -
|
| - def isInterestingBuilder(self, builder_status):
|
| - """ Override of gatekeeper.GateKeeper.isInterestingBuilder:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/master/gatekeeper.py?view=markup
|
| -
|
| - We modify it to actually check whether the builder should be considered by
|
| - the GateKeeper, as indicated in its category name.
|
| - """
|
| -
|
| - ret = (not builder_name_schema.IsTrybot(builder_status.getName()) and
|
| - chromium_notifier.ChromiumNotifier.isInterestingBuilder(self,
|
| - builder_status))
|
| - log.msg('[gatekeeper-debug2] ======================')
|
| - log.msg('[gatekeeper-debug2] is not trybot: %s' % (
|
| - not builder_name_schema.IsTrybot(builder_status.getName())))
|
| - log.msg('[gatekeeper-debug2] isInterestingBuilder: %s' % (
|
| - chromium_notifier.ChromiumNotifier.isInterestingBuilder(
|
| - self, builder_status)))
|
| - log.msg('[gatekeeper-debug2] builder_status.getName(): %s' % (
|
| - builder_status.getName()))
|
| - log.msg('[gatekeeper-debug2] ret: %s' % ret)
|
| - log.msg('[gatekeeper-debug2] ======================')
|
| - return ret
|
| -
|
| - def isInterestingStep(self, build_status, step_status, results):
|
| - """ Override of gatekeeper.GateKeeper.isInterestingStep:
|
| - http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/master/gatekeeper.py?view=markup
|
| -
|
| - We modify it to comment out the SVN revision comparision to determine if the
|
| - current build is older because Skia uses commit hashes.
|
| - """
|
| - # If we have not failed, or are not interested in this builder,
|
| - # then we have nothing to do.
|
| - if results[0] != FAILURE:
|
| - return False
|
| -
|
| - # Check if the slave is still alive. We should not close the tree for
|
| - # inactive slaves.
|
| - slave_name = build_status.getSlavename()
|
| - if slave_name in self.master_status.getSlaveNames():
|
| - # @type self.master_status: L{buildbot.status.builder.Status}
|
| - # @type self.parent: L{buildbot.master.BuildMaster}
|
| - # @rtype getSlave(): L{buildbot.status.builder.SlaveStatus}
|
| - slave_status = self.master_status.getSlave(slave_name)
|
| - if slave_status and not slave_status.isConnected():
|
| - log.msg('[gatekeeper] Slave %s was disconnected, '
|
| - 'not closing the tree' % slave_name)
|
| - return False
|
| -
|
| - # If the previous build step failed with the same result, we don't care
|
| - # about this step.
|
| - previous_build_status = build_status.getPreviousBuild()
|
| - if previous_build_status:
|
| - step_name = self.getName(step_status)
|
| - step_type = self.getGenericName(step_name)
|
| - previous_steps = [step for step in previous_build_status.getSteps()
|
| - if self.getGenericName(self.getName(step)) == step_type]
|
| - if len(previous_steps) == 1:
|
| - if previous_steps[0].getResults()[0] == FAILURE:
|
| - log.msg('[gatekeeper] Slave %s failed, but previously failed on '
|
| - 'the same step (%s). So not closing tree.' % (
|
| - (step_name, slave_name)))
|
| - return False
|
| - else:
|
| - log.msg('[gatekeeper] len(previous_steps) == %d which is weird' %
|
| - len(previous_steps))
|
| -
|
| - # If check_revisions=False that means that the tree closure request is
|
| - # coming from nightly scheduled bots, that need not necessarily have the
|
| - # revision info.
|
| - if not self.check_revisions:
|
| - return True
|
| -
|
| - # If we don't have a version stamp nor a blame list, then this is most
|
| - # likely a build started manually, and we don't want to close the
|
| - # tree.
|
| - latest_revision = build_utils.getLatestRevision(build_status)
|
| - if not latest_revision or not build_status.getResponsibleUsers():
|
| - log.msg('[gatekeeper] Slave %s failed, but no version stamp, '
|
| - 'so skipping.' % slave_name)
|
| - return False
|
| -
|
| - # If the tree is open, we don't want to close it again for the same
|
| - # revision, or an earlier one in case the build that just finished is a
|
| - # slow one and we already fixed the problem and manually opened the tree.
|
| - ############################### Added by rmistry ###########################
|
| - # rmistry: Commenting out the below SVN revision comparision because Skia
|
| - # uses commit hashes.
|
| - # TODO(rmistry): Figure out how to ensure that previous builds do not close
|
| - # the tree again.
|
| - #
|
| - # if latest_revision <= self._last_closure_revision:
|
| - # log.msg('[gatekeeper] Slave %s failed, but we already closed it '
|
| - # 'for a previous revision (old=%s, new=%s)' % (
|
| - # slave_name, str(self._last_closure_revision),
|
| - # str(latest_revision)))
|
| - # return False
|
| - ###########################################################################
|
| -
|
| - log.msg('[gatekeeper] Decided to close tree because of slave %s '
|
| - 'on revision %s' % (slave_name, str(latest_revision)))
|
| -
|
| - # Up to here, in theory we'd check if the tree is closed but this is too
|
| - # slow to check here. Instead, take a look only when we want to close the
|
| - # tree.
|
| - return True
|
| -
|
| -
|
| -# Fix try_job_base.TryJobBase._EMAIL_VALIDATOR to handle *.info. This was fixed
|
| -# in https://codereview.chromium.org/216293005 but we need this monkeypatch to
|
| -# pick it up without a DEPS roll.
|
| -try_job_base.TryJobBase._EMAIL_VALIDATOR = re.compile(
|
| - r'[a-zA-Z0-9][a-zA-Z0-9\.\+\-\_]*@[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,}$')
|
| -
|
| -
|
| -# Add logging to GitPoller._stop_on_failure
|
| -def _stop_on_failure(self, f):
|
| - "utility method to stop the service when a failure occurs"
|
| - log.err('GitPoller stopping due to failure: %s' % str(f))
|
| - if self.running:
|
| - d = defer.maybeDeferred(lambda : self.stopService())
|
| - d.addErrback(log.err, 'while stopping broken GitPoller service')
|
| - return f
|
| -
|
| -GitPoller._stop_on_failure = _stop_on_failure
|
|
|