1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17
18 from twisted.internet import defer
19 from twisted.python import log
20 from twisted.protocols import basic
21
22 from buildbot import pbutil
23 from buildbot.util.maildir import MaildirService
24 from buildbot.util import netstrings
25 from buildbot.process.properties import Properties
26 from buildbot.schedulers import base
27 from buildbot.status.buildset import BuildSetStatus
28
29
30 -class TryBase(base.BaseScheduler):
31
33 """
34 Make sure that C{builderNames} is a subset of the configured
35 C{self.builderNames}, returning an empty list if not. If
36 C{builderNames} is empty, use C{self.builderNames}.
37
38 @returns: list of builder names to build on
39 """
40
41
42
43
44
45 if builderNames:
46 for b in builderNames:
47 if not b in self.builderNames:
48 log.msg("%s got with builder %s" % (self, b))
49 log.msg(" but that wasn't in our list: %s"
50 % (self.builderNames,))
51 return []
52 else:
53 builderNames = self.builderNames
54 return builderNames
55
59
67
70
71 compare_attrs = TryBase.compare_attrs + ( 'jobdir', )
72
73 - def __init__(self, name, builderNames, jobdir,
74 properties={}):
79
84
86
87
88
89
90
91
92
93
94
95 p = netstrings.NetstringParser()
96 try:
97 p.feed(f.read())
98 except basic.NetstringParseError:
99 raise BadJobfile("unable to parse netstrings")
100 if not p.strings:
101 raise BadJobfile("could not find any complete netstrings")
102 ver = p.strings.pop(0)
103
104 if ver == "1":
105 buildsetID, branch, baserev, patchlevel, diff = p.strings[:5]
106 builderNames = p.strings[5:]
107 if branch == "":
108 branch = None
109 if baserev == "":
110 baserev = None
111 patchlevel = int(patchlevel)
112 repository=''
113 project=''
114 who=''
115 comment=''
116 elif ver == "2":
117 buildsetID, branch, baserev, patchlevel, diff, repository, project = p.strings[:7]
118 builderNames = p.strings[7:]
119 if branch == "":
120 branch = None
121 if baserev == "":
122 baserev = None
123 patchlevel = int(patchlevel)
124 who=''
125 comment=''
126 elif ver == "3":
127 buildsetID, branch, baserev, patchlevel, diff, repository, project, who = p.strings[:8]
128 builderNames = p.strings[8:]
129 if branch == "":
130 branch = None
131 if baserev == "":
132 baserev = None
133 patchlevel = int(patchlevel)
134 comment=''
135 elif ver == "4":
136 buildsetID, branch, baserev, patchlevel, diff, repository, project, who, comment = p.strings[:9]
137 builderNames = p.strings[9:]
138 if branch == "":
139 branch = None
140 if baserev == "":
141 baserev = None
142 patchlevel = int(patchlevel)
143
144 else:
145 raise BadJobfile("unknown version '%s'" % ver)
146 return dict(
147 builderNames=builderNames,
148 branch=branch,
149 baserev=baserev,
150 patch_body=diff,
151 patch_level=patchlevel,
152 repository=repository,
153 project=project,
154 who=who,
155 comment=comment,
156 jobid=buildsetID)
157
159 try:
160 parsed_job = self.parseJob(f)
161 builderNames = parsed_job['builderNames']
162 except BadJobfile:
163 log.msg("%s reports a bad jobfile in %s" % (self, filename))
164 log.err()
165 return defer.succeed(None)
166
167
168 builderNames = self.filterBuilderList(builderNames)
169 if not builderNames:
170 log.msg("incoming Try job did not specify any allowed builder names")
171 return defer.succeed(None)
172
173 who = ""
174 if parsed_job['who']:
175 who = parsed_job['who']
176
177 comment = ""
178 if parsed_job['comment']:
179 comment = parsed_job['comment']
180
181 d = self.master.db.sourcestampsets.addSourceStampSet()
182
183 def addsourcestamp(setid):
184 self.master.db.sourcestamps.addSourceStamp(
185 sourcestampsetid=setid,
186 branch=parsed_job['branch'],
187 revision=parsed_job['baserev'],
188 patch_body=parsed_job['patch_body'],
189 patch_level=parsed_job['patch_level'],
190 patch_author=who,
191 patch_comment=comment,
192 patch_subdir='',
193 project=parsed_job['project'],
194 repository=parsed_job['repository'])
195 return setid
196
197 d.addCallback(addsourcestamp)
198 def create_buildset(setid):
199 reason = "'try' job"
200 if parsed_job['who']:
201 reason += " by user %s" % parsed_job['who']
202 return self.addBuildsetForSourceStamp(ssid=None, setid=setid,
203 reason=reason, external_idstring=parsed_job['jobid'],
204 builderNames=builderNames)
205 d.addCallback(create_buildset)
206 return d
207
210 - def __init__(self, scheduler, username):
213
214 @defer.deferredGenerator
215 - def perspective_try(self, branch, revision, patch, repository, project,
216 builderNames, who="", comment="", properties={} ):
217 db = self.scheduler.master.db
218 log.msg("user %s requesting build on builders %s" % (self.username,
219 builderNames))
220
221
222 builderNames = self.scheduler.filterBuilderList(builderNames)
223 if not builderNames:
224 return
225
226 reason = "'try' job"
227
228 if who:
229 reason += " by user %s" % who
230
231 if comment:
232 reason += " (%s)" % comment
233
234 wfd = defer.waitForDeferred(db.sourcestampsets.addSourceStampSet())
235 yield wfd
236 sourcestampsetid = wfd.getResult()
237
238 wfd = defer.waitForDeferred(
239 db.sourcestamps.addSourceStamp(branch=branch, revision=revision,
240 repository=repository, project=project, patch_level=patch[0],
241 patch_body=patch[1], patch_subdir='', patch_author=who or '',
242 patch_comment=comment or '', sourcestampsetid = sourcestampsetid))
243
244 yield wfd
245 wfd.getResult()
246
247 requested_props = Properties()
248 requested_props.update(properties, "try build")
249 wfd = defer.waitForDeferred(
250 self.scheduler.addBuildsetForSourceStamp(setid=sourcestampsetid,
251 reason=reason, properties=requested_props,
252 builderNames=builderNames))
253 yield wfd
254 (bsid,brids) = wfd.getResult()
255
256
257 wfd = defer.waitForDeferred(
258 db.buildsets.getBuildset(bsid))
259 yield wfd
260 bsdict = wfd.getResult()
261
262 bss = BuildSetStatus(bsdict, self.scheduler.master.status)
263 from buildbot.status.client import makeRemote
264 r = makeRemote(bss)
265 yield r
266
273
276 compare_attrs = ( 'name', 'builderNames', 'port', 'userpass', 'properties' )
277
278 - def __init__(self, name, builderNames, port, userpass,
279 properties={}):
283
290 self.registrations = []
291 for user, passwd in self.userpass:
292 self.registrations.append(
293 self.master.pbmanager.register(self.port, user, passwd, factory))
294
296 d = defer.maybeDeferred(TryBase.stopService, self)
297 def unreg(_):
298 return defer.gatherResults(
299 [ reg.unregister() for reg in self.registrations ])
300 d.addCallback(unreg)
301 return d
302