Skip to content
This repository has been archived by the owner on Jun 11, 2019. It is now read-only.

Commit

Permalink
Backed out changeset b4503e3f8412
Browse files Browse the repository at this point in the history
--HG--
branch : production-0.8
  • Loading branch information
lsblakk committed Dec 14, 2010
1 parent 1a4a706 commit 0a98875
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 1 deletion.
49 changes: 49 additions & 0 deletions process/release.py
Expand Up @@ -8,6 +8,7 @@
from buildbot.status.mail import MailNotifier
from buildbot.process.factory import BuildFactory
from buildbot.process.properties import WithProperties
from buildbot.steps.trigger import Trigger

from buildbotcustom.l10n import DependentL10n
from buildbotcustom.status.mail import ChangeNotifier
Expand All @@ -22,6 +23,8 @@
TuxedoEntrySubmitterFactory, makeDummyBuilder
from buildbotcustom.changes.ftppoller import FtpPoller, LocalesFtpPoller
from release.platforms import ftp_platform_map, sl_platform_map
from buildbotcustom.scheduler import TriggerBouncerCheck
import BuildSlaves

DEFAULT_L10N_CHUNKS = 15

Expand All @@ -32,6 +35,8 @@ def generateReleaseBranchObjects(releaseConfig, branchConfig, staging):
l10nChunks = releaseConfig.get('l10nChunks', DEFAULT_L10N_CHUNKS)
tools_repo = '%s%s' % (branchConfig['hgurl'],
branchConfig['build_tools_repo_path'])
config_repo = '%s%s' % (branchConfig['hgurl'],
branchConfig['config_repo_path'])
if staging:
branchConfigFile = "mozilla/staging_config.py"
else:
Expand Down Expand Up @@ -326,6 +331,27 @@ def l10nBuilders(platform):
)
schedulers.append(s)

mirror_scheduler1 = TriggerBouncerCheck(
name=builderPrefix('ready-for-qa'),
configRepo=config_repo,
minUptake=10000,
builderNames=[builderPrefix('ready_for_qa'),
builderPrefix('final_verification')],
username=BuildSlaves.tuxedoUsername,
password=BuildSlaves.tuxedoPassword)

schedulers.append(mirror_scheduler1)

mirror_scheduler2 = TriggerBouncerCheck(
name=builderPrefix('ready-for-release'),
configRepo=config_repo,
minUptake=45000,
builderNames=[builderPrefix('ready_for_release')],
username=BuildSlaves.tuxedoUsername,
password=BuildSlaves.tuxedoPassword)

schedulers.append(mirror_scheduler2)

# Purposely, there is not a Scheduler for ReleaseFinalVerification
# This is a step run very shortly before release, and is triggered manually
# from the waterfall
Expand Down Expand Up @@ -799,6 +825,13 @@ def l10nBuilders(platform):
scriptName='scripts/release/push-to-mirrors.sh',
)

push_to_mirrors_factory.addStep(Trigger(
schedulerNames=[builderPrefix('ready-for-qa'),
builderPrefix('ready-for-release')],
copy_properties=['revision', 'release_config']
))


builders.append({
'name': builderPrefix('push_to_mirrors'),
'slavenames': branchConfig['platforms']['linux']['slaves'],
Expand Down Expand Up @@ -829,6 +862,22 @@ def l10nBuilders(platform):
'env': builder_env,
})

notify_builders.append(builderPrefix('final_verification'))

builders.append(makeDummyBuilder(
name=builderPrefix('ready_for_qa'),
slaves=branchConfig['platforms']['linux']['slaves'],
category=builderPrefix(''),
))
notify_builders.append(builderPrefix('ready_for_qa'))

builders.append(makeDummyBuilder(
name=builderPrefix('ready_for_release'),
slaves=branchConfig['platforms']['linux']['slaves'],
category=builderPrefix(''),
))
notify_builders.append(builderPrefix('ready_for_release'))

if releaseConfig['majorUpdateRepoPath']:
# Not attached to any Scheduler
major_update_factory = MajorUpdateFactory(
Expand Down
120 changes: 119 additions & 1 deletion scheduler.py
Expand Up @@ -3,17 +3,22 @@
# Contributor(s):
# Chris AtLee <catlee@mozilla.com>

from twisted.internet import defer
from twisted.internet import defer, reactor
from twisted.python import log
from twisted.internet.task import LoopingCall
from twisted.web.client import getPage

from buildbot.scheduler import Scheduler
from buildbot.schedulers.base import BaseScheduler
from buildbot.schedulers.timed import Nightly
from buildbot.schedulers.triggerable import Triggerable
from buildbot.sourcestamp import SourceStamp
from buildbot.process.properties import Properties

from buildbot.util import now

from util.tuxedo import get_release_uptake

import time

class MultiScheduler(Scheduler):
Expand Down Expand Up @@ -215,6 +220,119 @@ def do_add_build_and_remove_changes(t, buildersPerChange):
d.addCallback(lambda buildersPerChange: self.parent.db.runInteraction(do_add_build_and_remove_changes, buildersPerChange))
return d


class TriggerBouncerCheck(Triggerable):

compare_attrs = Triggerable.compare_attrs + \
('minUptake', 'configRepo', 'checkMARs', 'username',
'password', 'pollInterval', 'pollTimeout')
working = False
loop = None
release_config = None
revision = None
configRepo = None

def __init__(self, minUptake, configRepo, checkMARs=True,
username=None, password=None, pollInterval=5*60,
pollTimeout=12*60*60, **kwargs):
self.minUptake = minUptake
self.configRepo = configRepo
self.checkMARs = checkMARs
self.username = username
self.password = password
self.pollInterval = pollInterval
self.pollTimeout = pollTimeout
self.ss = None
self.set_props = None
Triggerable.__init__(self, **kwargs)


def trigger(self, ss, set_props=None):
self.ss = ss
self.set_props = set_props

props = Properties()
props.updateFromProperties(self.properties)
if set_props:
props.updateFromProperties(set_props)

self.revision = props.getProperty('revision')
assert self.revision, 'revision should be set'
self.release_config = props.getProperty('release_config')
assert self.release_config, 'release_config should be set'

def _run_loop(_):
self.loop = LoopingCall(self.poll)
reactor.callLater(0, self.loop.start, self.pollInterval)
reactor.callLater(self.pollTimeout, self.stopLoop,
'Timeout after %s' % self.pollTimeout)

d = self.getReleaseConfig()
d.addCallback(_run_loop)

def stopLoop(self, reason=None):
if reason:
log.msg('%s: Stopping uptake monitoring: %s' %
(self.__class__.__name__, reason))
if self.loop.running:
self.loop.stop()
else:
log.msg('%s: Loop has been alredy stopped' %
self.__class__.__name__)

def getReleaseConfig(self):
url = str('%s/raw-file/%s/%s' %
(self.configRepo, self.revision, self.release_config))
d = getPage(url)

def setReleaseConfig(res):
c = {}
exec res in c
self.release_config = c.get('releaseConfig')
log.msg('%s: release_config loaded' % self.__class__.__name__)

d.addCallback(setReleaseConfig)
return d

def poll(self):
if self.working:
log.msg('%s: Not polling because last poll is still working'
% self.__class__.__name__)
return defer.succeed(None)
self.working = True
log.msg('%s: polling' % self.__class__.__name__)
bouncerProductName = self.release_config.get('bouncerProductName') or \
self.release_config.get('productName').capitalize()
d = get_release_uptake(
tuxedoServerUrl=self.release_config.get('tuxedoServerUrl'),
bouncerProductName=bouncerProductName,
version=self.release_config.get('version'),
oldVersion=self.release_config.get('oldVersion'),
checkMARs=self.checkMARs,
username=self.username,
password=self.password)
d.addCallback(self.checkUptake)
d.addCallbacks(self.finished_ok, self.finished_failure)
return d

def checkUptake(self, uptake):
log.msg('%s: uptake is %s' % (self.__class__.__name__, uptake))
if uptake >= self.minUptake:
self.stopLoop('Reached required uptake: %s' % uptake)
Triggerable.trigger(self, self.ss, self.set_props)

def finished_ok(self, res):
log.msg('%s: polling finished' % (self.__class__.__name__))
assert self.working
self.working = False
return res

def finished_failure(self, f):
log.msg('%s failed:\n%s' % (self.__class__.__name__, f.getTraceback()))
assert self.working
self.working = False
return None # eat the failure

def makePropertiesScheduler(base_class, propfuncs, *args, **kw):
"""Return a subclass of `base_class` that will call each of `propfuncs` to
generate a set of properties to attach to new buildsets.
Expand Down

0 comments on commit 0a98875

Please sign in to comment.