Package buildbot :: Module interfaces
[frames] | no frames]

Source Code for Module buildbot.interfaces

   1  # This file is part of Buildbot.  Buildbot is free software: you can 
   2  # redistribute it and/or modify it under the terms of the GNU General Public 
   3  # License as published by the Free Software Foundation, version 2. 
   4  # 
   5  # This program is distributed in the hope that it will be useful, but WITHOUT 
   6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
   7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
   8  # details. 
   9  # 
  10  # You should have received a copy of the GNU General Public License along with 
  11  # this program; if not, write to the Free Software Foundation, Inc., 51 
  12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
  13  # 
  14  # Copyright Buildbot Team Members 
  15   
  16  """Interface documentation. 
  17   
  18  Define the interfaces that are implemented by various buildbot classes. 
  19  """ 
  20  # E0211: Method has no argument 
  21  # E0213: Method should have "self" as first argument 
  22  # pylint: disable-msg=E0211,E0213 
  23   
  24  from zope.interface import Interface, Attribute 
  25   
  26  # exceptions that can be raised while trying to start a build 
27 -class NoSlaveError(Exception):
28 pass
29 -class BuilderInUseError(Exception):
30 pass
31 -class BuildSlaveTooOldError(Exception):
32 pass
33 -class LatentBuildSlaveFailedToSubstantiate(Exception):
34 pass
35 36 # other exceptions
37 -class BuildbotNotRunningError(Exception):
38 pass
39
40 -class ParameterError(Exception):
41 pass
42
43 -class IChangeSource(Interface):
44 """ 45 Service which feeds Change objects to the changemaster. When files or 46 directories are changed in version control, this object should represent 47 the changes as a change dictionary and call:: 48 49 self.master.addChange(who=.., rev=.., ..) 50 51 See 'Writing Change Sources' in the manual for more information. 52 """ 53 master = Attribute('master', 54 'Pointer to BuildMaster, automatically set when started.') 55
56 - def describe():
57 """Return a string which briefly describes this source."""
58
59 -class ISourceStamp(Interface):
60 """ 61 @cvar branch: branch from which source was drawn 62 @type branch: string or None 63 64 @cvar revision: revision of the source, or None to use CHANGES 65 @type revision: varies depending on VC 66 67 @cvar patch: patch applied to the source, or None if no patch 68 @type patch: None or tuple (level diff) 69 70 @cvar changes: the source step should check out the latest revision 71 in the given changes 72 @type changes: tuple of L{buildbot.changes.changes.Change} instances, 73 all of which are on the same branch 74 75 @cvar project: project this source code represents 76 @type project: string 77 78 @cvar repository: repository from which source was drawn 79 @type repository: string 80 """ 81
82 - def canBeMergedWith(self, other):
83 """ 84 Can this SourceStamp be merged with OTHER? 85 """
86
87 - def mergeWith(self, others):
88 """Generate a SourceStamp for the merger of me and all the other 89 SourceStamps. This is called by a Build when it starts, to figure 90 out what its sourceStamp should be."""
91
92 - def getAbsoluteSourceStamp(self, got_revision):
93 """Get a new SourceStamp object reflecting the actual revision found 94 by a Source step."""
95
96 - def getText(self):
97 """Returns a list of strings to describe the stamp. These are 98 intended to be displayed in a narrow column. If more space is 99 available, the caller should join them together with spaces before 100 presenting them to the user."""
101
102 -class IEmailSender(Interface):
103 """I know how to send email, and can be used by other parts of the 104 Buildbot to contact developers.""" 105 pass
106
107 -class IEmailLookup(Interface):
108 - def getAddress(user):
109 """Turn a User-name string into a valid email address. Either return 110 a string (with an @ in it), None (to indicate that the user cannot 111 be reached by email), or a Deferred which will fire with the same."""
112
113 -class IStatus(Interface):
114 """I am an object, obtainable from the buildmaster, which can provide 115 status information.""" 116
117 - def getTitle():
118 """Return the name of the project that this Buildbot is working 119 for."""
120 - def getTitleURL():
121 """Return the URL of this Buildbot's project."""
122 - def getBuildbotURL():
123 """Return the URL of the top-most Buildbot status page, or None if 124 this Buildbot does not provide a web status page."""
125 - def getURLForThing(thing):
126 """Return the URL of a page which provides information on 'thing', 127 which should be an object that implements one of the status 128 interfaces defined in L{buildbot.interfaces}. Returns None if no 129 suitable page is available (or if no Waterfall is running)."""
130
131 - def getChangeSources():
132 """Return a list of IChangeSource objects."""
133
134 - def getChange(number):
135 """Return an IChange object."""
136
137 - def getSchedulers():
138 """Return a list of ISchedulerStatus objects for all 139 currently-registered Schedulers."""
140
141 - def getBuilderNames(categories=None):
142 """Return a list of the names of all current Builders."""
143 - def getBuilder(name):
144 """Return the IBuilderStatus object for a given named Builder. Raises 145 KeyError if there is no Builder by that name."""
146
147 - def getSlaveNames():
148 """Return a list of buildslave names, suitable for passing to 149 getSlave()."""
150 - def getSlave(name):
151 """Return the ISlaveStatus object for a given named buildslave."""
152
153 - def getBuildSets():
154 """ 155 Return a list of un-completed build sets. 156 157 @returns: list of L{IBuildSetStatus} implementations, via Deferred. 158 """
159
160 - def generateFinishedBuilds(builders=[], branches=[], 161 num_builds=None, finished_before=None, 162 max_search=200):
163 """Return a generator that will produce IBuildStatus objects each 164 time you invoke its .next() method, starting with the most recent 165 finished build and working backwards. 166 167 @param builders: this is a list of Builder names, and the generator 168 will only produce builds that ran on the given 169 Builders. If the list is empty, produce builds from 170 all Builders. 171 172 @param branches: this is a list of branch names, and the generator 173 will only produce builds that used the given 174 branches. If the list is empty, produce builds from 175 all branches. 176 177 @param num_builds: the generator will stop after providing this many 178 builds. The default of None means to produce as 179 many builds as possible. 180 181 @type finished_before: int: a timestamp, seconds since the epoch 182 @param finished_before: if provided, do not produce any builds that 183 finished after the given timestamp. 184 185 @type max_search: int 186 @param max_search: this method may have to examine a lot of builds 187 to find some that match the search parameters, 188 especially if there aren't any matching builds. 189 This argument imposes a hard limit on the number 190 of builds that will be examined within any given 191 Builder. 192 """
193
194 - def subscribe(receiver):
195 """Register an IStatusReceiver to receive new status events. The 196 receiver will immediately be sent a set of 'builderAdded' messages 197 for all current builders. It will receive further 'builderAdded' and 198 'builderRemoved' messages as the config file is reloaded and builders 199 come and go. It will also receive 'buildsetSubmitted' messages for 200 all outstanding BuildSets (and each new BuildSet that gets 201 submitted). No additional messages will be sent unless the receiver 202 asks for them by calling .subscribe on the IBuilderStatus objects 203 which accompany the addedBuilder message."""
204
205 - def unsubscribe(receiver):
206 """Unregister an IStatusReceiver. No further status messgaes will be 207 delivered."""
208
209 -class IBuildSetStatus(Interface):
210 """I represent a set of Builds, each run on a separate Builder but all 211 using the same source tree.""" 212
213 - def getReason():
214 pass
215 - def getID():
216 """Return the BuildSet's ID string, if any. The 'try' feature uses a 217 random string as a BuildSetID to relate submitted jobs with the 218 resulting BuildSet."""
219 - def getResponsibleUsers():
220 pass # not implemented
221 - def getInterestedUsers():
222 pass # not implemented
223 - def getBuilderNames():
224 """Return a list of the names of all Builders on which this set will 225 do builds. 226 227 @returns: list of names via Deferred"""
228 - def isFinished():
229 pass
230 - def waitUntilSuccess():
231 """Return a Deferred that fires (with this IBuildSetStatus object) 232 when the outcome of the BuildSet is known, i.e., upon the first 233 failure, or after all builds complete successfully."""
234 - def waitUntilFinished():
235 """Return a Deferred that fires (with this IBuildSetStatus object) 236 when all builds have finished."""
237 - def getResults():
238 """Return SUCCESS/FAILURE, or None if the buildset is not finished 239 yet"""
240 241
242 -class IBuildRequestStatus(Interface):
243 """I represent a request to build a particular set of source code on a 244 particular Builder. These requests may be merged by the time they are 245 finally turned into a Build.""" 246
247 - def getSourceStamp():
248 """ 249 Get a SourceStamp object which can be used to re-create the source tree 250 that this build used. This method will return an absolute SourceStamp 251 if possible, and its results may change as the build progresses. 252 Specifically, a "HEAD" build may later be more accurately specified by 253 an absolute SourceStamp with the specific revision information. 254 255 This method will return None if the source information is no longer 256 available. 257 258 @returns: SourceStamp via Deferred 259 """
260
261 - def getBuilds():
262 """Return a list of IBuildStatus objects for each Build that has been 263 started in an attempt to satify this BuildRequest."""
264
265 - def subscribe(observer):
266 """Register a callable that will be invoked (with a single 267 IBuildStatus object) for each Build that is created to satisfy this 268 request. There may be multiple Builds created in an attempt to handle 269 the request: they may be interrupted by the user or abandoned due to 270 a lost slave. The last Build (the one which actually gets to run to 271 completion) is said to 'satisfy' the BuildRequest. The observer will 272 be called once for each of these Builds, both old and new."""
273 - def unsubscribe(observer):
274 """Unregister the callable that was registered with subscribe()."""
275 - def getSubmitTime():
276 """Return the time when this request was submitted. Returns a 277 Deferred."""
278 279
280 -class ISlaveStatus(Interface):
281 - def getName():
282 """Return the name of the build slave."""
283
284 - def getAdmin():
285 """Return a string with the slave admin's contact data."""
286
287 - def getHost():
288 """Return a string with the slave host info."""
289
290 - def isConnected():
291 """Return True if the slave is currently online, False if not."""
292
293 - def lastMessageReceived():
294 """Return a timestamp (seconds since epoch) indicating when the most 295 recent message was received from the buildslave."""
296
297 -class ISchedulerStatus(Interface):
298 - def getName():
299 """Return the name of this Scheduler (a string)."""
300
301 - def getPendingBuildsets():
302 """Return an IBuildSet for all BuildSets that are pending. These 303 BuildSets are waiting for their tree-stable-timers to expire."""
304 # TODO: this is not implemented anywhere 305 306
307 -class IBuilderStatus(Interface):
308 - def getName():
309 """Return the name of this Builder (a string)."""
310
311 - def getCategory():
312 """Return the category of this builder (a string)."""
313
314 - def getState():
315 # TODO: this isn't nearly as meaningful as it used to be 316 """Return a tuple (state, builds) for this Builder. 'state' is the 317 so-called 'big-status', indicating overall status (as opposed to 318 which step is currently running). It is a string, one of 'offline', 319 'idle', or 'building'. 'builds' is a list of IBuildStatus objects 320 (possibly empty) representing the currently active builds."""
321
322 - def getSlaves():
323 """Return a list of ISlaveStatus objects for the buildslaves that are 324 used by this builder."""
325
327 """ 328 Get a L{IBuildRequestStatus} implementations for all unclaimed build 329 requests. 330 331 @returns: list of objects via Deferred 332 """
333
334 - def getCurrentBuilds():
335 """Return a list containing an IBuildStatus object for each build 336 currently in progress."""
337 # again, we could probably provide an object for 'waiting' and 338 # 'interlocked' too, but things like the Change list might still be 339 # subject to change 340
341 - def getLastFinishedBuild():
342 """Return the IBuildStatus object representing the last finished 343 build, which may be None if the builder has not yet finished any 344 builds."""
345
346 - def getBuild(number):
347 """Return an IBuildStatus object for a historical build. Each build 348 is numbered (starting at 0 when the Builder is first added), 349 getBuild(n) will retrieve the Nth such build. getBuild(-n) will 350 retrieve a recent build, with -1 being the most recent build 351 started. If the Builder is idle, this will be the same as 352 getLastFinishedBuild(). If the Builder is active, it will be an 353 unfinished build. This method will return None if the build is no 354 longer available. Older builds are likely to have less information 355 stored: Logs are the first to go, then Steps."""
356
357 - def getEvent(number):
358 """Return an IStatusEvent object for a recent Event. Builders 359 connecting and disconnecting are events, as are ping attempts. 360 getEvent(-1) will return the most recent event. Events are numbered, 361 but it probably doesn't make sense to ever do getEvent(+n)."""
362
363 - def generateFinishedBuilds(branches=[], 364 num_builds=None, 365 max_buildnum=None, finished_before=None, 366 max_search=200, 367 ):
368 """Return a generator that will produce IBuildStatus objects each 369 time you invoke its .next() method, starting with the most recent 370 finished build, then the previous build, and so on back to the oldest 371 build available. 372 373 @param branches: this is a list of branch names, and the generator 374 will only produce builds that involve the given 375 branches. If the list is empty, the generator will 376 produce all builds regardless of what branch they 377 used. 378 379 @param num_builds: if provided, the generator will stop after 380 providing this many builds. The default of None 381 means to produce as many builds as possible. 382 383 @param max_buildnum: if provided, the generator will start by 384 providing the build with this number, or the 385 highest-numbered preceding build (i.e. the 386 generator will not produce any build numbered 387 *higher* than max_buildnum). The default of None 388 means to start with the most recent finished 389 build. -1 means the same as None. -2 means to 390 start with the next-most-recent completed build, 391 etc. 392 393 @type finished_before: int: a timestamp, seconds since the epoch 394 @param finished_before: if provided, do not produce any builds that 395 finished after the given timestamp. 396 397 @type max_search: int 398 @param max_search: this method may have to examine a lot of builds 399 to find some that match the search parameters, 400 especially if there aren't any matching builds. 401 This argument imposes a hard limit on the number 402 of builds that will be examined. 403 """
404
405 - def subscribe(receiver):
406 """Register an IStatusReceiver to receive new status events. The 407 receiver will be given builderChangedState, buildStarted, and 408 buildFinished messages."""
409
410 - def unsubscribe(receiver):
411 """Unregister an IStatusReceiver. No further status messgaes will be 412 delivered."""
413
414 -class IEventSource(Interface):
415 - def eventGenerator(branches=[], categories=[], committers=[], minTime=0):
416 """This function creates a generator which will yield all of this 417 object's status events, starting with the most recent and progressing 418 backwards in time. These events provide the IStatusEvent interface. 419 At the moment they are all instances of buildbot.status.builder.Event 420 or buildbot.status.builder.BuildStepStatus . 421 422 @param branches: a list of branch names. The generator should only 423 return events that are associated with these branches. If the list is 424 empty, events for all branches should be returned (i.e. an empty list 425 means 'accept all' rather than 'accept none'). 426 427 @param categories: a list of category names. The generator 428 should only return events that are categorized within the 429 given category. If the list is empty, events for all 430 categories should be returned. 431 432 @param comitters: a list of committers. The generator should only 433 return events caused by one of the listed committers. If the list is 434 empty or None, events from every committers should be returned. 435 436 @param minTime: a timestamp. Do not generate events occuring prior to 437 this timestamp. 438 """
439
440 -class IBuildStatus(Interface):
441 """I represent the status of a single Build/BuildRequest. It could be 442 in-progress or finished.""" 443
444 - def getBuilder():
445 """ 446 Return the BuilderStatus that owns this build. 447 448 @rtype: implementor of L{IBuilderStatus} 449 """
450
451 - def isFinished():
452 """Return a boolean. True means the build has finished, False means 453 it is still running."""
454
455 - def waitUntilFinished():
456 """Return a Deferred that will fire when the build finishes. If the 457 build has already finished, this deferred will fire right away. The 458 callback is given this IBuildStatus instance as an argument."""
459
460 - def getProperty(propname):
461 """Return the value of the build property with the given name. Raises 462 KeyError if there is no such property on this build."""
463
464 - def getReason():
465 """Return a string that indicates why the build was run. 'changes', 466 'forced', and 'periodic' are the most likely values. 'try' will be 467 added in the future."""
468
469 - def getSourceStamp():
470 """Return a SourceStamp object which can be used to re-create 471 the source tree that this build used. 472 473 This method will return None if the source information is no longer 474 available."""
475 # TODO: it should be possible to expire the patch but still remember 476 # that the build was r123+something. 477
478 - def getChanges():
479 """Return a list of Change objects which represent which source 480 changes went into the build."""
481
482 - def getResponsibleUsers():
483 """Return a list of Users who are to blame for the changes that went 484 into this build. If anything breaks (at least anything that wasn't 485 already broken), blame them. Specifically, this is the set of users 486 who were responsible for the Changes that went into this build. Each 487 User is a string, corresponding to their name as known by the VC 488 repository."""
489
490 - def getInterestedUsers():
491 """Return a list of Users who will want to know about the results of 492 this build. This is a superset of getResponsibleUsers(): it adds 493 people who are interested in this build but who did not actually 494 make the Changes that went into it (build sheriffs, code-domain 495 owners)."""
496
497 - def getNumber():
498 """Within each builder, each Build has a number. Return it."""
499
500 - def getPreviousBuild():
501 """Convenience method. Returns None if the previous build is 502 unavailable."""
503
504 - def getSteps():
505 """Return a list of IBuildStepStatus objects. For invariant builds 506 (those which always use the same set of Steps), this should always 507 return the complete list, however some of the steps may not have 508 started yet (step.getTimes()[0] will be None). For variant builds, 509 this may not be complete (asking again later may give you more of 510 them)."""
511
512 - def getTimes():
513 """Returns a tuple of (start, end). 'start' and 'end' are the times 514 (seconds since the epoch) when the Build started and finished. If 515 the build is still running, 'end' will be None."""
516 517 # while the build is running, the following methods make sense. 518 # Afterwards they return None 519
520 - def getETA():
521 """Returns the number of seconds from now in which the build is 522 expected to finish, or None if we can't make a guess. This guess will 523 be refined over time."""
524
525 - def getCurrentStep():
526 """Return an IBuildStepStatus object representing the currently 527 active step."""
528 529 # Once you know the build has finished, the following methods are legal. 530 # Before ths build has finished, they all return None. 531
532 - def getSlavename():
533 """Return the name of the buildslave which handled this build."""
534
535 - def getText():
536 """Returns a list of strings to describe the build. These are 537 intended to be displayed in a narrow column. If more space is 538 available, the caller should join them together with spaces before 539 presenting them to the user."""
540
541 - def getResults():
542 """Return a constant describing the results of the build: one of the 543 constants in buildbot.status.builder: SUCCESS, WARNINGS, 544 FAILURE, SKIPPED or EXCEPTION."""
545
546 - def getLogs():
547 """Return a list of logs that describe the build as a whole. Some 548 steps will contribute their logs, while others are are less important 549 and will only be accessible through the IBuildStepStatus objects. 550 Each log is an object which implements the IStatusLog interface."""
551
552 - def getTestResults():
553 """Return a dictionary that maps test-name tuples to ITestResult 554 objects. This may return an empty or partially-filled dictionary 555 until the build has completed."""
556 557 # subscription interface 558
559 - def subscribe(receiver, updateInterval=None):
560 """Register an IStatusReceiver to receive new status events. The 561 receiver will be given stepStarted and stepFinished messages. If 562 'updateInterval' is non-None, buildETAUpdate messages will be sent 563 every 'updateInterval' seconds."""
564
565 - def unsubscribe(receiver):
566 """Unregister an IStatusReceiver. No further status messgaes will be 567 delivered."""
568
569 -class ITestResult(Interface):
570 """I describe the results of a single unit test.""" 571
572 - def getName():
573 """Returns a tuple of strings which make up the test name. Tests may 574 be arranged in a hierarchy, so looking for common prefixes may be 575 useful."""
576
577 - def getResults():
578 """Returns a constant describing the results of the test: SUCCESS, 579 WARNINGS, FAILURE."""
580
581 - def getText():
582 """Returns a list of short strings which describe the results of the 583 test in slightly more detail. Suggested components include 584 'failure', 'error', 'passed', 'timeout'."""
585
586 - def getLogs():
587 # in flux, it may be possible to provide more structured information 588 # like python Failure instances 589 """Returns a dictionary of test logs. The keys are strings like 590 'stdout', 'log', 'exceptions'. The values are strings."""
591 592
593 -class IBuildStepStatus(Interface):
594 """I hold status for a single BuildStep.""" 595
596 - def getName():
597 """Returns a short string with the name of this step. This string 598 may have spaces in it."""
599
600 - def getBuild():
601 """Returns the IBuildStatus object which contains this step."""
602
603 - def getTimes():
604 """Returns a tuple of (start, end). 'start' and 'end' are the times 605 (seconds since the epoch) when the Step started and finished. If the 606 step has not yet started, 'start' will be None. If the step is still 607 running, 'end' will be None."""
608
609 - def getExpectations():
610 """Returns a list of tuples (name, current, target). Each tuple 611 describes a single axis along which the step's progress can be 612 measured. 'name' is a string which describes the axis itself, like 613 'filesCompiled' or 'tests run' or 'bytes of output'. 'current' is a 614 number with the progress made so far, while 'target' is the value 615 that we expect (based upon past experience) to get to when the build 616 is finished. 617 618 'current' will change over time until the step is finished. It is 619 'None' until the step starts. When the build is finished, 'current' 620 may or may not equal 'target' (which is merely the expectation based 621 upon previous builds)."""
622
623 - def getURLs():
624 """Returns a dictionary of URLs. Each key is a link name (a short 625 string, like 'results' or 'coverage'), and each value is a URL. These 626 links will be displayed along with the LogFiles. 627 """
628
629 - def getLogs():
630 """Returns a list of IStatusLog objects. If the step has not yet 631 finished, this list may be incomplete (asking again later may give 632 you more of them)."""
633 634
635 - def isFinished():
636 """Return a boolean. True means the step has finished, False means it 637 is still running."""
638
639 - def waitUntilFinished():
640 """Return a Deferred that will fire when the step finishes. If the 641 step has already finished, this deferred will fire right away. The 642 callback is given this IBuildStepStatus instance as an argument."""
643 644 # while the step is running, the following methods make sense. 645 # Afterwards they return None 646
647 - def getETA():
648 """Returns the number of seconds from now in which the step is 649 expected to finish, or None if we can't make a guess. This guess will 650 be refined over time."""
651 652 # Once you know the step has finished, the following methods are legal. 653 # Before ths step has finished, they all return None. 654
655 - def getText():
656 """Returns a list of strings which describe the step. These are 657 intended to be displayed in a narrow column. If more space is 658 available, the caller should join them together with spaces before 659 presenting them to the user."""
660
661 - def getResults():
662 """Return a tuple describing the results of the step: (result, 663 strings). 'result' is one of the constants in 664 buildbot.status.builder: SUCCESS, WARNINGS, FAILURE, or SKIPPED. 665 'strings' is an optional list of strings that the step wants to 666 append to the overall build's results. These strings are usually 667 more terse than the ones returned by getText(): in particular, 668 successful Steps do not usually contribute any text to the overall 669 build."""
670 671 # subscription interface 672
673 - def subscribe(receiver, updateInterval=10):
674 """Register an IStatusReceiver to receive new status events. The 675 receiver will be given logStarted and logFinished messages. It will 676 also be given a ETAUpdate message every 'updateInterval' seconds."""
677
678 - def unsubscribe(receiver):
679 """Unregister an IStatusReceiver. No further status messgaes will be 680 delivered."""
681
682 -class IStatusEvent(Interface):
683 """I represent a Builder Event, something non-Build related that can 684 happen to a Builder.""" 685
686 - def getTimes():
687 """Returns a tuple of (start, end) like IBuildStepStatus, but end==0 688 indicates that this is a 'point event', which has no duration. 689 SlaveConnect/Disconnect are point events. Ping is not: it starts 690 when requested and ends when the response (positive or negative) is 691 returned"""
692
693 - def getText():
694 """Returns a list of strings which describe the event. These are 695 intended to be displayed in a narrow column. If more space is 696 available, the caller should join them together with spaces before 697 presenting them to the user."""
698 699 700 LOG_CHANNEL_STDOUT = 0 701 LOG_CHANNEL_STDERR = 1 702 LOG_CHANNEL_HEADER = 2 703
704 -class IStatusLog(Interface):
705 """I represent a single Log, which is a growing list of text items that 706 contains some kind of output for a single BuildStep. I might be finished, 707 in which case this list has stopped growing. 708 709 Each Log has a name, usually something boring like 'log' or 'output'. 710 These names are not guaranteed to be unique, however they are usually 711 chosen to be useful within the scope of a single step (i.e. the Compile 712 step might produce both 'log' and 'warnings'). The name may also have 713 spaces. If you want something more globally meaningful, at least within a 714 given Build, try:: 715 716 '%s.%s' % (log.getStep.getName(), log.getName()) 717 718 The Log can be presented as plain text, or it can be accessed as a list 719 of items, each of which has a channel indicator (header, stdout, stderr) 720 and a text chunk. An HTML display might represent the interleaved 721 channels with different styles, while a straight download-the-text 722 interface would just want to retrieve a big string. 723 724 The 'header' channel is used by ShellCommands to prepend a note about 725 which command is about to be run ('running command FOO in directory 726 DIR'), and append another note giving the exit code of the process. 727 728 Logs can be streaming: if the Log has not yet finished, you can 729 subscribe to receive new chunks as they are added. 730 731 A ShellCommand will have a Log associated with it that gathers stdout 732 and stderr. Logs may also be created by parsing command output or 733 through other synthetic means (grepping for all the warnings in a 734 compile log, or listing all the test cases that are going to be run). 735 Such synthetic Logs are usually finished as soon as they are created.""" 736 737
738 - def getName():
739 """Returns a short string with the name of this log, probably 'log'. 740 """
741
742 - def getStep():
743 """Returns the IBuildStepStatus which owns this log."""
744 # TODO: can there be non-Step logs? 745
746 - def isFinished():
747 """Return a boolean. True means the log has finished and is closed, 748 False means it is still open and new chunks may be added to it."""
749
750 - def waitUntilFinished():
751 """Return a Deferred that will fire when the log is closed. If the 752 log has already finished, this deferred will fire right away. The 753 callback is given this IStatusLog instance as an argument."""
754
755 - def subscribe(receiver, catchup):
756 """Register an IStatusReceiver to receive chunks (with logChunk) as 757 data is added to the Log. If you use this, you will also want to use 758 waitUntilFinished to find out when the listener can be retired. 759 Subscribing to a closed Log is a no-op. 760 761 If 'catchup' is True, the receiver will immediately be sent a series 762 of logChunk messages to bring it up to date with the partially-filled 763 log. This allows a status client to join a Log already in progress 764 without missing any data. If the Log has already finished, it is too 765 late to catch up: just do getText() instead. 766 767 If the Log is very large, the receiver will be called many times with 768 a lot of data. There is no way to throttle this data. If the receiver 769 is planning on sending the data on to somewhere else, over a narrow 770 connection, you can get a throttleable subscription by using 771 C{subscribeConsumer} instead."""
772
773 - def unsubscribe(receiver):
774 """Remove a receiver previously registered with subscribe(). Attempts 775 to remove a receiver which was not previously registered is a no-op. 776 """
777
778 - def subscribeConsumer(consumer):
779 """Register an L{IStatusLogConsumer} to receive all chunks of the 780 logfile, including all the old entries and any that will arrive in 781 the future. The consumer will first have their C{registerProducer} 782 method invoked with a reference to an object that can be told 783 C{pauseProducing}, C{resumeProducing}, and C{stopProducing}. Then the 784 consumer's C{writeChunk} method will be called repeatedly with each 785 (channel, text) tuple in the log, starting with the very first. The 786 consumer will be notified with C{finish} when the log has been 787 exhausted (which can only happen when the log is finished). Note that 788 a small amount of data could be written via C{writeChunk} even after 789 C{pauseProducing} has been called. 790 791 To unsubscribe the consumer, use C{producer.stopProducing}."""
792 793 # once the log has finished, the following methods make sense. They can 794 # be called earlier, but they will only return the contents of the log up 795 # to the point at which they were called. You will lose items that are 796 # added later. Use C{subscribe} or C{subscribeConsumer} to avoid missing 797 # anything. 798
799 - def hasContents():
800 """Returns True if the LogFile still has contents available. Returns 801 False for logs that have been pruned. Clients should test this before 802 offering to show the contents of any log."""
803
804 - def getText():
805 """Return one big string with the contents of the Log. This merges 806 all non-header chunks together."""
807
808 - def readlines(channel=LOG_CHANNEL_STDOUT):
809 """Read lines from one channel of the logfile. This returns an 810 iterator that will provide single lines of text (including the 811 trailing newline). 812 """
813
814 - def getTextWithHeaders():
815 """Return one big string with the contents of the Log. This merges 816 all chunks (including headers) together."""
817
818 - def getChunks():
819 """Generate a list of (channel, text) tuples. 'channel' is a number, 820 0 for stdout, 1 for stderr, 2 for header. (note that stderr is merged 821 into stdout if PTYs are in use)."""
822
823 -class IStatusLogConsumer(Interface):
824 """I am an object which can be passed to IStatusLog.subscribeConsumer(). 825 I represent a target for writing the contents of an IStatusLog. This 826 differs from a regular IStatusReceiver in that it can pause the producer. 827 This makes it more suitable for use in streaming data over network 828 sockets, such as an HTTP request. Note that the consumer can only pause 829 the producer until it has caught up with all the old data. After that 830 point, C{pauseProducing} is ignored and all new output from the log is 831 sent directoy to the consumer.""" 832
833 - def registerProducer(producer, streaming):
834 """A producer is being hooked up to this consumer. The consumer only 835 has to handle a single producer. It should send .pauseProducing and 836 .resumeProducing messages to the producer when it wants to stop or 837 resume the flow of data. 'streaming' will be set to True because the 838 producer is always a PushProducer. 839 """
840
841 - def unregisterProducer():
842 """The previously-registered producer has been removed. No further 843 pauseProducing or resumeProducing calls should be made. The consumer 844 should delete its reference to the Producer so it can be released."""
845
846 - def writeChunk(chunk):
847 """A chunk (i.e. a tuple of (channel, text)) is being written to the 848 consumer."""
849
850 - def finish():
851 """The log has finished sending chunks to the consumer."""
852
853 -class IStatusReceiver(Interface):
854 """I am an object which can receive build status updates. I may be 855 subscribed to an IStatus, an IBuilderStatus, or an IBuildStatus.""" 856
857 - def buildsetSubmitted(buildset):
858 """A new BuildSet has been submitted to the buildmaster. 859 860 @type buildset: implementor of L{IBuildSetStatus} 861 """
862
863 - def requestSubmitted(request):
864 """A new BuildRequest has been submitted to the buildmaster. 865 866 @type request: implementor of L{IBuildRequestStatus} 867 """
868
869 - def requestCancelled(builder, request):
870 """A BuildRequest has been cancelled on the given Builder. 871 872 @type builder: L{buildbot.status.builder.BuilderStatus} 873 @type request: implementor of L{IBuildRequestStatus} 874 """
875
876 - def builderAdded(builderName, builder):
877 """ 878 A new Builder has just been added. This method may return an 879 IStatusReceiver (probably 'self') which will be subscribed to receive 880 builderChangedState and buildStarted/Finished events. 881 882 @type builderName: string 883 @type builder: L{buildbot.status.builder.BuilderStatus} 884 @rtype: implementor of L{IStatusReceiver} 885 """
886
887 - def builderChangedState(builderName, state):
888 """Builder 'builderName' has changed state. The possible values for 889 'state' are 'offline', 'idle', and 'building'."""
890
891 - def buildStarted(builderName, build):
892 """Builder 'builderName' has just started a build. The build is an 893 object which implements IBuildStatus, and can be queried for more 894 information. 895 896 This method may return an IStatusReceiver (it could even return 897 'self'). If it does so, stepStarted and stepFinished methods will be 898 invoked on the object for the steps of this one build. This is a 899 convenient way to subscribe to all build steps without missing any. 900 This receiver will automatically be unsubscribed when the build 901 finishes. 902 903 It can also return a tuple of (IStatusReceiver, interval), in which 904 case buildETAUpdate messages are sent ever 'interval' seconds, in 905 addition to the stepStarted and stepFinished messages."""
906
907 - def buildETAUpdate(build, ETA):
908 """This is a periodic update on the progress this Build has made 909 towards completion."""
910
911 - def changeAdded(change):
912 """A new Change was added to the ChangeMaster. By the time this event 913 is received, all schedulers have already received the change."""
914
915 - def stepStarted(build, step):
916 """A step has just started. 'step' is the IBuildStepStatus which 917 represents the step: it can be queried for more information. 918 919 This method may return an IStatusReceiver (it could even return 920 'self'). If it does so, logStarted and logFinished methods will be 921 invoked on the object for logs created by this one step. This 922 receiver will be automatically unsubscribed when the step finishes. 923 924 Alternatively, the method may return a tuple of an IStatusReceiver 925 and an integer named 'updateInterval'. In addition to 926 logStarted/logFinished messages, it will also receive stepETAUpdate 927 messages about every updateInterval seconds."""
928
929 - def stepTextChanged(build, step, text):
930 """The text for a step has been updated. 931 932 This is called when calling setText() on the step status, and 933 hands in the text list."""
934
935 - def stepText2Changed(build, step, text2):
936 """The text2 for a step has been updated. 937 938 This is called when calling setText2() on the step status, and 939 hands in text2 list."""
940
941 - def stepETAUpdate(build, step, ETA, expectations):
942 """This is a periodic update on the progress this Step has made 943 towards completion. It gets an ETA (in seconds from the present) of 944 when the step ought to be complete, and a list of expectation tuples 945 (as returned by IBuildStepStatus.getExpectations) with more detailed 946 information."""
947
948 - def logStarted(build, step, log):
949 """A new Log has been started, probably because a step has just 950 started running a shell command. 'log' is the IStatusLog object 951 which can be queried for more information. 952 953 This method may return an IStatusReceiver (such as 'self'), in which 954 case the target's logChunk method will be invoked as text is added to 955 the logfile. This receiver will automatically be unsubsribed when the 956 log finishes."""
957
958 - def logChunk(build, step, log, channel, text):
959 """Some text has been added to this log. 'channel' is one of 960 LOG_CHANNEL_STDOUT, LOG_CHANNEL_STDERR, or LOG_CHANNEL_HEADER, as 961 defined in IStatusLog.getChunks."""
962
963 - def logFinished(build, step, log):
964 """A Log has been closed."""
965
966 - def stepFinished(build, step, results):
967 """A step has just finished. 'results' is the result tuple described 968 in IBuildStepStatus.getResults."""
969
970 - def buildFinished(builderName, build, results):
971 """ 972 A build has just finished. 'results' is the result tuple described 973 in L{IBuildStatus.getResults}. 974 975 @type builderName: string 976 @type build: L{buildbot.status.build.BuildStatus} 977 @type results: tuple 978 """
979
980 - def builderRemoved(builderName):
981 """The Builder has been removed."""
982
983 - def slaveConnected(slaveName):
984 """The slave has connected."""
985
986 - def slaveDisconnected(slaveName):
987 """The slave has disconnected."""
988
989 -class IControl(Interface):
990 - def addChange(change):
991 """Add a change to the change queue, for analysis by schedulers."""
992
993 - def getBuilder(name):
994 """Retrieve the IBuilderControl object for the given Builder."""
995
996 -class IBuilderControl(Interface):
997 - def submitBuildRequest(ss, reason, props=None):
998 """Create a BuildRequest, which will eventually cause a build of the 999 given SourceStamp to be run on this builder. This returns a 1000 BuildRequestStatus object via a Deferred, which can be used to keep 1001 track of the builds that are performed."""
1002
1003 - def rebuildBuild(buildStatus, reason="<rebuild, no reason given>"):
1004 """Rebuild something we've already built before. This submits a 1005 BuildRequest to our Builder using the same SourceStamp as the earlier 1006 build. This has no effect (but may eventually raise an exception) if 1007 this Build has not yet finished."""
1008
1010 """ 1011 Get a list of L{IBuildRequestControl} objects for this Builder. 1012 Each one corresponds to an unclaimed build request. 1013 1014 @returns: list of objects via Deferred 1015 """
1016
1017 - def getBuild(number):
1018 """Attempt to return an IBuildControl object for the given build. 1019 Returns None if no such object is available. This will only work for 1020 the build that is currently in progress: once the build finishes, 1021 there is nothing to control anymore."""
1022
1023 - def ping():
1024 """Attempt to contact the slave and see if it is still alive. This 1025 returns a Deferred which fires with either True (the slave is still 1026 alive) or False (the slave did not respond). As a side effect, adds an 1027 event to this builder's column in the waterfall display containing the 1028 results of the ping. Note that this may not fail for a long time, it is 1029 implemented in terms of the timeout on the underlying TCP connection."""
1030 # TODO: this ought to live in ISlaveControl, maybe with disconnect() 1031 # or something. However the event that is emitted is most useful in 1032 # the Builder column, so it kinda fits here too. 1033
1034 -class IBuildRequestControl(Interface):
1035 - def subscribe(observer):
1036 """Register a callable that will be invoked (with a single 1037 IBuildControl object) for each Build that is created to satisfy this 1038 request. There may be multiple Builds created in an attempt to handle 1039 the request: they may be interrupted by the user or abandoned due to 1040 a lost slave. The last Build (the one which actually gets to run to 1041 completion) is said to 'satisfy' the BuildRequest. The observer will 1042 be called once for each of these Builds, both old and new."""
1043 - def unsubscribe(observer):
1044 """Unregister the callable that was registered with subscribe()."""
1045 - def cancel():
1046 """Remove the build from the pending queue. Has no effect if the 1047 build has already been started."""
1048
1049 -class IBuildControl(Interface):
1050 - def getStatus():
1051 """Return an IBuildStatus object for the Build that I control."""
1052 - def stopBuild(reason="<no reason given>"):
1053 """Halt the build. This has no effect if the build has already 1054 finished."""
1055
1056 -class ILogFile(Interface):
1057 """This is the internal interface to a LogFile, used by the BuildStep to 1058 write data into the log. 1059 """
1060 - def addStdout(data):
1061 pass
1062 - def addStderr(data):
1063 pass
1064 - def addHeader(data):
1065 pass
1066 - def finish():
1067 """The process that is feeding the log file has finished, and no 1068 further data will be added. This closes the logfile."""
1069
1070 -class ILogObserver(Interface):
1071 """Objects which provide this interface can be used in a BuildStep to 1072 watch the output of a LogFile and parse it incrementally. 1073 """ 1074 1075 # internal methods
1076 - def setStep(step):
1077 pass
1078 - def setLog(log):
1079 pass
1080 1081 # methods called by the LogFile
1082 - def logChunk(build, step, log, channel, text):
1083 pass
1084
1085 -class IBuildSlave(Interface):
1086 # this is a marker interface for the BuildSlave class 1087 pass
1088
1089 -class ILatentBuildSlave(IBuildSlave):
1090 """A build slave that is not always running, but can run when requested. 1091 """ 1092 substantiated = Attribute('Substantiated', 1093 'Whether the latent build slave is currently ' 1094 'substantiated with a real instance.') 1095
1096 - def substantiate():
1097 """Request that the slave substantiate with a real instance. 1098 1099 Returns a deferred that will callback when a real instance has 1100 attached."""
1101 1102 # there is an insubstantiate too, but that is not used externally ATM. 1103
1104 - def buildStarted(sb):
1105 """Inform the latent build slave that a build has started. 1106 1107 @param sb: a L{LatentSlaveBuilder}. The sb is the one for whom the 1108 build finished. 1109 """
1110
1111 - def buildFinished(sb):
1112 """Inform the latent build slave that a build has finished. 1113 1114 @param sb: a L{LatentSlaveBuilder}. The sb is the one for whom the 1115 build finished. 1116 """
1117
1118 -class IRenderable(Interface):
1119 """An object that can be interpolated with properties from a build. 1120 """ 1121
1122 - def getRenderingFor(iprops):
1123 """Return the interpolation with the given properties 1124 1125 @param iprops: the L{IProperties} provider supplying the properties. 1126 """
1127 -class IProperties(Interface):
1128 """ 1129 An object providing access to build properties 1130 """ 1131
1132 - def getProperty(name, default=None):
1133 """Get the named property, returning the default if the property does 1134 not exist. 1135 1136 @param name: property name 1137 @type name: string 1138 1139 @param default: default value (default: @code{None}) 1140 1141 @returns: property value 1142 """
1143
1144 - def hasProperty(name):
1145 """Return true if the named property exists. 1146 1147 @param name: property name 1148 @type name: string 1149 @returns: boolean 1150 """
1151
1152 - def has_key(name):
1153 """Deprecated name for L{hasProperty}."""
1154
1155 - def setProperty(name, value, source, runtime=False):
1156 """Set the given property, overwriting any existing value. The source 1157 describes the source of the value for human interpretation. 1158 1159 @param name: property name 1160 @type name: string 1161 1162 @param value: property value 1163 @type value: JSON-able value 1164 1165 @param source: property source 1166 @type source: string 1167 1168 @param runtime: (optional) whether this property was set during the 1169 build's runtime: usually left at its default value 1170 @type runtime: boolean 1171 """
1172
1173 - def getProperties():
1174 """Get the L{buildbot.process.properties.Properties} instance storing 1175 these properties. Note that the interface for this class is not 1176 stable, so where possible the other methods of this interface should be 1177 used. 1178 1179 @returns: L{buildbot.process.properties.Properties} instance 1180 """
1181
1182 - def getBuild():
1183 """Get the L{buildbot.process.build.Build} instance for the current 1184 build. Note that this object is not available after the build is 1185 complete, at which point this method will return None. 1186 1187 Try to avoid using this method, as the API of L{Build} instances is not 1188 well-defined. 1189 1190 @returns L{buildbot.process.build.Build} instance 1191 """
1192
1193 - def render(value):
1194 """Render @code{value} as an L{IRenderable}. This essentially coerces 1195 @code{value} to an L{IRenderable} and calls its @L{getRenderingFor} 1196 method. 1197 1198 @name value: value to render 1199 @returns: rendered value 1200 """
1201