OLD | NEW |
| (Empty) |
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import datetime | |
6 import os | |
7 import traceback | |
8 | |
9 # These modules come from $(TOPLEVEL_DIR)/scripts , | |
10 # which must be in the PYTHONPATH. | |
11 from buildbot.status.web.baseweb import WebStatus | |
12 from master import master_utils | |
13 from master import slaves_list | |
14 from master.status_push import TryServerHttpStatusPush | |
15 | |
16 import skia_notifier | |
17 | |
18 # This module comes from $(TOPLEVEL_DIR)/site_config , | |
19 # which must be in the PYTHONPATH. | |
20 import config | |
21 | |
22 # These modules come from the local directory. | |
23 from skia_master_scripts import monkeypatches | |
24 from skia_master_scripts import utils | |
25 from skia_master_scripts import graphite_status_push | |
26 from webstatus import buildstatus | |
27 from webstatus import console | |
28 from webstatus import waterfall | |
29 import builder_name_schema | |
30 import master_source_cfg | |
31 import skia_vars | |
32 | |
33 | |
34 c = BuildmasterConfig = {} | |
35 c['change_source'] = [] | |
36 c['schedulers'] = [] | |
37 c['builders'] = [] | |
38 c['status'] = [] | |
39 | |
40 | |
41 def GetSkiaGateKeeper(): | |
42 """Returns the GateKeeper used by Skia. | |
43 | |
44 If any of the bots in the Build category (compile bots) fails the specified | |
45 build steps, then the tree is automatically closed and an email is sent about | |
46 the tree closure. | |
47 | |
48 Note: The tree is not closed if the last run of the builder had the same | |
49 failing step as the current run. The tree is also not closed if the | |
50 gatekeeper closed the tree less than 10 mins ago. | |
51 """ | |
52 # Run the gatekeeper only on the following categories and build steps. | |
53 categories_steps = { | |
54 builder_name_schema.BUILDER_ROLE_BUILD: | |
55 skia_vars.GetGlobalVariable('gatekeeper_steps') | |
56 } | |
57 return monkeypatches.SkiaGateKeeper( | |
58 fromaddr=config.Master.Skia.from_address, | |
59 categories_steps=categories_steps, | |
60 exclusions={}, | |
61 subject='buildbot %(result)s in %(projectName)s on %(builder)s, ' | |
62 'revision %(revision)s', | |
63 extraRecipients=config.Master.Skia.tree_closing_notification_recipients, | |
64 lookup=master_utils.FilterDomain(), | |
65 forgiving_steps=[], | |
66 useTls=config.Master.smtp_use_tls, | |
67 smtpUser=config.Master.smtp_user, | |
68 smtpPassword=SMTP_PASSWORD, | |
69 smtpPort=config.Master.smtp_port, | |
70 relayhost=config.Master.smtp_server, | |
71 tree_status_url=config.Master.Skia.tree_status_url, | |
72 check_revisions=True) | |
73 | |
74 | |
75 ActiveMaster = config.Master.set_active_master(os.environ.get('TESTING_MASTER', | |
76 'Skia')) | |
77 | |
78 ActiveMaster.running_revision = utils.get_current_revision() | |
79 ActiveMaster.launch_datetime = datetime.datetime.utcnow() | |
80 | |
81 # Load the builder configuration. | |
82 ActiveMaster.create_schedulers_and_builders(c) | |
83 | |
84 # Load the source configuration. | |
85 master_source_cfg.Update(config, ActiveMaster, c) | |
86 | |
87 # Associate the slaves to the manual builders. The configuration is in | |
88 # slaves.cfg. | |
89 slaves = slaves_list.SlavesList('slaves.cfg', ActiveMaster.__class__.__name__) | |
90 | |
91 # The SMTP password is only required if the master is a production host. | |
92 if ActiveMaster.is_production_host: | |
93 try: | |
94 SMTP_PASSWORD = open('.skia_buildbots_password').readline().strip() | |
95 except IOError, e: | |
96 traceback.print_exc() | |
97 raise Exception('Please create a .skia_buildbots_password file in the ' | |
98 'master directory if the master needs to run as a ' | |
99 'production host (Password is in valentine).') | |
100 else: | |
101 SMTP_PASSWORD = 'dummy_password' | |
102 | |
103 | |
104 for builder in c['builders']: | |
105 builder['slavenames'] = slaves.GetSlavesName(builder=builder['name']) | |
106 | |
107 | |
108 # The 'slaves' list defines the set of allowable buildslaves. List all the | |
109 # slaves registered to a builder. Remove dupes. | |
110 c['slaves'] = master_utils.AutoSetupSlaves(c['builders'], | |
111 config.Master.GetBotPassword()) | |
112 master_utils.VerifySetup(c, slaves) | |
113 | |
114 # For each slave instance, add the key/value pairs in its associated dictionary, | |
115 # defined in slaves.cfg, to its build properties. This allows us to access | |
116 # extra attributes defined in slaves.cfg using WithProperties. | |
117 for slave_instance in c['slaves']: | |
118 for slave_dict in slaves.GetSlaves(): | |
119 if slave_dict['hostname'] == slave_instance.identity()[0]: | |
120 slave_instance.properties.update(slave_dict, 'BuildSlave') | |
121 break | |
122 | |
123 # Adds common status and tools to this master. | |
124 c['buildbotURL'] = 'http://%s:%d/' % ( | |
125 ActiveMaster.master_host, ActiveMaster.master_port_alt) | |
126 master_utils.AutoSetupMaster(c, ActiveMaster, mail_notifier=False) | |
127 | |
128 # Reduce the number of on-disk builds and logs, to save disk space. | |
129 c['buildHorizon'] = 400 | |
130 c['logHorizon'] = 200 | |
131 | |
132 # Replace the default console and waterfall pages with our overrides and add | |
133 # the trybot and failures waterfalls. | |
134 for status in c['status']: | |
135 if issubclass(status.__class__, WebStatus): | |
136 status.putChild('console', console.ConsoleStatusResource()) | |
137 status.putChild('console_json', | |
138 console.ConsoleJsonStatusResource(status=status, | |
139 order_by_time=True)) | |
140 status.putChild('waterfall', waterfall.WaterfallStatusResource()) | |
141 status.putChild('trybots', waterfall.TrybotStatusResource()) | |
142 status.putChild('failures', waterfall.FailureWaterfallStatusResource()) | |
143 status.putChild('buildstatus', buildstatus.BuildStatusStatusResource()) | |
144 | |
145 | |
146 # Add our own mail notifier (only in production mode): | |
147 # email the committer (and skia-commit list) only if it changed test results | |
148 if ActiveMaster.is_production_host: | |
149 mail_notifier = skia_notifier.SkiaNotifier( | |
150 fromaddr=ActiveMaster.from_address, | |
151 sendToInterestedUsers=True, | |
152 extraRecipients=['skia-commit@googlegroups.com'], | |
153 useTls=config.Master.smtp_use_tls, | |
154 smtpUser=config.Master.smtp_user, | |
155 smtpPassword=SMTP_PASSWORD, | |
156 mode='change', | |
157 smtpPort=config.Master.smtp_port, | |
158 relayhost=config.Master.smtp_server, | |
159 lookup=master_utils.FilterDomain( | |
160 permitted_domains=config.Master.permitted_domains)) | |
161 c['status'].append(mail_notifier) | |
162 | |
163 # Try job result emails. | |
164 c['status'].append(skia_notifier.SkiaTryMailNotifier( | |
165 fromaddr=ActiveMaster.from_address, | |
166 # Subject is overridden in skia_notifier.SkiaTryMailNotifier.buildMessage | |
167 subject='try %(result)s for changelist "%(reason)s" at %(timestamp)s', | |
168 mode='all', | |
169 lookup=master_utils.FilterDomain( | |
170 permitted_domains=config.Master.permitted_domains), | |
171 useTls=config.Master.smtp_use_tls, | |
172 smtpUser=config.Master.smtp_user, | |
173 smtpPassword=SMTP_PASSWORD, | |
174 smtpPort=config.Master.smtp_port, | |
175 relayhost=config.Master.smtp_server, | |
176 footer="""Skia Trybot documentation: <a href= | |
177 "https://sites.google.com/site/skiadocs/developer-documentation/skia-trybots"> | |
178 https://sites.google.com/site/skiadocs/developer-documentation/skia-trybots</a> | |
179 <br/></body></html>""")) | |
180 | |
181 c['status'].append( | |
182 TryServerHttpStatusPush(serverUrl=ActiveMaster.code_review_site)) | |
183 | |
184 # Add the gatekeeper | |
185 c['status'].append(GetSkiaGateKeeper()) | |
186 # Add the graphite pusher | |
187 c['status'].append(graphite_status_push.GraphiteStatusPush()) | |
188 | |
189 | |
190 c['mergeRequests'] = utils.CanMergeBuildRequests | |
OLD | NEW |