Ticket #87: 124.patch
| File 124.patch, 127.4 kB (added by dustin, 9 months ago) |
|---|
-
old-124/buildbot/buildset.py
old new 1 2 1 from buildbot.process import base 3 2 from buildbot.status import builder 3 from buildbot.process.properties import Properties 4 4 5 5 6 6 class BuildSet: … … 11 11 (source.changes=list).""" 12 12 13 13 def __init__(self, builderNames, source, reason=None, bsid=None, 14 scheduler=None, custom_props=None):14 properties=None): 15 15 """ 16 16 @param source: a L{buildbot.sourcestamp.SourceStamp} 17 17 """ … … 19 19 self.source = source 20 20 self.reason = reason 21 21 22 if not custom_props: custom_props = {}23 self.custom_props = custom_props22 self.properties = Properties() 23 if properties: self.properties.updateFromProperties(properties) 24 24 25 25 self.stillHopeful = True 26 26 self.status = bss = builder.BuildSetStatus(source, reason, 27 27 builderNames, bsid) 28 self.scheduler = scheduler29 28 30 29 def waitUntilSuccess(self): 31 30 return self.status.waitUntilSuccess() … … 41 40 # create the requests 42 41 for b in builders: 43 42 req = base.BuildRequest(self.reason, self.source, b.name, 44 scheduler=self.scheduler, 45 custom_props=self.custom_props) 43 properties=self.properties) 46 44 reqs.append((b, req)) 47 45 self.requests.append(req) 48 46 d = req.waitUntilFinished() -
old-124/buildbot/buildslave.py
old new 11 11 from buildbot.status.builder import SlaveStatus 12 12 from buildbot.status.mail import MailNotifier 13 13 from buildbot.interfaces import IBuildSlave 14 from buildbot.process.properties import Properties 14 15 15 16 class BuildSlave(NewCredPerspective, service.MultiService): 16 17 """This is the master-side representative for a remote buildbot slave. … … 26 27 implements(IBuildSlave) 27 28 28 29 def __init__(self, name, password, max_builds=None, 29 notify_on_missing=[], missing_timeout=3600): 30 notify_on_missing=[], missing_timeout=3600, 31 properties={}): 30 32 """ 31 33 @param name: botname this machine will supply when it connects 32 34 @param password: password this machine will supply when … … 34 36 @param max_builds: maximum number of simultaneous builds that will 35 37 be run concurrently on this buildslave (the 36 38 default is None for no limit) 39 @param properties: properties that will be applied to builds run on 40 this slave 41 @type properties: dictionary 37 42 """ 38 43 service.MultiService.__init__(self) 39 44 self.slavename = name … … 44 49 self.slave_commands = None 45 50 self.slavebuilders = [] 46 51 self.max_builds = max_builds 52 53 self.properties = Properties() 54 self.properties.update(properties, "BuildSlave") 55 self.properties.setProperty("slavename", name, "BuildSlave") 56 47 57 self.lastMessageReceived = 0 48 58 if isinstance(notify_on_missing, str): 49 59 notify_on_missing = [notify_on_missing] -
old-124/buildbot/clients/debug.py
old new 105 105 if revision == '': 106 106 revision = None 107 107 reason = "debugclient 'Request Build' button pushed" 108 custom_props = {}108 properties = {} 109 109 d = self.remote.callRemote("requestBuild", 110 name, reason, branch, revision, custom_props)110 name, reason, branch, revision, properties) 111 111 d.addErrback(self.err) 112 112 113 113 def do_ping(self, widget): -
old-124/buildbot/interfaces.py
old new 38 38 class IScheduler(Interface): 39 39 """I watch for Changes in the source tree and decide when to trigger 40 40 Builds. I create BuildSet objects and submit them to the BuildMaster. I 41 am a service, and the BuildMaster is always my parent.""" 41 am a service, and the BuildMaster is always my parent. 42 43 @ivar properties: properties to be applied to all builds started by this 44 scheduler 45 @type properties: L<buildbot.process.properties.Properties> 46 """ 42 47 43 48 def addChange(change): 44 49 """A Change has just been dispatched by one of the ChangeSources. -
old-124/buildbot/master.py
old new 27 27 from buildbot.sourcestamp import SourceStamp 28 28 from buildbot.buildslave import BuildSlave 29 29 from buildbot import interfaces 30 from buildbot.process.properties import Properties 30 31 31 32 ######################################## 32 33 … … 227 228 def detached(self, mind): 228 229 pass 229 230 230 def perspective_requestBuild(self, buildername, reason, branch, revision, custom_props): 231 assert isinstance(custom_props, dict), \ 232 "custom_props must be a dict (not %r)" % (custom_props,) 233 234 # Provide default values for any custom build properties the 235 # client did not send. 236 for propertyDict in (self.master.customBuildProperties or []): 237 custom_props.setdefault(propertyDict['propertyName'], "") 238 231 def perspective_requestBuild(self, buildername, reason, branch, revision, properties={}): 239 232 c = interfaces.IControl(self.master) 240 233 bc = c.getBuilder(buildername) 241 234 ss = SourceStamp(branch, revision) 242 br = BuildRequest(reason, ss, builderName=buildername, custom_props=custom_props) 235 properties = Properties() 236 properties.update(properties, "remote requestBuild") 237 br = BuildRequest(reason, ss, builderName=buildername, properties=properties) 243 238 bc.requestBuild(br) 244 239 245 240 def perspective_pingBuilder(self, buildername): … … 347 342 projectURL = None 348 343 buildbotURL = None 349 344 change_svc = None 350 customBuildProperties = None345 properties = Properties() 351 346 352 347 def __init__(self, basedir, configFileName="master.cfg"): 353 348 service.MultiService.__init__(self) … … 503 498 "schedulers", "builders", 504 499 "slavePortnum", "debugPassword", "manhole", 505 500 "status", "projectName", "projectURL", "buildbotURL", 506 " customBuildProperties"501 "properties" 507 502 ) 508 503 for k in config.keys(): 509 504 if k not in known_keys: … … 531 526 projectName = config.get('projectName') 532 527 projectURL = config.get('projectURL') 533 528 buildbotURL = config.get('buildbotURL') 534 customBuildProperties = config.get('customBuildProperties')529 properties = config.get('properties', {}) 535 530 536 531 except KeyError, e: 537 532 log.msg("config dictionary is missing a required parameter") … … 663 658 else: 664 659 locks[l.name] = l 665 660 661 if not isinstance(properties, dict): 662 raise ValueError("c['properties'] must be a dictionary") 663 666 664 # slavePortnum supposed to be a strports specification 667 665 if type(slavePortnum) is int: 668 666 slavePortnum = "tcp:%d" % slavePortnum … … 677 675 self.projectName = projectName 678 676 self.projectURL = projectURL 679 677 self.buildbotURL = buildbotURL 680 self.customBuildProperties = customBuildProperties 678 679 self.properties = Properties() 680 self.properties.update(properties, self.configFileName) 681 681 682 682 # self.slaves: Disconnect any that were attached and removed from the 683 683 # list. Update self.checker with the new list of passwords, including -
old-124/buildbot/process/base.py
old new 11 11 from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, EXCEPTION 12 12 from buildbot.status.builder import Results, BuildRequestStatus 13 13 from buildbot.status.progress import BuildProgress 14 from buildbot.process.properties import Properties 14 15 15 16 class BuildRequest: 16 17 """I represent a request to a specific Builder to run a single build. … … 39 40 provide this, but for forced builds the user requesting the 40 41 build will provide a string. 41 42 42 @type custom_props: dictionary.43 @ivar custom_props: custom user properties.43 @type properties: Properties object 44 @ivar properties: properties that should be applied to this build 44 45 45 46 @ivar status: the IBuildStatus object which tracks our status 46 47 … … 52 53 source = None 53 54 builder = None 54 55 startCount = 0 # how many times we have tried to start this build 55 custom_props = {}56 56 57 57 implements(interfaces.IBuildRequestControl) 58 58 59 def __init__(self, reason, source, builderName=None, scheduler=None, custom_props=None):59 def __init__(self, reason, source, builderName=None, properties=None): 60 60 # TODO: remove the =None on builderName, it is there so I don't have 61 61 # to change a lot of tests that create BuildRequest objects 62 62 assert interfaces.ISourceStamp(source, None) 63 63 self.reason = reason 64 64 self.source = source 65 self.scheduler = scheduler66 65 67 if not custom_props: custom_props = {} 68 self.custom_props = custom_props 69 assert isinstance(self.custom_props, dict), \ 70 "custom_props must be a dict (not %r)" % (self.custom_props,) 66 self.properties = Properties() 67 if properties: 68 self.properties.updateFromProperties(properties) 71 69 72 70 self.start_watchers = [] 73 71 self.finish_watchers = [] … … 95 93 self.finish_watchers.append(d) 96 94 return d 97 95 98 def customProps(self):99 return self.custom_props100 101 96 # these are called by the Builder 102 97 103 98 def requestSubmitted(self, builder): … … 182 177 # build a source stamp 183 178 self.source = requests[0].mergeWith(requests[1:]) 184 179 self.reason = requests[0].mergeReasons(requests[1:]) 185 self.scheduler = requests[0].scheduler186 187 # Set custom properties.188 self.custom_properties = requests[0].customProps()189 190 #self.abandoned = False191 180 192 181 self.progress = None 193 182 self.currentStep = None … … 207 196 def getSourceStamp(self): 208 197 return self.source 209 198 210 def setProperty(self, propname, value ):199 def setProperty(self, propname, value, source): 211 200 """Set a property on this build. This may only be called after the 212 201 build has started, so that it has a BuildStatus object where the 213 202 properties can live.""" 214 self.build_status.setProperty(propname, value )203 self.build_status.setProperty(propname, value, source) 215 204 216 def get CustomProperties(self):217 return self. custom_properties205 def getProperties(self): 206 return self.build_status.getProperties() 218 207 219 208 def getProperty(self, propname): 220 return self.build_status. properties[propname]209 return self.build_status.getProperty(propname) 221 210 222 211 def allChanges(self): 223 212 return self.source.changes … … 275 264 def getSlaveName(self): 276 265 return self.slavebuilder.slave.slavename 277 266 278 def setupStatus(self, build_status): 279 self.build_status = build_status 280 self.setProperty("buildername", self.builder.name) 281 self.setProperty("buildnumber", self.build_status.number) 282 self.setProperty("branch", self.source.branch) 283 self.setProperty("revision", self.source.revision) 284 if self.scheduler is None: 285 self.setProperty("scheduler", "none") 286 else: 287 self.setProperty("scheduler", self.scheduler.name) 288 for key, userProp in self.custom_properties.items(): 289 self.setProperty(key, userProp) 267 def setupProperties(self): 268 props = self.getProperties() 269 270 # start with global properties from the configuration 271 buildmaster = self.builder.botmaster.parent 272 props.updateFromProperties(buildmaster.properties) 273 274 # get any properties from requests (this is the path through 275 # which schedulers will send us properties) 276 for rq in self.requests: 277 props.updateFromProperties(rq.properties) 278 279 # now set some properties of our own, corresponding to the 280 # build itself 281 props.setProperty("buildername", self.builder.name, "Build") 282 props.setProperty("buildnumber", self.build_status.number, "Build") 283 props.setProperty("branch", self.source.branch, "Build") 284 props.setProperty("revision", self.source.revision, "Build") 290 285 291 286 def setupSlaveBuilder(self, slavebuilder): 292 287 self.slavebuilder = slavebuilder 288 289 # navigate our way back to the L{buildbot.buildslave.BuildSlave} 290 # object that came from the config, and get its properties 291 buildslave_properties = slavebuilder.slave.properties 292 self.getProperties().updateFromProperties(buildslave_properties) 293 293 294 self.slavename = slavebuilder.slave.slavename 294 295 self.build_status.setSlavename(self.slavename) 295 self.setProperty("slavename", self.slavename)296 296 297 297 def startBuild(self, build_status, expectations, slavebuilder): 298 298 """This method sets up the build, then starts it by invoking the … … 305 305 # the Deferred returned by this method. 306 306 307 307 log.msg("%s.startBuild" % self) 308 self. setupStatus(build_status)308 self.build_status = build_status 309 309 # now that we have a build_status, we can set properties 310 self.setupProperties() 310 311 self.setupSlaveBuilder(slavebuilder) 311 312 312 313 # convert all locks into their real forms -
old-124/buildbot/process/builder.py
old new 253 253 @type building: list of L{buildbot.process.base.Build} 254 254 @ivar building: Builds that are actively running 255 255 256 @type slaves: list of L{buildbot.buildslave.BuildSlave} objects 257 @ivar slaves: the slaves currently available for building 256 258 """ 257 259 258 260 expectations = None # this is created the first time we get a good build … … 445 447 """This is invoked by the BuildSlave when the self.slavename bot 446 448 registers their builder. 447 449 448 @type slave: L{buildbot. master.BuildSlave}450 @type slave: L{buildbot.buildslave.BuildSlave} 449 451 @param slave: the BuildSlave that represents the buildslave as a whole 450 452 @type remote: L{twisted.spread.pb.RemoteReference} 451 453 @param remote: a reference to the L{buildbot.slave.bot.SlaveBuilder} -
old-124/buildbot/process/buildstep.py
old new 632 632 def getProperty(self, propname): 633 633 return self.build.getProperty(propname) 634 634 635 def setProperty(self, propname, value ):636 self.build.setProperty(propname, value )635 def setProperty(self, propname, value, source): 636 self.build.setProperty(propname, value, source) 637 637 638 638 def startStep(self, remote): 639 639 """Begin the step. This returns a Deferred that will fire when the … … 1092 1092 self.step_status.setText(self.getText(cmd, results)) 1093 1093 self.step_status.setText2(self.maybeGetText2(cmd, results)) 1094 1094 1095 class _BuildPropertyMapping: 1096 def __init__(self, build): 1097 self.build = build 1098 def __getitem__(self, name): 1099 p = self.build.getProperty(name) 1100 if p is None: 1101 p = "" 1102 return p 1103 1104 class WithProperties(util.ComparableMixin): 1105 """This is a marker class, used in ShellCommand's command= argument to 1106 indicate that we want to interpolate a build property. 1107 """ 1108 1109 compare_attrs = ('fmtstring', 'args') 1110 1111 def __init__(self, fmtstring, *args): 1112 self.fmtstring = fmtstring 1113 self.args = args 1114 1115 def render(self, build): 1116 pmap = _BuildPropertyMapping(build) 1117 if self.args: 1118 strings = [] 1119 for name in self.args: 1120 strings.append(pmap[name]) 1121 s = self.fmtstring % tuple(strings) 1122 else: 1123 s = self.fmtstring % pmap 1124 return s 1125 1126 def render_properties(s, build): 1127 """Return a string based on s and build that is suitable for use 1128 in a running BuildStep. If s is a string, return s. If s is a 1129 WithProperties object, return the result of s.render(build). 1130 Otherwise, return str(s). 1131 """ 1132 if isinstance(s, (str, unicode)): 1133 return s 1134 elif isinstance(s, WithProperties): 1135 return s.render(build) 1136 else: 1137 return str(s) 1095 # (WithProeprties used to be available in this module) 1096 from buildbot.process.properties import WithProperties -
old-124/buildbot/process/properties.py
old new 1 from zope.interface import implements 2 from buildbot import util 3 from twisted.python import log 4 from twisted.python.failure import Failure 5 6 class Properties(util.ComparableMixin): 7 """ 8 I represent a set of properties that can be interpolated into various 9 strings in buildsteps. 10 11 @ivar properties: dictionary mapping property values to tuples 12 (value, source), where source is a string identifing the source 13 of the property. 14 15 Objects of this class can be read like a dictionary -- in this case, 16 only the property value is returned. 17 18 As a special case, a property value of None is returned as an empty 19 string when used as a mapping. 20 """ 21 22 compare_attrs = ('properties') 23 24 def __init__(self, **kwargs): 25 """ 26 @param kwargs: initial property values (for testing) 27 """ 28 self.properties = {} 29 if kwargs: self.update(kwargs, "TEST") 30 31 def __getitem__(self, name): 32 """Just get the value for this property, special-casing None -> ''""" 33 rv = self.properties[name][0] 34 if rv is None: rv = '' 35 return rv 36 37 def has_key(self, name): 38 return self.properties.has_key(name) 39 40 def getProperty(self, name, default=None): 41 """Get the value for the given property, with no None -> '' special case""" 42 return self.properties.get(name, (default,))[0] 43 44 def getPropertySource(self, name): 45 return self.properties[name][1] 46 47 def asList(self): 48 """Return the properties as a sorted list of (name, value, source)""" 49 l = [ (k, v[0], v[1]) for k,v in self.properties.items() ] 50 l.sort() 51 return l 52 53 def __repr__(self): 54 return repr(dict([ (k,v[0]) for k,v in self.properties.iteritems() ])) 55 56 def setProperty(self, name, value, source): 57 self.properties[name] = (value, source) 58 59 def update(self, dict, source): 60 """Update this object from a dictionary, with an explicit source specified.""" 61 for k, v in dict.items(): 62 self.properties[k] = (v, source) 63 64 def updateFromProperties(self, other): 65 """Update this object based on another object; the other object's """ 66 self.properties.update(other.properties) 67 68 def render(self, value): 69 """ 70 Return a variant of value that has any WithProperties objects 71 substituted. This recurses into Python's compound data types. 72 """ 73 if isinstance(value, (str, unicode)): 74 return value 75 elif isinstance(value, WithProperties): 76 return value.render(self) 77 elif isinstance(value, list): 78 return [ self.render(e) for e in value ] 79 elif isinstance(value, tuple): 80 return tuple([ self.render(e) for e in value ]) 81 elif isinstance(value, dict): 82 return dict([ (self.render(k), self.render(v)) for k,v in value.iteritems() ]) 83 else: 84 return value 85 86 class WithProperties(util.ComparableMixin): 87 """This is a marker class, used in ShellCommand's command= argument to 88 indicate that we want to interpolate a build property. 89 """ 90 91 compare_attrs = ('fmtstring', 'args') 92 93 def __init__(self, fmtstring, *args): 94 self.fmtstring = fmtstring 95 self.args = args 96 97 def render(self, properties): 98 if self.args: 99 strings = [] 100 for name in self.args: 101 strings.append(properties[name]) 102 s = self.fmtstring % tuple(strings) 103 else: 104 s = self.fmtstring % properties 105 return s -
old-124/buildbot/scheduler.py
old new 14 14 from buildbot.status import builder 15 15 from buildbot.sourcestamp import SourceStamp 16 16 from buildbot.changes.maildir import MaildirService 17 from buildbot.process.properties import Properties 17 18 18 19 19 20 class BaseScheduler(service.MultiService, util.ComparableMixin): 21 """ 22 A Schduler creates BuildSets and submits them to the BuildMaster. 23 24 @ivar name: name of the scheduler 25 26 @ivar properties: additional properties specified in this 27 scheduler's configuration 28 @type properties: Properties object 29 """ 20 30 implements(interfaces.IScheduler) 21 31 22 def __init__(self, name): 32 def __init__(self, name, properties={}): 33 """ 34 @param name: name for this scheduler 35 36 @param properties: properties to be propagated from this scheduler 37 @type properties: dict 38 """ 23 39 service.MultiService.__init__(self) 24 40 self.name = name 41 self.properties = Properties() 42 self.properties.update(properties, "Scheduler") 43 self.properties.setProperty("scheduler", name, "Scheduler") 25 44 26 45 def __repr__(self): 27 46 # TODO: why can't id() return a positive number? %d is ugly. 28 47 return "<Scheduler '%s' at %d>" % (self.name, id(self)) 29 48 30 def submit (self, bs):49 def submitBuildSet(self, bs): 31 50 self.parent.submitBuildSet(bs) 32 51 33 52 def addChange(self, change): … … 36 55 class BaseUpstreamScheduler(BaseScheduler): 37 56 implements(interfaces.IUpstreamScheduler) 38 57 39 def __init__(self, name ):40 BaseScheduler.__init__(self, name )58 def __init__(self, name, properties={}): 59 BaseScheduler.__init__(self, name, properties) 41 60 self.successWatchers = [] 42 61 43 62 def subscribeToSuccessfulBuilds(self, watcher): … … 45 64 def unsubscribeToSuccessfulBuilds(self, watcher): 46 65 self.successWatchers.remove(watcher) 47 66 48 def submit (self, bs):67 def submitBuildSet(self, bs): 49 68 d = bs.waitUntilFinished() 50 69 d.addCallback(self.buildSetFinished) 51 self.parent.submitBuildSet(bs)70 BaseScheduler.submitBuildSet(self, bs) 52 71 53 72 def buildSetFinished(self, bss): 54 73 if not self.running: … … 69 88 70 89 fileIsImportant = None 71 90 compare_attrs = ('name', 'treeStableTimer', 'builderNames', 'branch', 72 'fileIsImportant' )91 'fileIsImportant', 'properties') 73 92 74 93 def __init__(self, name, branch, treeStableTimer, builderNames, 75 fileIsImportant=None ):94 fileIsImportant=None, properties={}): 76 95 """ 77 96 @param name: the name of this Scheduler 78 97 @param branch: The branch name that the Scheduler should pay … … 94 113 build is triggered by an important change. 95 114 The default value of None means that all 96 115 Changes are important. 116 117 @param properties: properties to apply to all builds started from this 118 scheduler 97 119 """ 98 120 99 BaseUpstreamScheduler.__init__(self, name )121 BaseUpstreamScheduler.__init__(self, name, properties) 100 122 self.treeStableTimer = treeStableTimer 101 123 errmsg = ("The builderNames= argument to Scheduler must be a list " 102 124 "of Builder description names (i.e. the 'name' key of the " … … 171 193 # create a BuildSet, submit it to the BuildMaster 172 194 bs = buildset.BuildSet(self.builderNames, 173 195 SourceStamp(changes=changes), 174 scheduler=self)175 self.submit (bs)196 properties=self.properties) 197 self.submitBuildSet(bs) 176 198 177 199 def stopService(self): 178 200 self.stopTimer() … … 188 210 fileIsImportant = None 189 211 190 212 compare_attrs = ('name', 'branches', 'treeStableTimer', 'builderNames', 191 'fileIsImportant' )213 'fileIsImportant', 'properties') 192 214 193 215 def __init__(self, name, branches, treeStableTimer, builderNames, 194 fileIsImportant=None ):216 fileIsImportant=None, properties={}): 195 217 """ 196 218 @param name: the name of this Scheduler 197 219 @param branches: The branch names that the Scheduler should pay … … 216 238 build is triggered by an important change. 217 239 The default value of None means that all 218 240 Changes are important. 241 242 @param properties: properties to apply to all builds started from this 243 scheduler 219 244 """ 220 245 221 BaseUpstreamScheduler.__init__(self, name )246 BaseUpstreamScheduler.__init__(self, name, properties) 222 247 self.treeStableTimer = treeStableTimer 223 248 for b in builderNames: 224 249 assert isinstance(b, str) … … 272 297 self.schedulers[branch] = s 273 298 s.addChange(change) 274 299 275 def submitBuildSet(self, bs):276 self.parent.submitBuildSet(bs)277 278 300 279 301 class Dependent(BaseUpstreamScheduler): 280 302 """This scheduler runs some set of 'downstream' builds when the 281 303 'upstream' scheduler has completed successfully.""" 282 304 283 compare_attrs = ('name', 'upstream', 'builders' )305 compare_attrs = ('name', 'upstream', 'builders', 'properties') 284 306 285 def __init__(self, name, upstream, builderNames ):307 def __init__(self, name, upstream, builderNames, properties={}): 286 308 assert interfaces.IUpstreamScheduler.providedBy(upstream) 287 BaseUpstreamScheduler.__init__(self, name )309 BaseUpstreamScheduler.__init__(self, name, properties) 288 310 self.upstream = upstream 289 311 self.builderNames = builderNames 290 312 … … 305 327 return d 306 328 307 329 def upstreamBuilt(self, ss): 308 bs = buildset.BuildSet(self.builderNames, ss, scheduler=self) 309 self.submit(bs) 330 bs = buildset.BuildSet(self.builderNames, ss, 331 properties=self.properties) 332 self.submitBuildSet(bs) 310 333 311 334 312 335 … … 319 342 # TODO: consider having this watch another (changed-based) scheduler and 320 343 # merely enforce a minimum time between builds. 321 344 322 compare_attrs = ('name', 'builderNames', 'periodicBuildTimer', 'branch' )345 compare_attrs = ('name', 'builderNames', 'periodicBuildTimer', 'branch', 'properties') 323 346 324 347 def __init__(self, name, builderNames, periodicBuildTimer, 325 branch=None ):326 BaseUpstreamScheduler.__init__(self, name )348 branch=None, properties={}): 349 BaseUpstreamScheduler.__init__(self, name, properties) 327 350 self.builderNames = builderNames 328 351 self.periodicBuildTimer = periodicBuildTimer 329 352 self.branch = branch … … 344 367 def doPeriodicBuild(self): 345 368 bs = buildset.BuildSet(self.builderNames, 346 369 SourceStamp(branch=self.branch), 347 self.reason, scheduler=self) 348 self.submit(bs) 370 self.reason, 371 properties=self.properties) 372 self.submitBuildSet(bs) 349 373 350 374 351 375 … … 389 413 390 414 compare_attrs = ('name', 'builderNames', 391 415 'minute', 'hour', 'dayOfMonth', 'month', 392 'dayOfWeek', 'branch' )416 'dayOfWeek', 'branch', 'properties') 393 417 394 418 def __init__(self, name, builderNames, minute=0, hour='*', 395 419 dayOfMonth='*', month='*', dayOfWeek='*', 396 branch=None ):420 branch=None, properties={}): 397 421 # Setting minute=0 really makes this an 'Hourly' scheduler. This 398 422 # seemed like a better default than minute='*', which would result in 399 423 # a build every 60 seconds. 400 BaseUpstreamScheduler.__init__(self, name )424 BaseUpstreamScheduler.__init__(self, name, properties) 401 425 self.builderNames = builderNames 402 426 self.minute = minute 403 427 self.hour = hour … … 502 526 # And trigger a build 503 527 bs = buildset.BuildSet(self.builderNames, 504 528 SourceStamp(branch=self.branch), 505 self.reason, scheduler=self) 506 self.submit(bs) 529 self.reason, 530 properties=self.properties) 531 self.submitBuildSet(bs) 507 532 508 533 def addChange(self, change): 509 534 pass 510 535 511 536 512 537 513 class TryBase(service.MultiService, util.ComparableMixin): 514 implements(interfaces.IScheduler) 515 516 def __init__(self, name, builderNames): 517 service.MultiService.__init__(self) 518 self.name = name 538 class TryBase(BaseScheduler): 539 def __init__(self, name, builderNames, properties={}): 540 BaseScheduler.__init__(self, name, properties) 519 541 self.builderNames = builderNames 520 542 521 543 def listBuilderNames(self): … … 546 568 self.error = True 547 569 548 570 class Try_Jobdir(TryBase): 549 compare_attrs = ["name", "builderNames", "jobdir"]571 compare_attrs = ( 'name', 'builderNames', 'jobdir', 'properties' ) 550 572 551 def __init__(self, name, builderNames, jobdir ):552 TryBase.__init__(self, name, builderNames )573 def __init__(self, name, builderNames, jobdir, properties={}): 574 TryBase.__init__(self, name, builderNames, properties) 553 575 self.jobdir = jobdir 554 576 self.watcher = MaildirService() 555 577 self.watcher.setServiceParent(self) … … 624 646 return 625 647 626 648 reason = "'try' job" 627 bs = buildset.BuildSet(builderNames, ss, reason=reason, bsid=bsid, scheduler=self) 628 self.parent.submitBuildSet(bs) 649 bs = buildset.BuildSet(builderNames, ss, reason=reason, 650 bsid=bsid, properties=self.properties) 651 self.submitBuildSet(bs) 629 652 630 653 class Try_Userpass(TryBase): 631 compare_attrs = ["name", "builderNames", "port", "userpass"]654 compare_attrs = ( 'name', 'builderNames', 'port', 'userpass', 'properties' ) 632 655 implements(portal.IRealm) 633 656 634 def __init__(self, name, builderNames, port, userpass ):635 TryBase.__init__(self, name, builderNames )657 def __init__(self, name, builderNames, port, userpass, properties={}): 658 TryBase.__init__(self, name, builderNames, properties) 636 659 if type(port) is int: 637 660 port = "tcp:%d" % port 638 661 self.port = port … … 657 680 p = Try_Userpass_Perspective(self, avatarID) 658 681 return (pb.IPerspective, p, lambda: None) 659 682 660 def submitBuildSet(self, bs):661 return self.parent.submitBuildSet(bs)662 663 683 class Try_Userpass_Perspective(pbutil.NewCredPerspective): 664 684 def __init__(self, parent, username): 665 685 self.parent = parent 666 686 self.username = username 667 687 668 def perspective_try(self, branch, revision, patch, builderNames, 669 custom_props): 688 def perspective_try(self, branch, revision, patch, builderNames, properties={}): 670 689 log.msg("user %s requesting build on builders %s" % (self.username, 671 690 builderNames)) 672 691 for b in builderNames: … … 678 697 ss = SourceStamp(branch, revision, patch) 679 698 reason = "'try' job from user %s" % self.username 680 699 700 # roll the specified props in with our inherited props 701 combined_props = Properties() 702 combined_props.updateFromProperties(self.parent.properties) 703 combined_props.update(properties, "try build") 704 681 705 bs = buildset.BuildSet(builderNames, 682 706 ss, 683 707 reason=reason, 684 scheduler=self, 685 custom_props=custom_props) 708 properties=combined_props) 686 709 687 710 self.parent.submitBuildSet(bs) 688 711 … … 696 719 the builds that I fire have finished. 697 720 """ 698 721 699 def __init__(self, name, builderNames): 700 BaseUpstreamScheduler.__init__(self, name) 722 compare_attrs = ('name', 'builderNames', 'properties') 723 724 def __init__(self, name, builderNames, properties={}): 725 BaseUpstreamScheduler.__init__(self, name, properties) 701 726 self.builderNames = builderNames 702 727 703 728 def listBuilderNames(self): … … 706 731 def getPendingBuildTimes(self): 707 732 return [] 708 733 709 def trigger(self, ss, custom_props={}):734 def trigger(self, ss, set_props=None): 710 735 """Trigger this scheduler. Returns a deferred that will fire when the 711 736 buildset is finished. 712 737 """ 713 bs = buildset.BuildSet(self.builderNames, ss, scheduler=self, custom_props=custom_props) 738 739 # properties for this buildset are composed of our own properties, 740 # potentially overridden by anything from the triggering build 741 props = Properties() 742 props.updateFromProperties(self.properties) 743 if set_props: props.updateFromProperties(set_props) 744 745 bs = buildset.BuildSet(self.builderNames, ss, properties=props) 714 746 d = bs.waitUntilFinished() 715 self.submit (bs)747 self.submitBuildSet(bs) 716 748 return d -
old-124/buildbot/scripts/runner.py
old new 763 763 764 764 ["builder", "b", None, 765 765 "Run the trial build on this Builder. Can be used multiple times."], 766 [" customproperties", None, None,767 "A set of customproperties made available in the build environment, format:prop=value,propb=valueb..."],766 ["properties", None, None, 767 "A set of properties made available in the build environment, format:prop=value,propb=valueb..."], 768 768 ] 769 769 770 770 optFlags = [ … … 774 774 def __init__(self): 775 775 super(TryOptions, self).__init__() 776 776 self['builders'] = [] 777 self[' custom_props'] = {}777 self['properties'] = {} 778 778 779 779 def opt_builder(self, option): 780 780 self['builders'].append(option) 781 781 782 def opt_customproperties(self, option): 783 # We need to split the value of this option into a dictionary of custom 784 # properties 785 custom_props = {} 782 def opt_properties(self, option): 783 # We need to split the value of this option into a dictionary of properties 784 properties = {} 786 785 propertylist = option.split(",") 787 786 for i in range(0,len(propertylist)): 788 787 print propertylist[i] 789 788 splitproperty = propertylist[i].split("=") 790 custom_props[splitproperty[0]] = splitproperty[1]791 self[' custom_props'] = custom_props789 properties[splitproperty[0]] = splitproperty[1] 790 self['properties'] = properties 792 791 793 792 def opt_patchlevel(self, option): 794 793 self['patchlevel'] = int(option) -
old-124/buildbot/scripts/tryclient.py
old new 448 448 ss.revision, 449 449 ss.patch, 450 450 self.builderNames, 451 self.config.get(' custom_props', {}))451 self.config.get('properties', {})) 452 452 d.addCallback(self._deliverJob_pb2) 453 453 return d 454 454 def _deliverJob_pb2(self, status): -
old-124/buildbot/status/builder.py
old new 5 5 from twisted.persisted import styles 6 6 from twisted.internet import reactor, defer 7 7 from twisted.protocols import basic 8 from buildbot.process.properties import Properties 8 9 9 10 import os, shutil, sys, re, urllib, itertools 10 11 from cPickle import load, dump … … 888 889 889 890 class BuildStatus(styles.Versioned): 890 891 implements(interfaces.IBuildStatus, interfaces.IStatusEvent) 891 persistenceVersion = 2892 persistenceVersion = 3 892 893 893 894 source = None 894 895 reason = None … … 924 925 self.finishedWatchers = [] 925 926 self.steps = [] 926 927 self.testResults = {} 927 self.properties = {}928 self.properties = Properties() 928 929 929 930 # IBuildStatus 930 931 … … <937 938 def getProperty(self, propname):
![[Buildbot Logo]](/trac/chrome/site/header-text-transparent.png)