Changeset 2

Show
Ignore:
Timestamp:
11/25/05 18:09:24 (3 years ago)
Author:
warner
Message:

[project @ 2005-11-26 02:09:24 by warner]
Revision: arch@buildbot.sf.net--2004/buildbot--dev--0--patch-438
Creator: Brian Warner <warner@lothar.com>

add cron-style 'scheduler.Nightly', thanks to Dobes Vandermeer

  • docs/buildbot.texinfo (Scheduler Types): give a few hints about
    what Schedulers are available
  • buildbot/scheduler.py (Nightly): add new Scheduler based upon
    work by Dobes Vandermeer and hacked mercilessly by me. This offers
    'cron'-style build scheduling at certain times of day, week,
    month, or year.
  • buildbot/test/test_scheduler.py (Scheduling.testNightly): test it
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ChangeLog

    r1 r2  
    112005-11-25  Brian Warner  <warner@lothar.com> 
     2 
     3        * docs/buildbot.texinfo (Scheduler Types): give a few hints about 
     4        what Schedulers are available 
     5 
     6        * buildbot/scheduler.py (Nightly): add new Scheduler based upon 
     7        work by Dobes Vandermeer and hacked mercilessly by me. This offers 
     8        'cron'-style build scheduling at certain times of day, week, 
     9        month, or year. 
     10        * buildbot/test/test_scheduler.py (Scheduling.testNightly): test it 
    211 
    312        * buildbot/scheduler.py (Scheduler): change fileIsImportant 
  • buildbot/scheduler.py

    r1 r2  
    339339                               SourceStamp(branch=self.branch)) 
    340340        self.submit(bs) 
     341 
     342 
     343 
     344class Nightly(BaseUpstreamScheduler): 
     345    """Imitate 'cron' scheduling. This can be used to schedule a nightly 
     346    build, or one which runs are certain times of the day, week, or month. 
     347 
     348    Pass some subset of minute, hour, dayOfMonth, month, and dayOfWeek; each 
     349    may be a single number or a list of valid values. The builds will be 
     350    triggered whenever the current time matches these values. Wildcards are 
     351    represented by a '*' string. All fields default to a wildcard except 
     352    'minute', so with no fields this defaults to a build every hour, on the 
     353    hour. 
     354 
     355    For example, the following master.cfg clause will cause a build to be 
     356    started every night at 3:00am: 
     357 
     358     s = Nightly('nightly', ['builder1', 'builder2'], hour=3, minute=0) 
     359     c['schedules'].append(s) 
     360 
     361    This scheduler will perform a build each monday morning at 6:23am and 
     362    again at 8:23am: 
     363 
     364     s = Nightly('BeforeWork', ['builder1'], 
     365                 dayOfWeek=0, hour=[6,8], minute=23) 
     366 
     367    The following runs a build every two hours: 
     368 
     369     s = Nightly('every2hours', ['builder1'], hour=range(0, 24, 2)) 
     370 
     371    And this one will run only on December 24th: 
     372 
     373     s = Nightly('SleighPreflightCheck', ['flying_circuits', 'radar'], 
     374                 month=12, dayOfMonth=24, hour=12, minute=0) 
     375 
     376    For dayOfWeek and dayOfMonth, builds are triggered if the date matches 
     377    either of them.  Month and day numbers start at 1, not zero. 
     378    """ 
     379 
     380    compare_attrs = ('name', 'builderNames', 
     381                     'minute', 'hour', 'dayOfMonth', 'month', 
     382                     'dayOfWeek', 'branch') 
     383 
     384    def __init__(self, name, builderNames, minute=0, hour='*', 
     385                 dayOfMonth='*', month='*', dayOfWeek='*', 
     386                 branch=None): 
     387        # Setting minute=0 really makes this an 'Hourly' scheduler. This 
     388        # seemed like a better default than minute='*', which would result in 
     389        # a build every 60 seconds. 
     390        BaseUpstreamScheduler.__init__(self, name) 
     391        self.builderNames = builderNames 
     392        self.minute = minute 
     393        self.hour = hour 
     394        self.dayOfMonth = dayOfMonth 
     395        self.month = month 
     396        self.dayOfWeek = dayOfWeek 
     397        self.branch = branch 
     398        self.delayedRun = None 
     399        self.nextRunTime = None 
     400 
     401    def addTime(self, timetuple, secs): 
     402        return time.localtime(time.mktime(timetuple)+secs) 
     403    def findFirstValueAtLeast(self, values, value, default=None): 
     404        for v in values: 
     405            if v >= value: return v 
     406        return default 
     407 
     408    def setTimer(self): 
     409        self.nextRunTime = self.calculateNextRunTime() 
     410        self.delayedRun = reactor.callLater(self.nextRunTime - time.time(), 
     411                                            self.doPeriodicBuild) 
     412 
     413    def startService(self): 
     414        BaseUpstreamScheduler.startService(self) 
     415        self.setTimer() 
     416 
     417    def stopService(self): 
     418        BaseUpstreamScheduler.stopService(self) 
     419        self.delayedRun.cancel() 
     420 
     421    def isRunTime(self, timetuple): 
     422        def check(ourvalue, value): 
     423            if ourvalue == '*': return True 
     424            if isinstance(ourvalue, int): return value == ourvalue 
     425            return (value in ourvalue) 
     426 
     427        if not check(self.minute, timetuple[4]): 
     428            #print 'bad minute', timetuple[4], self.minute 
     429            return False 
     430 
     431        if not check(self.hour, timetuple[3]): 
     432            #print 'bad hour', timetuple[3], self.hour 
     433            return False 
     434 
     435        if not check(self.month, timetuple[1]): 
     436            #print 'bad month', timetuple[1], self.month 
     437            return False 
     438 
     439        if self.dayOfMonth != '*' and self.dayOfWeek != '*': 
     440            # They specified both day(s) of month AND day(s) of week. 
     441            # This means that we only have to match one of the two. If 
     442            # neither one matches, this time is not the right time. 
     443            if not (check(self.dayOfMonth, timetuple[2]) or 
     444                    check(self.dayOfWeek, timetuple[6])): 
     445                #print 'bad day' 
     446                return False 
     447        else: 
     448            if not check(self.dayOfMonth, timetuple[2]): 
     449                #print 'bad day of month' 
     450                return False 
     451 
     452            if not check(self.dayOfWeek, timetuple[6]): 
     453                #print 'bad day of week' 
     454                return False 
     455 
     456        return True 
     457 
     458    def calculateNextRunTime(self): 
     459        return self.calculateNextRunTimeFrom(time.time()) 
     460 
     461    def calculateNextRunTimeFrom(self, now): 
     462        dateTime = time.localtime(now) 
     463 
     464        # Remove seconds by advancing to at least the next minue 
     465        dateTime = self.addTime(dateTime, 60-dateTime[5]) 
     466 
     467        # Now we just keep adding minutes until we find something that matches 
     468 
     469        # It not an efficient algorithm, but it'll *work* for now 
     470        yearLimit = dateTime[0]+2 
     471        while not self.isRunTime(dateTime): 
     472            dateTime = self.addTime(dateTime, 60) 
     473            #print 'Trying', time.asctime(dateTime) 
     474            assert dateTime[0] < yearLimit, 'Something is wrong with this code' 
     475        return time.mktime(dateTime) 
     476 
     477    def listBuilderNames(self): 
     478        return self.builderNames 
     479 
     480    def getPendingBuildTimes(self): 
     481        # TODO: figure out when self.timer is going to fire next and report 
     482        # that 
     483        if self.nextRunTime is None: return [] 
     484        return [self.nextRunTime] 
     485 
     486    def doPeriodicBuild(self): 
     487        # Schedule the next run 
     488        self.setTimer() 
     489 
     490        # And trigger a build 
     491        bs = buildset.BuildSet(self.builderNames, 
     492                               SourceStamp(branch=self.branch)) 
     493        self.submit(bs) 
     494 
     495    def addChange(self, change): 
     496        pass 
     497 
     498 
    341499 
    342500class TryBase(service.MultiService, util.ComparableMixin): 
  • buildbot/test/test_scheduler.py

    r1 r2  
    11# -*- test-case-name: buildbot.test.test_scheduler -*- 
    22 
    3 import os 
     3import os, time 
    44 
    55from twisted.trial import unittest 
     
    4646        s1 = self.master.sets[0] 
    4747        self.failUnlessEqual(s1.builderNames, ["a","b"]) 
     48 
     49    def testNightly(self): 
     50        # now == 15-Nov-2005, 00:05:36 AM . By using mktime, this is 
     51        # converted into the local timezone, which happens to match what 
     52        # Nightly is going to do anyway. 
     53        MIN=60; HOUR=60*MIN; DAY=24*3600 
     54        now = time.mktime((2005, 11, 15, 0, 5, 36, 1, 319, 0)) 
     55 
     56        s = scheduler.Nightly('nightly', ["a"], hour=3) 
     57        t = s.calculateNextRunTimeFrom(now) 
     58        self.failUnlessEqual(int(t-now), 2*HOUR+54*MIN+24) 
     59 
     60        s = scheduler.Nightly('nightly', ["a"], minute=[3,8,54]) 
     61        t = s.calculateNextRunTimeFrom(now) 
     62        self.failUnlessEqual(int(t-now), 2*MIN+24) 
     63 
     64        s = scheduler.Nightly('nightly', ["a"], 
     65                              dayOfMonth=16, hour=1, minute=6) 
     66        t = s.calculateNextRunTimeFrom(now) 
     67        self.failUnlessEqual(int(t-now), DAY+HOUR+24) 
     68 
     69        s = scheduler.Nightly('nightly', ["a"], 
     70                              dayOfMonth=16, hour=1, minute=3) 
     71        t = s.calculateNextRunTimeFrom(now) 
     72        self.failUnlessEqual(int(t-now), DAY+57*MIN+24) 
     73 
     74        s = scheduler.Nightly('nightly', ["a"], 
     75                              dayOfMonth=15, hour=1, minute=3) 
     76        t = s.calculateNextRunTimeFrom(now) 
     77        self.failUnlessEqual(int(t-now), 57*MIN+24) 
     78 
     79        s = scheduler.Nightly('nightly', ["a"], 
     80                              dayOfMonth=15, hour=0, minute=3) 
     81        t = s.calculateNextRunTimeFrom(now) 
     82        self.failUnlessEqual(int(t-now), 30*DAY-3*MIN+24) 
     83 
    4884 
    4985    def isImportant(self, change): 
  • docs/buildbot.texinfo

    r1 r2  
    1 \input texinfo @c -*-texinfo-*- 
    2 @c %**start of header 
    3 @setfilename buildbot.info 
    4 @settitle BuildBot Manual 0.7.0+ 
    5 @c %**end of header 
    6  
    7 @copying 
    8 This is the BuildBot manual. 
    9  
    10 Copyright (C) 2005 Brian Warner 
    11  
    12 Copying and distribution of this file, with or without 
    13 modification, are permitted in any medium without royalty 
    14 provided the copyright notice and this notice are preserved. 
    15  
    16 @end copying 
    17  
    18 @titlepage 
    19 @title BuildBot 
    20 @page 
    21 @vskip 0pt plus 1filll 
    22 @insertcopying 
    23 @end titlepage 
    24  
    25 @c Output the table of the contents at the beginning. 
    26 @contents 
    27  
    28 @ifnottex 
    29 @node Top, Introduction, (dir), (dir) 
    30 @top BuildBot 
    31  
    32 @insertcopying 
    33 @end ifnottex 
    34  
    35 @menu 
    36 * Introduction::                What the BuildBot does. 
    37 * Installation::                Creating a buildmaster and buildslaves, 
    38                                 running them. 
    39 * Concepts::                    What goes on in the buildbot's little mind. 
    40 * Configuration::               Controlling the buildbot. 
    41 * Getting Source Code Changes::  Discovering when to run a build. 
    42 * Build Process::               Controlling how each build is run. 
    43 * Status Delivery::             Telling the world about the build's results. 
    44 * Command-line tool::            
    45 * Resources::                   Getting help. 
    46 * Developer's Appendix::         
    47 * Index::                       Complete index. 
    48  
    49 @detailmenu 
    50  --- The Detailed Node Listing --- 
    51  
    52 Introduction 
    53  
    54 * History and Philosophy::       
    55 * System Architecture::          
    56 * Control Flow::                 
    57  
    58 Installation 
    59  
    60 * Requirements::                 
    61 * Installing the code::          
    62 * Creating a buildmaster::       
    63 * Creating a buildslave::        
    64 * Launching the daemons::        
    65 * Logfiles::                     
    66 * Shutdown::                     
    67 * Maintenance::                  
    68 * Troubleshooting::              
    69  
    70 Troubleshooting 
    71  
    72 * Starting the buildslave::      
    73 * Connecting to the buildmaster::   
    74 * Forcing Builds::               
    75  
    76 Concepts 
    77  
    78 * Version Control Systems::      
    79 * Schedulers::                   
    80 * BuildSet::                     
    81 * BuildRequest::                 
    82 * Builder::                      
    83 * Users::                        
    84  
    85 Version Control Systems 
    86  
    87 * Generalizing VC Systems::      
    88 * Source Tree Specifications::   
    89 * How Different VC Systems Specify Sources::   
    90 * Attributes of Changes::        
    91  
    92 Users 
    93  
    94 * Doing Things With Users::      
    95 * Email Addresses::              
    96 * IRC Nicknames::                
    97 * Live Status Clients::          
    98  
    99 Configuration 
    100  
    101 * Config File Format::           
    102 * Loading the Config File::      
    103 * Defining the Project::         
    104 * Listing Change Sources and Schedulers::   
    105 * Setting the slaveport::        
    106 * Buildslave Specifiers::        
    107 * Defining Builders::            
    108 * Defining Status Targets::      
    109 * Debug options::                
    110  
    111 Listing Change Sources and Schedulers 
    112  
    113 * Build Dependencies::           
    114  
    115 Getting Source Code Changes 
    116  
    117 * Change Sources::               
    118  
    119 Change Sources 
    120  
    121 * Choosing ChangeSources::       
    122 * CVSToys - PBService::          
    123 * CVSToys - mail notification::   
    124 * Other mail notification ChangeSources::   
    125 * PBChangeSource::               
    126  
    127 Build Process 
    128  
    129 * Build Steps::                  
    130 * Interlocks::                   
    131 * Build Factories::              
    132  
    133 Build Steps 
    134  
    135 * Common Parameters::            
    136 * Source Checkout::              
    137 * ShellCommand::                 
    138 * Simple ShellCommand Subclasses::   
    139  
    140 Source Checkout 
    141  
    142 * CVS::                          
    143 * SVN::                          
    144 * Darcs::                        
    145 * Arch::                         
    146 * Bazaar::                       
    147 * P4Sync::                       
    148  
    149 Simple ShellCommand Subclasses 
    150  
    151 * Configure::                    
    152 * Compile::                      
    153 * Test::                         
    154  
    155 Build Factories 
    156  
    157 * BuildStep Objects::            
    158 * BuildFactory::                 
    159 * Process-Specific build factories::   
    160  
    161 BuildFactory 
    162  
    163 * BuildFactory Attributes::      
    164 * Quick builds::                 
    165  
    166 Process-Specific build factories 
    167  
    168 * GNUAutoconf::                  
    169 * CPAN::                         
    170 * Python distutils::             
    171 * Python/Twisted/trial projects::   
    172  
    173 Status Delivery 
    174  
    175 * HTML Waterfall::               
    176 * IRC Bot::                      
    177 * PBListener::                   
    178  
    179 Command-line tool 
    180  
    181 * Administrator Tools::          
    182 * Developer Tools::              
    183 * Other Tools::                  
    184 * .buildbot config directory::   
    185  
    186 Developer Tools 
    187  
    188 * statuslog::                    
    189 * statusgui::                    
    190 * try::                          
    191  
    192 Other Tools 
    193  
    194 * sendchange::                   
    195 * debugclient::                  
    196  
    197 @end detailmenu 
    198 @end menu 
    199  
    200 @node Introduction, Installation, Top, Top 
    201 @chapter Introduction 
    202  
    203 @cindex introduction 
    204  
    205 The BuildBot is a system to automate the compile/test cycle required by most 
    206 software projects to validate code changes. By automatically rebuilding and 
    207 testing the tree each time something has changed, build problems are 
    208 pinpointed quickly, before other developers are inconvenienced by the 
    209 failure. The guilty developer can be identified and harassed without human 
    210 intervention. By running the builds on a variety of platforms, developers 
    211 who do not have the facilities to test their changes everywhere before 
    212 checkin will at least know shortly afterwards whether they have broken the 
    213 build or not. Warning counts, lint checks, image size, compile time, and 
    214 other build parameters can be tracked over time, are more visible, and 
    215 are therefore easier to improve. 
    216  
    217 The overall goal is to reduce tree breakage and provide a platform to 
    218 run tests or code-quality checks that are too annoying or pedantic for 
    219 any human to waste their time with. Developers get immediate (and 
    220 potentially public) feedback about their changes, encouraging them to 
    221 be more careful about testing before checkin. 
    222  
    223 Features: 
    224  
    225 @itemize @bullet 
    226 @item 
    227 run builds on a variety of slave platforms 
    228 @item 
    229 arbitrary build process: handles projects using C, Python, whatever 
    230 @item 
    231 minimal host requirements: python and Twisted 
    232 @item 
    233 slaves can be behind a firewall if they can still do checkout 
    234 @item 
    235 status delivery through web page, email, IRC, other protocols 
    236 @item 
    237 track builds in progress, provide estimated completion time 
    238 @item 
    239 flexible configuration by subclassing generic build process classes 
    240 @item 
    241 debug tools to force a new build, submit fake Changes, query slave status 
    242 @item 
    243 released under the GPL 
    244 @end itemize 
    245  
    246 @menu 
    247 * History and Philosophy::       
    248 * System Architecture::          
    249 * Control Flow::                 
    250 @end menu 
    251  
    252  
    253 @node History and Philosophy, System Architecture, Introduction, Introduction 
    254 @section History and Philosophy 
    255  
    256 @cindex Philosophy of operation 
    257  
    258 The Buildbot was inspired by a similar project built for a development 
    259 team writing a cross-platform embedded system. The various components 
    260 of the project were supposed to compile and run on several flavors of 
    261 unix (linux, solaris, BSD), but individual developers had their own 
    262 preferences and tended to stick to a single platform. From time to 
    263 time, incompatibilities would sneak in (some unix platforms want to 
    264 use @code{string.h}, some prefer @code{strings.h}), and then the tree 
    265 would compile for some developers but not others. The buildbot was 
    266 written to automate the human process of walking into the office, 
    267 updating a tree, compiling (and discovering the breakage), finding the 
    268 developer at fault, and complaining to them about the problem they had 
    269 introduced. With multiple platforms it was difficult for developers to 
    270 do the right thing (compile their potential change on all platforms); 
    271 the buildbot offered a way to help. 
    272  
    273 Another problem was when programmers would change the behavior of a 
    274 library without warning its users, or change internal aspects that 
    275 other code was (unfortunately) depending upon. Adding unit tests to 
    276 the codebase helps here: if an application's unit tests pass despite 
    277 changes in the libraries it uses, you can have more confidence that 
    278 the library changes haven't broken anything. Many developers 
    279 complained that the unit tests were inconvenient or took too long to 
    280 run: having the buildbot run them reduces the developer's workload to 
    281 a minimum. 
    282  
    283 In general, having more visibility into the project is always good, 
    284 and automation makes it easier for developers to do the right thing. 
    285 When everyone can see the status of the project, developers are 
    286 encouraged to keep the tree in good working order. Unit tests that 
    287 aren't run on a regular basis tend to suffer from bitrot just like 
    288 code does: exercising them on a regular basis helps to keep them 
    289 functioning and useful. 
    290  
    291 The current version of the Buildbot is additionally targeted at 
    292 distributed free-software projects, where resources and platforms are 
    293 only available when provided by interested volunteers. The buildslaves 
    294 are designed to require an absolute minimum of configuration, reducing 
    295 the effort a potential volunteer needs to expend to be able to 
    296 contribute a new test environment to the project. The goal is for 
    297 anyone who wishes that a given project would run on their favorite 
    298 platform should be able to offer that project a buildslave, running on 
    299 that platform, where they can verify that their portability code 
    300 works, and keeps working. 
    301  
    302 @node System Architecture, Control Flow, History and Philosophy, Introduction 
    303 @comment  node-name,  next,  previous,  up 
    304 @section System Architecture 
    305  
    306 The Buildbot consists of a single @code{buildmaster} and one or more 
    307 @code{buildslaves}, connected in a star topology. The buildmaster 
    308 makes all decisions about what and when to build. It sends commands to 
    309 be run on the build slaves, which simply execute the commands and 
    310 return the results. (certain steps involve more local decision making, 
    311 where the overhead of sending a lot of commands back and forth would 
    312 be inappropriate, but in general the buildmaster is responsible for 
    313 everything). 
    314  
    315 The buildmaster is usually fed @code{Changes} by some sort of version 
    316 control system @xref{Change Sources}, which may cause builds to be 
    317 run. As the builds are performed, various status messages are 
    318 produced, which are then sent to any registered Status Targets 
    319 @xref{Status Delivery}. 
    320  
    321 @ifinfo 
    322 @smallexample 
    323 @group 
    324  TODO: picture of change sources, master, slaves, status targets 
    325  should look like docs/PyCon-2003/sources/overview.svg 
    326 @end group 
    327 @end smallexample 
    328 @end ifinfo 
    329 @ifnotinfo 
    330 @c @image{images/overview} 
    331 @end ifnotinfo 
    332  
    333 The buildmaster is configured and maintained by the ``buildmaster 
    334 admin'', who is generally the project team member responsible for 
    335 build process issues. Each buildslave is maintained by a ``buildslave 
    336 admin'', who do not need to be quite as involved. Generally slaves are 
    337 run by anyone who has an interest in seeing the project work well on 
    338 their platform. 
    339  
    340  
    341 @node Control Flow,  , System Architecture, Introduction 
    342 @comment  node-name,  next,  previous,  up 
    343 @section Control Flow 
    344  
    345 A day in the life of the buildbot: 
    346  
    347 @itemize @bullet 
    348  
    349 @item 
    350 A developer commits some source code changes to the repository. A hook 
    351 script or commit trigger of some sort sends information about this 
    352 change to the buildmaster through one of its configured Change 
    353 Sources. This notification might arrive via email, or over a network 
    354 connection (either initiated by the buildmaster as it ``subscribes'' 
    355 to changes, or by the commit trigger as it pushes Changes towards the 
    356 buildmaster). The Change contains information about who made the 
    357 change, what files were modified, which revision contains the change, 
    358 and any checkin comments. 
    359  
    360 @item 
    361 The buildmaster distributes this change to all of its configured 
    362 Schedulers. Any ``important'' changes cause the ``tree-stable-timer'' 
    363 to be started, and the Change is added to a list of those that will go 
    364 into a new Build. When the timer expires, a Build is started on each 
    365 of a set of configured Builders, all compiling/testing the same source 
    366 code. Unless configured otherwise, all Builds run in parallel on the 
    367 various buildslaves. 
    368  
    369 @item 
    370 The Build consists of a series of Steps. Each Step causes some number 
    371 of commands to be invoked on the remote buildslave associated with 
    372 that Builder. The first step is almost always to perform a checkout of 
    373 the appropriate revision from the same VC system that produced the 
    374 Change. The rest generally perform a compile and run unit tests. As 
    375 each Step runs, the buildslave reports back command output and return 
    376 status to the buildmaster. 
    377  
    378 @item 
    379 As the Build runs, status messages like ``Build Started'', ``Step 
    380 Started'', ``Build Finished'', etc, are published to a collection of 
    381 Status Targets. One of these targets is usually the HTML ``Waterfall'' 
    382 display, which shows a chronological list of events, and summarizes 
    383 the results of the most recent build at the top of each column. 
    384 Developers can periodically check this page to see how their changes 
    385 have fared. If they see red, they know that they've made a mistake and 
    386 need to fix it. If they see green, they know that they've done their 
    387 duty and don't need to worry about their change breaking anything. 
    388  
    389 @item 
    390 If a MailNotifier status target is active, the completion of a build 
    391 will cause email to be sent to any developers whose Changes were 
    392 incorporated into this Build. The MailNotifier can be configured to 
    393 only send mail upon failing builds, or for builds which have just 
    394 transitioned from passing to failing. Other status targets can provide 
    395 similar real-time notification via different communication channels, 
    396 like IRC. 
    397  
    398 @end itemize 
    399  
    400  
    401 @node Installation, Concepts, Introduction, Top 
    402 @chapter Installation 
    403  
    404 @menu 
    405 * Requirements::                 
    406 * Installing the code::          
    407 * Creating a buildmaster::       
    408 * Creating a buildslave::        
    409 * Launching the daemons::        
    410 * Logfiles::                     
    411 * Shutdown::                     
    412 * Maintenance::                  
    413 * Troubleshooting::              
    414 @end menu 
    415  
    416 @node Requirements, Installing the code, Installation, Installation 
    417 @section Requirements 
    418  
    419 At a bare minimum, you'll need the following (for both the buildmaster 
    420 and a buildslave): 
    421  
    422 @itemize @bullet 
    423 @item 
    424 Python: http://www.python.org 
    425  
    426 Buildbot requires python-2.2 or later, and is primarily developed 
    427 against python-2.3. The buildmaster uses generators, a feature which 
    428 is not available in python-2.1, and both master and slave require a 
    429 version of Twisted which only works with python-2.2 or later. Certain 
    430 features (like the inclusion of build logs in status emails) require 
    431 python-2.2.2 or later. The IRC ``force build'' command requires 
    432 python-2.3 (for the shlex.split function). 
    433  
    434 @item 
    435 Twisted: http://twistedmatrix.com 
    436  
    437 Both the buildmaster and the buildslaves require Twisted-1.3.0 or 
    438 later. It has been mainly developed against Twisted-2.0.1, but has 
    439 been tested against Twisted-2.1.0 (the most recent as of this 
    440 writing), and might even work on versions as old as Twisted-1.1.0, but 
    441 as always the most recent version is recommended. 
    442  
    443 Twisted-1.3.0 and earlier were released as a single monolithic 
    444 package. When you run Buildbot against Twisted-2.0.0 or later (which 
    445 are split into a number of smaller subpackages), you'll need at least 
    446 "Twisted" (the core package), and you'll also want TwistedMail, 
    447 TwistedWeb, and TwistedWords (for sending email, serving a web status 
    448 page, and delivering build status via IRC, respectively). 
    449 @end itemize 
    450  
    451 Certain other packages may be useful on the system running the 
    452 buildmaster: 
    453  
    454 @itemize @bullet 
    455 @item 
    456 CVSToys: http://purl.net/net/CVSToys 
    457  
    458 If your buildmaster uses FreshCVSSource to receive change notification 
    459 from a cvstoys daemon, it will require CVSToys be installed (tested 
    460 with CVSToys-1.0.10). If the it doesn't use that source (i.e. if you 
    461 only use a mail-parsing change source, or the SVN notification 
    462 script), you will not need CVSToys. 
    463  
    464 @end itemize 
    465  
    466 And of course, your project's build process will impose additional 
    467 requirements on the buildslaves. These hosts must have all the tools 
    468 necessary to compile and test your project's source code. 
    469  
    470  
    471 @node Installing the code, Creating a buildmaster, Requirements, Installation 
    472 @section Installing the code 
    473  
    474 @cindex installation 
    475  
    476 The Buildbot is installed using the standard python @code{distutils} 
    477 module. After unpacking the tarball, the process is: 
    478  
    479 @example 
    480 python setup.py build 
    481 python setup.py install 
    482 @end example 
    483  
    484 where the install step may need to be done as root. This will put the 
    485 bulk of the code in somewhere like 
    486 /usr/lib/python2.3/site-packages/buildbot . It will also install the 
    487 @code{buildbot} command-line tool in /usr/bin/buildbot. 
    488  
    489 To test this, shift to a different directory (like /tmp), and run: 
    490  
    491 @example 
    492 buildbot --version 
    493 @end example 
    494  
    495 If it shows you the versions of Buildbot and Twisted, the install went 
    496 ok. If it says @code{no such command} or it gets an @code{ImportError} 
    497 when it tries to load the libaries, then something went wrong. 
    498 @code{pydoc buildbot} is another useful diagnostic tool. 
    499  
    500 Windows users will find these files in other places. You will need to 
    501 make sure that python can find the libraries, and will probably find 
    502 it convenient to have @code{buildbot} on your PATH. 
    503  
    504 If you wish, you can run the buildbot unit test suite like this: 
    505  
    506 @example 
    507 PYTHONPATH=. trial -v buildbot.test 
    508 @end example 
    509  
    510 This should run up to 175 tests, depending upon what VC tools you have 
    511 installed. On my desktop machine it takes about four minutes to 
    512 complete. Nothing should fail, a few might be skipped. If any of the 
    513 tests fail, you should stop and investigate the cause before 
    514 continuing the installation process, as it will probably be easier to 
    515 track down the bug early. 
    516  
    517 If you cannot or do not wish to install the buildbot into a site-wide 
    518 location like @file{/usr} or @file{/usr/local}, you can also install 
    519 it into the account's home directory. Do the install command like 
    520 this: 
    521  
    522 @example 
    523 python setup.py install --home=~ 
    524 @end example 
    525  
    526 That will populate @file{~/lib/python} and create 
    527 @file{~/bin/buildbot}. Make sure this lib directory is on your 
    528 @code{PYTHONPATH}. 
    529  
    530  
    531 @node Creating a buildmaster, Creating a buildslave, Installing the code, Installation 
    532 @section Creating a buildmaster 
    533  
    534 As you learned earlier (@pxref{System Architecture}), the buildmaster 
    535 runs on a central host (usually one that is publically visible, so 
    536 everybody can check on the status of the project), and controls all 
    537 aspects of the buildbot system. Let us call this host 
    538 @code{buildbot.example.org}. 
    539  
    540 You may wish to create a separate user account for the buildmaster, 
    541 perhaps named @code{buildmaster}. This can help keep your personal 
    542 configuration distinct from that of the buildmaster and is useful if 
    543 you have to use a mail-based notification system (@pxref{Change 
    544 Sources}). However, the Buildbot will work just fine with your regular 
    545 user account. 
    546  
    547 You need to choose a directory for the buildmaster, called the 
    548 @code{basedir}. This directory will be owned by the buildmaster, which 
    549 will use configuration files therein, and create status files as it 
    550 runs. @file{~/Buildbot} is a likely value. If you run multiple 
    551 buildmasters in the same account, or if you run both masters and 
    552 slaves, you may want a more distinctive name like 
    553 @file{~/Buildbot/master/gnomovision} or 
    554 @file{~/Buildmasters/fooproject}. If you are using a separate user 
    555 account, this might just be @file{~buildmaster/masters/fooprojects}. 
    556  
    557 Once you've picked a directory, use the @command{buildbot master} 
    558 command to create the directory and populate it with startup files: 
    559  
    560 @example 
    561 buildbot master @var{basedir} 
    562 @end example 
    563  
    564 You will need to create a configuration file (@pxref{Configuration}) 
    565 before starting the buildmaster. Most of the rest of this manual is 
    566 dedicated to explaining how to do this. A sample configuration file is 
    567 placed in the working directory, named @file{master.cfg.sample}, which 
    568 can be copied to @file{master.cfg} and edited to suit your purposes. 
    569  
    570 (Internal details: This command creates a file named 
    571 @file{buildbot.tac} that contains all the state necessary to create 
    572 the buildmaster. Twisted has a tool called @code{twistd} which can use 
    573 this .tac file to create and launch a buildmaster instance. twistd 
    574 takes care of logging and daemonization (running the program in the 
    575 background). @file{/usr/bin/buildbot} is a front end which runs twistd 
    576 for you.) 
    577  
    578 In addition to @file{buildbot.tac}, a small @file{Makefile.sample} is 
    579 installed. This can be used as the basis for customized daemon startup, 
    580 @xref{Launching the daemons}. 
    581  
    582  
    583 @node Creating a buildslave, Launching the daemons, Creating a buildmaster, Installation 
    584 @section Creating a buildslave 
    585  
    586 Typically, you will be adding a buildslave to an existing buildmaster, 
    587 to provide additional architecture coverage. The buildbot 
    588 administrator will give you several pieces of information necessary to 
    589 connect to the buildmaster. You should also be somewhat familiar with 
    590 the project being tested, so you can troubleshoot build problems 
    591 locally. 
    592  
    593 The buildbot exists to make sure that the project's stated ``how to 
    594 build it'' process actually works. To this end, the buildslave should 
    595 run in an environment just like that of your regular developers. 
    596 Typically the project build process is documented somewhere 
    597 (@file{README}, @file{INSTALL}, etc), in a document that should 
    598 mention all library dependencies and contain a basic set of build 
    599 instructions. This document will be useful as you configure the host 
    600 and account in which the buildslave runs. 
    601  
    602 Here's a good checklist for setting up a buildslave: 
    603  
    604 @enumerate 
    605 @item 
    606 Set up the account 
    607  
    608 It is recommended (although not mandatory) to set up a separate user 
    609 account for the buildslave. This account is frequently named 
    610 @code{buildbot} or @code{buildslave}. This serves to isolate your 
    611 personal working environment from that of the slave's, and helps to 
    612 minimize the security threat posed by letting possibly-unknown 
    613 contributors run arbitrary code on your system. The account should 
    614 have a minimum of fancy init scripts. 
    615  
    616 @item 
    617 Install the buildbot code 
    618  
    619 Follow the instructions given earlier (@pxref{Installing the code}). 
    620 If you use a separate buildslave account, and you didn't install the 
    621 buildbot code to a shared location, then you will need to install it 
    622 with @code{--home=~} for each account that needs it. 
    623  
    624 @item 
    625 Set up the host 
    626  
    627 Make sure the host can actually reach the buildmaster. Usually the 
    628 buildmaster is running a status webserver on the same machine, so 
    629 simply point your web browser at it and see if you can get there. 
    630 Install whatever additional packages or libraries the project's 
    631 INSTALL document advises. (or not: if your buildslave is supposed to 
    632 make sure that building without optional libraries still works, then 
    633 don't install those libraries). 
    634  
    635 Again, these libraries don't necessarily have to be installed to a 
    636 site-wide shared location, but they must be available to your build 
    637 process. Accomplishing this is usually very specific to the build 
    638 process, so installing them to @file{/usr} or @file{/usr/local} is 
    639 usually the best approach. 
    640  
    641 @item 
    642 Test the build process 
    643  
    644 Follow the instructions in the INSTALL document, in the buildslave's 
    645 account. Perform a full CVS (or whatever) checkout, configure, make, 
    646 run tests, etc. Confirm that the build works without manual fussing. 
    647 If it doesn't work when you do it by hand, it will be unlikely to work 
    648 when the buildbot attempts to do it in an automated fashion. 
    649  
    650 @item 
    651 Choose a base directory 
    652  
    653 This should be somewhere in the buildslave's account, typically named 
    654 after the project which is being tested. The buildslave will not touch 
    655 any file outside of this directory. Something like @file{~/Buildbot} 
    656 or @file{~/Buildslaves/fooproject} is appropriate. 
    657  
    658 @item 
    659 Get the buildmaster host/port, botname, and password 
    660  
    661 When the buildbot admin configures the buildmaster to accept and use 
    662 your buildslave, they will provide you with the following pieces of 
    663 information: 
    664  
    665 @itemize @bullet 
    666 @item 
    667 your buildslave's name 
    668 @item 
    669 the password assigned to your buildslave 
    670 @item 
    671 the hostname and port number of the buildmaster, i.e. buildbot.example.org:8007 
    672 @end itemize 
    673  
    674 @item 
    675 Create the buildslave 
    676  
    677 Now run the 'buildbot' command as follows: 
    678  
    679 @example 
    680 buildbot slave @var{BASEDIR} @var{MASTERHOST}:@var{PORT} @var{SLAVENAME} @var{PASSWORD} 
    681 @end example 
    682  
    683 This will create the base directory and a collection of files inside, 
    684 including the @file{buildbot.tac} file that contains all the 
    685 information you passed to the @code{buildbot} command. 
    686  
    687 @item 
    688 Fill in the hostinfo files 
    689  
    690 When it first connects, the buildslave will send a few files up to the 
    691 buildmaster which describe the host that it is running on. These files 
    692 are presented on the web status display so that developers have more 
    693 information to reproduce any test failures that are witnessed by the 
    694 buildbot. There are sample files in the @file{info} subdirectory of 
    695 the buildbot's base directory. You should edit these to correctly 
    696 describe you and your host. 
    697  
    698 @file{BASEDIR/info/admin} should contain your name and email address. 
    699 This is the ``buildslave admin address'', and will be visible from the 
    700 build status page (so you may wish to munge it a bit if 
    701 address-harvesting spambots are a concern). 
    702  
    703 @file{BASEDIR/info/host} should be filled with a brief description of 
    704 the host: OS, version, memory size, CPU speed, versions of relevant 
    705 libraries installed, and finally the version of the buildbot code 
    706 which is running the buildslave. 
    707  
    708 If you run many buildslaves, you may want to create a single 
    709 @file{~buildslave/info} file and share it among all the buildslaves 
    710 with symlinks. 
    711  
    712 @end enumerate 
    713  
    714  
    715 @node Launching the daemons, Logfiles, Creating a buildslave, Installation 
    716 @section Launching the daemons 
    717  
    718 Both the buildmaster and the buildslave run as daemon programs. To 
    719 launch them, pass the working directory to the @code{buildbot} 
    720 command: 
    721  
    722 @example 
    723 buildbot start @var{BASEDIR} 
    724 @end example 
    725  
    726 This command will start the daemon and then return, so normally it 
    727 will not produce any output. To verify that the programs are indeed 
    728 running, look for a pair of files named @file{twistd.log} and 
    729 @file{twistd.pid} that should be created in the working directory. 
    730 @file{twistd.pid} contains the process ID of the newly-spawned daemon. 
    731  
    732 When the buildslave connects to the buildmaster, new directories will 
    733 start appearing in its base directory. The buildmaster tells the slave 
    734 to create a directory for each Builder which will be using that slave. 
    735 All build operations are performed within these directories: CVS 
    736 checkouts, compiles, and tests. 
    737  
    738 Once you get everything running, you will want to arrange for the 
    739 buildbot daemons to be started at boot time. One way is to use 
    740 @code{cron}, by putting them in a @@reboot crontab entry: 
    741  
    742 @example 
    743 @@reboot buildbot @var{BASEDIR} 
    744 @end example 
    745  
    746 It is important to remember that the environment provided to cron jobs 
    747 and init scripts can be quite different that your normal runtime. 
    748 There may be fewer environment variables specified, and the PATH may 
    749 be shorter than usual. It is a good idea to test out this method of 
    750 launching the buildslave by using a cron job with a time in the near 
    751 future, with the same command, and then check @file{twistd.log} to 
    752 make sure the slave actually started correctly. Common problems here 
    753 are for @file{/usr/local} or @file{~/bin} to not be on your 
    754 @code{PATH}, or for @code{PYTHONPATH} to not be set correctly. 
    755 Sometimes @code{HOME} is messed up too. 
    756  
    757 To modify the way the daemons are started (perhaps you want to set 
    758 some environment variables first, or perform some cleanup each time), 
    759 you can create a file named @file{Makefile.buildbot} in the base 
    760 directory. When the @file{buildbot} front-end tool is told to 
    761 @command{start} the daemon, and it sees this file (and 
    762 @file{/usr/bin/make} exists), it will do @command{make -f 
    763 Makefile.buildbot start} instead of its usual action (which involves 
    764 running @command{twistd}). When the buildmaster or buildslave is 
    765 installed, a @file{Makefile.sample} is created which implements the 
    766 same behavior as the the @file{buildbot} tool uses, so if you want to 
    767 customize the process, just copy @file{Makefile.sample} to 
    768 @file{Makefile.buildbot} and edit it as necessary. 
    769  
    770 @node Logfiles, Shutdown, Launching the daemons, Installation 
    771 @section Logfiles 
    772  
    773 @cindex logfiles 
    774  
    775 While a buildbot daemon runs, it emits text to a logfile, named 
    776 @file{twistd.log}. A command like @code{tail -f twistd.log} is useful 
    777 to watch the command output as it runs. 
    778  
    779 The buildmaster will announce any errors with its configuration file 
    780 in the logfile, so it is a good idea to look at the log at startup 
    781 time to check for any problems. Most buildmaster activities will cause 
    782 lines to be added to the log. 
    783  
    784 @node Shutdown, Maintenance, Logfiles, Installation 
    785 @section Shutdown 
    786  
    787 To stop a buildmaster or buildslave manually, use: 
    788  
    789 @example 
    790 buildbot stop @var{BASEDIR} 
    791 @end example 
    792  
    793 This simply looks for the @file{twistd.pid} file and kills whatever 
    794 process is identified within. 
    795  
    796 At system shutdown, all processes are sent a @code{SIGKILL}. The 
    797 buildmaster and buildslave will respond to this by shutting down 
    798 normally. 
    799  
    800 The buildmaster will respond to a @code{SIGHUP} by re-reading its 
    801 config file. The following shortcut is available: 
    802  
    803 @example 
    804 buildbot sighup @var{BASEDIR} 
    805 @end example 
    806  
    807 @node Maintenance, Troubleshooting, Shutdown, Installation 
    808 @section Maintenance 
    809  
    810 It is a good idea to check the buildmaster's status page every once in 
    811 a while, to see if your buildslave is still online. Eventually the 
    812 buildbot will probably be enhanced to send you email (via the 
    813 @file{info/admin} email address) when the slave has been offline for 
    814 more than a few hours. 
    815  
    816 If you find you can no longer provide a buildslave to the project, please 
    817 let the project admins know, so they can put out a call for a 
    818 replacement. 
    819  
    820 The Buildbot records status and logs output continually, each time a 
    821 build is performed. The status tends to be small, but the build logs 
    822 can become quite large. Each build and log are recorded in a separate 
    823 file, arranged hierarchically under the buildmaster's base directory. 
    824 To prevent these files from growing without bound, you should 
    825 periodically delete old build logs. A simple cron job to delete 
    826 anything older than, say, two weeks should do the job. The only trick 
    827 is to leave the @file{buildbot.tac} and other support files alone, for 
    828 which find's @code{-mindepth} argument helps skip everything in the 
    829 top directory. You can use something like the following: 
    830  
    831 @example 
    832 @@weekly cd BASEDIR && find . -mindepth 2 -type f -mtime +14 -exec rm @{@