Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/buildbot/docs/buildbot.info-1
diff options
context:
space:
mode:
Diffstat (limited to 'buildbot/docs/buildbot.info-1')
-rw-r--r--buildbot/docs/buildbot.info-17278
1 files changed, 0 insertions, 7278 deletions
diff --git a/buildbot/docs/buildbot.info-1 b/buildbot/docs/buildbot.info-1
deleted file mode 100644
index 5dcf913..0000000
--- a/buildbot/docs/buildbot.info-1
+++ /dev/null
@@ -1,7278 +0,0 @@
-This is buildbot.info, produced by makeinfo version 4.11 from
-buildbot.texinfo.
-
-This is the BuildBot manual.
-
- Copyright (C) 2005,2006 Brian Warner
-
- Copying and distribution of this file, with or without
-modification, are permitted in any medium without royalty provided
-the copyright notice and this notice are preserved.
-
-
-File: buildbot.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir)
-
-BuildBot
-********
-
-This is the BuildBot manual.
-
- Copyright (C) 2005,2006 Brian Warner
-
- Copying and distribution of this file, with or without
-modification, are permitted in any medium without royalty provided
-the copyright notice and this notice are preserved.
-
-* Menu:
-
-* Introduction:: What the BuildBot does.
-* Installation:: Creating a buildmaster and buildslaves,
- running them.
-* Concepts:: What goes on in the buildbot's little mind.
-* Configuration:: Controlling the buildbot.
-* Getting Source Code Changes:: Discovering when to run a build.
-* Build Process:: Controlling how each build is run.
-* Status Delivery:: Telling the world about the build's results.
-* Command-line tool::
-* Resources:: Getting help.
-* Developer's Appendix::
-* Index of Useful Classes::
-* Index of master.cfg keys::
-* Index:: Complete index.
-
- --- The Detailed Node Listing ---
-
-Introduction
-
-* History and Philosophy::
-* System Architecture::
-* Control Flow::
-
-System Architecture
-
-* BuildSlave Connections::
-* Buildmaster Architecture::
-* Status Delivery Architecture::
-
-Installation
-
-* Requirements::
-* Installing the code::
-* Creating a buildmaster::
-* Upgrading an Existing Buildmaster::
-* Creating a buildslave::
-* Launching the daemons::
-* Logfiles::
-* Shutdown::
-* Maintenance::
-* Troubleshooting::
-
-Creating a buildslave
-
-* Buildslave Options::
-
-Troubleshooting
-
-* Starting the buildslave::
-* Connecting to the buildmaster::
-* Forcing Builds::
-
-Concepts
-
-* Version Control Systems::
-* Schedulers::
-* BuildSet::
-* BuildRequest::
-* Builder::
-* Users::
-* Build Properties::
-
-Version Control Systems
-
-* Generalizing VC Systems::
-* Source Tree Specifications::
-* How Different VC Systems Specify Sources::
-* Attributes of Changes::
-
-Users
-
-* Doing Things With Users::
-* Email Addresses::
-* IRC Nicknames::
-* Live Status Clients::
-
-Configuration
-
-* Config File Format::
-* Loading the Config File::
-* Testing the Config File::
-* Defining the Project::
-* Change Sources and Schedulers::
-* Setting the slaveport::
-* Buildslave Specifiers::
-* On-Demand ("Latent") Buildslaves::
-* Defining Global Properties::
-* Defining Builders::
-* Defining Status Targets::
-* Debug options::
-
-Change Sources and Schedulers
-
-* Scheduler Scheduler::
-* AnyBranchScheduler::
-* Dependent Scheduler::
-* Periodic Scheduler::
-* Nightly Scheduler::
-* Try Schedulers::
-* Triggerable Scheduler::
-
-Buildslave Specifiers
-* When Buildslaves Go Missing::
-
-On-Demand ("Latent") Buildslaves
-* Amazon Web Services Elastic Compute Cloud ("AWS EC2")::
-* Dangers with Latent Buildslaves::
-* Writing New Latent Buildslaves::
-
-Getting Source Code Changes
-
-* Change Sources::
-* Choosing ChangeSources::
-* CVSToys - PBService::
-* Mail-parsing ChangeSources::
-* PBChangeSource::
-* P4Source::
-* BonsaiPoller::
-* SVNPoller::
-* MercurialHook::
-* Bzr Hook::
-* Bzr Poller::
-
-Mail-parsing ChangeSources
-
-* Subscribing the Buildmaster::
-* Using Maildirs::
-* Parsing Email Change Messages::
-
-Parsing Email Change Messages
-
-* FCMaildirSource::
-* SyncmailMaildirSource::
-* BonsaiMaildirSource::
-* SVNCommitEmailMaildirSource::
-
-Build Process
-
-* Build Steps::
-* Interlocks::
-* Build Factories::
-
-Build Steps
-
-* Common Parameters::
-* Using Build Properties::
-* Source Checkout::
-* ShellCommand::
-* Simple ShellCommand Subclasses::
-* Python BuildSteps::
-* Transferring Files::
-* Steps That Run on the Master::
-* Triggering Schedulers::
-* Writing New BuildSteps::
-
-Source Checkout
-
-* CVS::
-* SVN::
-* Darcs::
-* Mercurial::
-* Arch::
-* Bazaar::
-* Bzr::
-* P4::
-* Git::
-
-Simple ShellCommand Subclasses
-
-* Configure::
-* Compile::
-* Test::
-* TreeSize::
-* PerlModuleTest::
-* SetProperty::
-
-Python BuildSteps
-
-* BuildEPYDoc::
-* PyFlakes::
-* PyLint::
-
-Writing New BuildSteps
-
-* BuildStep LogFiles::
-* Reading Logfiles::
-* Adding LogObservers::
-* BuildStep URLs::
-
-Build Factories
-
-* BuildStep Objects::
-* BuildFactory::
-* Process-Specific build factories::
-
-BuildStep Objects
-
-* BuildFactory Attributes::
-* Quick builds::
-
-BuildFactory
-
-* BuildFactory Attributes::
-* Quick builds::
-
-Process-Specific build factories
-
-* GNUAutoconf::
-* CPAN::
-* Python distutils::
-* Python/Twisted/trial projects::
-
-Status Delivery
-
-* WebStatus::
-* MailNotifier::
-* IRC Bot::
-* PBListener::
-* Writing New Status Plugins::
-
-WebStatus
-
-* WebStatus Configuration Parameters::
-* Buildbot Web Resources::
-* XMLRPC server::
-* HTML Waterfall::
-
-Command-line tool
-
-* Administrator Tools::
-* Developer Tools::
-* Other Tools::
-* .buildbot config directory::
-
-Developer Tools
-
-* statuslog::
-* statusgui::
-* try::
-
-waiting for results
-
-* try --diff::
-
-Other Tools
-
-* sendchange::
-* debugclient::
-
-
-File: buildbot.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top
-
-1 Introduction
-**************
-
-The BuildBot is a system to automate the compile/test cycle required
-by most software projects to validate code changes. By automatically
-rebuilding and testing the tree each time something has changed,
-build problems are pinpointed quickly, before other developers are
-inconvenienced by the failure. The guilty developer can be identified
-and harassed without human intervention. By running the builds on a
-variety of platforms, developers who do not have the facilities to
-test their changes everywhere before checkin will at least know
-shortly afterwards whether they have broken the build or not. Warning
-counts, lint checks, image size, compile time, and other build
-parameters can be tracked over time, are more visible, and are
-therefore easier to improve.
-
- The overall goal is to reduce tree breakage and provide a platform
-to run tests or code-quality checks that are too annoying or pedantic
-for any human to waste their time with. Developers get immediate (and
-potentially public) feedback about their changes, encouraging them to
-be more careful about testing before checkin.
-
- Features:
-
- * run builds on a variety of slave platforms
-
- * arbitrary build process: handles projects using C, Python,
- whatever
-
- * minimal host requirements: python and Twisted
-
- * slaves can be behind a firewall if they can still do checkout
-
- * status delivery through web page, email, IRC, other protocols
-
- * track builds in progress, provide estimated completion time
-
- * flexible configuration by subclassing generic build process
- classes
-
- * debug tools to force a new build, submit fake Changes, query
- slave status
-
- * released under the GPL
-
-* Menu:
-
-* History and Philosophy::
-* System Architecture::
-* Control Flow::
-
-
-File: buildbot.info, Node: History and Philosophy, Next: System Architecture, Prev: Introduction, Up: Introduction
-
-1.1 History and Philosophy
-==========================
-
-The Buildbot was inspired by a similar project built for a development
-team writing a cross-platform embedded system. The various components
-of the project were supposed to compile and run on several flavors of
-unix (linux, solaris, BSD), but individual developers had their own
-preferences and tended to stick to a single platform. From time to
-time, incompatibilities would sneak in (some unix platforms want to
-use `string.h', some prefer `strings.h'), and then the tree would
-compile for some developers but not others. The buildbot was written
-to automate the human process of walking into the office, updating a
-tree, compiling (and discovering the breakage), finding the developer
-at fault, and complaining to them about the problem they had
-introduced. With multiple platforms it was difficult for developers to
-do the right thing (compile their potential change on all platforms);
-the buildbot offered a way to help.
-
- Another problem was when programmers would change the behavior of a
-library without warning its users, or change internal aspects that
-other code was (unfortunately) depending upon. Adding unit tests to
-the codebase helps here: if an application's unit tests pass despite
-changes in the libraries it uses, you can have more confidence that
-the library changes haven't broken anything. Many developers
-complained that the unit tests were inconvenient or took too long to
-run: having the buildbot run them reduces the developer's workload to
-a minimum.
-
- In general, having more visibility into the project is always good,
-and automation makes it easier for developers to do the right thing.
-When everyone can see the status of the project, developers are
-encouraged to keep the tree in good working order. Unit tests that
-aren't run on a regular basis tend to suffer from bitrot just like
-code does: exercising them on a regular basis helps to keep them
-functioning and useful.
-
- The current version of the Buildbot is additionally targeted at
-distributed free-software projects, where resources and platforms are
-only available when provided by interested volunteers. The buildslaves
-are designed to require an absolute minimum of configuration, reducing
-the effort a potential volunteer needs to expend to be able to
-contribute a new test environment to the project. The goal is for
-anyone who wishes that a given project would run on their favorite
-platform should be able to offer that project a buildslave, running on
-that platform, where they can verify that their portability code
-works, and keeps working.
-
-
-File: buildbot.info, Node: System Architecture, Next: Control Flow, Prev: History and Philosophy, Up: Introduction
-
-1.2 System Architecture
-=======================
-
-The Buildbot consists of a single `buildmaster' and one or more
-`buildslaves', connected in a star topology. The buildmaster makes
-all decisions about what, when, and how to build. It sends commands
-to be run on the build slaves, which simply execute the commands and
-return the results. (certain steps involve more local decision
-making, where the overhead of sending a lot of commands back and
-forth would be inappropriate, but in general the buildmaster is
-responsible for everything).
-
- The buildmaster is usually fed `Changes' by some sort of version
-control system (*note Change Sources::), which may cause builds to be
-run. As the builds are performed, various status messages are
-produced, which are then sent to any registered Status Targets (*note
-Status Delivery::).
-
-
- +------------------+ +-----------+
- | |---------->| Browser |
- | BuildMaster | +-----------+
- Changes | |--------------->+--------+
- +----------->| | Build Status | email |
- | | |------------+ +--------+
- | | |-------+ | +---------------+
- | +------------------+ | +---->| Status Client |
-+----------+ | ^ | ^ | +---------------+
-| Change | | | C| | | +-----+
-| Sources | | | o| | +------------>| IRC |
-| | | | m| |R +-----+
-| CVS | v | m| |e
-| SVN | +---------+ a| |s
-| Darcs | | Build | n| |u
-| .. etc | | Slave | d| |l
-| | +---------+ s| |t
-| | v |s
-+----------+ +---------+
- | Build |
- | Slave |
- +---------+
-
- The buildmaster is configured and maintained by the "buildmaster
-admin", who is generally the project team member responsible for
-build process issues. Each buildslave is maintained by a "buildslave
-admin", who do not need to be quite as involved. Generally slaves are
-run by anyone who has an interest in seeing the project work well on
-their favorite platform.
-
-* Menu:
-
-* BuildSlave Connections::
-* Buildmaster Architecture::
-* Status Delivery Architecture::
-
-
-File: buildbot.info, Node: BuildSlave Connections, Next: Buildmaster Architecture, Prev: System Architecture, Up: System Architecture
-
-1.2.1 BuildSlave Connections
-----------------------------
-
-The buildslaves are typically run on a variety of separate machines,
-at least one per platform of interest. These machines connect to the
-buildmaster over a TCP connection to a publically-visible port. As a
-result, the buildslaves can live behind a NAT box or similar
-firewalls, as long as they can get to buildmaster. The TCP connections
-are initiated by the buildslave and accepted by the buildmaster, but
-commands and results travel both ways within this connection. The
-buildmaster is always in charge, so all commands travel exclusively
-from the buildmaster to the buildslave.
-
- To perform builds, the buildslaves must typically obtain source
-code from a CVS/SVN/etc repository. Therefore they must also be able
-to reach the repository. The buildmaster provides instructions for
-performing builds, but does not provide the source code itself.
-
-
-
-Repository| | BuildMaster | |
- (CVS/SVN)| | ^|^^^ |
- | | / c \ |
-----------+ +------------------/--o----\-+
- ^ / m ^ \
- | / m | \
- checkout/update --+ a | +--
- | TCP| n | |TCP
- | | d | |
- | | s | |
- | | | | |
- | | | r |
- | | | e |
- -N-A-T-|- - - - -N-A-T- - - - -|- |- s-|- - - - -N-A-T- - -
- | | | u |
- | | | l |
- | +------------------|--|--t-|-+
- | | | | s | |
- +----| v | |
- | | |
- | | |
- | |
- | BuildSlave |
- +----------------------------+
-
-
-File: buildbot.info, Node: Buildmaster Architecture, Next: Status Delivery Architecture, Prev: BuildSlave Connections, Up: System Architecture
-
-1.2.2 Buildmaster Architecture
-------------------------------
-
-The Buildmaster consists of several pieces:
-
-
-
- +---------------+
- | Change Source |----->----+
- +---------------+ |
- Changes
- |
- +---------------+ v
- | Change Source |----->----+
- +---------------+ v
- +-----+-------+
- | |
- v v
- +-----------+ +-----------+
- | Scheduler | | Scheduler |
- +-----------+ +-----------+
- | | |
- +------+---------+ +---+ +-----+
- | | | |
- v | | Build
- : : : v v : Request
- : : : : |
- : ---- : : : |
- : ---- : : ---- : |
- +======+ +======+ : v :
- | | : :
- v v : :
- +---------+ +---------+ :queue :
- | Builder | | Builder | +======+
- +---------+ +---------+ |
- v
- +---------+
- | Builder |
- +---------+
-
- * Change Sources, which create a Change object each time something
- is modified in the VC repository. Most ChangeSources listen for
- messages from a hook script of some sort. Some sources actively
- poll the repository on a regular basis. All Changes are fed to
- the Schedulers.
-
- * Schedulers, which decide when builds should be performed. They
- collect Changes into BuildRequests, which are then queued for
- delivery to Builders until a buildslave is available.
-
- * Builders, which control exactly _how_ each build is performed
- (with a series of BuildSteps, configured in a BuildFactory). Each
- Build is run on a single buildslave.
-
- * Status plugins, which deliver information about the build results
- through protocols like HTTP, mail, and IRC.
-
-
-
-
- +-----------------+
- | BuildSlave |
- | |
- | |
- +-------+ | +------------+ |
- |Builder|----Build----->|SlaveBuilder| |
- +-------+ | +------------+ |
- | |
- | +------------+ |
- +-Build---->|SlaveBuilder| |
- | | +------------+ |
- +-------+ | | |
- |Builder|---+ +-----------------+
- +-------+ |
- |
- | +-----------------+
- Build | BuildSlave |
- | | |
- | | |
- | | +------------+ |
- +------->|SlaveBuilder| |
- | +------------+ |
- +-------+ | |
- |Builder|--+ | +------------+ |
- +-------+ +-------->|SlaveBuilder| |
- | +------------+ |
- | |
- +-----------------+
-
- Each Builder is configured with a list of BuildSlaves that it will
-use for its builds. These buildslaves are expected to behave
-identically: the only reason to use multiple BuildSlaves for a single
-Builder is to provide a measure of load-balancing.
-
- Within a single BuildSlave, each Builder creates its own
-SlaveBuilder instance. These SlaveBuilders operate independently from
-each other. Each gets its own base directory to work in. It is quite
-common to have many Builders sharing the same buildslave. For
-example, there might be two buildslaves: one for i386, and a second
-for PowerPC. There may then be a pair of Builders that do a full
-compile/test run, one for each architecture, and a lone Builder that
-creates snapshot source tarballs if the full builders complete
-successfully. The full builders would each run on a single
-buildslave, whereas the tarball creation step might run on either
-buildslave (since the platform doesn't matter when creating source
-tarballs). In this case, the mapping would look like:
-
- Builder(full-i386) -> BuildSlaves(slave-i386)
- Builder(full-ppc) -> BuildSlaves(slave-ppc)
- Builder(source-tarball) -> BuildSlaves(slave-i386, slave-ppc)
-
- and each BuildSlave would have two SlaveBuilders inside it, one
-for a full builder, and a second for the source-tarball builder.
-
- Once a SlaveBuilder is available, the Builder pulls one or more
-BuildRequests off its incoming queue. (It may pull more than one if it
-determines that it can merge the requests together; for example, there
-may be multiple requests to build the current HEAD revision). These
-requests are merged into a single Build instance, which includes the
-SourceStamp that describes what exact version of the source code
-should be used for the build. The Build is then randomly assigned to a
-free SlaveBuilder and the build begins.
-
- The behaviour when BuildRequests are merged can be customized,
-*note Merging BuildRequests::.
-
-
-File: buildbot.info, Node: Status Delivery Architecture, Prev: Buildmaster Architecture, Up: System Architecture
-
-1.2.3 Status Delivery Architecture
-----------------------------------
-
-The buildmaster maintains a central Status object, to which various
-status plugins are connected. Through this Status object, a full
-hierarchy of build status objects can be obtained.
-
-
-
- Status Objects Status Plugins User Clients
-
- +------+ +---------+ +-----------+
- |Status|<--------------+-->|Waterfall|<-------|Web Browser|
- +------+ | +---------+ +-----------+
- | +-----+ |
- v v |
-+-------+ +-------+ | +---+ +----------+
-|Builder| |Builder| +---->|IRC|<----------->IRC Server|
-|Status | |Status | | +---+ +----------+
-+-------+ +-------+ |
- | +----+ |
- v v | +------------+ +----+
-+------+ +------+ +-->|MailNotifier|---->|SMTP|
-|Build | |Build | +------------+ +----+
-|Status| |Status|
-+------+ +------+
- | +-----+
- v v
-+------+ +------+
-|Step | |Step |
-|Status| |Status|
-+------+ +------+
- | +---+
- v v
-+----+ +----+
-|Log | |Log |
-|File| |File|
-+----+ +----+
-
- The configuration file controls which status plugins are active.
-Each status plugin gets a reference to the top-level Status object.
-From there they can request information on each Builder, Build, Step,
-and LogFile. This query-on-demand interface is used by the
-html.Waterfall plugin to create the main status page each time a web
-browser hits the main URL.
-
- The status plugins can also subscribe to hear about new Builds as
-they occur: this is used by the MailNotifier to create new email
-messages for each recently-completed Build.
-
- The Status object records the status of old builds on disk in the
-buildmaster's base directory. This allows it to return information
-about historical builds.
-
- There are also status objects that correspond to Schedulers and
-BuildSlaves. These allow status plugins to report information about
-upcoming builds, and the online/offline status of each buildslave.
-
-
-File: buildbot.info, Node: Control Flow, Prev: System Architecture, Up: Introduction
-
-1.3 Control Flow
-================
-
-A day in the life of the buildbot:
-
- * A developer commits some source code changes to the repository.
- A hook script or commit trigger of some sort sends information
- about this change to the buildmaster through one of its
- configured Change Sources. This notification might arrive via
- email, or over a network connection (either initiated by the
- buildmaster as it "subscribes" to changes, or by the commit
- trigger as it pushes Changes towards the buildmaster). The
- Change contains information about who made the change, what
- files were modified, which revision contains the change, and any
- checkin comments.
-
- * The buildmaster distributes this change to all of its configured
- Schedulers. Any "important" changes cause the "tree-stable-timer"
- to be started, and the Change is added to a list of those that
- will go into a new Build. When the timer expires, a Build is
- started on each of a set of configured Builders, all
- compiling/testing the same source code. Unless configured
- otherwise, all Builds run in parallel on the various buildslaves.
-
- * The Build consists of a series of Steps. Each Step causes some
- number of commands to be invoked on the remote buildslave
- associated with that Builder. The first step is almost always to
- perform a checkout of the appropriate revision from the same VC
- system that produced the Change. The rest generally perform a
- compile and run unit tests. As each Step runs, the buildslave
- reports back command output and return status to the buildmaster.
-
- * As the Build runs, status messages like "Build Started", "Step
- Started", "Build Finished", etc, are published to a collection of
- Status Targets. One of these targets is usually the HTML
- "Waterfall" display, which shows a chronological list of events,
- and summarizes the results of the most recent build at the top
- of each column. Developers can periodically check this page to
- see how their changes have fared. If they see red, they know
- that they've made a mistake and need to fix it. If they see
- green, they know that they've done their duty and don't need to
- worry about their change breaking anything.
-
- * If a MailNotifier status target is active, the completion of a
- build will cause email to be sent to any developers whose
- Changes were incorporated into this Build. The MailNotifier can
- be configured to only send mail upon failing builds, or for
- builds which have just transitioned from passing to failing.
- Other status targets can provide similar real-time notification
- via different communication channels, like IRC.
-
-
-
-File: buildbot.info, Node: Installation, Next: Concepts, Prev: Introduction, Up: Top
-
-2 Installation
-**************
-
-* Menu:
-
-* Requirements::
-* Installing the code::
-* Creating a buildmaster::
-* Upgrading an Existing Buildmaster::
-* Creating a buildslave::
-* Launching the daemons::
-* Logfiles::
-* Shutdown::
-* Maintenance::
-* Troubleshooting::
-
-
-File: buildbot.info, Node: Requirements, Next: Installing the code, Prev: Installation, Up: Installation
-
-2.1 Requirements
-================
-
-At a bare minimum, you'll need the following (for both the buildmaster
-and a buildslave):
-
- * Python: http://www.python.org
-
- Buildbot requires python-2.3 or later, and is primarily developed
- against python-2.4. It is also tested against python-2.5 .
-
- * Twisted: http://twistedmatrix.com
-
- Both the buildmaster and the buildslaves require Twisted-2.0.x or
- later. It has been tested against all releases of Twisted up to
- Twisted-2.5.0 (the most recent as of this writing). As always,
- the most recent version is recommended.
-
- Twisted is delivered as a collection of subpackages. You'll need
- at least "Twisted" (the core package), and you'll also want
- TwistedMail, TwistedWeb, and TwistedWords (for sending email,
- serving a web status page, and delivering build status via IRC,
- respectively). You might also want TwistedConch (for the
- encrypted Manhole debug port). Note that Twisted requires
- ZopeInterface to be installed as well.
-
-
- Certain other packages may be useful on the system running the
-buildmaster:
-
- * CVSToys: http://purl.net/net/CVSToys
-
- If your buildmaster uses FreshCVSSource to receive change
- notification from a cvstoys daemon, it will require CVSToys be
- installed (tested with CVSToys-1.0.10). If the it doesn't use
- that source (i.e. if you only use a mail-parsing change source,
- or the SVN notification script), you will not need CVSToys.
-
-
- And of course, your project's build process will impose additional
-requirements on the buildslaves. These hosts must have all the tools
-necessary to compile and test your project's source code.
-
-
-File: buildbot.info, Node: Installing the code, Next: Creating a buildmaster, Prev: Requirements, Up: Installation
-
-2.2 Installing the code
-=======================
-
-The Buildbot is installed using the standard python `distutils'
-module. After unpacking the tarball, the process is:
-
- python setup.py build
- python setup.py install
-
- where the install step may need to be done as root. This will put
-the bulk of the code in somewhere like
-/usr/lib/python2.3/site-packages/buildbot . It will also install the
-`buildbot' command-line tool in /usr/bin/buildbot.
-
- To test this, shift to a different directory (like /tmp), and run:
-
- buildbot --version
-
- If it shows you the versions of Buildbot and Twisted, the install
-went ok. If it says `no such command' or it gets an `ImportError'
-when it tries to load the libaries, then something went wrong.
-`pydoc buildbot' is another useful diagnostic tool.
-
- Windows users will find these files in other places. You will need
-to make sure that python can find the libraries, and will probably
-find it convenient to have `buildbot' on your PATH.
-
- If you wish, you can run the buildbot unit test suite like this:
-
- PYTHONPATH=. trial buildbot.test
-
- This should run up to 192 tests, depending upon what VC tools you
-have installed. On my desktop machine it takes about five minutes to
-complete. Nothing should fail, a few might be skipped. If any of the
-tests fail, you should stop and investigate the cause before
-continuing the installation process, as it will probably be easier to
-track down the bug early.
-
- If you cannot or do not wish to install the buildbot into a
-site-wide location like `/usr' or `/usr/local', you can also install
-it into the account's home directory. Do the install command like
-this:
-
- python setup.py install --home=~
-
- That will populate `~/lib/python' and create `~/bin/buildbot'.
-Make sure this lib directory is on your `PYTHONPATH'.
-
-
-File: buildbot.info, Node: Creating a buildmaster, Next: Upgrading an Existing Buildmaster, Prev: Installing the code, Up: Installation
-
-2.3 Creating a buildmaster
-==========================
-
-As you learned earlier (*note System Architecture::), the buildmaster
-runs on a central host (usually one that is publically visible, so
-everybody can check on the status of the project), and controls all
-aspects of the buildbot system. Let us call this host
-`buildbot.example.org'.
-
- You may wish to create a separate user account for the buildmaster,
-perhaps named `buildmaster'. This can help keep your personal
-configuration distinct from that of the buildmaster and is useful if
-you have to use a mail-based notification system (*note Change
-Sources::). However, the Buildbot will work just fine with your
-regular user account.
-
- You need to choose a directory for the buildmaster, called the
-`basedir'. This directory will be owned by the buildmaster, which
-will use configuration files therein, and create status files as it
-runs. `~/Buildbot' is a likely value. If you run multiple
-buildmasters in the same account, or if you run both masters and
-slaves, you may want a more distinctive name like
-`~/Buildbot/master/gnomovision' or `~/Buildmasters/fooproject'. If
-you are using a separate user account, this might just be
-`~buildmaster/masters/fooproject'.
-
- Once you've picked a directory, use the `buildbot create-master'
-command to create the directory and populate it with startup files:
-
- buildbot create-master BASEDIR
-
- You will need to create a configuration file (*note
-Configuration::) before starting the buildmaster. Most of the rest of
-this manual is dedicated to explaining how to do this. A sample
-configuration file is placed in the working directory, named
-`master.cfg.sample', which can be copied to `master.cfg' and edited
-to suit your purposes.
-
- (Internal details: This command creates a file named
-`buildbot.tac' that contains all the state necessary to create the
-buildmaster. Twisted has a tool called `twistd' which can use this
-.tac file to create and launch a buildmaster instance. twistd takes
-care of logging and daemonization (running the program in the
-background). `/usr/bin/buildbot' is a front end which runs twistd for
-you.)
-
- In addition to `buildbot.tac', a small `Makefile.sample' is
-installed. This can be used as the basis for customized daemon
-startup, *Note Launching the daemons::.
-
-
-File: buildbot.info, Node: Upgrading an Existing Buildmaster, Next: Creating a buildslave, Prev: Creating a buildmaster, Up: Installation
-
-2.4 Upgrading an Existing Buildmaster
-=====================================
-
-If you have just installed a new version of the Buildbot code, and you
-have buildmasters that were created using an older version, you'll
-need to upgrade these buildmasters before you can use them. The
-upgrade process adds and modifies files in the buildmaster's base
-directory to make it compatible with the new code.
-
- buildbot upgrade-master BASEDIR
-
- This command will also scan your `master.cfg' file for
-incompatbilities (by loading it and printing any errors or deprecation
-warnings that occur). Each buildbot release tries to be compatible
-with configurations that worked cleanly (i.e. without deprecation
-warnings) on the previous release: any functions or classes that are
-to be removed will first be deprecated in a release, to give users a
-chance to start using their replacement.
-
- The 0.7.6 release introduced the `public_html/' directory, which
-contains `index.html' and other files served by the `WebStatus' and
-`Waterfall' status displays. The `upgrade-master' command will create
-these files if they do not already exist. It will not modify existing
-copies, but it will write a new copy in e.g. `index.html.new' if the
-new version differs from the version that already exists.
-
- The `upgrade-master' command is idempotent. It is safe to run it
-multiple times. After each upgrade of the buildbot code, you should
-use `upgrade-master' on all your buildmasters.
-
-
-File: buildbot.info, Node: Creating a buildslave, Next: Launching the daemons, Prev: Upgrading an Existing Buildmaster, Up: Installation
-
-2.5 Creating a buildslave
-=========================
-
-Typically, you will be adding a buildslave to an existing buildmaster,
-to provide additional architecture coverage. The buildbot
-administrator will give you several pieces of information necessary to
-connect to the buildmaster. You should also be somewhat familiar with
-the project being tested, so you can troubleshoot build problems
-locally.
-
- The buildbot exists to make sure that the project's stated "how to
-build it" process actually works. To this end, the buildslave should
-run in an environment just like that of your regular developers.
-Typically the project build process is documented somewhere
-(`README', `INSTALL', etc), in a document that should mention all
-library dependencies and contain a basic set of build instructions.
-This document will be useful as you configure the host and account in
-which the buildslave runs.
-
- Here's a good checklist for setting up a buildslave:
-
- 1. Set up the account
-
- It is recommended (although not mandatory) to set up a separate
- user account for the buildslave. This account is frequently named
- `buildbot' or `buildslave'. This serves to isolate your personal
- working environment from that of the slave's, and helps to
- minimize the security threat posed by letting possibly-unknown
- contributors run arbitrary code on your system. The account
- should have a minimum of fancy init scripts.
-
- 2. Install the buildbot code
-
- Follow the instructions given earlier (*note Installing the
- code::). If you use a separate buildslave account, and you
- didn't install the buildbot code to a shared location, then you
- will need to install it with `--home=~' for each account that
- needs it.
-
- 3. Set up the host
-
- Make sure the host can actually reach the buildmaster. Usually
- the buildmaster is running a status webserver on the same
- machine, so simply point your web browser at it and see if you
- can get there. Install whatever additional packages or
- libraries the project's INSTALL document advises. (or not: if
- your buildslave is supposed to make sure that building without
- optional libraries still works, then don't install those
- libraries).
-
- Again, these libraries don't necessarily have to be installed to
- a site-wide shared location, but they must be available to your
- build process. Accomplishing this is usually very specific to
- the build process, so installing them to `/usr' or `/usr/local'
- is usually the best approach.
-
- 4. Test the build process
-
- Follow the instructions in the INSTALL document, in the
- buildslave's account. Perform a full CVS (or whatever) checkout,
- configure, make, run tests, etc. Confirm that the build works
- without manual fussing. If it doesn't work when you do it by
- hand, it will be unlikely to work when the buildbot attempts to
- do it in an automated fashion.
-
- 5. Choose a base directory
-
- This should be somewhere in the buildslave's account, typically
- named after the project which is being tested. The buildslave
- will not touch any file outside of this directory. Something
- like `~/Buildbot' or `~/Buildslaves/fooproject' is appropriate.
-
- 6. Get the buildmaster host/port, botname, and password
-
- When the buildbot admin configures the buildmaster to accept and
- use your buildslave, they will provide you with the following
- pieces of information:
-
- * your buildslave's name
-
- * the password assigned to your buildslave
-
- * the hostname and port number of the buildmaster, i.e.
- buildbot.example.org:8007
-
- 7. Create the buildslave
-
- Now run the 'buildbot' command as follows:
-
- buildbot create-slave BASEDIR MASTERHOST:PORT SLAVENAME PASSWORD
-
- This will create the base directory and a collection of files
- inside, including the `buildbot.tac' file that contains all the
- information you passed to the `buildbot' command.
-
- 8. Fill in the hostinfo files
-
- When it first connects, the buildslave will send a few files up
- to the buildmaster which describe the host that it is running
- on. These files are presented on the web status display so that
- developers have more information to reproduce any test failures
- that are witnessed by the buildbot. There are sample files in
- the `info' subdirectory of the buildbot's base directory. You
- should edit these to correctly describe you and your host.
-
- `BASEDIR/info/admin' should contain your name and email address.
- This is the "buildslave admin address", and will be visible from
- the build status page (so you may wish to munge it a bit if
- address-harvesting spambots are a concern).
-
- `BASEDIR/info/host' should be filled with a brief description of
- the host: OS, version, memory size, CPU speed, versions of
- relevant libraries installed, and finally the version of the
- buildbot code which is running the buildslave.
-
- If you run many buildslaves, you may want to create a single
- `~buildslave/info' file and share it among all the buildslaves
- with symlinks.
-
-
-* Menu:
-
-* Buildslave Options::
-
-
-File: buildbot.info, Node: Buildslave Options, Prev: Creating a buildslave, Up: Creating a buildslave
-
-2.5.1 Buildslave Options
-------------------------
-
-There are a handful of options you might want to use when creating the
-buildslave with the `buildbot create-slave <options> DIR <params>'
-command. You can type `buildbot create-slave --help' for a summary.
-To use these, just include them on the `buildbot create-slave'
-command line, like this:
-
- buildbot create-slave --umask=022 ~/buildslave buildmaster.example.org:42012 myslavename mypasswd
-
-`--usepty'
- This is a boolean flag that tells the buildslave whether to
- launch child processes in a PTY or with regular pipes (the
- default) when the master does not specify. This option is
- deprecated, as this particular parameter is better specified on
- the master.
-
-`--umask'
- This is a string (generally an octal representation of an
- integer) which will cause the buildslave process' "umask" value
- to be set shortly after initialization. The "twistd"
- daemonization utility forces the umask to 077 at startup (which
- means that all files created by the buildslave or its child
- processes will be unreadable by any user other than the
- buildslave account). If you want build products to be readable
- by other accounts, you can add `--umask=022' to tell the
- buildslave to fix the umask after twistd clobbers it. If you want
- build products to be _writable_ by other accounts too, use
- `--umask=000', but this is likely to be a security problem.
-
-`--keepalive'
- This is a number that indicates how frequently "keepalive"
- messages should be sent from the buildslave to the buildmaster,
- expressed in seconds. The default (600) causes a message to be
- sent to the buildmaster at least once every 10 minutes. To set
- this to a lower value, use e.g. `--keepalive=120'.
-
- If the buildslave is behind a NAT box or stateful firewall, these
- messages may help to keep the connection alive: some NAT boxes
- tend to forget about a connection if it has not been used in a
- while. When this happens, the buildmaster will think that the
- buildslave has disappeared, and builds will time out. Meanwhile
- the buildslave will not realize than anything is wrong.
-
-`--maxdelay'
- This is a number that indicates the maximum amount of time the
- buildslave will wait between connection attempts, expressed in
- seconds. The default (300) causes the buildslave to wait at most
- 5 minutes before trying to connect to the buildmaster again.
-
-`--log-size'
- This is the size in bytes when to rotate the Twisted log files.
-
-`--log-count'
- This is the number of log rotations to keep around. You can
- either specify a number or `None' (the default) to keep all
- `twistd.log' files around.
-
-
-
-File: buildbot.info, Node: Launching the daemons, Next: Logfiles, Prev: Creating a buildslave, Up: Installation
-
-2.6 Launching the daemons
-=========================
-
-Both the buildmaster and the buildslave run as daemon programs. To
-launch them, pass the working directory to the `buildbot' command:
-
- buildbot start BASEDIR
-
- This command will start the daemon and then return, so normally it
-will not produce any output. To verify that the programs are indeed
-running, look for a pair of files named `twistd.log' and `twistd.pid'
-that should be created in the working directory. `twistd.pid'
-contains the process ID of the newly-spawned daemon.
-
- When the buildslave connects to the buildmaster, new directories
-will start appearing in its base directory. The buildmaster tells the
-slave to create a directory for each Builder which will be using that
-slave. All build operations are performed within these directories:
-CVS checkouts, compiles, and tests.
-
- Once you get everything running, you will want to arrange for the
-buildbot daemons to be started at boot time. One way is to use
-`cron', by putting them in a @reboot crontab entry(1):
-
- @reboot buildbot start BASEDIR
-
- When you run `crontab' to set this up, remember to do it as the
-buildmaster or buildslave account! If you add this to your crontab
-when running as your regular account (or worse yet, root), then the
-daemon will run as the wrong user, quite possibly as one with more
-authority than you intended to provide.
-
- It is important to remember that the environment provided to cron
-jobs and init scripts can be quite different that your normal runtime.
-There may be fewer environment variables specified, and the PATH may
-be shorter than usual. It is a good idea to test out this method of
-launching the buildslave by using a cron job with a time in the near
-future, with the same command, and then check `twistd.log' to make
-sure the slave actually started correctly. Common problems here are
-for `/usr/local' or `~/bin' to not be on your `PATH', or for
-`PYTHONPATH' to not be set correctly. Sometimes `HOME' is messed up
-too.
-
- To modify the way the daemons are started (perhaps you want to set
-some environment variables first, or perform some cleanup each time),
-you can create a file named `Makefile.buildbot' in the base
-directory. When the `buildbot' front-end tool is told to `start' the
-daemon, and it sees this file (and `/usr/bin/make' exists), it will
-do `make -f Makefile.buildbot start' instead of its usual action
-(which involves running `twistd'). When the buildmaster or buildslave
-is installed, a `Makefile.sample' is created which implements the
-same behavior as the the `buildbot' tool uses, so if you want to
-customize the process, just copy `Makefile.sample' to
-`Makefile.buildbot' and edit it as necessary.
-
- Some distributions may include conveniences to make starting
-buildbot at boot time easy. For instance, with the default buildbot
-package in Debian-based distributions, you may only need to modify
-`/etc/default/buildbot' (see also `/etc/init.d/buildbot', which reads
-the configuration in `/etc/default/buildbot').
-
- ---------- Footnotes ----------
-
- (1) this @reboot syntax is understood by Vixie cron, which is the
-flavor usually provided with linux systems. Other unices may have a
-cron that doesn't understand @reboot
-
-
-File: buildbot.info, Node: Logfiles, Next: Shutdown, Prev: Launching the daemons, Up: Installation
-
-2.7 Logfiles
-============
-
-While a buildbot daemon runs, it emits text to a logfile, named
-`twistd.log'. A command like `tail -f twistd.log' is useful to watch
-the command output as it runs.
-
- The buildmaster will announce any errors with its configuration
-file in the logfile, so it is a good idea to look at the log at
-startup time to check for any problems. Most buildmaster activities
-will cause lines to be added to the log.
-
-
-File: buildbot.info, Node: Shutdown, Next: Maintenance, Prev: Logfiles, Up: Installation
-
-2.8 Shutdown
-============
-
-To stop a buildmaster or buildslave manually, use:
-
- buildbot stop BASEDIR
-
- This simply looks for the `twistd.pid' file and kills whatever
-process is identified within.
-
- At system shutdown, all processes are sent a `SIGKILL'. The
-buildmaster and buildslave will respond to this by shutting down
-normally.
-
- The buildmaster will respond to a `SIGHUP' by re-reading its
-config file. Of course, this only works on unix-like systems with
-signal support, and won't work on Windows. The following shortcut is
-available:
-
- buildbot reconfig BASEDIR
-
- When you update the Buildbot code to a new release, you will need
-to restart the buildmaster and/or buildslave before it can take
-advantage of the new code. You can do a `buildbot stop BASEDIR' and
-`buildbot start BASEDIR' in quick succession, or you can use the
-`restart' shortcut, which does both steps for you:
-
- buildbot restart BASEDIR
-
- There are certain configuration changes that are not handled
-cleanly by `buildbot reconfig'. If this occurs, `buildbot restart' is
-a more robust tool to fully switch over to the new configuration.
-
- `buildbot restart' may also be used to start a stopped Buildbot
-instance. This behaviour is useful when writing scripts that stop,
-start and restart Buildbot.
-
- A buildslave may also be gracefully shutdown from the *note
-WebStatus:: status plugin. This is useful to shutdown a buildslave
-without interrupting any current builds. The buildmaster will wait
-until the buildslave is finished all its current builds, and will
-then tell the buildslave to shutdown.
-
-
-File: buildbot.info, Node: Maintenance, Next: Troubleshooting, Prev: Shutdown, Up: Installation
-
-2.9 Maintenance
-===============
-
-It is a good idea to check the buildmaster's status page every once in
-a while, to see if your buildslave is still online. Eventually the
-buildbot will probably be enhanced to send you email (via the
-`info/admin' email address) when the slave has been offline for more
-than a few hours.
-
- If you find you can no longer provide a buildslave to the project,
-please let the project admins know, so they can put out a call for a
-replacement.
-
- The Buildbot records status and logs output continually, each time
-a build is performed. The status tends to be small, but the build logs
-can become quite large. Each build and log are recorded in a separate
-file, arranged hierarchically under the buildmaster's base directory.
-To prevent these files from growing without bound, you should
-periodically delete old build logs. A simple cron job to delete
-anything older than, say, two weeks should do the job. The only trick
-is to leave the `buildbot.tac' and other support files alone, for
-which find's `-mindepth' argument helps skip everything in the top
-directory. You can use something like the following:
-
- @weekly cd BASEDIR && find . -mindepth 2 i-path './public_html/*' -prune -o -type f -mtime +14 -exec rm {} \;
- @weekly cd BASEDIR && find twistd.log* -mtime +14 -exec rm {} \;
-
-
-File: buildbot.info, Node: Troubleshooting, Prev: Maintenance, Up: Installation
-
-2.10 Troubleshooting
-====================
-
-Here are a few hints on diagnosing common problems.
-
-* Menu:
-
-* Starting the buildslave::
-* Connecting to the buildmaster::
-* Forcing Builds::
-
-
-File: buildbot.info, Node: Starting the buildslave, Next: Connecting to the buildmaster, Prev: Troubleshooting, Up: Troubleshooting
-
-2.10.1 Starting the buildslave
-------------------------------
-
-Cron jobs are typically run with a minimal shell (`/bin/sh', not
-`/bin/bash'), and tilde expansion is not always performed in such
-commands. You may want to use explicit paths, because the `PATH' is
-usually quite short and doesn't include anything set by your shell's
-startup scripts (`.profile', `.bashrc', etc). If you've installed
-buildbot (or other python libraries) to an unusual location, you may
-need to add a `PYTHONPATH' specification (note that python will do
-tilde-expansion on `PYTHONPATH' elements by itself). Sometimes it is
-safer to fully-specify everything:
-
- @reboot PYTHONPATH=~/lib/python /usr/local/bin/buildbot start /usr/home/buildbot/basedir
-
- Take the time to get the @reboot job set up. Otherwise, things
-will work fine for a while, but the first power outage or system
-reboot you have will stop the buildslave with nothing but the cries
-of sorrowful developers to remind you that it has gone away.
-
-
-File: buildbot.info, Node: Connecting to the buildmaster, Next: Forcing Builds, Prev: Starting the buildslave, Up: Troubleshooting
-
-2.10.2 Connecting to the buildmaster
-------------------------------------
-
-If the buildslave cannot connect to the buildmaster, the reason should
-be described in the `twistd.log' logfile. Some common problems are an
-incorrect master hostname or port number, or a mistyped bot name or
-password. If the buildslave loses the connection to the master, it is
-supposed to attempt to reconnect with an exponentially-increasing
-backoff. Each attempt (and the time of the next attempt) will be
-logged. If you get impatient, just manually stop and re-start the
-buildslave.
-
- When the buildmaster is restarted, all slaves will be disconnected,
-and will attempt to reconnect as usual. The reconnect time will depend
-upon how long the buildmaster is offline (i.e. how far up the
-exponential backoff curve the slaves have travelled). Again,
-`buildbot stop BASEDIR; buildbot start BASEDIR' will speed up the
-process.
-
-
-File: buildbot.info, Node: Forcing Builds, Prev: Connecting to the buildmaster, Up: Troubleshooting
-
-2.10.3 Forcing Builds
----------------------
-
-From the buildmaster's main status web page, you can force a build to
-be run on your build slave. Figure out which column is for a builder
-that runs on your slave, click on that builder's name, and the page
-that comes up will have a "Force Build" button. Fill in the form, hit
-the button, and a moment later you should see your slave's
-`twistd.log' filling with commands being run. Using `pstree' or `top'
-should also reveal the cvs/make/gcc/etc processes being run by the
-buildslave. Note that the same web page should also show the `admin'
-and `host' information files that you configured earlier.
-
-
-File: buildbot.info, Node: Concepts, Next: Configuration, Prev: Installation, Up: Top
-
-3 Concepts
-**********
-
-This chapter defines some of the basic concepts that the Buildbot
-uses. You'll need to understand how the Buildbot sees the world to
-configure it properly.
-
-* Menu:
-
-* Version Control Systems::
-* Schedulers::
-* BuildSet::
-* BuildRequest::
-* Builder::
-* Users::
-* Build Properties::
-
-
-File: buildbot.info, Node: Version Control Systems, Next: Schedulers, Prev: Concepts, Up: Concepts
-
-3.1 Version Control Systems
-===========================
-
-These source trees come from a Version Control System of some kind.
-CVS and Subversion are two popular ones, but the Buildbot supports
-others. All VC systems have some notion of an upstream `repository'
-which acts as a server(1), from which clients can obtain source trees
-according to various parameters. The VC repository provides source
-trees of various projects, for different branches, and from various
-points in time. The first thing we have to do is to specify which
-source tree we want to get.
-
-* Menu:
-
-* Generalizing VC Systems::
-* Source Tree Specifications::
-* How Different VC Systems Specify Sources::
-* Attributes of Changes::
-
- ---------- Footnotes ----------
-
- (1) except Darcs, but since the Buildbot never modifies its local
-source tree we can ignore the fact that Darcs uses a less centralized
-model
-
-
-File: buildbot.info, Node: Generalizing VC Systems, Next: Source Tree Specifications, Prev: Version Control Systems, Up: Version Control Systems
-
-3.1.1 Generalizing VC Systems
------------------------------
-
-For the purposes of the Buildbot, we will try to generalize all VC
-systems as having repositories that each provide sources for a variety
-of projects. Each project is defined as a directory tree with source
-files. The individual files may each have revisions, but we ignore
-that and treat the project as a whole as having a set of revisions
-(CVS is really the only VC system still in widespread use that has
-per-file revisions.. everything modern has moved to atomic tree-wide
-changesets). Each time someone commits a change to the project, a new
-revision becomes available. These revisions can be described by a
-tuple with two items: the first is a branch tag, and the second is
-some kind of revision stamp or timestamp. Complex projects may have
-multiple branch tags, but there is always a default branch. The
-timestamp may be an actual timestamp (such as the -D option to CVS),
-or it may be a monotonically-increasing transaction number (such as
-the change number used by SVN and P4, or the revision number used by
-Arch/Baz/Bazaar, or a labeled tag used in CVS)(1). The SHA1 revision
-ID used by Monotone, Mercurial, and Git is also a kind of revision
-stamp, in that it specifies a unique copy of the source tree, as does
-a Darcs "context" file.
-
- When we aren't intending to make any changes to the sources we
-check out (at least not any that need to be committed back upstream),
-there are two basic ways to use a VC system:
-
- * Retrieve a specific set of source revisions: some tag or key is
- used to index this set, which is fixed and cannot be changed by
- subsequent developers committing new changes to the tree.
- Releases are built from tagged revisions like this, so that they
- can be rebuilt again later (probably with controlled
- modifications).
-
- * Retrieve the latest sources along a specific branch: some tag is
- used to indicate which branch is to be used, but within that
- constraint we want to get the latest revisions.
-
- Build personnel or CM staff typically use the first approach: the
-build that results is (ideally) completely specified by the two
-parameters given to the VC system: repository and revision tag. This
-gives QA and end-users something concrete to point at when reporting
-bugs. Release engineers are also reportedly fond of shipping code that
-can be traced back to a concise revision tag of some sort.
-
- Developers are more likely to use the second approach: each morning
-the developer does an update to pull in the changes committed by the
-team over the last day. These builds are not easy to fully specify: it
-depends upon exactly when you did a checkout, and upon what local
-changes the developer has in their tree. Developers do not normally
-tag each build they produce, because there is usually significant
-overhead involved in creating these tags. Recreating the trees used by
-one of these builds can be a challenge. Some VC systems may provide
-implicit tags (like a revision number), while others may allow the use
-of timestamps to mean "the state of the tree at time X" as opposed to
-a tree-state that has been explicitly marked.
-
- The Buildbot is designed to help developers, so it usually works in
-terms of _the latest_ sources as opposed to specific tagged
-revisions. However, it would really prefer to build from reproducible
-source trees, so implicit revisions are used whenever possible.
-
- ---------- Footnotes ----------
-
- (1) many VC systems provide more complexity than this: in
-particular the local views that P4 and ClearCase can assemble out of
-various source directories are more complex than we're prepared to
-take advantage of here
-
-
-File: buildbot.info, Node: Source Tree Specifications, Next: How Different VC Systems Specify Sources, Prev: Generalizing VC Systems, Up: Version Control Systems
-
-3.1.2 Source Tree Specifications
---------------------------------
-
-So for the Buildbot's purposes we treat each VC system as a server
-which can take a list of specifications as input and produce a source
-tree as output. Some of these specifications are static: they are
-attributes of the builder and do not change over time. Others are more
-variable: each build will have a different value. The repository is
-changed over time by a sequence of Changes, each of which represents a
-single developer making changes to some set of files. These Changes
-are cumulative(1).
-
- For normal builds, the Buildbot wants to get well-defined source
-trees that contain specific Changes, and exclude other Changes that
-may have occurred after the desired ones. We assume that the Changes
-arrive at the buildbot (through one of the mechanisms described in
-*note Change Sources::) in the same order in which they are committed
-to the repository. The Buildbot waits for the tree to become "stable"
-before initiating a build, for two reasons. The first is that
-developers frequently make multiple related commits in quick
-succession, even when the VC system provides ways to make atomic
-transactions involving multiple files at the same time. Running a
-build in the middle of these sets of changes would use an inconsistent
-set of source files, and is likely to fail (and is certain to be less
-useful than a build which uses the full set of changes). The
-tree-stable-timer is intended to avoid these useless builds that
-include some of the developer's changes but not all. The second reason
-is that some VC systems (i.e. CVS) do not provide repository-wide
-transaction numbers, so that timestamps are the only way to refer to
-a specific repository state. These timestamps may be somewhat
-ambiguous, due to processing and notification delays. By waiting until
-the tree has been stable for, say, 10 minutes, we can choose a
-timestamp from the middle of that period to use for our source
-checkout, and then be reasonably sure that any clock-skew errors will
-not cause the build to be performed on an inconsistent set of source
-files.
-
- The Schedulers always use the tree-stable-timer, with a timeout
-that is configured to reflect a reasonable tradeoff between build
-latency and change frequency. When the VC system provides coherent
-repository-wide revision markers (such as Subversion's revision
-numbers, or in fact anything other than CVS's timestamps), the
-resulting Build is simply performed against a source tree defined by
-that revision marker. When the VC system does not provide this, a
-timestamp from the middle of the tree-stable period is used to
-generate the source tree(2).
-
- ---------- Footnotes ----------
-
- (1) Monotone's _multiple heads_ feature violates this assumption
-of cumulative Changes, but in most situations the changes don't occur
-frequently enough for this to be a significant problem
-
- (2) this `checkoutDelay' defaults to half the tree-stable timer,
-but it can be overridden with an argument to the Source Step
-
-
-File: buildbot.info, Node: How Different VC Systems Specify Sources, Next: Attributes of Changes, Prev: Source Tree Specifications, Up: Version Control Systems
-
-3.1.3 How Different VC Systems Specify Sources
-----------------------------------------------
-
-For CVS, the static specifications are `repository' and `module'. In
-addition to those, each build uses a timestamp (or omits the
-timestamp to mean `the latest') and `branch tag' (which defaults to
-HEAD). These parameters collectively specify a set of sources from
-which a build may be performed.
-
- Subversion (http://subversion.tigris.org) combines the repository,
-module, and branch into a single `Subversion URL' parameter. Within
-that scope, source checkouts can be specified by a numeric `revision
-number' (a repository-wide monotonically-increasing marker, such that
-each transaction that changes the repository is indexed by a
-different revision number), or a revision timestamp. When branches
-are used, the repository and module form a static `baseURL', while
-each build has a `revision number' and a `branch' (which defaults to a
-statically-specified `defaultBranch'). The `baseURL' and `branch' are
-simply concatenated together to derive the `svnurl' to use for the
-checkout.
-
- Perforce (http://www.perforce.com/) is similar. The server is
-specified through a `P4PORT' parameter. Module and branch are
-specified in a single depot path, and revisions are depot-wide. When
-branches are used, the `p4base' and `defaultBranch' are concatenated
-together to produce the depot path.
-
- Arch (http://wiki.gnuarch.org/) and Bazaar
-(http://bazaar.canonical.com/) specify a repository by URL, as well
-as a `version' which is kind of like a branch name. Arch uses the
-word `archive' to represent the repository. Arch lets you push
-changes from one archive to another, removing the strict
-centralization required by CVS and SVN. It retains the distinction
-between repository and working directory that most other VC systems
-use. For complex multi-module directory structures, Arch has a
-built-in `build config' layer with which the checkout process has two
-steps. First, an initial bootstrap checkout is performed to retrieve
-a set of build-config files. Second, one of these files is used to
-figure out which archives/modules should be used to populate
-subdirectories of the initial checkout.
-
- Builders which use Arch and Bazaar therefore have a static archive
-`url', and a default "branch" (which is a string that specifies a
-complete category-branch-version triple). Each build can have its own
-branch (the category-branch-version string) to override the default,
-as well as a revision number (which is turned into a -patch-NN suffix
-when performing the checkout).
-
- Bzr (http://bazaar-vcs.org) (which is a descendant of Arch/Bazaar,
-and is frequently referred to as "Bazaar") has the same sort of
-repository-vs-workspace model as Arch, but the repository data can
-either be stored inside the working directory or kept elsewhere
-(either on the same machine or on an entirely different machine). For
-the purposes of Buildbot (which never commits changes), the repository
-is specified with a URL and a revision number.
-
- The most common way to obtain read-only access to a bzr tree is via
-HTTP, simply by making the repository visible through a web server
-like Apache. Bzr can also use FTP and SFTP servers, if the buildslave
-process has sufficient privileges to access them. Higher performance
-can be obtained by running a special Bazaar-specific server. None of
-these matter to the buildbot: the repository URL just has to match the
-kind of server being used. The `repoURL' argument provides the
-location of the repository.
-
- Branches are expressed as subdirectories of the main central
-repository, which means that if branches are being used, the BZR step
-is given a `baseURL' and `defaultBranch' instead of getting the
-`repoURL' argument.
-
- Darcs (http://darcs.net/) doesn't really have the notion of a
-single master repository. Nor does it really have branches. In Darcs,
-each working directory is also a repository, and there are operations
-to push and pull patches from one of these `repositories' to another.
-For the Buildbot's purposes, all you need to do is specify the URL of
-a repository that you want to build from. The build slave will then
-pull the latest patches from that repository and build them. Multiple
-branches are implemented by using multiple repositories (possibly
-living on the same server).
-
- Builders which use Darcs therefore have a static `repourl' which
-specifies the location of the repository. If branches are being used,
-the source Step is instead configured with a `baseURL' and a
-`defaultBranch', and the two strings are simply concatenated together
-to obtain the repository's URL. Each build then has a specific branch
-which replaces `defaultBranch', or just uses the default one. Instead
-of a revision number, each build can have a "context", which is a
-string that records all the patches that are present in a given tree
-(this is the output of `darcs changes --context', and is considerably
-less concise than, e.g. Subversion's revision number, but the
-patch-reordering flexibility of Darcs makes it impossible to provide
-a shorter useful specification).
-
- Mercurial (http://selenic.com/mercurial) is like Darcs, in that
-each branch is stored in a separate repository. The `repourl',
-`baseURL', and `defaultBranch' arguments are all handled the same way
-as with Darcs. The "revision", however, is the hash identifier
-returned by `hg identify'.
-
- Git (http://git.or.cz/) also follows a decentralized model, and
-each repository can have several branches and tags. The source Step is
-configured with a static `repourl' which specifies the location of
-the repository. In addition, an optional `branch' parameter can be
-specified to check out code from a specific branch instead of the
-default "master" branch. The "revision" is specified as a SHA1 hash
-as returned by e.g. `git rev-parse'. No attempt is made to ensure
-that the specified revision is actually a subset of the specified
-branch.
-
-
-File: buildbot.info, Node: Attributes of Changes, Prev: How Different VC Systems Specify Sources, Up: Version Control Systems
-
-3.1.4 Attributes of Changes
----------------------------
-
-Who
-===
-
-Each Change has a `who' attribute, which specifies which developer is
-responsible for the change. This is a string which comes from a
-namespace controlled by the VC repository. Frequently this means it
-is a username on the host which runs the repository, but not all VC
-systems require this (Arch, for example, uses a fully-qualified `Arch
-ID', which looks like an email address, as does Darcs). Each
-StatusNotifier will map the `who' attribute into something
-appropriate for their particular means of communication: an email
-address, an IRC handle, etc.
-
-Files
-=====
-
-It also has a list of `files', which are just the tree-relative
-filenames of any files that were added, deleted, or modified for this
-Change. These filenames are used by the `fileIsImportant' function
-(in the Scheduler) to decide whether it is worth triggering a new
-build or not, e.g. the function could use the following function to
-only run a build if a C file were checked in:
-
- def has_C_files(change):
- for name in change.files:
- if name.endswith(".c"):
- return True
- return False
-
- Certain BuildSteps can also use the list of changed files to run a
-more targeted series of tests, e.g. the `python_twisted.Trial' step
-can run just the unit tests that provide coverage for the modified
-.py files instead of running the full test suite.
-
-Comments
-========
-
-The Change also has a `comments' attribute, which is a string
-containing any checkin comments.
-
-Revision
-========
-
-Each Change can have a `revision' attribute, which describes how to
-get a tree with a specific state: a tree which includes this Change
-(and all that came before it) but none that come after it. If this
-information is unavailable, the `.revision' attribute will be `None'.
-These revisions are provided by the ChangeSource, and consumed by the
-`computeSourceRevision' method in the appropriate `step.Source' class.
-
-`CVS'
- `revision' is an int, seconds since the epoch
-
-`SVN'
- `revision' is an int, the changeset number (r%d)
-
-`Darcs'
- `revision' is a large string, the output of `darcs changes
- --context'
-
-`Mercurial'
- `revision' is a short string (a hash ID), the output of `hg
- identify'
-
-`Arch/Bazaar'
- `revision' is the full revision ID (ending in -patch-%d)
-
-`P4'
- `revision' is an int, the transaction number
-
-`Git'
- `revision' is a short string (a SHA1 hash), the output of e.g.
- `git rev-parse'
-
-Branches
-========
-
-The Change might also have a `branch' attribute. This indicates that
-all of the Change's files are in the same named branch. The
-Schedulers get to decide whether the branch should be built or not.
-
- For VC systems like CVS, Arch, Monotone, and Git, the `branch'
-name is unrelated to the filename. (that is, the branch name and the
-filename inhabit unrelated namespaces). For SVN, branches are
-expressed as subdirectories of the repository, so the file's "svnurl"
-is a combination of some base URL, the branch name, and the filename
-within the branch. (In a sense, the branch name and the filename
-inhabit the same namespace). Darcs branches are subdirectories of a
-base URL just like SVN. Mercurial branches are the same as Darcs.
-
-`CVS'
- branch='warner-newfeature', files=['src/foo.c']
-
-`SVN'
- branch='branches/warner-newfeature', files=['src/foo.c']
-
-`Darcs'
- branch='warner-newfeature', files=['src/foo.c']
-
-`Mercurial'
- branch='warner-newfeature', files=['src/foo.c']
-
-`Arch/Bazaar'
- branch='buildbot-usebranches-0', files=['buildbot/master.py']
-
-`Git'
- branch='warner-newfeature', files=['src/foo.c']
-
-Links
-=====
-
-Finally, the Change might have a `links' list, which is intended to
-provide a list of URLs to a _viewcvs_-style web page that provides
-more detail for this Change, perhaps including the full file diffs.
-
-
-File: buildbot.info, Node: Schedulers, Next: BuildSet, Prev: Version Control Systems, Up: Concepts
-
-3.2 Schedulers
-==============
-
-Each Buildmaster has a set of `Scheduler' objects, each of which gets
-a copy of every incoming Change. The Schedulers are responsible for
-deciding when Builds should be run. Some Buildbot installations might
-have a single Scheduler, while others may have several, each for a
-different purpose.
-
- For example, a "quick" scheduler might exist to give immediate
-feedback to developers, hoping to catch obvious problems in the code
-that can be detected quickly. These typically do not run the full test
-suite, nor do they run on a wide variety of platforms. They also
-usually do a VC update rather than performing a brand-new checkout
-each time. You could have a "quick" scheduler which used a 30 second
-timeout, and feeds a single "quick" Builder that uses a VC
-`mode='update'' setting.
-
- A separate "full" scheduler would run more comprehensive tests a
-little while later, to catch more subtle problems. This scheduler
-would have a longer tree-stable-timer, maybe 30 minutes, and would
-feed multiple Builders (with a `mode=' of `'copy'', `'clobber'', or
-`'export'').
-
- The `tree-stable-timer' and `fileIsImportant' decisions are made
-by the Scheduler. Dependencies are also implemented here. Periodic
-builds (those which are run every N seconds rather than after new
-Changes arrive) are triggered by a special `Periodic' Scheduler
-subclass. The default Scheduler class can also be told to watch for
-specific branches, ignoring Changes on other branches. This may be
-useful if you have a trunk and a few release branches which should be
-tracked, but when you don't want to have the Buildbot pay attention
-to several dozen private user branches.
-
- When the setup has multiple sources of Changes the `category' can
-be used for `Scheduler' objects to filter out a subset of the
-Changes. Note that not all change sources can attach a category.
-
- Some Schedulers may trigger builds for other reasons, other than
-recent Changes. For example, a Scheduler subclass could connect to a
-remote buildmaster and watch for builds of a library to succeed before
-triggering a local build that uses that library.
-
- Each Scheduler creates and submits `BuildSet' objects to the
-`BuildMaster', which is then responsible for making sure the
-individual `BuildRequests' are delivered to the target `Builders'.
-
- `Scheduler' instances are activated by placing them in the
-`c['schedulers']' list in the buildmaster config file. Each Scheduler
-has a unique name.
-
-
-File: buildbot.info, Node: BuildSet, Next: BuildRequest, Prev: Schedulers, Up: Concepts
-
-3.3 BuildSet
-============
-
-A `BuildSet' is the name given to a set of Builds that all
-compile/test the same version of the tree on multiple Builders. In
-general, all these component Builds will perform the same sequence of
-Steps, using the same source code, but on different platforms or
-against a different set of libraries.
-
- The `BuildSet' is tracked as a single unit, which fails if any of
-the component Builds have failed, and therefore can succeed only if
-_all_ of the component Builds have succeeded. There are two kinds of
-status notification messages that can be emitted for a BuildSet: the
-`firstFailure' type (which fires as soon as we know the BuildSet will
-fail), and the `Finished' type (which fires once the BuildSet has
-completely finished, regardless of whether the overall set passed or
-failed).
-
- A `BuildSet' is created with a _source stamp_ tuple of (branch,
-revision, changes, patch), some of which may be None, and a list of
-Builders on which it is to be run. They are then given to the
-BuildMaster, which is responsible for creating a separate
-`BuildRequest' for each Builder.
-
- There are a couple of different likely values for the
-`SourceStamp':
-
-`(revision=None, changes=[CHANGES], patch=None)'
- This is a `SourceStamp' used when a series of Changes have
- triggered a build. The VC step will attempt to check out a tree
- that contains CHANGES (and any changes that occurred before
- CHANGES, but not any that occurred after them).
-
-`(revision=None, changes=None, patch=None)'
- This builds the most recent code on the default branch. This is
- the sort of `SourceStamp' that would be used on a Build that was
- triggered by a user request, or a Periodic scheduler. It is also
- possible to configure the VC Source Step to always check out the
- latest sources rather than paying attention to the Changes in the
- SourceStamp, which will result in same behavior as this.
-
-`(branch=BRANCH, revision=None, changes=None, patch=None)'
- This builds the most recent code on the given BRANCH. Again,
- this is generally triggered by a user request or Periodic build.
-
-`(revision=REV, changes=None, patch=(LEVEL, DIFF))'
- This checks out the tree at the given revision REV, then applies
- a patch (using `patch -pLEVEL <DIFF'). The *note try:: feature
- uses this kind of `SourceStamp'. If `patch' is None, the patching
- step is bypassed.
-
-
- The buildmaster is responsible for turning the `BuildSet' into a
-set of `BuildRequest' objects and queueing them on the appropriate
-Builders.
-
-
-File: buildbot.info, Node: BuildRequest, Next: Builder, Prev: BuildSet, Up: Concepts
-
-3.4 BuildRequest
-================
-
-A `BuildRequest' is a request to build a specific set of sources on a
-single specific `Builder'. Each `Builder' runs the `BuildRequest' as
-soon as it can (i.e. when an associated buildslave becomes free).
-`BuildRequest's are prioritized from oldest to newest, so when a
-buildslave becomes free, the `Builder' with the oldest `BuildRequest'
-is run.
-
- The `BuildRequest' contains the `SourceStamp' specification. The
-actual process of running the build (the series of Steps that will be
-executed) is implemented by the `Build' object. In this future this
-might be changed, to have the `Build' define _what_ gets built, and a
-separate `BuildProcess' (provided by the Builder) to define _how_ it
-gets built.
-
- `BuildRequest' is created with optional `Properties'. One of
-these, `owner', is collected by the resultant `Build' and added to
-the set of _interested users_ to which status notifications will be
-sent, depending on the configuration for each status object.
-
- The `BuildRequest' may be mergeable with other compatible
-`BuildRequest's. Builds that are triggered by incoming Changes will
-generally be mergeable. Builds that are triggered by user requests
-are generally not, unless they are multiple requests to build the
-_latest sources_ of the same branch.
-
-
-File: buildbot.info, Node: Builder, Next: Users, Prev: BuildRequest, Up: Concepts
-
-3.5 Builder
-===========
-
-The `Builder' is a long-lived object which controls all Builds of a
-given type. Each one is created when the config file is first parsed,
-and lives forever (or rather until it is removed from the config
-file). It mediates the connections to the buildslaves that do all the
-work, and is responsible for creating the `Build' objects that decide
-_how_ a build is performed (i.e., which steps are executed in what
-order).
-
- Each `Builder' gets a unique name, and the path name of a
-directory where it gets to do all its work (there is a
-buildmaster-side directory for keeping status information, as well as
-a buildslave-side directory where the actual checkout/compile/test
-commands are executed). It also gets a `BuildFactory', which is
-responsible for creating new `Build' instances: because the `Build'
-instance is what actually performs each build, choosing the
-`BuildFactory' is the way to specify what happens each time a build
-is done.
-
- Each `Builder' is associated with one of more `BuildSlaves'. A
-`Builder' which is used to perform OS-X builds (as opposed to Linux
-or Solaris builds) should naturally be associated with an OS-X-based
-buildslave.
-
- A `Builder' may be given a set of environment variables to be used
-in its *note ShellCommand::s. These variables will override anything
-in the buildslave's environment. Variables passed directly to a
-ShellCommand will override variables of the same name passed to the
-Builder.
-
- For example, if you a pool of identical slaves it is often easier
-to manage variables like PATH from Buildbot rather than manually
-editing it inside of the slaves' environment.
-
- f = factory.BuildFactory
- f.addStep(ShellCommand(
- command=['bash', './configure']))
- f.addStep(Compile())
-
- c['builders'] = [
- {'name': 'test', 'slavenames': ['slave1', 'slave2', 'slave3', 'slave4',
- 'slave5', 'slave6'],
- 'builddir': 'test', 'factory': f',
- 'env': {'PATH': '/opt/local/bin:/opt/app/bin:/usr/local/bin:/usr/bin'}}
-
-
-File: buildbot.info, Node: Users, Next: Build Properties, Prev: Builder, Up: Concepts
-
-3.6 Users
-=========
-
-Buildbot has a somewhat limited awareness of _users_. It assumes the
-world consists of a set of developers, each of whom can be described
-by a couple of simple attributes. These developers make changes to
-the source code, causing builds which may succeed or fail.
-
- Each developer is primarily known through the source control
-system. Each Change object that arrives is tagged with a `who' field
-that typically gives the account name (on the repository machine) of
-the user responsible for that change. This string is the primary key
-by which the User is known, and is displayed on the HTML status pages
-and in each Build's "blamelist".
-
- To do more with the User than just refer to them, this username
-needs to be mapped into an address of some sort. The responsibility
-for this mapping is left up to the status module which needs the
-address. The core code knows nothing about email addresses or IRC
-nicknames, just user names.
-
-* Menu:
-
-* Doing Things With Users::
-* Email Addresses::
-* IRC Nicknames::
-* Live Status Clients::
-
-
-File: buildbot.info, Node: Doing Things With Users, Next: Email Addresses, Prev: Users, Up: Users
-
-3.6.1 Doing Things With Users
------------------------------
-
-Each Change has a single User who is responsible for that Change. Most
-Builds have a set of Changes: the Build represents the first time
-these Changes have been built and tested by the Buildbot. The build
-has a "blamelist" that consists of a simple union of the Users
-responsible for all the Build's Changes.
-
- The Build provides (through the IBuildStatus interface) a list of
-Users who are "involved" in the build. For now this is equal to the
-blamelist, but in the future it will be expanded to include a "build
-sheriff" (a person who is "on duty" at that time and responsible for
-watching over all builds that occur during their shift), as well as
-per-module owners who simply want to keep watch over their domain
-(chosen by subdirectory or a regexp matched against the filenames
-pulled out of the Changes). The Involved Users are those who probably
-have an interest in the results of any given build.
-
- In the future, Buildbot will acquire the concept of "Problems",
-which last longer than builds and have beginnings and ends. For
-example, a test case which passed in one build and then failed in the
-next is a Problem. The Problem lasts until the test case starts
-passing again, at which point the Problem is said to be "resolved".
-
- If there appears to be a code change that went into the tree at the
-same time as the test started failing, that Change is marked as being
-resposible for the Problem, and the user who made the change is added
-to the Problem's "Guilty" list. In addition to this user, there may
-be others who share responsibility for the Problem (module owners,
-sponsoring developers). In addition to the Responsible Users, there
-may be a set of Interested Users, who take an interest in the fate of
-the Problem.
-
- Problems therefore have sets of Users who may want to be kept
-aware of the condition of the problem as it changes over time. If
-configured, the Buildbot can pester everyone on the Responsible list
-with increasing harshness until the problem is resolved, with the
-most harshness reserved for the Guilty parties themselves. The
-Interested Users may merely be told when the problem starts and
-stops, as they are not actually responsible for fixing anything.
-
-
-File: buildbot.info, Node: Email Addresses, Next: IRC Nicknames, Prev: Doing Things With Users, Up: Users
-
-3.6.2 Email Addresses
----------------------
-
-The `buildbot.status.mail.MailNotifier' class (*note MailNotifier::)
-provides a status target which can send email about the results of
-each build. It accepts a static list of email addresses to which each
-message should be delivered, but it can also be configured to send
-mail to the Build's Interested Users. To do this, it needs a way to
-convert User names into email addresses.
-
- For many VC systems, the User Name is actually an account name on
-the system which hosts the repository. As such, turning the name into
-an email address is a simple matter of appending
-"@repositoryhost.com". Some projects use other kinds of mappings (for
-example the preferred email address may be at "project.org" despite
-the repository host being named "cvs.project.org"), and some VC
-systems have full separation between the concept of a user and that
-of an account on the repository host (like Perforce). Some systems
-(like Arch) put a full contact email address in every change.
-
- To convert these names to addresses, the MailNotifier uses an
-EmailLookup object. This provides a .getAddress method which accepts
-a name and (eventually) returns an address. The default `MailNotifier'
-module provides an EmailLookup which simply appends a static string,
-configurable when the notifier is created. To create more complex
-behaviors (perhaps using an LDAP lookup, or using "finger" on a
-central host to determine a preferred address for the developer),
-provide a different object as the `lookup' argument.
-
- In the future, when the Problem mechanism has been set up, the
-Buildbot will need to send mail to arbitrary Users. It will do this
-by locating a MailNotifier-like object among all the buildmaster's
-status targets, and asking it to send messages to various Users. This
-means the User-to-address mapping only has to be set up once, in your
-MailNotifier, and every email message the buildbot emits will take
-advantage of it.
-
-
-File: buildbot.info, Node: IRC Nicknames, Next: Live Status Clients, Prev: Email Addresses, Up: Users
-
-3.6.3 IRC Nicknames
--------------------
-
-Like MailNotifier, the `buildbot.status.words.IRC' class provides a
-status target which can announce the results of each build. It also
-provides an interactive interface by responding to online queries
-posted in the channel or sent as private messages.
-
- In the future, the buildbot can be configured map User names to IRC
-nicknames, to watch for the recent presence of these nicknames, and to
-deliver build status messages to the interested parties. Like
-`MailNotifier' does for email addresses, the `IRC' object will have
-an `IRCLookup' which is responsible for nicknames. The mapping can be
-set up statically, or it can be updated by online users themselves
-(by claiming a username with some kind of "buildbot: i am user
-warner" commands).
-
- Once the mapping is established, the rest of the buildbot can ask
-the `IRC' object to send messages to various users. It can report on
-the likelihood that the user saw the given message (based upon how
-long the user has been inactive on the channel), which might prompt
-the Problem Hassler logic to send them an email message instead.
-
-
-File: buildbot.info, Node: Live Status Clients, Prev: IRC Nicknames, Up: Users
-
-3.6.4 Live Status Clients
--------------------------
-
-The Buildbot also offers a PB-based status client interface which can
-display real-time build status in a GUI panel on the developer's
-desktop. This interface is normally anonymous, but it could be
-configured to let the buildmaster know _which_ developer is using the
-status client. The status client could then be used as a
-message-delivery service, providing an alternative way to deliver
-low-latency high-interruption messages to the developer (like "hey,
-you broke the build").
-
-
-File: buildbot.info, Node: Build Properties, Prev: Users, Up: Concepts
-
-3.7 Build Properties
-====================
-
-Each build has a set of "Build Properties", which can be used by its
-BuildStep to modify their actions. These properties, in the form of
-key-value pairs, provide a general framework for dynamically altering
-the behavior of a build based on its circumstances.
-
- Properties come from a number of places:
- * global configuration - These properties apply to all builds.
-
- * schedulers - A scheduler can specify properties available to all
- the builds it starts.
-
- * buildslaves - A buildslave can pass properties on to the builds
- it performs.
-
- * builds - A build automatically sets a number of properties on
- itself.
-
- * steps - Steps of a build can set properties that are available
- to subsequent steps. In particular, source steps set a number
- of properties.
-
- Properties are very flexible, and can be used to implement all
-manner of functionality. Here are some examples:
-
- Most Source steps record the revision that they checked out in the
-`got_revision' property. A later step could use this property to
-specify the name of a fully-built tarball, dropped in an
-easily-acessible directory for later testing.
-
- Some projects want to perform nightly builds as well as in response
-to committed changes. Such a project would run two schedulers, both
-pointing to the same set of builders, but could provide an
-`is_nightly' property so that steps can distinguish the nightly
-builds, perhaps to run more resource-intensive tests.
-
- Some projects have different build processes on different systems.
-Rather than create a build factory for each slave, the steps can use
-buildslave properties to identify the unique aspects of each slave
-and adapt the build process dynamically.
-
-
-File: buildbot.info, Node: Configuration, Next: Getting Source Code Changes, Prev: Concepts, Up: Top
-
-4 Configuration
-***************
-
-The buildbot's behavior is defined by the "config file", which
-normally lives in the `master.cfg' file in the buildmaster's base
-directory (but this can be changed with an option to the `buildbot
-create-master' command). This file completely specifies which
-Builders are to be run, which slaves they should use, how Changes
-should be tracked, and where the status information is to be sent.
-The buildmaster's `buildbot.tac' file names the base directory;
-everything else comes from the config file.
-
- A sample config file was installed for you when you created the
-buildmaster, but you will need to edit it before your buildbot will do
-anything useful.
-
- This chapter gives an overview of the format of this file and the
-various sections in it. You will need to read the later chapters to
-understand how to fill in each section properly.
-
-* Menu:
-
-* Config File Format::
-* Loading the Config File::
-* Testing the Config File::
-* Defining the Project::
-* Change Sources and Schedulers::
-* Merging BuildRequests::
-* Setting the slaveport::
-* Buildslave Specifiers::
-* On-Demand ("Latent") Buildslaves::
-* Defining Global Properties::
-* Defining Builders::
-* Defining Status Targets::
-* Debug options::
-
-
-File: buildbot.info, Node: Config File Format, Next: Loading the Config File, Prev: Configuration, Up: Configuration
-
-4.1 Config File Format
-======================
-
-The config file is, fundamentally, just a piece of Python code which
-defines a dictionary named `BuildmasterConfig', with a number of keys
-that are treated specially. You don't need to know Python to do basic
-configuration, though, you can just copy the syntax of the sample
-file. If you _are_ comfortable writing Python code, however, you can
-use all the power of a full programming language to achieve more
-complicated configurations.
-
- The `BuildmasterConfig' name is the only one which matters: all
-other names defined during the execution of the file are discarded.
-When parsing the config file, the Buildmaster generally compares the
-old configuration with the new one and performs the minimum set of
-actions necessary to bring the buildbot up to date: Builders which are
-not changed are left untouched, and Builders which are modified get to
-keep their old event history.
-
- Basic Python syntax: comments start with a hash character ("#"),
-tuples are defined with `(parenthesis, pairs)', arrays are defined
-with `[square, brackets]', tuples and arrays are mostly
-interchangeable. Dictionaries (data structures which map "keys" to
-"values") are defined with curly braces: `{'key1': 'value1', 'key2':
-'value2'} '. Function calls (and object instantiation) can use named
-parameters, like `w = html.Waterfall(http_port=8010)'.
-
- The config file starts with a series of `import' statements, which
-make various kinds of Steps and Status targets available for later
-use. The main `BuildmasterConfig' dictionary is created, then it is
-populated with a variety of keys. These keys are broken roughly into
-the following sections, each of which is documented in the rest of
-this chapter:
-
- * Project Definitions
-
- * Change Sources / Schedulers
-
- * Slaveport
-
- * Buildslave Configuration
-
- * Builders / Interlocks
-
- * Status Targets
-
- * Debug options
-
- The config file can use a few names which are placed into its
-namespace:
-
-`basedir'
- the base directory for the buildmaster. This string has not been
- expanded, so it may start with a tilde. It needs to be expanded
- before use. The config file is located in
- `os.path.expanduser(os.path.join(basedir, 'master.cfg'))'
-
-
-
-File: buildbot.info, Node: Loading the Config File, Next: Testing the Config File, Prev: Config File Format, Up: Configuration
-
-4.2 Loading the Config File
-===========================
-
-The config file is only read at specific points in time. It is first
-read when the buildmaster is launched. Once it is running, there are
-various ways to ask it to reload the config file. If you are on the
-system hosting the buildmaster, you can send a `SIGHUP' signal to it:
-the `buildbot' tool has a shortcut for this:
-
- buildbot reconfig BASEDIR
-
- This command will show you all of the lines from `twistd.log' that
-relate to the reconfiguration. If there are any problems during the
-config-file reload, they will be displayed in these lines.
-
- The debug tool (`buildbot debugclient --master HOST:PORT') has a
-"Reload .cfg" button which will also trigger a reload. In the future,
-there will be other ways to accomplish this step (probably a
-password-protected button on the web page, as well as a privileged IRC
-command).
-
- When reloading the config file, the buildmaster will endeavor to
-change as little as possible about the running system. For example,
-although old status targets may be shut down and new ones started up,
-any status targets that were not changed since the last time the
-config file was read will be left running and untouched. Likewise any
-Builders which have not been changed will be left running. If a
-Builder is modified (say, the build process is changed) while a Build
-is currently running, that Build will keep running with the old
-process until it completes. Any previously queued Builds (or Builds
-which get queued after the reconfig) will use the new process.
-
-
-File: buildbot.info, Node: Testing the Config File, Next: Defining the Project, Prev: Loading the Config File, Up: Configuration
-
-4.3 Testing the Config File
-===========================
-
-To verify that the config file is well-formed and contains no
-deprecated or invalid elements, use the "checkconfig" command:
-
- % buildbot checkconfig master.cfg
- Config file is good!
-
- If the config file has deprecated features (perhaps because you've
-upgraded the buildmaster and need to update the config file to match),
-they will be announced by checkconfig. In this case, the config file
-will work, but you should really remove the deprecated items and use
-the recommended replacements instead:
-
- % buildbot checkconfig master.cfg
- /usr/lib/python2.4/site-packages/buildbot/master.py:559: DeprecationWarning: c['sources'] is
- deprecated as of 0.7.6 and will be removed by 0.8.0 . Please use c['change_source'] instead.
- warnings.warn(m, DeprecationWarning)
- Config file is good!
-
- If the config file is simply broken, that will be caught too:
-
- % buildbot checkconfig master.cfg
- Traceback (most recent call last):
- File "/usr/lib/python2.4/site-packages/buildbot/scripts/runner.py", line 834, in doCheckConfig
- ConfigLoader(configFile)
- File "/usr/lib/python2.4/site-packages/buildbot/scripts/checkconfig.py", line 31, in __init__
- self.loadConfig(configFile)
- File "/usr/lib/python2.4/site-packages/buildbot/master.py", line 480, in loadConfig
- exec f in localDict
- File "/home/warner/BuildBot/master/foolscap/master.cfg", line 90, in ?
- c[bogus] = "stuff"
- NameError: name 'bogus' is not defined
-
-
-File: buildbot.info, Node: Defining the Project, Next: Change Sources and Schedulers, Prev: Testing the Config File, Up: Configuration
-
-4.4 Defining the Project
-========================
-
-There are a couple of basic settings that you use to tell the buildbot
-what project it is working on. This information is used by status
-reporters to let users find out more about the codebase being
-exercised by this particular Buildbot installation.
-
- c['projectName'] = "Buildbot"
- c['projectURL'] = "http://buildbot.sourceforge.net/"
- c['buildbotURL'] = "http://localhost:8010/"
-
- `projectName' is a short string will be used to describe the
-project that this buildbot is working on. For example, it is used as
-the title of the waterfall HTML page.
-
- `projectURL' is a string that gives a URL for the project as a
-whole. HTML status displays will show `projectName' as a link to
-`projectURL', to provide a link from buildbot HTML pages to your
-project's home page.
-
- The `buildbotURL' string should point to the location where the
-buildbot's internal web server (usually the `html.Waterfall' page) is
-visible. This typically uses the port number set when you create the
-`Waterfall' object: the buildbot needs your help to figure out a
-suitable externally-visible host name.
-
- When status notices are sent to users (either by email or over
-IRC), `buildbotURL' will be used to create a URL to the specific build
-or problem that they are being notified about. It will also be made
-available to queriers (over IRC) who want to find out where to get
-more information about this buildbot.
-
- The `logCompressionLimit' enables bz2-compression of build logs on
-disk for logs that are bigger than the given size, or disables that
-completely if given `False'. The default value is 4k, which should be
-a reasonable default on most file systems. This setting has no impact
-on status plugins, and merely affects the required disk space on the
-master for build logs.
-
-
-File: buildbot.info, Node: Change Sources and Schedulers, Next: Merging BuildRequests, Prev: Defining the Project, Up: Configuration
-
-4.5 Change Sources and Schedulers
-=================================
-
-The `c['change_source']' key is the ChangeSource instance(1) that
-defines how the buildmaster learns about source code changes. More
-information about what goes here is available in *Note Getting Source
-Code Changes::.
-
- from buildbot.changes.pb import PBChangeSource
- c['change_source'] = PBChangeSource()
-
- (note: in buildbot-0.7.5 and earlier, this key was named
-`c['sources']', and required a list. `c['sources']' is deprecated as
-of buildbot-0.7.6 and is scheduled to be removed in a future release).
-
- `c['schedulers']' is a list of Scheduler instances, each of which
-causes builds to be started on a particular set of Builders. The two
-basic Scheduler classes you are likely to start with are `Scheduler'
-and `Periodic', but you can write a customized subclass to implement
-more complicated build scheduling.
-
- Scheduler arguments should always be specified by name (as keyword
-arguments), to allow for future expansion:
-
- sched = Scheduler(name="quick", builderNames=['lin', 'win'])
-
- All schedulers have several arguments in common:
-
-`name'
- Each Scheduler must have a unique name. This is used in status
- displays, and is also available in the build property
- `scheduler'.
-
-`builderNames'
- This is the set of builders which this scheduler should trigger,
- specified as a list of names (strings).
-
-`properties'
- This is a dictionary specifying properties that will be
- transmitted to all builds started by this scheduler.
-
-
- Here is a brief catalog of the available Scheduler types. All these
-Schedulers are classes in `buildbot.scheduler', and the docstrings
-there are the best source of documentation on the arguments taken by
-each one.
-
-* Menu:
-
-* Scheduler Scheduler::
-* AnyBranchScheduler::
-* Dependent Scheduler::
-* Periodic Scheduler::
-* Nightly Scheduler::
-* Try Schedulers::
-* Triggerable Scheduler::
-
- ---------- Footnotes ----------
-
- (1) To be precise, it is an object or a list of objects which all
-implement the `buildbot.interfaces.IChangeSource' Interface. It is
-unusual to have multiple ChangeSources, so this key accepts either a
-single ChangeSource or a sequence of them.
-
-
-File: buildbot.info, Node: Scheduler Scheduler, Next: AnyBranchScheduler, Prev: Change Sources and Schedulers, Up: Change Sources and Schedulers
-
-4.5.1 Scheduler Scheduler
--------------------------
-
-This is the original and still most popular Scheduler class. It
-follows exactly one branch, and starts a configurable
-tree-stable-timer after each change on that branch. When the timer
-expires, it starts a build on some set of Builders. The Scheduler
-accepts a `fileIsImportant' function which can be used to ignore some
-Changes if they do not affect any "important" files.
-
- The arguments to this scheduler are:
-
-`name'
-
-`builderNames'
-
-`properties'
-
-`branch'
- This Scheduler will pay attention to a single branch, ignoring
- Changes that occur on other branches. Setting `branch' equal to
- the special value of `None' means it should only pay attention to
- the default branch. Note that `None' is a keyword, not a string,
- so you want to use `None' and not `"None"'.
-
-`treeStableTimer'
- The Scheduler will wait for this many seconds before starting the
- build. If new changes are made during this interval, the timer
- will be restarted, so really the build will be started after a
- change and then after this many seconds of inactivity.
-
-`fileIsImportant'
- A callable which takes one argument, a Change instance, and
- returns `True' if the change is worth building, and `False' if
- it is not. Unimportant Changes are accumulated until the build
- is triggered by an important change. The default value of None
- means that all Changes are important.
-
-`categories'
- A list of categories of changes that this scheduler will respond
- to. If this is specified, then any non-matching changes are
- ignored.
-
-
- Example:
-
- from buildbot import scheduler
- quick = scheduler.Scheduler(name="quick",
- branch=None,
- treeStableTimer=60,
- builderNames=["quick-linux", "quick-netbsd"])
- full = scheduler.Scheduler(name="full",
- branch=None,
- treeStableTimer=5*60,
- builderNames=["full-linux", "full-netbsd", "full-OSX"])
- c['schedulers'] = [quick, full]
-
- In this example, the two "quick" builders are triggered 60 seconds
-after the tree has been changed. The "full" builds do not run quite
-so quickly (they wait 5 minutes), so hopefully if the quick builds
-fail due to a missing file or really simple typo, the developer can
-discover and fix the problem before the full builds are started. Both
-Schedulers only pay attention to the default branch: any changes on
-other branches are ignored by these Schedulers. Each Scheduler
-triggers a different set of Builders, referenced by name.
-
-
-File: buildbot.info, Node: AnyBranchScheduler, Next: Dependent Scheduler, Prev: Scheduler Scheduler, Up: Change Sources and Schedulers
-
-4.5.2 AnyBranchScheduler
-------------------------
-
-This scheduler uses a tree-stable-timer like the default one, but
-follows multiple branches at once. Each branch gets a separate timer.
-
- The arguments to this scheduler are:
-
-`name'
-
-`builderNames'
-
-`properties'
-
-`branches'
- This Scheduler will pay attention to any number of branches,
- ignoring Changes that occur on other branches. Branches are
- specified just as for the `Scheduler' class.
-
-`treeStableTimer'
- The Scheduler will wait for this many seconds before starting the
- build. If new changes are made during this interval, the timer
- will be restarted, so really the build will be started after a
- change and then after this many seconds of inactivity.
-
-`fileIsImportant'
- A callable which takes one argument, a Change instance, and
- returns `True' if the change is worth building, and `False' if
- it is not. Unimportant Changes are accumulated until the build
- is triggered by an important change. The default value of None
- means that all Changes are important.
-
-
-File: buildbot.info, Node: Dependent Scheduler, Next: Periodic Scheduler, Prev: AnyBranchScheduler, Up: Change Sources and Schedulers
-
-4.5.3 Dependent Scheduler
--------------------------
-
-It is common to wind up with one kind of build which should only be
-performed if the same source code was successfully handled by some
-other kind of build first. An example might be a packaging step: you
-might only want to produce .deb or RPM packages from a tree that was
-known to compile successfully and pass all unit tests. You could put
-the packaging step in the same Build as the compile and testing steps,
-but there might be other reasons to not do this (in particular you
-might have several Builders worth of compiles/tests, but only wish to
-do the packaging once). Another example is if you want to skip the
-"full" builds after a failing "quick" build of the same source code.
-Or, if one Build creates a product (like a compiled library) that is
-used by some other Builder, you'd want to make sure the consuming
-Build is run _after_ the producing one.
-
- You can use "Dependencies" to express this relationship to the
-Buildbot. There is a special kind of Scheduler named
-`scheduler.Dependent' that will watch an "upstream" Scheduler for
-builds to complete successfully (on all of its Builders). Each time
-that happens, the same source code (i.e. the same `SourceStamp') will
-be used to start a new set of builds, on a different set of Builders.
-This "downstream" scheduler doesn't pay attention to Changes at all.
-It only pays attention to the upstream scheduler.
-
- If the build fails on any of the Builders in the upstream set, the
-downstream builds will not fire. Note that, for SourceStamps
-generated by a ChangeSource, the `revision' is None, meaning HEAD.
-If any changes are committed between the time the upstream scheduler
-begins its build and the time the dependent scheduler begins its
-build, then those changes will be included in the downstream build.
-See the *note Triggerable Scheduler:: for a more flexible dependency
-mechanism that can avoid this problem.
-
- The arguments to this scheduler are:
-
-`name'
-
-`builderNames'
-
-`properties'
-
-`upstream'
- The upstream scheduler to watch. Note that this is an
- "instance", not the name of the scheduler.
-
- Example:
-
- from buildbot import scheduler
- tests = scheduler.Scheduler("just-tests", None, 5*60,
- ["full-linux", "full-netbsd", "full-OSX"])
- package = scheduler.Dependent("build-package",
- tests, # upstream scheduler -- no quotes!
- ["make-tarball", "make-deb", "make-rpm"])
- c['schedulers'] = [tests, package]
-
-
-File: buildbot.info, Node: Periodic Scheduler, Next: Nightly Scheduler, Prev: Dependent Scheduler, Up: Change Sources and Schedulers
-
-4.5.4 Periodic Scheduler
-------------------------
-
-This simple scheduler just triggers a build every N seconds.
-
- The arguments to this scheduler are:
-
-`name'
-
-`builderNames'
-
-`properties'
-
-`periodicBuildTimer'
- The time, in seconds, after which to start a build.
-
- Example:
-
- from buildbot import scheduler
- nightly = scheduler.Periodic(name="nightly",
- builderNames=["full-solaris"],
- periodicBuildTimer=24*60*60)
- c['schedulers'] = [nightly]
-
- The Scheduler in this example just runs the full solaris build once
-per day. Note that this Scheduler only lets you control the time
-between builds, not the absolute time-of-day of each Build, so this
-could easily wind up a "daily" or "every afternoon" scheduler
-depending upon when it was first activated.
-
-
-File: buildbot.info, Node: Nightly Scheduler, Next: Try Schedulers, Prev: Periodic Scheduler, Up: Change Sources and Schedulers
-
-4.5.5 Nightly Scheduler
------------------------
-
-This is highly configurable periodic build scheduler, which triggers
-a build at particular times of day, week, month, or year. The
-configuration syntax is very similar to the well-known `crontab'
-format, in which you provide values for minute, hour, day, and month
-(some of which can be wildcards), and a build is triggered whenever
-the current time matches the given constraints. This can run a build
-every night, every morning, every weekend, alternate Thursdays, on
-your boss's birthday, etc.
-
- Pass some subset of `minute', `hour', `dayOfMonth', `month', and
-`dayOfWeek'; each may be a single number or a list of valid values.
-The builds will be triggered whenever the current time matches these
-values. Wildcards are represented by a '*' string. All fields default
-to a wildcard except 'minute', so with no fields this defaults to a
-build every hour, on the hour. The full list of parameters is:
-
-`name'
-
-`builderNames'
-
-`properties'
-
-`branch'
- The branch to build, just as for `Scheduler'.
-
-`minute'
- The minute of the hour on which to start the build. This
- defaults to 0, meaning an hourly build.
-
-`hour'
- The hour of the day on which to start the build, in 24-hour
- notation. This defaults to *, meaning every hour.
-
-`month'
- The month in which to start the build, with January = 1. This
- defaults to *, meaning every month.
-
-`dayOfWeek'
- The day of the week to start a build, with Monday = 0. This
- defauls to *, meaning every day of the week.
-
-`onlyIfChanged'
- If this is true, then builds will not be scheduled at the
- designated time unless the source has changed since the previous
- build.
-
- For example, the following master.cfg clause will cause a build to
-be started every night at 3:00am:
-
- s = scheduler.Nightly(name='nightly',
- builderNames=['builder1', 'builder2'],
- hour=3,
- minute=0)
-
- This scheduler will perform a build each monday morning at 6:23am
-and again at 8:23am, but only if someone has committed code in the
-interim:
-
- s = scheduler.Nightly(name='BeforeWork',
- builderNames=['builder1'],
- dayOfWeek=0,
- hour=[6,8],
- minute=23,
- onlyIfChanged=True)
-
- The following runs a build every two hours, using Python's `range'
-function:
-
- s = Nightly(name='every2hours',
- builderNames=['builder1'],
- hour=range(0, 24, 2))
-
- Finally, this example will run only on December 24th:
-
- s = Nightly(name='SleighPreflightCheck',
- builderNames=['flying_circuits', 'radar'],
- month=12,
- dayOfMonth=24,
- hour=12,
- minute=0)
-
-
-File: buildbot.info, Node: Try Schedulers, Next: Triggerable Scheduler, Prev: Nightly Scheduler, Up: Change Sources and Schedulers
-
-4.5.6 Try Schedulers
---------------------
-
-This scheduler allows developers to use the `buildbot try' command to
-trigger builds of code they have not yet committed. See *note try::
-for complete details.
-
- Two implementations are available: `Try_Jobdir' and
-`Try_Userpass'. The former monitors a job directory, specified by
-the `jobdir' parameter, while the latter listens for PB connections
-on a specific `port', and authenticates against `userport'.
-
-
-File: buildbot.info, Node: Triggerable Scheduler, Prev: Try Schedulers, Up: Change Sources and Schedulers
-
-4.5.7 Triggerable Scheduler
----------------------------
-
-The `Triggerable' scheduler waits to be triggered by a Trigger step
-(see *note Triggering Schedulers::) in another build. That step can
-optionally wait for the scheduler's builds to complete. This provides
-two advantages over Dependent schedulers. First, the same scheduler
-can be triggered from multiple builds. Second, the ability to wait
-for a Triggerable's builds to complete provides a form of "subroutine
-call", where one or more builds can "call" a scheduler to perform
-some work for them, perhaps on other buildslaves.
-
- The parameters are just the basics:
-
-`name'
-
-`builderNames'
-
-`properties'
-
- This class is only useful in conjunction with the `Trigger' step.
-Here is a fully-worked example:
-
- from buildbot import scheduler
- from buildbot.process import factory
- from buildbot.steps import trigger
-
- checkin = scheduler.Scheduler(name="checkin",
- branch=None,
- treeStableTimer=5*60,
- builderNames=["checkin"])
- nightly = scheduler.Nightly(name='nightly',
- builderNames=['nightly'],
- hour=3,
- minute=0)
-
- mktarball = scheduler.Triggerable(name="mktarball",
- builderNames=["mktarball"])
- build = scheduler.Triggerable(name="build-all-platforms",
- builderNames=["build-all-platforms"])
- test = scheduler.Triggerable(name="distributed-test",
- builderNames=["distributed-test"])
- package = scheduler.Triggerable(name="package-all-platforms",
- builderNames=["package-all-platforms"])
-
- c['schedulers'] = [checkin, nightly, build, test, package]
-
- # on checkin, make a tarball, build it, and test it
- checkin_factory = factory.BuildFactory()
- checkin_factory.addStep(trigger.Trigger(schedulerNames=['mktarball'],
- waitForFinish=True))
- checkin_factory.addStep(trigger.Trigger(schedulerNames=['build-all-platforms'],
- waitForFinish=True))
- checkin_factory.addStep(trigger.Trigger(schedulerNames=['distributed-test'],
- waitForFinish=True))
-
- # and every night, make a tarball, build it, and package it
- nightly_factory = factory.BuildFactory()
- nightly_factory.addStep(trigger.Trigger(schedulerNames=['mktarball'],
- waitForFinish=True))
- nightly_factory.addStep(trigger.Trigger(schedulerNames=['build-all-platforms'],
- waitForFinish=True))
- nightly_factory.addStep(trigger.Trigger(schedulerNames=['package-all-platforms'],
- waitForFinish=True))
-
-
-File: buildbot.info, Node: Merging BuildRequests, Next: Setting the slaveport, Prev: Change Sources and Schedulers, Up: Configuration
-
-4.6 Merging BuildRequests
-=========================
-
-By default, buildbot merges BuildRequests that have the compatible
-SourceStamps. This behaviour can be customized with the
-`c['mergeRequests']' configuration key. This key specifies a function
-which is caleld with three arguments: a `Builder' and two
-`BuildRequest' objects. It should return true if the requests can be
-merged. For example:
-
- def mergeRequests(builder, req1, req2):
- """Don't merge buildrequest at all"""
- return False
- c['mergeRequests'] = mergeRequests
-
- In many cases, the details of the SourceStamps and BuildRequests
-are important. In this example, only BuildRequests with the same
-"reason" are merged; thus developers forcing builds for different
-reasons will see distinct builds.
-
- def mergeRequests(builder, req1, req2):
- if req1.source.canBeMergedWith(req2.source) and req1.reason == req2.reason:
- return True
- return False
- c['mergeRequests'] = mergeRequests
-
-
-File: buildbot.info, Node: Setting the slaveport, Next: Buildslave Specifiers, Prev: Merging BuildRequests, Up: Configuration
-
-4.7 Setting the slaveport
-=========================
-
-The buildmaster will listen on a TCP port of your choosing for
-connections from buildslaves. It can also use this port for
-connections from remote Change Sources, status clients, and debug
-tools. This port should be visible to the outside world, and you'll
-need to tell your buildslave admins about your choice.
-
- It does not matter which port you pick, as long it is externally
-visible, however you should probably use something larger than 1024,
-since most operating systems don't allow non-root processes to bind to
-low-numbered ports. If your buildmaster is behind a firewall or a NAT
-box of some sort, you may have to configure your firewall to permit
-inbound connections to this port.
-
- c['slavePortnum'] = 10000
-
- `c['slavePortnum']' is a _strports_ specification string, defined
-in the `twisted.application.strports' module (try `pydoc
-twisted.application.strports' to get documentation on the format).
-This means that you can have the buildmaster listen on a
-localhost-only port by doing:
-
- c['slavePortnum'] = "tcp:10000:interface=127.0.0.1"
-
- This might be useful if you only run buildslaves on the same
-machine, and they are all configured to contact the buildmaster at
-`localhost:10000'.
-
-
-File: buildbot.info, Node: Buildslave Specifiers, Next: On-Demand ("Latent") Buildslaves, Prev: Setting the slaveport, Up: Configuration
-
-4.8 Buildslave Specifiers
-=========================
-
-The `c['slaves']' key is a list of known buildslaves. In the common
-case, each buildslave is defined by an instance of the BuildSlave
-class. It represents a standard, manually started machine that will
-try to connect to the buildbot master as a slave. Contrast these
-with the "on-demand" latent buildslaves, such as the Amazon Web
-Service Elastic Compute Cloud latent buildslave discussed below.
-
- The BuildSlave class is instantiated with two values: (slavename,
-slavepassword). These are the same two values that need to be
-provided to the buildslave administrator when they create the
-buildslave.
-
- The slavenames must be unique, of course. The password exists to
-prevent evildoers from interfering with the buildbot by inserting
-their own (broken) buildslaves into the system and thus displacing the
-real ones.
-
- Buildslaves with an unrecognized slavename or a non-matching
-password will be rejected when they attempt to connect, and a message
-describing the problem will be put in the log file (see *note
-Logfiles::).
-
- from buildbot.buildslave import BuildSlave
- c['slaves'] = [BuildSlave('bot-solaris', 'solarispasswd')
- BuildSlave('bot-bsd', 'bsdpasswd')
- ]
-
- `BuildSlave' objects can also be created with an optional
-`properties' argument, a dictionary specifying properties that will
-be available to any builds performed on this slave. For example:
-
- from buildbot.buildslave import BuildSlave
- c['slaves'] = [BuildSlave('bot-solaris', 'solarispasswd',
- properties={'os':'solaris'}),
- ]
-
- The `BuildSlave' constructor can also take an optional
-`max_builds' parameter to limit the number of builds that it will
-execute simultaneously:
-
- from buildbot.buildslave import BuildSlave
- c['slaves'] = [BuildSlave("bot-linux", "linuxpassword", max_builds=2)]
-
- Historical note: in buildbot-0.7.5 and earlier, the `c['bots']'
-key was used instead, and it took a list of (name, password) tuples.
-This key is accepted for backwards compatibility, but is deprecated as
-of 0.7.6 and will go away in some future release.
-
-* Menu:
-
-* When Buildslaves Go Missing::
-
-
-File: buildbot.info, Node: When Buildslaves Go Missing, Up: Buildslave Specifiers
-
-4.8.1 When Buildslaves Go Missing
----------------------------------
-
-Sometimes, the buildslaves go away. One very common reason for this is
-when the buildslave process is started once (manually) and left
-running, but then later the machine reboots and the process is not
-automatically restarted.
-
- If you'd like to have the administrator of the buildslave (or other
-people) be notified by email when the buildslave has been missing for
-too long, just add the `notify_on_missing=' argument to the
-`BuildSlave' definition:
-
- c['slaves'] = [BuildSlave('bot-solaris', 'solarispasswd',
- notify_on_missing="bob@example.com"),
- ]
-
- By default, this will send email when the buildslave has been
-disconnected for more than one hour. Only one email per
-connection-loss event will be sent. To change the timeout, use
-`missing_timeout=' and give it a number of seconds (the default is
-3600).
-
- You can have the buildmaster send email to multiple recipients:
-just provide a list of addresses instead of a single one:
-
- c['slaves'] = [BuildSlave('bot-solaris', 'solarispasswd',
- notify_on_missing=["bob@example.com",
- "alice@example.org"],
- missing_timeout=300, # notify after 5 minutes
- ),
- ]
-
- The email sent this way will use a MailNotifier (*note
-MailNotifier::) status target, if one is configured. This provides a
-way for you to control the "from" address of the email, as well as
-the relayhost (aka "smarthost") to use as an SMTP server. If no
-MailNotifier is configured on this buildmaster, the
-buildslave-missing emails will be sent using a default configuration.
-
- Note that if you want to have a MailNotifier for buildslave-missing
-emails but not for regular build emails, just create one with
-builders=[], as follows:
-
- from buildbot.status import mail
- m = mail.MailNotifier(fromaddr="buildbot@localhost", builders=[],
- relayhost="smtp.example.org")
- c['status'].append(m)
- c['slaves'] = [BuildSlave('bot-solaris', 'solarispasswd',
- notify_on_missing="bob@example.com"),
- ]
-
-
-File: buildbot.info, Node: On-Demand ("Latent") Buildslaves, Next: Defining Global Properties, Prev: Buildslave Specifiers, Up: Configuration
-
-4.9 On-Demand ("Latent") Buildslaves
-====================================
-
-The standard buildbot model has slaves started manually. The
-previous section described how to configure the master for this
-approach.
-
- Another approach is to let the buildbot master start slaves when
-builds are ready, on-demand. Thanks to services such as Amazon Web
-Services' Elastic Compute Cloud ("AWS EC2"), this is relatively easy
-to set up, and can be very useful for some situations.
-
- The buildslaves that are started on-demand are called "latent"
-buildslaves. As of this writing, buildbot ships with an abstract
-base class for building latent buildslaves, and a concrete
-implementation for AWS EC2.
-
-* Menu:
-
-* Amazon Web Services Elastic Compute Cloud ("AWS EC2")::
-* Dangers with Latent Buildslaves::
-* Writing New Latent Buildslaves::
-
-
-File: buildbot.info, Node: Amazon Web Services Elastic Compute Cloud ("AWS EC2"), Next: Dangers with Latent Buildslaves, Up: On-Demand ("Latent") Buildslaves
-
-4.9.1 Amazon Web Services Elastic Compute Cloud ("AWS EC2")
------------------------------------------------------------
-
-AWS EC2 is a web service that allows you to start virtual machines in
-an Amazon data center. Please see their website for details, incuding
-costs. Using the AWS EC2 latent buildslaves involves getting an EC2
-account with AWS and setting up payment; customizing one or more EC2
-machine images ("AMIs") on your desired operating system(s) and
-publishing them (privately if needed); and configuring the buildbot
-master to know how to start your customized images for
-"substantiating" your latent slaves.
-
-* Menu:
-
-* Get an AWS EC2 Account::
-* Create an AMI::
-* Configure the Master with an EC2LatentBuildSlave::
-
-
-File: buildbot.info, Node: Get an AWS EC2 Account, Next: Create an AMI, Up: Amazon Web Services Elastic Compute Cloud ("AWS EC2")
-
-4.9.1.1 Get an AWS EC2 Account
-..............................
-
-To start off, to use the AWS EC2 latent buildslave, you need to get
-an AWS developer account and sign up for EC2. These instructions may
-help you get started:
-
- * Go to http://aws.amazon.com/ and click to "Sign Up Now" for an
- AWS account.
-
- * Once you are logged into your account, you need to sign up for
- EC2. Instructions for how to do this have changed over time
- because Amazon changes their website, so the best advice is to
- hunt for it. After signing up for EC2, it may say it wants you
- to upload an x.509 cert. You will need this to create images
- (see below) but it is not technically necessary for the buildbot
- master configuration.
-
- * You must enter a valid credit card before you will be able to
- use EC2. Do that under 'Payment Method'.
-
- * Make sure you're signed up for EC2 by going to 'Your
- Account'->'Account Activity' and verifying EC2 is listed.
-
-
-File: buildbot.info, Node: Create an AMI, Next: Configure the Master with an EC2LatentBuildSlave, Prev: Get an AWS EC2 Account, Up: Amazon Web Services Elastic Compute Cloud ("AWS EC2")
-
-4.9.1.2 Create an AMI
-.....................
-
-Now you need to create an AMI and configure the master. You may need
-to run through this cycle a few times to get it working, but these
-instructions should get you started.
-
- Creating an AMI is out of the scope of this document. The EC2
-Getting Started Guide is a good resource for this task. Here are a
-few additional hints.
-
- * When an instance of the image starts, it needs to automatically
- start a buildbot slave that connects to your master (to create a
- buildbot slave, *note Creating a buildslave::; to make a daemon,
- *note Launching the daemons::).
-
- * You may want to make an instance of the buildbot slave,
- configure it as a standard buildslave in the master (i.e., not
- as a latent slave), and test and debug it that way before you
- turn it into an AMI and convert to a latent slave in the master.
-
-
-File: buildbot.info, Node: Configure the Master with an EC2LatentBuildSlave, Prev: Create an AMI, Up: Amazon Web Services Elastic Compute Cloud ("AWS EC2")
-
-4.9.1.3 Configure the Master with an EC2LatentBuildSlave
-........................................................
-
-Now let's assume you have an AMI that should work with the
-EC2LatentBuildSlave. It's now time to set up your buildbot master
-configuration.
-
- You will need some information from your AWS account: the "Access
-Key Id" and the "Secret Access Key". If you've built the AMI
-yourself, you probably already are familiar with these values. If
-you have not, and someone has given you access to an AMI, these hints
-may help you find the necessary values:
-
- * While logged into your AWS account, find the "Access
- Identifiers" link (either on the left, or via "Your Account" ->
- "Access Identifiers".
-
- * On the page, you'll see alphanumeric values for "Your Access Key
- Id:" and "Your Secret Access Key:". Make a note of these. Later
- on, we'll call the first one your "identifier" and the second
- one your "secret_identifier."
-
- When creating an EC2LatentBuildSlave in the buildbot master
-configuration, the first three arguments are required. The name and
-password are the first two arguments, and work the same as with
-normal buildslaves. The next argument specifies the type of the EC2
-virtual machine (available options as of this writing include
-"m1.small", "m1.large", 'm1.xlarge", "c1.medium", and "c1.xlarge";
-see the EC2 documentation for descriptions of these machines).
-
- Here is the simplest example of configuring an EC2 latent
-buildslave. It specifies all necessary remaining values explicitly in
-the instantiation.
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- c['slaves'] = [EC2LatentBuildSlave('bot1', 'sekrit', 'm1.large',
- ami='ami-12345',
- identifier='publickey',
- secret_identifier='privatekey'
- )]
-
- The "ami" argument specifies the AMI that the master should start.
-The "identifier" argument specifies the AWS "Access Key Id," and the
-"secret_identifier" specifies the AWS "Secret Access Key." Both the
-AMI and the account information can be specified in alternate ways.
-
- Note that whoever has your identifier and secret_identifier values
-can request AWS work charged to your account, so these values need to
-be carefully protected. Another way to specify these access keys is
-to put them in a separate file. You can then make the access
-privileges stricter for this separate file, and potentially let more
-people read your main configuration file.
-
- By default, you can make an .ec2 directory in the home folder of
-the user running the buildbot master. In that directory, create a
-file called aws_id. The first line of that file should be your
-access key id; the second line should be your secret access key id.
-Then you can instantiate the build slave as follows.
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- c['slaves'] = [EC2LatentBuildSlave('bot1', 'sekrit', 'm1.large',
- ami='ami-12345')]
-
- If you want to put the key information in another file, use the
-"aws_id_file_path" initialization argument.
-
- Previous examples used a particular AMI. If the Buildbot master
-will be deployed in a process-controlled environment, it may be
-convenient to specify the AMI more flexibly. Rather than specifying
-an individual AMI, specify one or two AMI filters.
-
- In all cases, the AMI that sorts last by its location (the S3
-bucket and manifest name) will be preferred.
-
- One available filter is to specify the acceptable AMI owners, by
-AWS account number (the 12 digit number, usually rendered in AWS with
-hyphens like "1234-5678-9012", should be entered as in integer).
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- bot1 = EC2LatentBuildSlave('bot1', 'sekrit', 'm1.large',
- valid_ami_owners=[11111111111,
- 22222222222],
- identifier='publickey',
- secret_identifier='privatekey'
- )
-
- The other available filter is to provide a regular expression
-string that will be matched against each AMI's location (the S3
-bucket and manifest name).
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- bot1 = EC2LatentBuildSlave(
- 'bot1', 'sekrit', 'm1.large',
- valid_ami_location_regex=r'buildbot\-.*/image.manifest.xml',
- identifier='publickey', secret_identifier='privatekey')
-
- The regular expression can specify a group, which will be
-preferred for the sorting. Only the first group is used; subsequent
-groups are ignored.
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- bot1 = EC2LatentBuildSlave(
- 'bot1', 'sekrit', 'm1.large',
- valid_ami_location_regex=r'buildbot\-.*\-(.*)/image.manifest.xml',
- identifier='publickey', secret_identifier='privatekey')
-
- If the group can be cast to an integer, it will be. This allows
-10 to sort after 1, for instance.
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- bot1 = EC2LatentBuildSlave(
- 'bot1', 'sekrit', 'm1.large',
- valid_ami_location_regex=r'buildbot\-.*\-(\d+)/image.manifest.xml',
- identifier='publickey', secret_identifier='privatekey')
-
- In addition to using the password as a handshake between the
-master and the slave, you may want to use a firewall to assert that
-only machines from a specific IP can connect as slaves. This is
-possible with AWS EC2 by using the Elastic IP feature. To configure,
-generate a Elastic IP in AWS, and then specify it in your
-configuration using the "elastic_ip" argument.
-
- from buildbot.ec2buildslave import EC2LatentBuildSlave
- c['slaves'] = [EC2LatentBuildSlave('bot1', 'sekrit', 'm1.large',
- 'ami-12345',
- identifier='publickey',
- secret_identifier='privatekey',
- elastic_ip='208.77.188.166'
- )]
-
- The EC2LatentBuildSlave supports all other configuration from the
-standard BuildSlave. The "missing_timeout" and "notify_on_missing"
-specify how long to wait for an EC2 instance to attach before
-considering the attempt to have failed, and email addresses to alert,
-respectively. "missing_timeout" defaults to 20 minutes.
-
- The "build_wait_timeout" allows you to specify how long an
-EC2LatentBuildSlave should wait after a build for another build
-before it shuts down the EC2 instance. It defaults to 10 minutes.
-
- "keypair_name" and "security_name" allow you to specify different
-names for these AWS EC2 values. They both default to
-"latent_buildbot_slave".
-
-
-File: buildbot.info, Node: Dangers with Latent Buildslaves, Next: Writing New Latent Buildslaves, Prev: Amazon Web Services Elastic Compute Cloud ("AWS EC2"), Up: On-Demand ("Latent") Buildslaves
-
-4.9.2 Dangers with Latent Buildslaves
--------------------------------------
-
-Any latent build slave that interacts with a for-fee service, such as
-the EC2LatentBuildSlave, brings significant risks. As already
-identified, the configuraton will need access to account information
-that, if obtained by a criminal, can be used to charge services to
-your account. Also, bugs in the buildbot software may lead to
-unnecessary charges. In particular, if the master neglects to shut
-down an instance for some reason, a virtual machine may be running
-unnecessarily, charging against your account. Manual and/or automatic
-(e.g. nagios with a plugin using a library like boto) double-checking
-may be appropriate.
-
- A comparitively trivial note is that currently if two instances
-try to attach to the same latent buildslave, it is likely that the
-system will become confused. This should not occur, unless, for
-instance, you configure a normal build slave to connect with the
-authentication of a latent buildbot. If the situation occurs, stop
-all attached instances and restart the master.
-
-
-File: buildbot.info, Node: Writing New Latent Buildslaves, Prev: Dangers with Latent Buildslaves, Up: On-Demand ("Latent") Buildslaves
-
-4.9.3 Writing New Latent Buildslaves
-------------------------------------
-
-Writing a new latent buildslave should only require subclassing
-`buildbot.buildslave.AbstractLatentBuildSlave' and implementing
-start_instance and stop_instance.
-
- def start_instance(self):
- # responsible for starting instance that will try to connect with this
- # master. Should return deferred. Problems should use an errback. The
- # callback value can be None, or can be an iterable of short strings to
- # include in the "substantiate success" status message, such as
- # identifying the instance that started.
- raise NotImplementedError
-
- def stop_instance(self, fast=False):
- # responsible for shutting down instance. Return a deferred. If `fast`,
- # we're trying to shut the master down, so callback as soon as is safe.
- # Callback value is ignored.
- raise NotImplementedError
-
- See `buildbot.ec2buildslave.EC2LatentBuildSlave' for an example,
-or see the test example `buildbot.test_slaves.FakeLatentBuildSlave'.
-
-
-File: buildbot.info, Node: Defining Global Properties, Next: Defining Builders, Prev: On-Demand ("Latent") Buildslaves, Up: Configuration
-
-4.10 Defining Global Properties
-===============================
-
-The `'properties'' configuration key defines a dictionary of
-properties that will be available to all builds started by the
-buildmaster:
-
- c['properties'] = {
- 'Widget-version' : '1.2',
- 'release-stage' : 'alpha'
- }
-
-
-File: buildbot.info, Node: Defining Builders, Next: Defining Status Targets, Prev: Defining Global Properties, Up: Configuration
-
-4.11 Defining Builders
-======================
-
-The `c['builders']' key is a list of dictionaries which specify the
-Builders. The Buildmaster runs a collection of Builders, each of
-which handles a single type of build (e.g. full versus quick), on a
-single build slave. A Buildbot which makes sure that the latest code
-("HEAD") compiles correctly across four separate architecture will
-have four Builders, each performing the same build but on different
-slaves (one per platform).
-
- Each Builder gets a separate column in the waterfall display. In
-general, each Builder runs independently (although various kinds of
-interlocks can cause one Builder to have an effect on another).
-
- Each Builder specification dictionary has several required keys:
-
-`name'
- This specifies the Builder's name, which is used in status
- reports.
-
-`slavename'
- This specifies which buildslave will be used by this Builder.
- `slavename' must appear in the `c['slaves']' list. Each
- buildslave can accomodate multiple Builders.
-
-`slavenames'
- If you provide `slavenames' instead of `slavename', you can give
- a list of buildslaves which are capable of running this Builder.
- If multiple buildslaves are available for any given Builder, you
- will have some measure of redundancy: in case one slave goes
- offline, the others can still keep the Builder working. In
- addition, multiple buildslaves will allow multiple simultaneous
- builds for the same Builder, which might be useful if you have a
- lot of forced or "try" builds taking place.
-
- If you use this feature, it is important to make sure that the
- buildslaves are all, in fact, capable of running the given
- build. The slave hosts should be configured similarly, otherwise
- you will spend a lot of time trying (unsuccessfully) to
- reproduce a failure that only occurs on some of the buildslaves
- and not the others. Different platforms, operating systems,
- versions of major programs or libraries, all these things mean
- you should use separate Builders.
-
-`builddir'
- This specifies the name of a subdirectory (under the base
- directory) in which everything related to this builder will be
- placed. On the buildmaster, this holds build status information.
- On the buildslave, this is where checkouts, compiles, and tests
- are run.
-
-`factory'
- This is a `buildbot.process.factory.BuildFactory' instance which
- controls how the build is performed. Full details appear in
- their own chapter, *Note Build Process::. Parameters like the
- location of the CVS repository and the compile-time options used
- for the build are generally provided as arguments to the
- factory's constructor.
-
-
- Other optional keys may be set on each Builder:
-
-`category'
- If provided, this is a string that identifies a category for the
- builder to be a part of. Status clients can limit themselves to a
- subset of the available categories. A common use for this is to
- add new builders to your setup (for a new module, or for a new
- buildslave) that do not work correctly yet and allow you to
- integrate them with the active builders. You can put these new
- builders in a test category, make your main status clients
- ignore them, and have only private status clients pick them up.
- As soon as they work, you can move them over to the active
- category.
-
-
-
-File: buildbot.info, Node: Defining Status Targets, Next: Debug options, Prev: Defining Builders, Up: Configuration
-
-4.12 Defining Status Targets
-============================
-
-The Buildmaster has a variety of ways to present build status to
-various users. Each such delivery method is a "Status Target" object
-in the configuration's `status' list. To add status targets, you just
-append more objects to this list:
-
- c['status'] = []
-
- from buildbot.status import html
- c['status'].append(html.Waterfall(http_port=8010))
-
- from buildbot.status import mail
- m = mail.MailNotifier(fromaddr="buildbot@localhost",
- extraRecipients=["builds@lists.example.com"],
- sendToInterestedUsers=False)
- c['status'].append(m)
-
- from buildbot.status import words
- c['status'].append(words.IRC(host="irc.example.com", nick="bb",
- channels=["#example"]))
-
- Status delivery has its own chapter, *Note Status Delivery::, in
-which all the built-in status targets are documented.
-
-
-File: buildbot.info, Node: Debug options, Prev: Defining Status Targets, Up: Configuration
-
-4.13 Debug options
-==================
-
-If you set `c['debugPassword']', then you can connect to the
-buildmaster with the diagnostic tool launched by `buildbot
-debugclient MASTER:PORT'. From this tool, you can reload the config
-file, manually force builds, and inject changes, which may be useful
-for testing your buildmaster without actually commiting changes to
-your repository (or before you have the Change Sources set up). The
-debug tool uses the same port number as the slaves do:
-`c['slavePortnum']', and is authenticated with this password.
-
- c['debugPassword'] = "debugpassword"
-
- If you set `c['manhole']' to an instance of one of the classes in
-`buildbot.manhole', you can telnet or ssh into the buildmaster and
-get an interactive Python shell, which may be useful for debugging
-buildbot internals. It is probably only useful for buildbot
-developers. It exposes full access to the buildmaster's account
-(including the ability to modify and delete files), so it should not
-be enabled with a weak or easily guessable password.
-
- There are three separate `Manhole' classes. Two of them use SSH,
-one uses unencrypted telnet. Two of them use a username+password
-combination to grant access, one of them uses an SSH-style
-`authorized_keys' file which contains a list of ssh public keys.
-
-`manhole.AuthorizedKeysManhole'
- You construct this with the name of a file that contains one SSH
- public key per line, just like `~/.ssh/authorized_keys'. If you
- provide a non-absolute filename, it will be interpreted relative
- to the buildmaster's base directory.
-
-`manhole.PasswordManhole'
- This one accepts SSH connections but asks for a username and
- password when authenticating. It accepts only one such pair.
-
-`manhole.TelnetManhole'
- This accepts regular unencrypted telnet connections, and asks
- for a username/password pair before providing access. Because
- this username/password is transmitted in the clear, and because
- Manhole access to the buildmaster is equivalent to granting full
- shell privileges to both the buildmaster and all the buildslaves
- (and to all accounts which then run code produced by the
- buildslaves), it is highly recommended that you use one of the
- SSH manholes instead.
-
-
- # some examples:
- from buildbot import manhole
- c['manhole'] = manhole.AuthorizedKeysManhole(1234, "authorized_keys")
- c['manhole'] = manhole.PasswordManhole(1234, "alice", "mysecretpassword")
- c['manhole'] = manhole.TelnetManhole(1234, "bob", "snoop_my_password_please")
-
- The `Manhole' instance can be configured to listen on a specific
-port. You may wish to have this listening port bind to the loopback
-interface (sometimes known as "lo0", "localhost", or 127.0.0.1) to
-restrict access to clients which are running on the same host.
-
- from buildbot.manhole import PasswordManhole
- c['manhole'] = PasswordManhole("tcp:9999:interface=127.0.0.1","admin","passwd")
-
- To have the `Manhole' listen on all interfaces, use `"tcp:9999"'
-or simply 9999. This port specification uses
-`twisted.application.strports', so you can make it listen on SSL or
-even UNIX-domain sockets if you want.
-
- Note that using any Manhole requires that the TwistedConch package
-be installed, and that you be using Twisted version 2.0 or later.
-
- The buildmaster's SSH server will use a different host key than the
-normal sshd running on a typical unix host. This will cause the ssh
-client to complain about a "host key mismatch", because it does not
-realize there are two separate servers running on the same host. To
-avoid this, use a clause like the following in your `.ssh/config'
-file:
-
- Host remotehost-buildbot
- HostName remotehost
- HostKeyAlias remotehost-buildbot
- Port 9999
- # use 'user' if you use PasswordManhole and your name is not 'admin'.
- # if you use AuthorizedKeysManhole, this probably doesn't matter.
- User admin
-
-
-File: buildbot.info, Node: Getting Source Code Changes, Next: Build Process, Prev: Configuration, Up: Top
-
-5 Getting Source Code Changes
-*****************************
-
-The most common way to use the Buildbot is centered around the idea of
-`Source Trees': a directory tree filled with source code of some form
-which can be compiled and/or tested. Some projects use languages that
-don't involve any compilation step: nevertheless there may be a
-`build' phase where files are copied or rearranged into a form that
-is suitable for installation. Some projects do not have unit tests,
-and the Buildbot is merely helping to make sure that the sources can
-compile correctly. But in all of these cases, the thing-being-tested
-is a single source tree.
-
- A Version Control System mantains a source tree, and tells the
-buildmaster when it changes. The first step of each Build is typically
-to acquire a copy of some version of this tree.
-
- This chapter describes how the Buildbot learns about what Changes
-have occurred. For more information on VC systems and Changes, see
-*note Version Control Systems::.
-
-* Menu:
-
-* Change Sources::
-* Choosing ChangeSources::
-* CVSToys - PBService::
-* Mail-parsing ChangeSources::
-* PBChangeSource::
-* P4Source::
-* BonsaiPoller::
-* SVNPoller::
-* MercurialHook::
-* Bzr Hook::
-* Bzr Poller::
-
-
-File: buildbot.info, Node: Change Sources, Next: Choosing ChangeSources, Prev: Getting Source Code Changes, Up: Getting Source Code Changes
-
-5.1 Change Sources
-==================
-
-Each Buildmaster watches a single source tree. Changes can be provided
-by a variety of ChangeSource types, however any given project will
-typically have only a single ChangeSource active. This section
-provides a description of all available ChangeSource types and
-explains how to set up each of them.
-
- There are a variety of ChangeSources available, some of which are
-meant to be used in conjunction with other tools to deliver Change
-events from the VC repository to the buildmaster.
-
- * CVSToys This ChangeSource opens a TCP connection from the
- buildmaster to a waiting FreshCVS daemon that lives on the
- repository machine, and subscribes to hear about Changes.
-
- * MaildirSource This one watches a local maildir-format inbox for
- email sent out by the repository when a change is made. When a
- message arrives, it is parsed to create the Change object. A
- variety of parsing functions are available to accomodate
- different email-sending tools.
-
- * PBChangeSource This ChangeSource listens on a local TCP socket
- for inbound connections from a separate tool. Usually, this tool
- would be run on the VC repository machine in a commit hook. It
- is expected to connect to the TCP socket and send a Change
- message over the network connection. The `buildbot sendchange'
- command is one example of a tool that knows how to send these
- messages, so you can write a commit script for your VC system
- that calls it to deliver the Change. There are other tools in
- the contrib/ directory that use the same protocol.
-
-
- As a quick guide, here is a list of VC systems and the
-ChangeSources that might be useful with them. All of these
-ChangeSources are in the `buildbot.changes' module.
-
-`CVS'
- * freshcvs.FreshCVSSource (connected via TCP to the freshcvs
- daemon)
-
- * mail.FCMaildirSource (watching for email sent by a freshcvs
- daemon)
-
- * mail.BonsaiMaildirSource (watching for email sent by Bonsai)
-
- * mail.SyncmailMaildirSource (watching for email sent by
- syncmail)
-
- * pb.PBChangeSource (listening for connections from `buildbot
- sendchange' run in a loginfo script)
-
- * pb.PBChangeSource (listening for connections from a
- long-running `contrib/viewcvspoll.py' polling process which
- examines the ViewCVS database directly
-
-`SVN'
- * pb.PBChangeSource (listening for connections from
- `contrib/svn_buildbot.py' run in a postcommit script)
-
- * pb.PBChangeSource (listening for connections from a
- long-running `contrib/svn_watcher.py' or
- `contrib/svnpoller.py' polling process
-
- * mail.SVNCommitEmailMaildirSource (watching for email sent
- by commit-email.pl)
-
- * svnpoller.SVNPoller (polling the SVN repository)
-
-`Darcs'
- * pb.PBChangeSource (listening for connections from
- `contrib/darcs_buildbot.py' in a commit script
-
-`Mercurial'
- * pb.PBChangeSource (listening for connections from
- `contrib/hg_buildbot.py' run in an 'incoming' hook)
-
- * pb.PBChangeSource (listening for connections from
- `buildbot/changes/hgbuildbot.py' run as an in-process
- 'changegroup' hook)
-
-`Arch/Bazaar'
- * pb.PBChangeSource (listening for connections from
- `contrib/arch_buildbot.py' run in a commit hook)
-
-`Bzr (the newer Bazaar)'
- * pb.PBChangeSource (listening for connections from
- `contrib/bzr_buildbot.py' run in a post-change-branch-tip
- or commit hook)
-
- * `contrib/bzr_buildbot.py''s BzrPoller (polling the Bzr
- repository)
-
-`Git'
- * pb.PBChangeSource (listening for connections from
- `contrib/git_buildbot.py' run in the post-receive hook)
-
-
- All VC systems can be driven by a PBChangeSource and the `buildbot
-sendchange' tool run from some form of commit script. If you write
-an email parsing function, they can also all be driven by a suitable
-`MaildirSource'.
-
-
-File: buildbot.info, Node: Choosing ChangeSources, Next: CVSToys - PBService, Prev: Change Sources, Up: Getting Source Code Changes
-
-5.2 Choosing ChangeSources
-==========================
-
-The `master.cfg' configuration file has a dictionary key named
-`BuildmasterConfig['change_source']', which holds the active
-`IChangeSource' object. The config file will typically create an
-object from one of the classes described below and stuff it into this
-key.
-
- Each buildmaster typically has just a single ChangeSource, since
-it is only watching a single source tree. But if, for some reason,
-you need multiple sources, just set `c['change_source']' to a list of
-ChangeSources.. it will accept that too.
-
- s = FreshCVSSourceNewcred(host="host", port=4519,
- user="alice", passwd="secret",
- prefix="Twisted")
- BuildmasterConfig['change_source'] = [s]
-
- Each source tree has a nominal `top'. Each Change has a list of
-filenames, which are all relative to this top location. The
-ChangeSource is responsible for doing whatever is necessary to
-accomplish this. Most sources have a `prefix' argument: a partial
-pathname which is stripped from the front of all filenames provided to
-that `ChangeSource'. Files which are outside this sub-tree are
-ignored by the changesource: it does not generate Changes for those
-files.
-
-
-File: buildbot.info, Node: CVSToys - PBService, Next: Mail-parsing ChangeSources, Prev: Choosing ChangeSources, Up: Getting Source Code Changes
-
-5.3 CVSToys - PBService
-=======================
-
-The CVSToys (http://purl.net/net/CVSToys) package provides a server
-which runs on the machine that hosts the CVS repository it watches.
-It has a variety of ways to distribute commit notifications, and
-offers a flexible regexp-based way to filter out uninteresting
-changes. One of the notification options is named `PBService' and
-works by listening on a TCP port for clients. These clients subscribe
-to hear about commit notifications.
-
- The buildmaster has a CVSToys-compatible `PBService' client built
-in. There are two versions of it, one for old versions of CVSToys
-(1.0.9 and earlier) which used the `oldcred' authentication
-framework, and one for newer versions (1.0.10 and later) which use
-`newcred'. Both are classes in the `buildbot.changes.freshcvs'
-package.
-
- `FreshCVSSourceNewcred' objects are created with the following
-parameters:
-
-``host' and `port''
- these specify where the CVSToys server can be reached
-
-``user' and `passwd''
- these specify the login information for the CVSToys server
- (`freshcvs'). These must match the server's values, which are
- defined in the `freshCfg' configuration file (which lives in the
- CVSROOT directory of the repository).
-
-``prefix''
- this is the prefix to be found and stripped from filenames
- delivered by the CVSToys server. Most projects live in
- sub-directories of the main repository, as siblings of the
- CVSROOT sub-directory, so typically this prefix is set to that
- top sub-directory name.
-
-
-Example
-=======
-
-To set up the freshCVS server, add a statement like the following to
-your `freshCfg' file:
-
- pb = ConfigurationSet([
- (None, None, None, PBService(userpass=('foo', 'bar'), port=4519)),
- ])
-
- This will announce all changes to a client which connects to port
-4519 using a username of 'foo' and a password of 'bar'.
-
- Then add a clause like this to your buildmaster's `master.cfg':
-
- BuildmasterConfig['change_source'] = FreshCVSSource("cvs.example.com", 4519,
- "foo", "bar",
- prefix="glib/")
-
- where "cvs.example.com" is the host that is running the FreshCVS
-daemon, and "glib" is the top-level directory (relative to the
-repository's root) where all your source code lives. Most projects
-keep one or more projects in the same repository (along with CVSROOT/
-to hold admin files like loginfo and freshCfg); the prefix= argument
-tells the buildmaster to ignore everything outside that directory,
-and to strip that common prefix from all pathnames it handles.
-
-
-File: buildbot.info, Node: Mail-parsing ChangeSources, Next: PBChangeSource, Prev: CVSToys - PBService, Up: Getting Source Code Changes
-
-5.4 Mail-parsing ChangeSources
-==============================
-
-Many projects publish information about changes to their source tree
-by sending an email message out to a mailing list, frequently named
-PROJECT-commits or PROJECT-changes. Each message usually contains a
-description of the change (who made the change, which files were
-affected) and sometimes a copy of the diff. Humans can subscribe to
-this list to stay informed about what's happening to the source tree.
-
- The Buildbot can also be subscribed to a -commits mailing list, and
-can trigger builds in response to Changes that it hears about. The
-buildmaster admin needs to arrange for these email messages to arrive
-in a place where the buildmaster can find them, and configure the
-buildmaster to parse the messages correctly. Once that is in place,
-the email parser will create Change objects and deliver them to the
-Schedulers (see *note Change Sources and Schedulers::) just like any
-other ChangeSource.
-
- There are two components to setting up an email-based ChangeSource.
-The first is to route the email messages to the buildmaster, which is
-done by dropping them into a "maildir". The second is to actually
-parse the messages, which is highly dependent upon the tool that was
-used to create them. Each VC system has a collection of favorite
-change-emailing tools, and each has a slightly different format, so
-each has a different parsing function. There is a separate
-ChangeSource variant for each parsing function.
-
- Once you've chosen a maildir location and a parsing function,
-create the change source and put it in `c['change_source']':
-
- from buildbot.changes.mail import SyncmailMaildirSource
- c['change_source'] = SyncmailMaildirSource("~/maildir-buildbot",
- prefix="/trunk/")
-
-* Menu:
-
-* Subscribing the Buildmaster::
-* Using Maildirs::
-* Parsing Email Change Messages::
-
-
-File: buildbot.info, Node: Subscribing the Buildmaster, Next: Using Maildirs, Prev: Mail-parsing ChangeSources, Up: Mail-parsing ChangeSources
-
-5.4.1 Subscribing the Buildmaster
----------------------------------
-
-The recommended way to install the buildbot is to create a dedicated
-account for the buildmaster. If you do this, the account will probably
-have a distinct email address (perhaps <buildmaster@example.org>).
-Then just arrange for this account's email to be delivered to a
-suitable maildir (described in the next section).
-
- If the buildbot does not have its own account, "extension
-addresses" can be used to distinguish between email intended for the
-buildmaster and email intended for the rest of the account. In most
-modern MTAs, the e.g. `foo@example.org' account has control over
-every email address at example.org which begins with "foo", such that
-email addressed to <account-foo@example.org> can be delivered to a
-different destination than <account-bar@example.org>. qmail does this
-by using separate .qmail files for the two destinations (`.qmail-foo'
-and `.qmail-bar', with `.qmail' controlling the base address and
-`.qmail-default' controlling all other extensions). Other MTAs have
-similar mechanisms.
-
- Thus you can assign an extension address like
-<foo-buildmaster@example.org> to the buildmaster, and retain
-<foo@example.org> for your own use.
-
-
-File: buildbot.info, Node: Using Maildirs, Next: Parsing Email Change Messages, Prev: Subscribing the Buildmaster, Up: Mail-parsing ChangeSources
-
-5.4.2 Using Maildirs
---------------------
-
-A "maildir" is a simple directory structure originally developed for
-qmail that allows safe atomic update without locking. Create a base
-directory with three subdirectories: "new", "tmp", and "cur". When
-messages arrive, they are put into a uniquely-named file (using pids,
-timestamps, and random numbers) in "tmp". When the file is complete,
-it is atomically renamed into "new". Eventually the buildmaster
-notices the file in "new", reads and parses the contents, then moves
-it into "cur". A cronjob can be used to delete files in "cur" at
-leisure.
-
- Maildirs are frequently created with the `maildirmake' tool, but a
-simple `mkdir -p ~/MAILDIR/{cur,new,tmp}' is pretty much equivalent.
-
- Many modern MTAs can deliver directly to maildirs. The usual
-.forward or .procmailrc syntax is to name the base directory with a
-trailing slash, so something like `~/MAILDIR/' . qmail and postfix are
-maildir-capable MTAs, and procmail is a maildir-capable MDA (Mail
-Delivery Agent).
-
- For MTAs which cannot put files into maildirs directly, the
-"safecat" tool can be executed from a .forward file to accomplish the
-same thing.
-
- The Buildmaster uses the linux DNotify facility to receive
-immediate notification when the maildir's "new" directory has
-changed. When this facility is not available, it polls the directory
-for new messages, every 10 seconds by default.
-
-
-File: buildbot.info, Node: Parsing Email Change Messages, Prev: Using Maildirs, Up: Mail-parsing ChangeSources
-
-5.4.3 Parsing Email Change Messages
------------------------------------
-
-The second component to setting up an email-based ChangeSource is to
-parse the actual notices. This is highly dependent upon the VC system
-and commit script in use.
-
- A couple of common tools used to create these change emails are:
-
-`CVS'
-
- `CVSToys MailNotifier'
- *note FCMaildirSource::
-
- `Bonsai notification'
- *note BonsaiMaildirSource::
-
- `syncmail'
- *note SyncmailMaildirSource::
-
-`SVN'
-
- `svnmailer'
- http://opensource.perlig.de/en/svnmailer/
-
- `commit-email.pl'
- *note SVNCommitEmailMaildirSource::
-
-`Mercurial'
-
- `NotifyExtension'
- http://www.selenic.com/mercurial/wiki/index.cgi/NotifyExtension
-
-`Git'
-
- `post-receive-email'
- http://git.kernel.org/?p=git/git.git;a=blob;f=contrib/hooks/post-receive-email;hb=HEAD
-
-
- The following sections describe the parsers available for each of
-these tools.
-
- Most of these parsers accept a `prefix=' argument, which is used
-to limit the set of files that the buildmaster pays attention to. This
-is most useful for systems like CVS and SVN which put multiple
-projects in a single repository (or use repository names to indicate
-branches). Each filename that appears in the email is tested against
-the prefix: if the filename does not start with the prefix, the file
-is ignored. If the filename _does_ start with the prefix, that prefix
-is stripped from the filename before any further processing is done.
-Thus the prefix usually ends with a slash.
-
-* Menu:
-
-* FCMaildirSource::
-* SyncmailMaildirSource::
-* BonsaiMaildirSource::
-* SVNCommitEmailMaildirSource::
-
-
-File: buildbot.info, Node: FCMaildirSource, Next: SyncmailMaildirSource, Prev: Parsing Email Change Messages, Up: Parsing Email Change Messages
-
-5.4.3.1 FCMaildirSource
-.......................
-
-http://twistedmatrix.com/users/acapnotic/wares/code/CVSToys/
-
- This parser works with the CVSToys `MailNotification' action,
-which will send email to a list of recipients for each commit. This
-tends to work better than using `/bin/mail' from within the
-CVSROOT/loginfo file directly, as CVSToys will batch together all
-files changed during the same CVS invocation, and can provide more
-information (like creating a ViewCVS URL for each file changed).
-
- The Buildbot's `FCMaildirSource' knows for to parse these CVSToys
-messages and turn them into Change objects. It can be given two
-parameters: the directory name of the maildir root, and the prefix to
-strip.
-
- from buildbot.changes.mail import FCMaildirSource
- c['change_source'] = FCMaildirSource("~/maildir-buildbot")
-
-
-File: buildbot.info, Node: SyncmailMaildirSource, Next: BonsaiMaildirSource, Prev: FCMaildirSource, Up: Parsing Email Change Messages
-
-5.4.3.2 SyncmailMaildirSource
-.............................
-
-http://sourceforge.net/projects/cvs-syncmail
-
- `SyncmailMaildirSource' knows how to parse the message format used
-by the CVS "syncmail" script.
-
- from buildbot.changes.mail import SyncmailMaildirSource
- c['change_source'] = SyncmailMaildirSource("~/maildir-buildbot")
-
-
-File: buildbot.info, Node: BonsaiMaildirSource, Next: SVNCommitEmailMaildirSource, Prev: SyncmailMaildirSource, Up: Parsing Email Change Messages
-
-5.4.3.3 BonsaiMaildirSource
-...........................
-
-http://www.mozilla.org/bonsai.html
-
- `BonsaiMaildirSource' parses messages sent out by Bonsai, the CVS
-tree-management system built by Mozilla.
-
- from buildbot.changes.mail import BonsaiMaildirSource
- c['change_source'] = BonsaiMaildirSource("~/maildir-buildbot")
-
-
-File: buildbot.info, Node: SVNCommitEmailMaildirSource, Prev: BonsaiMaildirSource, Up: Parsing Email Change Messages
-
-5.4.3.4 SVNCommitEmailMaildirSource
-...................................
-
-`SVNCommitEmailMaildirSource' parses message sent out by the
-`commit-email.pl' script, which is included in the Subversion
-distribution.
-
- It does not currently handle branches: all of the Change objects
-that it creates will be associated with the default (i.e. trunk)
-branch.
-
- from buildbot.changes.mail import SVNCommitEmailMaildirSource
- c['change_source'] = SVNCommitEmailMaildirSource("~/maildir-buildbot")
-
-
-File: buildbot.info, Node: PBChangeSource, Next: P4Source, Prev: Mail-parsing ChangeSources, Up: Getting Source Code Changes
-
-5.5 PBChangeSource
-==================
-
-The last kind of ChangeSource actually listens on a TCP port for
-clients to connect and push change notices _into_ the Buildmaster.
-This is used by the built-in `buildbot sendchange' notification tool,
-as well as the VC-specific `contrib/svn_buildbot.py',
-`contrib/arch_buildbot.py', `contrib/hg_buildbot.py' tools, and the
-`buildbot.changes.hgbuildbot' hook. These tools are run by the
-repository (in a commit hook script), and connect to the buildmaster
-directly each time a file is comitted. This is also useful for
-creating new kinds of change sources that work on a `push' model
-instead of some kind of subscription scheme, for example a script
-which is run out of an email .forward file.
-
- This ChangeSource can be configured to listen on its own TCP port,
-or it can share the port that the buildmaster is already using for the
-buildslaves to connect. (This is possible because the
-`PBChangeSource' uses the same protocol as the buildslaves, and they
-can be distinguished by the `username' attribute used when the
-initial connection is established). It might be useful to have it
-listen on a different port if, for example, you wanted to establish
-different firewall rules for that port. You could allow only the SVN
-repository machine access to the `PBChangeSource' port, while
-allowing only the buildslave machines access to the slave port. Or you
-could just expose one port and run everything over it. _Note: this
-feature is not yet implemented, the PBChangeSource will always share
-the slave port and will always have a `user' name of `change', and a
-passwd of `changepw'. These limitations will be removed in the
-future._.
-
- The `PBChangeSource' is created with the following arguments. All
-are optional.
-
-``port''
- which port to listen on. If `None' (which is the default), it
- shares the port used for buildslave connections. _Not
- Implemented, always set to `None'_.
-
-``user' and `passwd''
- The user/passwd account information that the client program must
- use to connect. Defaults to `change' and `changepw'. _Not
- Implemented, `user' is currently always set to `change',
- `passwd' is always set to `changepw'_.
-
-``prefix''
- The prefix to be found and stripped from filenames delivered
- over the connection. Any filenames which do not start with this
- prefix will be removed. If all the filenames in a given Change
- are removed, the that whole Change will be dropped. This string
- should probably end with a directory separator.
-
- This is useful for changes coming from version control systems
- that represent branches as parent directories within the
- repository (like SVN and Perforce). Use a prefix of 'trunk/' or
- 'project/branches/foobranch/' to only follow one branch and to
- get correct tree-relative filenames. Without a prefix, the
- PBChangeSource will probably deliver Changes with filenames like
- `trunk/foo.c' instead of just `foo.c'. Of course this also
- depends upon the tool sending the Changes in (like `buildbot
- sendchange') and what filenames it is delivering: that tool may
- be filtering and stripping prefixes at the sending end.
-
-
-
-File: buildbot.info, Node: P4Source, Next: BonsaiPoller, Prev: PBChangeSource, Up: Getting Source Code Changes
-
-5.6 P4Source
-============
-
-The `P4Source' periodically polls a Perforce
-(http://www.perforce.com/) depot for changes. It accepts the
-following arguments:
-
-``p4base''
- The base depot path to watch, without the trailing '/...'.
-
-``p4port''
- The Perforce server to connect to (as host:port).
-
-``p4user''
- The Perforce user.
-
-``p4passwd''
- The Perforce password.
-
-``p4bin''
- An optional string parameter. Specify the location of the
- perforce command line binary (p4). You only need to do this if
- the perforce binary is not in the path of the buildbot user.
- Defaults to "p4".
-
-``split_file''
- A function that maps a pathname, without the leading `p4base',
- to a (branch, filename) tuple. The default just returns (None,
- branchfile), which effectively disables branch support. You
- should supply a function which understands your repository
- structure.
-
-``pollinterval''
- How often to poll, in seconds. Defaults to 600 (10 minutes).
-
-``histmax''
- The maximum number of changes to inspect at a time. If more than
- this number occur since the last poll, older changes will be
- silently ignored.
-
-Example
-=======
-
-This configuration uses the `P4PORT', `P4USER', and `P4PASSWD'
-specified in the buildmaster's environment. It watches a project in
-which the branch name is simply the next path component, and the file
-is all path components after.
-
- import buildbot.changes.p4poller
- s = p4poller.P4Source(p4base='//depot/project/',
- split_file=lambda branchfile: branchfile.split('/',1),
- )
- c['change_source'] = s
-
-
-File: buildbot.info, Node: BonsaiPoller, Next: SVNPoller, Prev: P4Source, Up: Getting Source Code Changes
-
-5.7 BonsaiPoller
-================
-
-The `BonsaiPoller' periodically polls a Bonsai server. This is a CGI
-script accessed through a web server that provides information about
-a CVS tree, for example the Mozilla bonsai server at
-`http://bonsai.mozilla.org'. Bonsai servers are usable by both humans
-and machines. In this case, the buildbot's change source forms a
-query which asks about any files in the specified branch which have
-changed since the last query.
-
- Please take a look at the BonsaiPoller docstring for details about
-the arguments it accepts.
-
-
-File: buildbot.info, Node: SVNPoller, Next: MercurialHook, Prev: BonsaiPoller, Up: Getting Source Code Changes
-
-5.8 SVNPoller
-=============
-
-The `buildbot.changes.svnpoller.SVNPoller' is a ChangeSource which
-periodically polls a Subversion (http://subversion.tigris.org/)
-repository for new revisions, by running the `svn log' command in a
-subshell. It can watch a single branch or multiple branches.
-
- `SVNPoller' accepts the following arguments:
-
-`svnurl'
- The base URL path to watch, like
- `svn://svn.twistedmatrix.com/svn/Twisted/trunk', or
- `http://divmod.org/svn/Divmod/', or even
- `file:///home/svn/Repository/ProjectA/branches/1.5/'. This must
- include the access scheme, the location of the repository (both
- the hostname for remote ones, and any additional directory names
- necessary to get to the repository), and the sub-path within the
- repository's virtual filesystem for the project and branch of
- interest.
-
- The `SVNPoller' will only pay attention to files inside the
- subdirectory specified by the complete svnurl.
-
-`split_file'
- A function to convert pathnames into (branch, relative_pathname)
- tuples. Use this to explain your repository's branch-naming
- policy to `SVNPoller'. This function must accept a single string
- and return a two-entry tuple. There are a few utility functions
- in `buildbot.changes.svnpoller' that can be used as a
- `split_file' function, see below for details.
-
- The default value always returns (None, path), which indicates
- that all files are on the trunk.
-
- Subclasses of `SVNPoller' can override the `split_file' method
- instead of using the `split_file=' argument.
-
-`svnuser'
- An optional string parameter. If set, the `--user' argument will
- be added to all `svn' commands. Use this if you have to
- authenticate to the svn server before you can do `svn info' or
- `svn log' commands.
-
-`svnpasswd'
- Like `svnuser', this will cause a `--password' argument to be
- passed to all svn commands.
-
-`pollinterval'
- How often to poll, in seconds. Defaults to 600 (checking once
- every 10 minutes). Lower this if you want the buildbot to notice
- changes faster, raise it if you want to reduce the network and
- CPU load on your svn server. Please be considerate of public SVN
- repositories by using a large interval when polling them.
-
-`histmax'
- The maximum number of changes to inspect at a time. Every
- POLLINTERVAL seconds, the `SVNPoller' asks for the last HISTMAX
- changes and looks through them for any ones it does not already
- know about. If more than HISTMAX revisions have been committed
- since the last poll, older changes will be silently ignored.
- Larger values of histmax will cause more time and memory to be
- consumed on each poll attempt. `histmax' defaults to 100.
-
-`svnbin'
- This controls the `svn' executable to use. If subversion is
- installed in a weird place on your system (outside of the
- buildmaster's `$PATH'), use this to tell `SVNPoller' where to
- find it. The default value of "svn" will almost always be
- sufficient.
-
-
-Branches
-========
-
-Each source file that is tracked by a Subversion repository has a
-fully-qualified SVN URL in the following form:
-(REPOURL)(PROJECT-plus-BRANCH)(FILEPATH). When you create the
-`SVNPoller', you give it a `svnurl' value that includes all of the
-REPOURL and possibly some portion of the PROJECT-plus-BRANCH string.
-The `SVNPoller' is responsible for producing Changes that contain a
-branch name and a FILEPATH (which is relative to the top of a
-checked-out tree). The details of how these strings are split up
-depend upon how your repository names its branches.
-
-PROJECT/BRANCHNAME/FILEPATH repositories
-----------------------------------------
-
-One common layout is to have all the various projects that share a
-repository get a single top-level directory each. Then under a given
-project's directory, you get two subdirectories, one named "trunk"
-and another named "branches". Under "branches" you have a bunch of
-other directories, one per branch, with names like "1.5.x" and
-"testing". It is also common to see directories like "tags" and
-"releases" next to "branches" and "trunk".
-
- For example, the Twisted project has a subversion server on
-"svn.twistedmatrix.com" that hosts several sub-projects. The
-repository is available through a SCHEME of "svn:". The primary
-sub-project is Twisted, of course, with a repository root of
-"svn://svn.twistedmatrix.com/svn/Twisted". Another sub-project is
-Informant, with a root of
-"svn://svn.twistedmatrix.com/svn/Informant", etc. Inside any
-checked-out Twisted tree, there is a file named bin/trial (which is
-used to run unit test suites).
-
- The trunk for Twisted is in
-"svn://svn.twistedmatrix.com/svn/Twisted/trunk", and the
-fully-qualified SVN URL for the trunk version of `trial' would be
-"svn://svn.twistedmatrix.com/svn/Twisted/trunk/bin/trial". The same
-SVNURL for that file on a branch named "1.5.x" would be
-"svn://svn.twistedmatrix.com/svn/Twisted/branches/1.5.x/bin/trial".
-
- To set up a `SVNPoller' that watches the Twisted trunk (and
-nothing else), we would use the following:
-
- from buildbot.changes.svnpoller import SVNPoller
- c['change_source'] = SVNPoller("svn://svn.twistedmatrix.com/svn/Twisted/trunk")
-
- In this case, every Change that our `SVNPoller' produces will have
-`.branch=None', to indicate that the Change is on the trunk. No
-other sub-projects or branches will be tracked.
-
- If we want our ChangeSource to follow multiple branches, we have
-to do two things. First we have to change our `svnurl=' argument to
-watch more than just ".../Twisted/trunk". We will set it to
-".../Twisted" so that we'll see both the trunk and all the branches.
-Second, we have to tell `SVNPoller' how to split the
-(PROJECT-plus-BRANCH)(FILEPATH) strings it gets from the repository
-out into (BRANCH) and (FILEPATH) pairs.
-
- We do the latter by providing a "split_file" function. This
-function is responsible for splitting something like
-"branches/1.5.x/bin/trial" into `branch'="branches/1.5.x" and
-`filepath'="bin/trial". This function is always given a string that
-names a file relative to the subdirectory pointed to by the
-`SVNPoller''s `svnurl=' argument. It is expected to return a
-(BRANCHNAME, FILEPATH) tuple (in which FILEPATH is relative to the
-branch indicated), or None to indicate that the file is outside any
-project of interest.
-
- (note that we want to see "branches/1.5.x" rather than just
-"1.5.x" because when we perform the SVN checkout, we will probably
-append the branch name to the baseURL, which requires that we keep the
-"branches" component in there. Other VC schemes use a different
-approach towards branches and may not require this artifact.)
-
- If your repository uses this same PROJECT/BRANCH/FILEPATH naming
-scheme, the following function will work:
-
- def split_file_branches(path):
- pieces = path.split('/')
- if pieces[0] == 'trunk':
- return (None, '/'.join(pieces[1:]))
- elif pieces[0] == 'branches':
- return ('/'.join(pieces[0:2]),
- '/'.join(pieces[2:]))
- else:
- return None
-
- This function is provided as
-`buildbot.changes.svnpoller.split_file_branches' for your
-convenience. So to have our Twisted-watching `SVNPoller' follow
-multiple branches, we would use this:
-
- from buildbot.changes.svnpoller import SVNPoller, split_file_branches
- c['change_source'] = SVNPoller("svn://svn.twistedmatrix.com/svn/Twisted",
- split_file=split_file_branches)
-
- Changes for all sorts of branches (with names like
-"branches/1.5.x", and None to indicate the trunk) will be delivered
-to the Schedulers. Each Scheduler is then free to use or ignore each
-branch as it sees fit.
-
-BRANCHNAME/PROJECT/FILEPATH repositories
-----------------------------------------
-
-Another common way to organize a Subversion repository is to put the
-branch name at the top, and the projects underneath. This is
-especially frequent when there are a number of related sub-projects
-that all get released in a group.
-
- For example, Divmod.org hosts a project named "Nevow" as well as
-one named "Quotient". In a checked-out Nevow tree there is a directory
-named "formless" that contains a python source file named
-"webform.py". This repository is accessible via webdav (and thus uses
-an "http:" scheme) through the divmod.org hostname. There are many
-branches in this repository, and they use a (BRANCHNAME)/(PROJECT)
-naming policy.
-
- The fully-qualified SVN URL for the trunk version of webform.py is
-`http://divmod.org/svn/Divmod/trunk/Nevow/formless/webform.py'. You
-can do an `svn co' with that URL and get a copy of the latest
-version. The 1.5.x branch version of this file would have a URL of
-`http://divmod.org/svn/Divmod/branches/1.5.x/Nevow/formless/webform.py'.
-The whole Nevow trunk would be checked out with
-`http://divmod.org/svn/Divmod/trunk/Nevow', while the Quotient trunk
-would be checked out using
-`http://divmod.org/svn/Divmod/trunk/Quotient'.
-
- Now suppose we want to have an `SVNPoller' that only cares about
-the Nevow trunk. This case looks just like the PROJECT/BRANCH layout
-described earlier:
-
- from buildbot.changes.svnpoller import SVNPoller
- c['change_source'] = SVNPoller("http://divmod.org/svn/Divmod/trunk/Nevow")
-
- But what happens when we want to track multiple Nevow branches? We
-have to point our `svnurl=' high enough to see all those branches,
-but we also don't want to include Quotient changes (since we're only
-building Nevow). To accomplish this, we must rely upon the
-`split_file' function to help us tell the difference between files
-that belong to Nevow and those that belong to Quotient, as well as
-figuring out which branch each one is on.
-
- from buildbot.changes.svnpoller import SVNPoller
- c['change_source'] = SVNPoller("http://divmod.org/svn/Divmod",
- split_file=my_file_splitter)
-
- The `my_file_splitter' function will be called with
-repository-relative pathnames like:
-
-`trunk/Nevow/formless/webform.py'
- This is a Nevow file, on the trunk. We want the Change that
- includes this to see a filename of `formless/webform.py"', and a
- branch of None
-
-`branches/1.5.x/Nevow/formless/webform.py'
- This is a Nevow file, on a branch. We want to get
- branch="branches/1.5.x" and filename="formless/webform.py".
-
-`trunk/Quotient/setup.py'
- This is a Quotient file, so we want to ignore it by having
- `my_file_splitter' return None.
-
-`branches/1.5.x/Quotient/setup.py'
- This is also a Quotient file, which should be ignored.
-
- The following definition for `my_file_splitter' will do the job:
-
- def my_file_splitter(path):
- pieces = path.split('/')
- if pieces[0] == 'trunk':
- branch = None
- pieces.pop(0) # remove 'trunk'
- elif pieces[0] == 'branches':
- pieces.pop(0) # remove 'branches'
- # grab branch name
- branch = 'branches/' + pieces.pop(0)
- else:
- return None # something weird
- projectname = pieces.pop(0)
- if projectname != 'Nevow':
- return None # wrong project
- return (branch, '/'.join(pieces))
-
-
-File: buildbot.info, Node: MercurialHook, Next: Bzr Hook, Prev: SVNPoller, Up: Getting Source Code Changes
-
-5.9 MercurialHook
-=================
-
-Since Mercurial is written in python, the hook script can invoke
-Buildbot's `sendchange' function directly, rather than having to
-spawn an external process. This function delivers the same sort of
-changes as `buildbot sendchange' and the various hook scripts in
-contrib/, so you'll need to add a `pb.PBChangeSource' to your
-buildmaster to receive these changes.
-
- To set this up, first choose a Mercurial repository that represents
-your central "official" source tree. This will be the same repository
-that your buildslaves will eventually pull from. Install Buildbot on
-the machine that hosts this repository, using the same version of
-python as Mercurial is using (so that the Mercurial hook can import
-code from buildbot). Then add the following to the `.hg/hgrc' file in
-that repository, replacing the buildmaster hostname/portnumber as
-appropriate for your buildbot:
-
- [hooks]
- changegroup.buildbot = python:buildbot.changes.hgbuildbot.hook
-
- [hgbuildbot]
- master = buildmaster.example.org:9987
-
- (Note that Mercurial lets you define multiple `changegroup' hooks
-by giving them distinct names, like `changegroup.foo' and
-`changegroup.bar', which is why we use `changegroup.buildbot' in this
-example. There is nothing magical about the "buildbot" suffix in the
-hook name. The `[hgbuildbot]' section _is_ special, however, as it is
-the only section that the buildbot hook pays attention to.)
-
- Also note that this runs as a `changegroup' hook, rather than as
-an `incoming' hook. The `changegroup' hook is run with multiple
-revisions at a time (say, if multiple revisions are being pushed to
-this repository in a single `hg push' command), whereas the
-`incoming' hook is run with just one revision at a time. The
-`hgbuildbot.hook' function will only work with the `changegroup' hook.
-
- The `[hgbuildbot]' section has two other parameters that you might
-specify, both of which control the name of the branch that is
-attached to the changes coming from this hook.
-
- One common branch naming policy for Mercurial repositories is to
-use it just like Darcs: each branch goes into a separate repository,
-and all the branches for a single project share a common parent
-directory. For example, you might have `/var/repos/PROJECT/trunk/'
-and `/var/repos/PROJECT/release'. To use this style, use the
-`branchtype = dirname' setting, which simply uses the last component
-of the repository's enclosing directory as the branch name:
-
- [hgbuildbot]
- master = buildmaster.example.org:9987
- branchtype = dirname
-
- Another approach is to use Mercurial's built-in branches (the kind
-created with `hg branch' and listed with `hg branches'). This feature
-associates persistent names with particular lines of descent within a
-single repository. (note that the buildbot `source.Mercurial'
-checkout step does not yet support this kind of branch). To have the
-commit hook deliver this sort of branch name with the Change object,
-use `branchtype = inrepo':
-
- [hgbuildbot]
- master = buildmaster.example.org:9987
- branchtype = inrepo
-
- Finally, if you want to simply specify the branchname directly, for
-all changes, use `branch = BRANCHNAME'. This overrides `branchtype':
-
- [hgbuildbot]
- master = buildmaster.example.org:9987
- branch = trunk
-
- If you use `branch=' like this, you'll need to put a separate
-.hgrc in each repository. If you use `branchtype=', you may be able
-to use the same .hgrc for all your repositories, stored in `~/.hgrc'
-or `/etc/mercurial/hgrc'.
-
-
-File: buildbot.info, Node: Bzr Hook, Next: Bzr Poller, Prev: MercurialHook, Up: Getting Source Code Changes
-
-5.10 Bzr Hook
-=============
-
-Bzr is also written in Python, and the Bzr hook depends on Twisted to
-send the changes.
-
- To install, put `contrib/bzr_buildbot.py' in one of your plugins
-locations a bzr plugins directory (e.g., `~/.bazaar/plugins'). Then,
-in one of your bazaar conf files (e.g., `~/.bazaar/locations.conf'),
-set the location you want to connect with buildbot with these keys:
-
-`buildbot_on'
- one of 'commit', 'push, or 'change'. Turns the plugin on to
- report changes via commit, changes via push, or any changes to
- the trunk. 'change' is recommended.
-
-`buildbot_server'
- (required to send to a buildbot master) the URL of the buildbot
- master to which you will connect (as of this writing, the same
- server and port to which slaves connect).
-
-`buildbot_port'
- (optional, defaults to 9989) the port of the buildbot master to
- which you will connect (as of this writing, the same server and
- port to which slaves connect)
-
-`buildbot_pqm'
- (optional, defaults to not pqm) Normally, the user that commits
- the revision is the user that is responsible for the change.
- When run in a pqm (Patch Queue Manager, see
- https://launchpad.net/pqm) environment, the user that commits is
- the Patch Queue Manager, and the user that committed the
- *parent* revision is responsible for the change. To turn on the
- pqm mode, set this value to any of (case-insensitive) "Yes",
- "Y", "True", or "T".
-
-`buildbot_dry_run'
- (optional, defaults to not a dry run) Normally, the post-commit
- hook will attempt to communicate with the configured buildbot
- server and port. If this parameter is included and any of
- (case-insensitive) "Yes", "Y", "True", or "T", then the hook
- will simply print what it would have sent, but not attempt to
- contact the buildbot master.
-
-`buildbot_send_branch_name'
- (optional, defaults to not sending the branch name) If your
- buildbot's bzr source build step uses a repourl, do *not* turn
- this on. If your buildbot's bzr build step uses a baseURL, then
- you may set this value to any of (case-insensitive) "Yes", "Y",
- "True", or "T" to have the buildbot master append the branch
- name to the baseURL.
-
-
- When buildbot no longer has a hardcoded password, it will be a
-configuration option here as well.
-
- Here's a simple example that you might have in your
-`~/.bazaar/locations.conf'.
-
- [chroot-*:///var/local/myrepo/mybranch]
- buildbot_on = change
- buildbot_server = localhost
-
-
-File: buildbot.info, Node: Bzr Poller, Prev: Bzr Hook, Up: Getting Source Code Changes
-
-5.11 Bzr Poller
-===============
-
-If you cannot insert a Bzr hook in the server, you can use the Bzr
-Poller. To use, put `contrib/bzr_buildbot.py' somewhere that your
-buildbot configuration can import it. Even putting it in the same
-directory as the master.cfg should work. Install the poller in the
-buildbot configuration as with any other change source. Minimally,
-provide a URL that you want to poll (bzr://, bzr+ssh://, or lp:),
-though make sure the buildbot user has necessary privileges. You may
-also want to specify these optional values.
-
-`poll_interval'
- The number of seconds to wait between polls. Defaults to 10
- minutes.
-
-`branch_name'
- Any value to be used as the branch name. Defaults to None, or
- specify a string, or specify the constants from
- `bzr_buildbot.py' SHORT or FULL to get the short branch name or
- full branch address.
-
-`blame_merge_author'
- normally, the user that commits the revision is the user that is
- responsible for the change. When run in a pqm (Patch Queue
- Manager, see https://launchpad.net/pqm) environment, the user
- that commits is the Patch Queue Manager, and the user that
- committed the merged, *parent* revision is responsible for the
- change. set this value to True if this is pointed against a
- PQM-managed branch.
-
-
-File: buildbot.info, Node: Build Process, Next: Status Delivery, Prev: Getting Source Code Changes, Up: Top
-
-6 Build Process
-***************
-
-A `Build' object is responsible for actually performing a build. It
-gets access to a remote `SlaveBuilder' where it may run commands, and
-a `BuildStatus' object where it must emit status events. The `Build'
-is created by the Builder's `BuildFactory'.
-
- The default `Build' class is made up of a fixed sequence of
-`BuildSteps', executed one after another until all are complete (or
-one of them indicates that the build should be halted early). The
-default `BuildFactory' creates instances of this `Build' class with a
-list of `BuildSteps', so the basic way to configure the build is to
-provide a list of `BuildSteps' to your `BuildFactory'.
-
- More complicated `Build' subclasses can make other decisions:
-execute some steps only if certain files were changed, or if certain
-previous steps passed or failed. The base class has been written to
-allow users to express basic control flow without writing code, but
-you can always subclass and customize to achieve more specialized
-behavior.
-
-* Menu:
-
-* Build Steps::
-* Interlocks::
-* Build Factories::
-
-
-File: buildbot.info, Node: Build Steps, Next: Interlocks, Prev: Build Process, Up: Build Process
-
-6.1 Build Steps
-===============
-
-`BuildStep's are usually specified in the buildmaster's configuration
-file, in a list that goes into the `BuildFactory'. The `BuildStep'
-instances in this list are used as templates to construct new
-independent copies for each build (so that state can be kept on the
-`BuildStep' in one build without affecting a later build). Each
-`BuildFactory' can be created with a list of steps, or the factory
-can be created empty and then steps added to it using the `addStep'
-method:
-
- from buildbot.steps import source, shell
- from buildbot.process import factory
-
- f = factory.BuildFactory()
- f.addStep(source.SVN(svnurl="http://svn.example.org/Trunk/"))
- f.addStep(shell.ShellCommand(command=["make", "all"]))
- f.addStep(shell.ShellCommand(command=["make", "test"]))
-
- In earlier versions (0.7.5 and older), these steps were specified
-with a tuple of (step_class, keyword_arguments). Steps can still be
-specified this way, but the preferred form is to pass actual
-`BuildStep' instances to `addStep', because that gives the
-`BuildStep' class a chance to do some validation on the arguments.
-
- If you have a common set of steps which are used in several
-factories, the `addSteps' method may be handy. It takes an iterable
-of `BuildStep' instances.
-
- setup_steps = [
- source.SVN(svnurl="http://svn.example.org/Trunk/")
- shell.ShellCommand(command="./setup")
- ]
- quick = factory.BuildFactory()
- quick.addSteps(setup_steps)
- quick.addStep(shell.shellCommand(command="make quick"))
-
- The rest of this section lists all the standard BuildStep objects
-available for use in a Build, and the parameters which can be used to
-control each.
-
-* Menu:
-
-* Common Parameters::
-* Using Build Properties::
-* Source Checkout::
-* ShellCommand::
-* Simple ShellCommand Subclasses::
-* Python BuildSteps::
-* Transferring Files::
-* Steps That Run on the Master::
-* Triggering Schedulers::
-* Writing New BuildSteps::
-
-
-File: buildbot.info, Node: Common Parameters, Next: Using Build Properties, Prev: Build Steps, Up: Build Steps
-
-6.1.1 Common Parameters
------------------------
-
-The standard `Build' runs a series of `BuildStep's in order, only
-stopping when it runs out of steps or if one of them requests that
-the build be halted. It collects status information from each one to
-create an overall build status (of SUCCESS, WARNINGS, or FAILURE).
-
- All BuildSteps accept some common parameters. Some of these control
-how their individual status affects the overall build. Others are used
-to specify which `Locks' (see *note Interlocks::) should be acquired
-before allowing the step to run.
-
- Arguments common to all `BuildStep' subclasses:
-
-`name'
- the name used to describe the step on the status display. It is
- also used to give a name to any LogFiles created by this step.
-
-`haltOnFailure'
- if True, a FAILURE of this build step will cause the build to
- halt immediately. Steps with `alwaysRun=True' are still run.
- Generally speaking, haltOnFailure implies flunkOnFailure (the
- default for most BuildSteps). In some cases, particularly series
- of tests, it makes sense to haltOnFailure if something fails
- early on but not flunkOnFailure. This can be achieved with
- haltOnFailure=True, flunkOnFailure=False.
-
-`flunkOnWarnings'
- when True, a WARNINGS or FAILURE of this build step will mark the
- overall build as FAILURE. The remaining steps will still be
- executed.
-
-`flunkOnFailure'
- when True, a FAILURE of this build step will mark the overall
- build as a FAILURE. The remaining steps will still be executed.
-
-`warnOnWarnings'
- when True, a WARNINGS or FAILURE of this build step will mark the
- overall build as having WARNINGS. The remaining steps will still
- be executed.
-
-`warnOnFailure'
- when True, a FAILURE of this build step will mark the overall
- build as having WARNINGS. The remaining steps will still be
- executed.
-
-`alwaysRun'
- if True, this build step will always be run, even if a previous
- buildstep with `haltOnFailure=True' has failed.
-
-`locks'
- a list of Locks (instances of `buildbot.locks.SlaveLock' or
- `buildbot.locks.MasterLock') that should be acquired before
- starting this Step. The Locks will be released when the step is
- complete. Note that this is a list of actual Lock instances, not
- names. Also note that all Locks must have unique names.
-
-
-
-File: buildbot.info, Node: Using Build Properties, Next: Source Checkout, Prev: Common Parameters, Up: Build Steps
-
-6.1.2 Using Build Properties
-----------------------------
-
-Build properties are a generalized way to provide configuration
-information to build steps; see *note Build Properties::.
-
- Some build properties are inherited from external sources - global
-properties, schedulers, or buildslaves. Some build properties are
-set when the build starts, such as the SourceStamp information. Other
-properties can be set by BuildSteps as they run, for example the
-various Source steps will set the `got_revision' property to the
-source revision that was actually checked out (which can be useful
-when the SourceStamp in use merely requested the "latest revision":
-`got_revision' will tell you what was actually built).
-
- In custom BuildSteps, you can get and set the build properties with
-the `getProperty'/`setProperty' methods. Each takes a string for the
-name of the property, and returns or accepts an arbitrary(1) object.
-For example:
-
- class MakeTarball(ShellCommand):
- def start(self):
- if self.getProperty("os") == "win":
- self.setCommand([ ... ]) # windows-only command
- else:
- self.setCommand([ ... ]) # equivalent for other systems
- ShellCommand.start(self)
-
-WithProperties
-==============
-
-You can use build properties in ShellCommands by using the
-`WithProperties' wrapper when setting the arguments of the
-ShellCommand. This interpolates the named build properties into the
-generated shell command. Most step parameters accept
-`WithProperties'. Please file bugs for any parameters which do not.
-
- from buildbot.steps.shell import ShellCommand
- from buildbot.process.properties import WithProperties
-
- f.addStep(ShellCommand(
- command=["tar", "czf",
- WithProperties("build-%s.tar.gz", "revision"),
- "source"]))
-
- If this BuildStep were used in a tree obtained from Subversion, it
-would create a tarball with a name like `build-1234.tar.gz'.
-
- The `WithProperties' function does `printf'-style string
-interpolation, using strings obtained by calling
-`build.getProperty(propname)'. Note that for every `%s' (or `%d',
-etc), you must have exactly one additional argument to indicate which
-build property you want to insert.
-
- You can also use python dictionary-style string interpolation by
-using the `%(propname)s' syntax. In this form, the property name goes
-in the parentheses, and WithProperties takes _no_ additional
-arguments:
-
- f.addStep(ShellCommand(
- command=["tar", "czf",
- WithProperties("build-%(revision)s.tar.gz"),
- "source"]))
-
- Don't forget the extra "s" after the closing parenthesis! This is
-the cause of many confusing errors.
-
- The dictionary-style interpolation supports a number of more
-advanced syntaxes, too.
-
-`propname:-replacement'
- If `propname' exists, substitute its value; otherwise,
- substitute `replacement'. `replacement' may be empty
- (`%(propname:-)s')
-
-`propname:+replacement'
- If `propname' exists, substitute `replacement'; otherwise,
- substitute an empty string.
-
-
- Although these are similar to shell substitutions, no other
-substitutions are currently supported, and `replacement' in the above
-cannot contain more substitutions.
-
- Note: like python, you can either do positional-argument
-interpolation _or_ keyword-argument interpolation, not both. Thus you
-cannot use a string like `WithProperties("foo-%(revision)s-%s",
-"branch")'.
-
-Common Build Properties
-=======================
-
-The following build properties are set when the build is started, and
-are available to all steps.
-
-`branch'
- This comes from the build's SourceStamp, and describes which
- branch is being checked out. This will be `None' (which
- interpolates into `WithProperties' as an empty string) if the
- build is on the default branch, which is generally the trunk.
- Otherwise it will be a string like "branches/beta1.4". The exact
- syntax depends upon the VC system being used.
-
-`revision'
- This also comes from the SourceStamp, and is the revision of the
- source code tree that was requested from the VC system. When a
- build is requested of a specific revision (as is generally the
- case when the build is triggered by Changes), this will contain
- the revision specification. This is always a string, although
- the syntax depends upon the VC system in use: for SVN it is an
- integer, for Mercurial it is a short string, for Darcs it is a
- rather large string, etc.
-
- If the "force build" button was pressed, the revision will be
- `None', which means to use the most recent revision available.
- This is a "trunk build". This will be interpolated as an empty
- string.
-
-`got_revision'
- This is set when a Source step checks out the source tree, and
- provides the revision that was actually obtained from the VC
- system. In general this should be the same as `revision',
- except for trunk builds, where `got_revision' indicates what
- revision was current when the checkout was performed. This can
- be used to rebuild the same source code later.
-
- Note that for some VC systems (Darcs in particular), the
- revision is a large string containing newlines, and is not
- suitable for interpolation into a filename.
-
-`buildername'
- This is a string that indicates which Builder the build was a
- part of. The combination of buildername and buildnumber
- uniquely identify a build.
-
-`buildnumber'
- Each build gets a number, scoped to the Builder (so the first
- build performed on any given Builder will have a build number of
- 0). This integer property contains the build's number.
-
-`slavename'
- This is a string which identifies which buildslave the build is
- running on.
-
-`scheduler'
- If the build was started from a scheduler, then this property
- will contain the name of that scheduler.
-
-
- ---------- Footnotes ----------
-
- (1) Build properties are serialized along with the build results,
-so they must be serializable. For this reason, the value of any build
-property should be simple inert data: strings, numbers, lists,
-tuples, and dictionaries. They should not contain class instances.
-
-
-File: buildbot.info, Node: Source Checkout, Next: ShellCommand, Prev: Using Build Properties, Up: Build Steps
-
-6.1.3 Source Checkout
----------------------
-
-The first step of any build is typically to acquire the source code
-from which the build will be performed. There are several classes to
-handle this, one for each of the different source control system that
-Buildbot knows about. For a description of how Buildbot treats source
-control in general, see *note Version Control Systems::.
-
- All source checkout steps accept some common parameters to control
-how they get the sources and where they should be placed. The
-remaining per-VC-system parameters are mostly to specify where
-exactly the sources are coming from.
-
-`mode'
- a string describing the kind of VC operation that is desired.
- Defaults to `update'.
-
- `update'
- specifies that the CVS checkout/update should be performed
- directly into the workdir. Each build is performed in the
- same directory, allowing for incremental builds. This
- minimizes disk space, bandwidth, and CPU time. However, it
- may encounter problems if the build process does not handle
- dependencies properly (sometimes you must do a "clean
- build" to make sure everything gets compiled), or if source
- files are deleted but generated files can influence test
- behavior (e.g. python's .pyc files), or when source
- directories are deleted but generated files prevent CVS
- from removing them. Builds ought to be correct regardless
- of whether they are done "from scratch" or incrementally,
- but it is useful to test both kinds: this mode exercises the
- incremental-build style.
-
- `copy'
- specifies that the CVS workspace should be maintained in a
- separate directory (called the 'copydir'), using checkout
- or update as necessary. For each build, a new workdir is
- created with a copy of the source tree (rm -rf workdir; cp
- -r copydir workdir). This doubles the disk space required,
- but keeps the bandwidth low (update instead of a full
- checkout). A full 'clean' build is performed each time. This
- avoids any generated-file build problems, but is still
- occasionally vulnerable to CVS problems such as a
- repository being manually rearranged, causing CVS errors on
- update which are not an issue with a full checkout.
-
- `clobber'
- specifes that the working directory should be deleted each
- time, necessitating a full checkout for each build. This
- insures a clean build off a complete checkout, avoiding any
- of the problems described above. This mode exercises the
- "from-scratch" build style.
-
- `export'
- this is like `clobber', except that the 'cvs export'
- command is used to create the working directory. This
- command removes all CVS metadata files (the CVS/
- directories) from the tree, which is sometimes useful for
- creating source tarballs (to avoid including the metadata
- in the tar file).
-
-`workdir'
- like all Steps, this indicates the directory where the build
- will take place. Source Steps are special in that they perform
- some operations outside of the workdir (like creating the
- workdir itself).
-
-`alwaysUseLatest'
- if True, bypass the usual "update to the last Change" behavior,
- and always update to the latest changes instead.
-
-`retry'
- If set, this specifies a tuple of `(delay, repeats)' which means
- that when a full VC checkout fails, it should be retried up to
- REPEATS times, waiting DELAY seconds between attempts. If you
- don't provide this, it defaults to `None', which means VC
- operations should not be retried. This is provided to make life
- easier for buildslaves which are stuck behind poor network
- connections.
-
-
- My habit as a developer is to do a `cvs update' and `make' each
-morning. Problems can occur, either because of bad code being checked
-in, or by incomplete dependencies causing a partial rebuild to fail
-where a complete from-scratch build might succeed. A quick Builder
-which emulates this incremental-build behavior would use the
-`mode='update'' setting.
-
- On the other hand, other kinds of dependency problems can cause a
-clean build to fail where a partial build might succeed. This
-frequently results from a link step that depends upon an object file
-that was removed from a later version of the tree: in the partial
-tree, the object file is still around (even though the Makefiles no
-longer know how to create it).
-
- "official" builds (traceable builds performed from a known set of
-source revisions) are always done as clean builds, to make sure it is
-not influenced by any uncontrolled factors (like leftover files from a
-previous build). A "full" Builder which behaves this way would want
-to use the `mode='clobber'' setting.
-
- Each VC system has a corresponding source checkout class: their
-arguments are described on the following pages.
-
-* Menu:
-
-* CVS::
-* SVN::
-* Darcs::
-* Mercurial::
-* Arch::
-* Bazaar::
-* Bzr::
-* P4::
-* Git::
-
-
-File: buildbot.info, Node: CVS, Next: SVN, Prev: Source Checkout, Up: Source Checkout
-
-6.1.3.1 CVS
-...........
-
-The `CVS' build step performs a CVS (http://www.nongnu.org/cvs/)
-checkout or update. It takes the following arguments:
-
-`cvsroot'
- (required): specify the CVSROOT value, which points to a CVS
- repository, probably on a remote machine. For example, the
- cvsroot value you would use to get a copy of the Buildbot source
- code is
- `:pserver:anonymous@cvs.sourceforge.net:/cvsroot/buildbot'
-
-`cvsmodule'
- (required): specify the cvs `module', which is generally a
- subdirectory of the CVSROOT. The cvsmodule for the Buildbot
- source code is `buildbot'.
-
-`branch'
- a string which will be used in a `-r' argument. This is most
- useful for specifying a branch to work on. Defaults to `HEAD'.
-
-`global_options'
- a list of flags to be put before the verb in the CVS command.
-
-`checkoutDelay'
- if set, the number of seconds to put between the timestamp of
- the last known Change and the value used for the `-D' option.
- Defaults to half of the parent Build's treeStableTimer.
-
-
-
-File: buildbot.info, Node: SVN, Next: Darcs, Prev: CVS, Up: Source Checkout
-
-6.1.3.2 SVN
-...........
-
-The `SVN' build step performs a Subversion
-(http://subversion.tigris.org) checkout or update. There are two
-basic ways of setting up the checkout step, depending upon whether
-you are using multiple branches or not.
-
- If all of your builds use the same branch, then you should create
-the `SVN' step with the `svnurl' argument:
-
-`svnurl'
- (required): this specifies the `URL' argument that will be given
- to the `svn checkout' command. It dictates both where the
- repository is located and which sub-tree should be extracted. In
- this respect, it is like a combination of the CVS `cvsroot' and
- `cvsmodule' arguments. For example, if you are using a remote
- Subversion repository which is accessible through HTTP at a URL
- of `http://svn.example.com/repos', and you wanted to check out
- the `trunk/calc' sub-tree, you would use
- `svnurl="http://svn.example.com/repos/trunk/calc"' as an argument
- to your `SVN' step.
-
- If, on the other hand, you are building from multiple branches,
-then you should create the `SVN' step with the `baseURL' and
-`defaultBranch' arguments instead:
-
-`baseURL'
- (required): this specifies the base repository URL, to which a
- branch name will be appended. It should probably end in a slash.
-
-`defaultBranch'
- this specifies the name of the branch to use when a Build does
- not provide one of its own. This will be appended to `baseURL' to
- create the string that will be passed to the `svn checkout'
- command.
-
-`username'
- if specified, this will be passed to the `svn' binary with a
- `--username' option.
-
-`password'
- if specified, this will be passed to the `svn' binary with a
- `--password' option. The password itself will be suitably
- obfuscated in the logs.
-
-
- If you are using branches, you must also make sure your
-`ChangeSource' will report the correct branch names.
-
-branch example
-==============
-
-Let's suppose that the "MyProject" repository uses branches for the
-trunk, for various users' individual development efforts, and for
-several new features that will require some amount of work (involving
-multiple developers) before they are ready to merge onto the trunk.
-Such a repository might be organized as follows:
-
- svn://svn.example.org/MyProject/trunk
- svn://svn.example.org/MyProject/branches/User1/foo
- svn://svn.example.org/MyProject/branches/User1/bar
- svn://svn.example.org/MyProject/branches/User2/baz
- svn://svn.example.org/MyProject/features/newthing
- svn://svn.example.org/MyProject/features/otherthing
-
- Further assume that we want the Buildbot to run tests against the
-trunk and against all the feature branches (i.e., do a
-checkout/compile/build of branch X when a file has been changed on
-branch X, when X is in the set [trunk, features/newthing,
-features/otherthing]). We do not want the Buildbot to automatically
-build any of the user branches, but it should be willing to build a
-user branch when explicitly requested (most likely by the user who
-owns that branch).
-
- There are three things that need to be set up to accomodate this
-system. The first is a ChangeSource that is capable of identifying the
-branch which owns any given file. This depends upon a user-supplied
-function, in an external program that runs in the SVN commit hook and
-connects to the buildmaster's `PBChangeSource' over a TCP connection.
-(you can use the "`buildbot sendchange'" utility for this purpose,
-but you will still need an external program to decide what value
-should be passed to the `--branch=' argument). For example, a change
-to a file with the SVN url of
-"svn://svn.example.org/MyProject/features/newthing/src/foo.c" should
-be broken down into a Change instance with
-`branch='features/newthing'' and `file='src/foo.c''.
-
- The second piece is an `AnyBranchScheduler' which will pay
-attention to the desired branches. It will not pay attention to the
-user branches, so it will not automatically start builds in response
-to changes there. The AnyBranchScheduler class requires you to
-explicitly list all the branches you want it to use, but it would not
-be difficult to write a subclass which used
-`branch.startswith('features/'' to remove the need for this explicit
-list. Or, if you want to build user branches too, you can use
-AnyBranchScheduler with `branches=None' to indicate that you want it
-to pay attention to all branches.
-
- The third piece is an `SVN' checkout step that is configured to
-handle the branches correctly, with a `baseURL' value that matches
-the way the ChangeSource splits each file's URL into base, branch,
-and file.
-
- from buildbot.changes.pb import PBChangeSource
- from buildbot.scheduler import AnyBranchScheduler
- from buildbot.process import source, factory
- from buildbot.steps import source, shell
-
- c['change_source'] = PBChangeSource()
- s1 = AnyBranchScheduler('main',
- ['trunk', 'features/newthing', 'features/otherthing'],
- 10*60, ['test-i386', 'test-ppc'])
- c['schedulers'] = [s1]
-
- f = factory.BuildFactory()
- f.addStep(source.SVN(mode='update',
- baseURL='svn://svn.example.org/MyProject/',
- defaultBranch='trunk'))
- f.addStep(shell.Compile(command="make all"))
- f.addStep(shell.Test(command="make test"))
-
- c['builders'] = [
- {'name':'test-i386', 'slavename':'bot-i386', 'builddir':'test-i386',
- 'factory':f },
- {'name':'test-ppc', 'slavename':'bot-ppc', 'builddir':'test-ppc',
- 'factory':f },
- ]
-
- In this example, when a change arrives with a `branch' attribute
-of "trunk", the resulting build will have an SVN step that
-concatenates "svn://svn.example.org/MyProject/" (the baseURL) with
-"trunk" (the branch name) to get the correct svn command. If the
-"newthing" branch has a change to "src/foo.c", then the SVN step will
-concatenate "svn://svn.example.org/MyProject/" with
-"features/newthing" to get the svnurl for checkout.
-
-
-File: buildbot.info, Node: Darcs, Next: Mercurial, Prev: SVN, Up: Source Checkout
-
-6.1.3.3 Darcs
-.............
-
-The `Darcs' build step performs a Darcs (http://darcs.net/) checkout
-or update.
-
- Like *Note SVN::, this step can either be configured to always
-check out a specific tree, or set up to pull from a particular branch
-that gets specified separately for each build. Also like SVN, the
-repository URL given to Darcs is created by concatenating a `baseURL'
-with the branch name, and if no particular branch is requested, it
-uses a `defaultBranch'. The only difference in usage is that each
-potential Darcs repository URL must point to a fully-fledged
-repository, whereas SVN URLs usually point to sub-trees of the main
-Subversion repository. In other words, doing an SVN checkout of
-`baseURL' is legal, but silly, since you'd probably wind up with a
-copy of every single branch in the whole repository. Doing a Darcs
-checkout of `baseURL' is just plain wrong, since the parent directory
-of a collection of Darcs repositories is not itself a valid
-repository.
-
- The Darcs step takes the following arguments:
-
-`repourl'
- (required unless `baseURL' is provided): the URL at which the
- Darcs source repository is available.
-
-`baseURL'
- (required unless `repourl' is provided): the base repository URL,
- to which a branch name will be appended. It should probably end
- in a slash.
-
-`defaultBranch'
- (allowed if and only if `baseURL' is provided): this specifies
- the name of the branch to use when a Build does not provide one
- of its own. This will be appended to `baseURL' to create the
- string that will be passed to the `darcs get' command.
-
-
-File: buildbot.info, Node: Mercurial, Next: Arch, Prev: Darcs, Up: Source Checkout
-
-6.1.3.4 Mercurial
-.................
-
-The `Mercurial' build step performs a Mercurial
-(http://selenic.com/mercurial) (aka "hg") checkout or update.
-
- Branches are handled just like *Note Darcs::.
-
- The Mercurial step takes the following arguments:
-
-`repourl'
- (required unless `baseURL' is provided): the URL at which the
- Mercurial source repository is available.
-
-`baseURL'
- (required unless `repourl' is provided): the base repository URL,
- to which a branch name will be appended. It should probably end
- in a slash.
-
-`defaultBranch'
- (allowed if and only if `baseURL' is provided): this specifies
- the name of the branch to use when a Build does not provide one
- of its own. This will be appended to `baseURL' to create the
- string that will be passed to the `hg clone' command.
-
-
-File: buildbot.info, Node: Arch, Next: Bazaar, Prev: Mercurial, Up: Source Checkout
-
-6.1.3.5 Arch
-............
-
-The `Arch' build step performs an Arch (http://gnuarch.org/) checkout
-or update using the `tla' client. It takes the following arguments:
-
-`url'
- (required): this specifies the URL at which the Arch source
- archive is available.
-
-`version'
- (required): this specifies which "development line" (like a
- branch) should be used. This provides the default branch name,
- but individual builds may specify a different one.
-
-`archive'
- (optional): Each repository knows its own archive name. If this
- parameter is provided, it must match the repository's archive
- name. The parameter is accepted for compatibility with the
- `Bazaar' step, below.
-
-
-
-File: buildbot.info, Node: Bazaar, Next: Bzr, Prev: Arch, Up: Source Checkout
-
-6.1.3.6 Bazaar
-..............
-
-`Bazaar' is an alternate implementation of the Arch VC system, which
-uses a client named `baz'. The checkout semantics are just different
-enough from `tla' that there is a separate BuildStep for it.
-
- It takes exactly the same arguments as `Arch', except that the
-`archive=' parameter is required. (baz does not emit the archive name
-when you do `baz register-archive', so we must provide it ourselves).
-
-
-File: buildbot.info, Node: Bzr, Next: P4, Prev: Bazaar, Up: Source Checkout
-
-6.1.3.7 Bzr
-...........
-
-`bzr' is a descendant of Arch/Baz, and is frequently referred to as
-simply "Bazaar". The repository-vs-workspace model is similar to
-Darcs, but it uses a strictly linear sequence of revisions (one
-history per branch) like Arch. Branches are put in subdirectories.
-This makes it look very much like Mercurial, so it takes the same
-arguments:
-
-`repourl'
- (required unless `baseURL' is provided): the URL at which the
- Bzr source repository is available.
-
-`baseURL'
- (required unless `repourl' is provided): the base repository URL,
- to which a branch name will be appended. It should probably end
- in a slash.
-
-`defaultBranch'
- (allowed if and only if `baseURL' is provided): this specifies
- the name of the branch to use when a Build does not provide one
- of its own. This will be appended to `baseURL' to create the
- string that will be passed to the `bzr checkout' command.
-
-
-File: buildbot.info, Node: P4, Next: Git, Prev: Bzr, Up: Source Checkout
-
-6.1.3.8 P4
-..........
-
-The `P4' build step creates a Perforce (http://www.perforce.com/)
-client specification and performs an update.
-
-`p4base'
- A view into the Perforce depot without branch name or trailing
- "...". Typically "//depot/proj/".
-
-`defaultBranch'
- A branch name to append on build requests if none is specified.
- Typically "trunk".
-
-`p4port'
- (optional): the host:port string describing how to get to the P4
- Depot (repository), used as the -p argument for all p4 commands.
-
-`p4user'
- (optional): the Perforce user, used as the -u argument to all p4
- commands.
-
-`p4passwd'
- (optional): the Perforce password, used as the -p argument to
- all p4 commands.
-
-`p4extra_views'
- (optional): a list of (depotpath, clientpath) tuples containing
- extra views to be mapped into the client specification. Both
- will have "/..." appended automatically. The client name and
- source directory will be prepended to the client path.
-
-`p4client'
- (optional): The name of the client to use. In mode='copy' and
- mode='update', it's particularly important that a unique name is
- used for each checkout directory to avoid incorrect
- synchronization. For this reason, Python percent substitution
- will be performed on this value to replace %(slave)s with the
- slave name and %(builder)s with the builder name. The default is
- "buildbot_%(slave)s_%(build)s".
-
-
-File: buildbot.info, Node: Git, Prev: P4, Up: Source Checkout
-
-6.1.3.9 Git
-...........
-
-The `Git' build step clones or updates a Git (http://git.or.cz/)
-repository and checks out the specified branch or revision. Note that
-the buildbot supports Git version 1.2.0 and later: earlier versions
-(such as the one shipped in Ubuntu 'Dapper') do not support the `git
-init' command that the buildbot uses.
-
- The Git step takes the following arguments:
-
-`repourl'
- (required): the URL of the upstream Git repository.
-
-`branch'
- (optional): this specifies the name of the branch to use when a
- Build does not provide one of its own. If this this parameter is
- not specified, and the Build does not provide a branch, the
- "master" branch will be used.
-
-
-File: buildbot.info, Node: ShellCommand, Next: Simple ShellCommand Subclasses, Prev: Source Checkout, Up: Build Steps
-
-6.1.4 ShellCommand
-------------------
-
-This is a useful base class for just about everything you might want
-to do during a build (except for the initial source checkout). It runs
-a single command in a child shell on the buildslave. All stdout/stderr
-is recorded into a LogFile. The step finishes with a status of FAILURE
-if the command's exit code is non-zero, otherwise it has a status of
-SUCCESS.
-
- The preferred way to specify the command is with a list of argv
-strings, since this allows for spaces in filenames and avoids doing
-any fragile shell-escaping. You can also specify the command with a
-single string, in which case the string is given to '/bin/sh -c
-COMMAND' for parsing.
-
- On Windows, commands are run via `cmd.exe /c' which works well.
-However, if you're running a batch file, the error level does not get
-propagated correctly unless you add 'call' before your batch file's
-name: `cmd=['call', 'myfile.bat', ...]'.
-
- All ShellCommands are run by default in the "workdir", which
-defaults to the "`build'" subdirectory of the slave builder's base
-directory. The absolute path of the workdir will thus be the slave's
-basedir (set as an option to `buildbot create-slave', *note Creating
-a buildslave::) plus the builder's basedir (set in the builder's
-`c['builddir']' key in master.cfg) plus the workdir itself (a
-class-level attribute of the BuildFactory, defaults to "`build'").
-
- `ShellCommand' arguments:
-
-`command'
- a list of strings (preferred) or single string (discouraged)
- which specifies the command to be run. A list of strings is
- preferred because it can be used directly as an argv array.
- Using a single string (with embedded spaces) requires the
- buildslave to pass the string to /bin/sh for interpretation,
- which raises all sorts of difficult questions about how to
- escape or interpret shell metacharacters.
-
-`env'
- a dictionary of environment strings which will be added to the
- child command's environment. For example, to run tests with a
- different i18n language setting, you might use
-
- f.addStep(ShellCommand(command=["make", "test"],
- env={'LANG': 'fr_FR'}))
-
- These variable settings will override any existing ones in the
- buildslave's environment or the environment specified in the
- Builder. The exception is PYTHONPATH, which is merged with
- (actually prepended to) any existing $PYTHONPATH setting. The
- value is treated as a list of directories to prepend, and a
- single string is treated like a one-item list. For example, to
- prepend both `/usr/local/lib/python2.3' and
- `/home/buildbot/lib/python' to any existing $PYTHONPATH setting,
- you would do something like the following:
-
- f.addStep(ShellCommand(
- command=["make", "test"],
- env={'PYTHONPATH': ["/usr/local/lib/python2.3",
- "/home/buildbot/lib/python"] }))
-
-`want_stdout'
- if False, stdout from the child process is discarded rather than
- being sent to the buildmaster for inclusion in the step's
- LogFile.
-
-`want_stderr'
- like `want_stdout' but for stderr. Note that commands run through
- a PTY do not have separate stdout/stderr streams: both are
- merged into stdout.
-
-`usePTY'
- Should this command be run in a `pty'? The default is to
- observe the configuration of the client (*note Buildslave
- Options::), but specifying `True' or `False' here will override
- the default.
-
- The advantage of using a PTY is that "grandchild" processes are
- more likely to be cleaned up if the build is interrupted or
- times out (since it enables the use of a "process group" in
- which all child processes will be placed). The disadvantages:
- some forms of Unix have problems with PTYs, some of your unit
- tests may behave differently when run under a PTY (generally
- those which check to see if they are being run interactively),
- and PTYs will merge the stdout and stderr streams into a single
- output stream (which means the red-vs-black coloring in the
- logfiles will be lost).
-
-`logfiles'
- Sometimes commands will log interesting data to a local file,
- rather than emitting everything to stdout or stderr. For
- example, Twisted's "trial" command (which runs unit tests) only
- presents summary information to stdout, and puts the rest into a
- file named `_trial_temp/test.log'. It is often useful to watch
- these files as the command runs, rather than using `/bin/cat' to
- dump their contents afterwards.
-
- The `logfiles=' argument allows you to collect data from these
- secondary logfiles in near-real-time, as the step is running. It
- accepts a dictionary which maps from a local Log name (which is
- how the log data is presented in the build results) to a remote
- filename (interpreted relative to the build's working
- directory). Each named file will be polled on a regular basis
- (every couple of seconds) as the build runs, and any new text
- will be sent over to the buildmaster.
-
- f.addStep(ShellCommand(
- command=["make", "test"],
- logfiles={"triallog": "_trial_temp/test.log"}))
-
-`timeout'
- if the command fails to produce any output for this many
- seconds, it is assumed to be locked up and will be killed.
-
-`description'
- This will be used to describe the command (on the Waterfall
- display) while the command is still running. It should be a
- single imperfect-tense verb, like "compiling" or "testing". The
- preferred form is a list of short strings, which allows the HTML
- Waterfall display to create narrower columns by emitting a <br>
- tag between each word. You may also provide a single string.
-
-`descriptionDone'
- This will be used to describe the command once it has finished. A
- simple noun like "compile" or "tests" should be used. Like
- `description', this may either be a list of short strings or a
- single string.
-
- If neither `description' nor `descriptionDone' are set, the
- actual command arguments will be used to construct the
- description. This may be a bit too wide to fit comfortably on
- the Waterfall display.
-
- f.addStep(ShellCommand(command=["make", "test"],
- description=["testing"],
- descriptionDone=["tests"]))
-
-`logEnviron'
- If this option is true (the default), then the step's logfile
- will describe the environment variables on the slave. In
- situations where the environment is not relevant and is long, it
- may be easier to set `logEnviron=False'.
-
-
-
-File: buildbot.info, Node: Simple ShellCommand Subclasses, Next: Python BuildSteps, Prev: ShellCommand, Up: Build Steps
-
-6.1.5 Simple ShellCommand Subclasses
-------------------------------------
-
-Several subclasses of ShellCommand are provided as starting points for
-common build steps. These are all very simple: they just override a
-few parameters so you don't have to specify them yourself, making the
-master.cfg file less verbose.
-
-* Menu:
-
-* Configure::
-* Compile::
-* Test::
-* TreeSize::
-* PerlModuleTest::
-* SetProperty::
-
-
-File: buildbot.info, Node: Configure, Next: Compile, Prev: Simple ShellCommand Subclasses, Up: Simple ShellCommand Subclasses
-
-6.1.5.1 Configure
-.................
-
-This is intended to handle the `./configure' step from autoconf-style
-projects, or the `perl Makefile.PL' step from perl MakeMaker.pm-style
-modules. The default command is `./configure' but you can change this
-by providing a `command=' parameter.
-
-
-File: buildbot.info, Node: Compile, Next: Test, Prev: Configure, Up: Simple ShellCommand Subclasses
-
-6.1.5.2 Compile
-...............
-
-This is meant to handle compiling or building a project written in C.
-The default command is `make all'. When the compile is finished, the
-log file is scanned for GCC warning messages, a summary log is
-created with any problems that were seen, and the step is marked as
-WARNINGS if any were discovered. The number of warnings is stored in a
-Build Property named "warnings-count", which is accumulated over all
-Compile steps (so if two warnings are found in one step, and three are
-found in another step, the overall build will have a "warnings-count"
-property of 5.
-
- The default regular expression used to detect a warning is
-`'.*warning[: ].*'' , which is fairly liberal and may cause
-false-positives. To use a different regexp, provide a
-`warningPattern=' argument, or use a subclass which sets the
-`warningPattern' attribute:
-
- f.addStep(Compile(command=["make", "test"],
- warningPattern="^Warning: "))
-
- The `warningPattern=' can also be a pre-compiled python regexp
-object: this makes it possible to add flags like `re.I' (to use
-case-insensitive matching).
-
- (TODO: this step needs to be extended to look for GCC error
-messages as well, and collect them into a separate logfile, along
-with the source code filenames involved).
-
-
-File: buildbot.info, Node: Test, Next: TreeSize, Prev: Compile, Up: Simple ShellCommand Subclasses
-
-6.1.5.3 Test
-............
-
-This is meant to handle unit tests. The default command is `make
-test', and the `warnOnFailure' flag is set.
-
-
-File: buildbot.info, Node: TreeSize, Next: PerlModuleTest, Prev: Test, Up: Simple ShellCommand Subclasses
-
-6.1.5.4 TreeSize
-................
-
-This is a simple command that uses the 'du' tool to measure the size
-of the code tree. It puts the size (as a count of 1024-byte blocks,
-aka 'KiB' or 'kibibytes') on the step's status text, and sets a build
-property named 'tree-size-KiB' with the same value.
-
-
-File: buildbot.info, Node: PerlModuleTest, Next: SetProperty, Prev: TreeSize, Up: Simple ShellCommand Subclasses
-
-6.1.5.5 PerlModuleTest
-......................
-
-This is a simple command that knows how to run tests of perl modules.
-It parses the output to determine the number of tests passed and
-failed and total number executed, saving the results for later query.
-
-
-File: buildbot.info, Node: SetProperty, Prev: PerlModuleTest, Up: Simple ShellCommand Subclasses
-
-6.1.5.6 SetProperty
-...................
-
-This buildstep is similar to ShellCommand, except that it captures the
-output of the command into a property. It is usually used like this:
-
- f.addStep(SetProperty(command="uname -a", property="uname"))
-
- This runs `uname -a' and captures its stdout, stripped of leading
-and trailing whitespace, in the property "uname". To avoid stripping,
-add `strip=False'. The `property' argument can be specified as a
-`WithProperties' object.
-
- The more advanced usage allows you to specify a function to extract
-properties from the command output. Here you can use regular
-expressions, string interpolation, or whatever you would like. The
-function is called with three arguments: the exit status of the
-command, its standard output as a string, and its standard error as a
-string. It should return a dictionary containing all new properties.
-
- def glob2list(rc, stdout, stderr):
- jpgs = [ l.strip() for l in stdout.split('\n') ]
- return { 'jpgs' : jpgs }
- f.addStep(SetProperty(command="ls -1 *.jpg", extract_fn=glob2list))
-
- Note that any ordering relationship of the contents of stdout and
-stderr is lost. For example, given
-
- f.addStep(SetProperty(
- command="echo output1; echo error >&2; echo output2",
- extract_fn=my_extract))
-
- Then `my_extract' will see `stdout="output1\noutput2\n"' and
-`stderr="error\n"'.
-
-
-File: buildbot.info, Node: Python BuildSteps, Next: Transferring Files, Prev: Simple ShellCommand Subclasses, Up: Build Steps
-
-6.1.6 Python BuildSteps
------------------------
-
-Here are some BuildSteps that are specifcally useful for projects
-implemented in Python.
-
-* Menu:
-
-* BuildEPYDoc::
-* PyFlakes::
-* PyLint::
-
-
-File: buildbot.info, Node: BuildEPYDoc, Next: PyFlakes, Up: Python BuildSteps
-
-6.1.6.1 BuildEPYDoc
-...................
-
-epydoc (http://epydoc.sourceforge.net/) is a tool for generating API
-documentation for Python modules from their docstrings. It reads all
-the .py files from your source tree, processes the docstrings
-therein, and creates a large tree of .html files (or a single .pdf
-file).
-
- The `buildbot.steps.python.BuildEPYDoc' step will run `epydoc' to
-produce this API documentation, and will count the errors and
-warnings from its output.
-
- You must supply the command line to be used. The default is `make
-epydocs', which assumes that your project has a Makefile with an
-"epydocs" target. You might wish to use something like `epydoc -o
-apiref source/PKGNAME' instead. You might also want to add `--pdf' to
-generate a PDF file instead of a large tree of HTML files.
-
- The API docs are generated in-place in the build tree (under the
-workdir, in the subdirectory controlled by the "-o" argument). To
-make them useful, you will probably have to copy them to somewhere
-they can be read. A command like `rsync -ad apiref/
-dev.example.com:~public_html/current-apiref/' might be useful. You
-might instead want to bundle them into a tarball and publish it in the
-same place where the generated install tarball is placed.
-
- from buildbot.steps.python import BuildEPYDoc
-
- ...
- f.addStep(BuildEPYDoc(command=["epydoc", "-o", "apiref", "source/mypkg"]))
-
-
-File: buildbot.info, Node: PyFlakes, Next: PyLint, Prev: BuildEPYDoc, Up: Python BuildSteps
-
-6.1.6.2 PyFlakes
-................
-
-PyFlakes (http://divmod.org/trac/wiki/DivmodPyflakes) is a tool to
-perform basic static analysis of Python code to look for simple
-errors, like missing imports and references of undefined names. It is
-like a fast and simple form of the C "lint" program. Other tools
-(like pychecker) provide more detailed results but take longer to run.
-
- The `buildbot.steps.python.PyFlakes' step will run pyflakes and
-count the various kinds of errors and warnings it detects.
-
- You must supply the command line to be used. The default is `make
-pyflakes', which assumes you have a top-level Makefile with a
-"pyflakes" target. You might want to use something like `pyflakes .'
-or `pyflakes src'.
-
- from buildbot.steps.python import PyFlakes
-
- ...
- f.addStep(PyFlakes(command=["pyflakes", "src"]))
-
-
-File: buildbot.info, Node: PyLint, Prev: PyFlakes, Up: Python BuildSteps
-
-6.1.6.3 PyLint
-..............
-
-Similarly, the `buildbot.steps.python.PyLint' step will run pylint and
-analyze the results.
-
- You must supply the command line to be used. There is no default.
-
- from buildbot.steps.python import PyLint
-
- ...
- f.addStep(PyLint(command=["pylint", "src"]))
-
-
-File: buildbot.info, Node: Transferring Files, Next: Steps That Run on the Master, Prev: Python BuildSteps, Up: Build Steps
-
-6.1.7 Transferring Files
-------------------------
-
-Most of the work involved in a build will take place on the
-buildslave. But occasionally it is useful to do some work on the
-buildmaster side. The most basic way to involve the buildmaster is
-simply to move a file from the slave to the master, or vice versa.
-There are a pair of BuildSteps named `FileUpload' and `FileDownload'
-to provide this functionality. `FileUpload' moves a file _up to_ the
-master, while `FileDownload' moves a file _down from_ the master.
-
- As an example, let's assume that there is a step which produces an
-HTML file within the source tree that contains some sort of generated
-project documentation. We want to move this file to the buildmaster,
-into a `~/public_html' directory, so it can be visible to developers.
-This file will wind up in the slave-side working directory under the
-name `docs/reference.html'. We want to put it into the master-side
-`~/public_html/ref.html'.
-
- from buildbot.steps.shell import ShellCommand
- from buildbot.steps.transfer import FileUpload
-
- f.addStep(ShellCommand(command=["make", "docs"]))
- f.addStep(FileUpload(slavesrc="docs/reference.html",
- masterdest="~/public_html/ref.html"))
-
- The `masterdest=' argument will be passed to os.path.expanduser,
-so things like "~" will be expanded properly. Non-absolute paths will
-be interpreted relative to the buildmaster's base directory.
-Likewise, the `slavesrc=' argument will be expanded and interpreted
-relative to the builder's working directory.
-
- To move a file from the master to the slave, use the
-`FileDownload' command. For example, let's assume that some step
-requires a configuration file that, for whatever reason, could not be
-recorded in the source code repository or generated on the buildslave
-side:
-
- from buildbot.steps.shell import ShellCommand
- from buildbot.steps.transfer import FileUpload
-
- f.addStep(FileDownload(mastersrc="~/todays_build_config.txt",
- slavedest="build_config.txt"))
- f.addStep(ShellCommand(command=["make", "config"]))
-
- Like `FileUpload', the `mastersrc=' argument is interpreted
-relative to the buildmaster's base directory, and the `slavedest='
-argument is relative to the builder's working directory. If the
-buildslave is running in `~buildslave', and the builder's "builddir"
-is something like `tests-i386', then the workdir is going to be
-`~buildslave/tests-i386/build', and a `slavedest=' of `foo/bar.html'
-will get put in `~buildslave/tests-i386/build/foo/bar.html'. Both of
-these commands will create any missing intervening directories.
-
-Other Parameters
-----------------
-
-The `maxsize=' argument lets you set a maximum size for the file to
-be transferred. This may help to avoid surprises: transferring a
-100MB coredump when you were expecting to move a 10kB status file
-might take an awfully long time. The `blocksize=' argument controls
-how the file is sent over the network: larger blocksizes are slightly
-more efficient but also consume more memory on each end, and there is
-a hard-coded limit of about 640kB.
-
- The `mode=' argument allows you to control the access permissions
-of the target file, traditionally expressed as an octal integer. The
-most common value is probably 0755, which sets the "x" executable bit
-on the file (useful for shell scripts and the like). The default
-value for `mode=' is None, which means the permission bits will
-default to whatever the umask of the writing process is. The default
-umask tends to be fairly restrictive, but at least on the buildslave
-you can make it less restrictive with a -umask command-line option at
-creation time (*note Buildslave Options::).
-
-Transfering Directories
------------------------
-
-To transfer complete directories from the buildslave to the master,
-there is a BuildStep named `DirectoryUpload'. It works like
-`FileUpload', just for directories. However it does not support the
-`maxsize', `blocksize' and `mode' arguments. As an example, let's
-assume an generated project documentation, which consists of many
-files (like the output of doxygen or epydoc). We want to move the
-entire documentation to the buildmaster, into a `~/public_html/docs'
-directory. On the slave-side the directory can be found under `docs':
-
- from buildbot.steps.shell import ShellCommand
- from buildbot.steps.transfer import DirectoryUpload
-
- f.addStep(ShellCommand(command=["make", "docs"]))
- f.addStep(DirectoryUpload(slavesrc="docs",
- masterdest="~/public_html/docs"))
-
- The DirectoryUpload step will create all necessary directories and
-transfers empty directories, too.
-
-
-File: buildbot.info, Node: Steps That Run on the Master, Next: Triggering Schedulers, Prev: Transferring Files, Up: Build Steps
-
-6.1.8 Steps That Run on the Master
-----------------------------------
-
-Occasionally, it is useful to execute some task on the master, for
-example to create a directory, deploy a build result, or trigger some
-other centralized processing. This is possible, in a limited
-fashion, with the `MasterShellCommand' step.
-
- This step operates similarly to a regular `ShellCommand', but
-executes on the master, instead of the slave. To be clear, the
-enclosing `Build' object must still have a slave object, just as for
-any other step - only, in this step, the slave does not do anything.
-
- In this example, the step renames a tarball based on the day of
-the week.
-
- from buildbot.steps.transfer import FileUpload
- from buildbot.steps.master import MasterShellCommand
-
- f.addStep(FileUpload(slavesrc="widgetsoft.tar.gz",
- masterdest="/var/buildoutputs/widgetsoft-new.tar.gz"))
- f.addStep(MasterShellCommand(command="""
- cd /var/buildoutputs;
- mv widgetsoft-new.tar.gz widgetsoft-`date +%a`.tar.gz"""))
-
-
-File: buildbot.info, Node: Triggering Schedulers, Next: Writing New BuildSteps, Prev: Steps That Run on the Master, Up: Build Steps
-
-6.1.9 Triggering Schedulers
----------------------------
-
-The counterpart to the Triggerable described in section *note
-Triggerable Scheduler:: is the Trigger BuildStep.
-
- from buildbot.steps.trigger import Trigger
- f.addStep(Trigger(schedulerNames=['build-prep'],
- waitForFinish=True,
- updateSourceStamp=True))
-
- The `schedulerNames=' argument lists the Triggerables that should
-be triggered when this step is executed. Note that it is possible,
-but not advisable, to create a cycle where a build continually
-triggers itself, because the schedulers are specified by name.
-
- If `waitForFinish' is True, then the step will not finish until
-all of the builds from the triggered schedulers have finished. If this
-argument is False (the default) or not given, then the buildstep
-succeeds immediately after triggering the schedulers.
-
- If `updateSourceStamp' is True (the default), then step updates
-the SourceStamp given to the Triggerables to include `got_revision'
-(the revision actually used in this build) as `revision' (the
-revision to use in the triggered builds). This is useful to ensure
-that all of the builds use exactly the same SourceStamp, even if
-other Changes have occurred while the build was running.
-
-
-File: buildbot.info, Node: Writing New BuildSteps, Prev: Triggering Schedulers, Up: Build Steps
-
-6.1.10 Writing New BuildSteps
------------------------------
-
-While it is a good idea to keep your build process self-contained in
-the source code tree, sometimes it is convenient to put more
-intelligence into your Buildbot configuration. One way to do this is
-to write a custom BuildStep. Once written, this Step can be used in
-the `master.cfg' file.
-
- The best reason for writing a custom BuildStep is to better parse
-the results of the command being run. For example, a BuildStep that
-knows about JUnit could look at the logfiles to determine which tests
-had been run, how many passed and how many failed, and then report
-more detailed information than a simple `rc==0' -based "good/bad"
-decision.
-
-* Menu:
-
-* Writing BuildStep Constructors::
-* BuildStep LogFiles::
-* Reading Logfiles::
-* Adding LogObservers::
-* BuildStep URLs::
-
-
-File: buildbot.info, Node: Writing BuildStep Constructors, Next: BuildStep LogFiles, Up: Writing New BuildSteps
-
-6.1.10.1 Writing BuildStep Constructors
-.......................................
-
-BuildStep classes have some extra equipment, because they are their
-own factories. Consider the use of a BuildStep in `master.cfg':
-
- f.addStep(MyStep(someopt="stuff", anotheropt=1))
-
- This creates a single instance of class `MyStep'. However,
-Buildbot needs a new object each time the step is executed. this is
-accomplished by storing the information required to instantiate a new
-object in the `factory' attribute. When the time comes to construct
-a new Build, BuildFactory consults this attribute (via
-`getStepFactory') and instantiates a new step object.
-
- When writing a new step class, then, keep in mind are that you
-cannot do anything "interesting" in the constructor - limit yourself
-to checking and storing arguments. To ensure that these arguments
-are provided to any new objects, call `self.addFactoryArguments' with
-any keyword arguments your constructor needs.
-
- Keep a `**kwargs' argument on the end of your options, and pass
-that up to the parent class's constructor.
-
- The whole thing looks like this:
-
- class Frobinfy(LoggingBuildStep):
- def __init__(self,
- frob_what="frobee",
- frob_how_many=None,
- frob_how=None,
- **kwargs)
-
- # check
- if frob_how_many is None:
- raise TypeError("Frobinfy argument how_many is required")
-
- # call parent
- LoggingBuildStep.__init__(self, **kwargs)
-
- # and record arguments for later
- self.addFactoryArguments(
- frob_what=frob_what,
- frob_how_many=frob_how_many,
- frob_how=frob_how)
-
- class FastFrobnify(Frobnify):
- def __init__(self,
- speed=5,
- **kwargs)
- Frobnify.__init__(self, **kwargs)
- self.addFactoryArguments(
- speed=speed)
-
-
-File: buildbot.info, Node: BuildStep LogFiles, Next: Reading Logfiles, Prev: Writing BuildStep Constructors, Up: Writing New BuildSteps
-
-6.1.10.2 BuildStep LogFiles
-...........................
-
-Each BuildStep has a collection of "logfiles". Each one has a short
-name, like "stdio" or "warnings". Each LogFile contains an arbitrary
-amount of text, usually the contents of some output file generated
-during a build or test step, or a record of everything that was
-printed to stdout/stderr during the execution of some command.
-
- These LogFiles are stored to disk, so they can be retrieved later.
-
- Each can contain multiple "channels", generally limited to three
-basic ones: stdout, stderr, and "headers". For example, when a
-ShellCommand runs, it writes a few lines to the "headers" channel to
-indicate the exact argv strings being run, which directory the command
-is being executed in, and the contents of the current environment
-variables. Then, as the command runs, it adds a lot of "stdout" and
-"stderr" messages. When the command finishes, a final "header" line
-is added with the exit code of the process.
-
- Status display plugins can format these different channels in
-different ways. For example, the web page shows LogFiles as text/html,
-with header lines in blue text, stdout in black, and stderr in red. A
-different URL is available which provides a text/plain format, in
-which stdout and stderr are collapsed together, and header lines are
-stripped completely. This latter option makes it easy to save the
-results to a file and run `grep' or whatever against the output.
-
- Each BuildStep contains a mapping (implemented in a python
-dictionary) from LogFile name to the actual LogFile objects. Status
-plugins can get a list of LogFiles to display, for example, a list of
-HREF links that, when clicked, provide the full contents of the
-LogFile.
-
-Using LogFiles in custom BuildSteps
-===================================
-
-The most common way for a custom BuildStep to use a LogFile is to
-summarize the results of a ShellCommand (after the command has
-finished running). For example, a compile step with thousands of lines
-of output might want to create a summary of just the warning messages.
-If you were doing this from a shell, you would use something like:
-
- grep "warning:" output.log >warnings.log
-
- In a custom BuildStep, you could instead create a "warnings"
-LogFile that contained the same text. To do this, you would add code
-to your `createSummary' method that pulls lines from the main output
-log and creates a new LogFile with the results:
-
- def createSummary(self, log):
- warnings = []
- for line in log.readlines():
- if "warning:" in line:
- warnings.append()
- self.addCompleteLog('warnings', "".join(warnings))
-
- This example uses the `addCompleteLog' method, which creates a new
-LogFile, puts some text in it, and then "closes" it, meaning that no
-further contents will be added. This LogFile will appear in the HTML
-display under an HREF with the name "warnings", since that is the
-name of the LogFile.
-
- You can also use `addHTMLLog' to create a complete (closed)
-LogFile that contains HTML instead of plain text. The normal LogFile
-will be HTML-escaped if presented through a web page, but the HTML
-LogFile will not. At the moment this is only used to present a pretty
-HTML representation of an otherwise ugly exception traceback when
-something goes badly wrong during the BuildStep.
-
- In contrast, you might want to create a new LogFile at the
-beginning of the step, and add text to it as the command runs. You
-can create the LogFile and attach it to the build by calling
-`addLog', which returns the LogFile object. You then add text to this
-LogFile by calling methods like `addStdout' and `addHeader'. When you
-are done, you must call the `finish' method so the LogFile can be
-closed. It may be useful to create and populate a LogFile like this
-from a LogObserver method *Note Adding LogObservers::.
-
- The `logfiles=' argument to `ShellCommand' (see *note
-ShellCommand::) creates new LogFiles and fills them in realtime by
-asking the buildslave to watch a actual file on disk. The buildslave
-will look for additions in the target file and report them back to
-the BuildStep. These additions will be added to the LogFile by
-calling `addStdout'. These secondary LogFiles can be used as the
-source of a LogObserver just like the normal "stdio" LogFile.
-
-
-File: buildbot.info, Node: Reading Logfiles, Next: Adding LogObservers, Prev: BuildStep LogFiles, Up: Writing New BuildSteps
-
-6.1.10.3 Reading Logfiles
-.........................
-
-Once a LogFile has been added to a BuildStep with `addLog()',
-`addCompleteLog()', `addHTMLLog()', or `logfiles=', your BuildStep
-can retrieve it by using `getLog()':
-
- class MyBuildStep(ShellCommand):
- logfiles = { "nodelog": "_test/node.log" }
-
- def evaluateCommand(self, cmd):
- nodelog = self.getLog("nodelog")
- if "STARTED" in nodelog.getText():
- return SUCCESS
- else:
- return FAILURE
-
- For a complete list of the methods you can call on a LogFile,
-please see the docstrings on the `IStatusLog' class in
-`buildbot/interfaces.py'.
-
-
-File: buildbot.info, Node: Adding LogObservers, Next: BuildStep URLs, Prev: Reading Logfiles, Up: Writing New BuildSteps
-
-6.1.10.4 Adding LogObservers
-............................
-
-Most shell commands emit messages to stdout or stderr as they operate,
-especially if you ask them nicely with a `--verbose' flag of some
-sort. They may also write text to a log file while they run. Your
-BuildStep can watch this output as it arrives, to keep track of how
-much progress the command has made. You can get a better measure of
-progress by counting the number of source files compiled or test cases
-run than by merely tracking the number of bytes that have been written
-to stdout. This improves the accuracy and the smoothness of the ETA
-display.
-
- To accomplish this, you will need to attach a `LogObserver' to one
-of the log channels, most commonly to the "stdio" channel but perhaps
-to another one which tracks a log file. This observer is given all
-text as it is emitted from the command, and has the opportunity to
-parse that output incrementally. Once the observer has decided that
-some event has occurred (like a source file being compiled), it can
-use the `setProgress' method to tell the BuildStep about the progress
-that this event represents.
-
- There are a number of pre-built `LogObserver' classes that you can
-choose from (defined in `buildbot.process.buildstep', and of course
-you can subclass them to add further customization. The
-`LogLineObserver' class handles the grunt work of buffering and
-scanning for end-of-line delimiters, allowing your parser to operate
-on complete stdout/stderr lines. (Lines longer than a set maximum
-length are dropped; the maximum defaults to 16384 bytes, but you can
-change it by calling `setMaxLineLength()' on your `LogLineObserver'
-instance. Use `sys.maxint' for effective infinity.)
-
- For example, let's take a look at the `TrialTestCaseCounter',
-which is used by the Trial step to count test cases as they are run.
-As Trial executes, it emits lines like the following:
-
- buildbot.test.test_config.ConfigTest.testDebugPassword ... [OK]
- buildbot.test.test_config.ConfigTest.testEmpty ... [OK]
- buildbot.test.test_config.ConfigTest.testIRC ... [FAIL]
- buildbot.test.test_config.ConfigTest.testLocks ... [OK]
-
- When the tests are finished, trial emits a long line of "======"
-and then some lines which summarize the tests that failed. We want to
-avoid parsing these trailing lines, because their format is less
-well-defined than the "[OK]" lines.
-
- The parser class looks like this:
-
- from buildbot.process.buildstep import LogLineObserver
-
- class TrialTestCaseCounter(LogLineObserver):
- _line_re = re.compile(r'^([\w\.]+) \.\.\. \[([^\]]+)\]$')
- numTests = 0
- finished = False
-
- def outLineReceived(self, line):
- if self.finished:
- return
- if line.startswith("=" * 40):
- self.finished = True
- return
-
- m = self._line_re.search(line.strip())
- if m:
- testname, result = m.groups()
- self.numTests += 1
- self.step.setProgress('tests', self.numTests)
-
- This parser only pays attention to stdout, since that's where trial
-writes the progress lines. It has a mode flag named `finished' to
-ignore everything after the "====" marker, and a scary-looking
-regular expression to match each line while hopefully ignoring other
-messages that might get displayed as the test runs.
-
- Each time it identifies a test has been completed, it increments
-its counter and delivers the new progress value to the step with
-`self.step.setProgress'. This class is specifically measuring
-progress along the "tests" metric, in units of test cases (as opposed
-to other kinds of progress like the "output" metric, which measures
-in units of bytes). The Progress-tracking code uses each progress
-metric separately to come up with an overall completion percentage
-and an ETA value.
-
- To connect this parser into the `Trial' BuildStep,
-`Trial.__init__' ends with the following clause:
-
- # this counter will feed Progress along the 'test cases' metric
- counter = TrialTestCaseCounter()
- self.addLogObserver('stdio', counter)
- self.progressMetrics += ('tests',)
-
- This creates a TrialTestCaseCounter and tells the step that the
-counter wants to watch the "stdio" log. The observer is automatically
-given a reference to the step in its `.step' attribute.
-
-A Somewhat Whimsical Example
-----------------------------
-
-Let's say that we've got some snazzy new unit-test framework called
-Framboozle. It's the hottest thing since sliced bread. It slices, it
-dices, it runs unit tests like there's no tomorrow. Plus if your unit
-tests fail, you can use its name for a Web 2.1 startup company, make
-millions of dollars, and hire engineers to fix the bugs for you, while
-you spend your afternoons lazily hang-gliding along a scenic pacific
-beach, blissfully unconcerned about the state of your tests.(1)
-
- To run a Framboozle-enabled test suite, you just run the
-'framboozler' command from the top of your source code tree. The
-'framboozler' command emits a bunch of stuff to stdout, but the most
-interesting bit is that it emits the line "FNURRRGH!" every time it
-finishes running a test case(2). You'd like to have a test-case
-counting LogObserver that watches for these lines and counts them,
-because counting them will help the buildbot more accurately
-calculate how long the build will take, and this will let you know
-exactly how long you can sneak out of the office for your
-hang-gliding lessons without anyone noticing that you're gone.
-
- This will involve writing a new BuildStep (probably named
-"Framboozle") which inherits from ShellCommand. The BuildStep class
-definition itself will look something like this:
-
- # START
- from buildbot.steps.shell import ShellCommand
- from buildbot.process.buildstep import LogLineObserver
-
- class FNURRRGHCounter(LogLineObserver):
- numTests = 0
- def outLineReceived(self, line):
- if "FNURRRGH!" in line:
- self.numTests += 1
- self.step.setProgress('tests', self.numTests)
-
- class Framboozle(ShellCommand):
- command = ["framboozler"]
-
- def __init__(self, **kwargs):
- ShellCommand.__init__(self, **kwargs) # always upcall!
- counter = FNURRRGHCounter())
- self.addLogObserver('stdio', counter)
- self.progressMetrics += ('tests',)
- # FINISH
-
- So that's the code that we want to wind up using. How do we
-actually deploy it?
-
- You have a couple of different options.
-
- Option 1: The simplest technique is to simply put this text
-(everything from START to FINISH) in your master.cfg file, somewhere
-before the BuildFactory definition where you actually use it in a
-clause like:
-
- f = BuildFactory()
- f.addStep(SVN(svnurl="stuff"))
- f.addStep(Framboozle())
-
- Remember that master.cfg is secretly just a python program with one
-job: populating the BuildmasterConfig dictionary. And python programs
-are allowed to define as many classes as they like. So you can define
-classes and use them in the same file, just as long as the class is
-defined before some other code tries to use it.
-
- This is easy, and it keeps the point of definition very close to
-the point of use, and whoever replaces you after that unfortunate
-hang-gliding accident will appreciate being able to easily figure out
-what the heck this stupid "Framboozle" step is doing anyways. The
-downside is that every time you reload the config file, the Framboozle
-class will get redefined, which means that the buildmaster will think
-that you've reconfigured all the Builders that use it, even though
-nothing changed. Bleh.
-
- Option 2: Instead, we can put this code in a separate file, and
-import it into the master.cfg file just like we would the normal
-buildsteps like ShellCommand and SVN.
-
- Create a directory named ~/lib/python, put everything from START to
-FINISH in ~/lib/python/framboozle.py, and run your buildmaster using:
-
- PYTHONPATH=~/lib/python buildbot start MASTERDIR
-
- or use the `Makefile.buildbot' to control the way `buildbot start'
-works. Or add something like this to something like your ~/.bashrc or
-~/.bash_profile or ~/.cshrc:
-
- export PYTHONPATH=~/lib/python
-
- Once we've done this, our master.cfg can look like:
-
- from framboozle import Framboozle
- f = BuildFactory()
- f.addStep(SVN(svnurl="stuff"))
- f.addStep(Framboozle())
-
- or:
-
- import framboozle
- f = BuildFactory()
- f.addStep(SVN(svnurl="stuff"))
- f.addStep(framboozle.Framboozle())
-
- (check out the python docs for details about how "import" and
-"from A import B" work).
-
- What we've done here is to tell python that every time it handles
-an "import" statement for some named module, it should look in our
-~/lib/python/ for that module before it looks anywhere else. After our
-directories, it will try in a bunch of standard directories too
-(including the one where buildbot is installed). By setting the
-PYTHONPATH environment variable, you can add directories to the front
-of this search list.
-
- Python knows that once it "import"s a file, it doesn't need to
-re-import it again. This means that reconfiguring the buildmaster
-(with "buildbot reconfig", for example) won't make it think the
-Framboozle class has changed every time, so the Builders that use it
-will not be spuriously restarted. On the other hand, you either have
-to start your buildmaster in a slightly weird way, or you have to
-modify your environment to set the PYTHONPATH variable.
-
- Option 3: Install this code into a standard python library
-directory
-
- Find out what your python's standard include path is by asking it:
-
- 80:warner@luther% python
- Python 2.4.4c0 (#2, Oct 2 2006, 00:57:46)
- [GCC 4.1.2 20060928 (prerelease) (Debian 4.1.1-15)] on linux2
- Type "help", "copyright", "credits" or "license" for more information.
- >>> import sys
- >>> import pprint
- >>> pprint.pprint(sys.path)
- ['',
- '/usr/lib/python24.zip',
- '/usr/lib/python2.4',
- '/usr/lib/python2.4/plat-linux2',
- '/usr/lib/python2.4/lib-tk',
- '/usr/lib/python2.4/lib-dynload',
- '/usr/local/lib/python2.4/site-packages',
- '/usr/lib/python2.4/site-packages',
- '/usr/lib/python2.4/site-packages/Numeric',
- '/var/lib/python-support/python2.4',
- '/usr/lib/site-python']
-
- In this case, putting the code into
-/usr/local/lib/python2.4/site-packages/framboozle.py would work just
-fine. We can use the same master.cfg "import framboozle" statement as
-in Option 2. By putting it in a standard include directory (instead of
-the decidedly non-standard ~/lib/python), we don't even have to set
-PYTHONPATH to anything special. The downside is that you probably have
-to be root to write to one of those standard include directories.
-
- Option 4: Submit the code for inclusion in the Buildbot
-distribution
-
- Make a fork of buildbot on http://github.com/djmitche/buildbot or
-post a patch in a bug at http://buildbot.net. In either case, post a
-note about your patch to the mailing list, so others can provide
-feedback and, eventually, commit it.
-
- from buildbot.steps import framboozle
- f = BuildFactory()
- f.addStep(SVN(svnurl="stuff"))
- f.addStep(framboozle.Framboozle())
-
- And then you don't even have to install framboozle.py anywhere on
-your system, since it will ship with Buildbot. You don't have to be
-root, you don't have to set PYTHONPATH. But you do have to make a
-good case for Framboozle being worth going into the main
-distribution, you'll probably have to provide docs and some unit test
-cases, you'll need to figure out what kind of beer the author likes,
-and then you'll have to wait until the next release. But in some
-environments, all this is easier than getting root on your
-buildmaster box, so the tradeoffs may actually be worth it.
-
- Putting the code in master.cfg (1) makes it available to that
-buildmaster instance. Putting it in a file in a personal library
-directory (2) makes it available for any buildmasters you might be
-running. Putting it in a file in a system-wide shared library
-directory (3) makes it available for any buildmasters that anyone on
-that system might be running. Getting it into the buildbot's upstream
-repository (4) makes it available for any buildmasters that anyone in
-the world might be running. It's all a matter of how widely you want
-to deploy that new class.
-
- ---------- Footnotes ----------
-
- (1) framboozle.com is still available. Remember, I get 10% :).
-
- (2) Framboozle gets very excited about running unit tests.
-
-
-File: buildbot.info, Node: BuildStep URLs, Prev: Adding LogObservers, Up: Writing New BuildSteps
-
-6.1.10.5 BuildStep URLs
-.......................
-
-Each BuildStep has a collection of "links". Like its collection of
-LogFiles, each link has a name and a target URL. The web status page
-creates HREFs for each link in the same box as it does for LogFiles,
-except that the target of the link is the external URL instead of an
-internal link to a page that shows the contents of the LogFile.
-
- These external links can be used to point at build information
-hosted on other servers. For example, the test process might produce
-an intricate description of which tests passed and failed, or some
-sort of code coverage data in HTML form, or a PNG or GIF image with a
-graph of memory usage over time. The external link can provide an
-easy way for users to navigate from the buildbot's status page to
-these external web sites or file servers. Note that the step itself is
-responsible for insuring that there will be a document available at
-the given URL (perhaps by using `scp' to copy the HTML output to a
-`~/public_html/' directory on a remote web server). Calling `addURL'
-does not magically populate a web server.
-
- To set one of these links, the BuildStep should call the `addURL'
-method with the name of the link and the target URL. Multiple URLs can
-be set.
-
- In this example, we assume that the `make test' command causes a
-collection of HTML files to be created and put somewhere on the
-coverage.example.org web server, in a filename that incorporates the
-build number.
-
- class TestWithCodeCoverage(BuildStep):
- command = ["make", "test",
- WithProperties("buildnum=%s" % "buildnumber")]
-
- def createSummary(self, log):
- buildnumber = self.getProperty("buildnumber")
- url = "http://coverage.example.org/builds/%s.html" % buildnumber
- self.addURL("coverage", url)
-
- You might also want to extract the URL from some special message
-output by the build process itself:
-
- class TestWithCodeCoverage(BuildStep):
- command = ["make", "test",
- WithProperties("buildnum=%s" % "buildnumber")]
-
- def createSummary(self, log):
- output = StringIO(log.getText())
- for line in output.readlines():
- if line.startswith("coverage-url:"):
- url = line[len("coverage-url:"):].strip()
- self.addURL("coverage", url)
- return
-
- Note that a build process which emits both stdout and stderr might
-cause this line to be split or interleaved between other lines. It
-might be necessary to restrict the getText() call to only stdout with
-something like this:
-
- output = StringIO("".join([c[1]
- for c in log.getChunks()
- if c[0] == LOG_CHANNEL_STDOUT]))
-
- Of course if the build is run under a PTY, then stdout and stderr
-will be merged before the buildbot ever sees them, so such
-interleaving will be unavoidable.
-
-
-File: buildbot.info, Node: Interlocks, Next: Build Factories, Prev: Build Steps, Up: Build Process
-
-6.2 Interlocks
-==============
-
-Until now, we assumed that a master can run builds at any slave
-whenever needed or desired. Some times, you want to enforce
-additional constraints on builds. For reasons like limited network
-bandwidth, old slave machines, or a self-willed data base server, you
-may want to limit the number of builds (or build steps) that can
-access a resource.
-
- The mechanism used by Buildbot is known as the read/write lock.(1)
-It allows either many readers or a single writer but not a
-combination of readers and writers. The general lock has been
-modified and extended for use in Buildbot. Firstly, the general lock
-allows an infinite number of readers. In Buildbot, we often want to
-put an upper limit on the number of readers, for example allowing two
-out of five possible builds at the same time. To do this, the lock
-counts the number of active readers. Secondly, the terms _read mode_
-and _write mode_ are confusing in Buildbot context. They have been
-replaced by _counting mode_ (since the lock counts them) and
-_exclusive mode_. As a result of these changes, locks in Buildbot
-allow a number of builds (upto some fixed number) in counting mode,
-or they allow one build in exclusive mode.
-
- Often, not all slaves are equal. To allow for this situation,
-Buildbot allows to have a separate upper limit on the count for each
-slave. In this way, you can have at most 3 concurrent builds at a
-fast slave, 2 at a slightly older slave, and 1 at all other slaves.
-
- The final thing you can specify when you introduce a new lock is
-its scope. Some constraints are global - they must be enforced over
-all slaves. Other constraints are local to each slave. A _master
-lock_ is used for the global constraints. You can ensure for example
-that at most one build (of all builds running at all slaves) accesses
-the data base server. With a _slave lock_ you can add a limit local
-to each slave. With such a lock, you can for example enforce an upper
-limit to the number of active builds at a slave, like above.
-
- Time for a few examples. Below a master lock is defined to protect
-a data base, and a slave lock is created to limit the number of
-builds at each slave.
-
- from buildbot import locks
-
- db_lock = locks.MasterLock("database")
- build_lock = locks.SlaveLock("slave_builds",
- maxCount = 1,
- maxCountForSlave = { 'fast': 3, 'new': 2 })
-
- After importing locks from buildbot, `db_lock' is defined to be a
-master lock. The `"database"' string is used for uniquely identifying
-the lock. At the next line, a slave lock called `build_lock' is
-created. It is identified by the `"slave_builds"' string. Since the
-requirements of the lock are a bit more complicated, two optional
-arguments are also specified. The `maxCount' parameter sets the
-default limit for builds in counting mode to `1'. For the slave
-called `'fast'' however, we want to have at most three builds, and
-for the slave called `'new'' the upper limit is two builds running at
-the same time.
-
- The next step is using the locks in builds. Buildbot allows a
-lock to be used during an entire build (from beginning to end), or
-only during a single build step. In the latter case, the lock is
-claimed for use just before the step starts, and released again when
-the step ends. To prevent deadlocks,(2) it is not possible to claim
-or release locks at other times.
-
- To use locks, you should add them with a `locks' argument. Each
-use of a lock is either in counting mode (that is, possibly shared
-with other builds) or in exclusive mode. A build or build step
-proceeds only when it has acquired all locks. If a build or step
-needs a lot of locks, it may be starved(3) by other builds that need
-fewer locks.
-
- To illustrate use of locks, a few examples.
-
- from buildbot import locks
- from buildbot.steps import source, shell
- from buildbot.process import factory
-
- db_lock = locks.MasterLock("database")
- build_lock = locks.SlaveLock("slave_builds",
- maxCount = 1,
- maxCountForSlave = { 'fast': 3, 'new': 2 })
-
- f = factory.BuildFactory()
- f.addStep(source.SVN(svnurl="http://example.org/svn/Trunk"))
- f.addStep(shell.ShellCommand(command="make all"))
- f.addStep(shell.ShellCommand(command="make test",
- locks=[db_lock.access('exclusive')]))
-
- b1 = {'name': 'full1', 'slavename': 'fast', 'builddir': 'f1', 'factory': f,
- 'locks': [build_lock.access('counting')] }
-
- b2 = {'name': 'full2', 'slavename': 'new', 'builddir': 'f2', 'factory': f.
- 'locks': [build_lock.access('counting')] }
-
- b3 = {'name': 'full3', 'slavename': 'old', 'builddir': 'f3', 'factory': f.
- 'locks': [build_lock.access('counting')] }
-
- b4 = {'name': 'full4', 'slavename': 'other', 'builddir': 'f4', 'factory': f.
- 'locks': [build_lock.access('counting')] }
-
- c['builders'] = [b1, b2, b3, b4]
-
- Here we have four slaves `b1', `b2', `b3', and `b4'. Each slave
-performs the same checkout, make, and test build step sequence. We
-want to enforce that at most one test step is executed between all
-slaves due to restrictions with the data base server. This is done by
-adding the `locks=' parameter with the third step. It takes a list of
-locks with their access mode. In this case only the `db_lock' is
-needed. The exclusive access mode is used to ensure there is at most
-one slave that executes the test step.
-
- In addition to exclusive accessing the data base, we also want
-slaves to stay responsive even under the load of a large number of
-builds being triggered. For this purpose, the slave lock called
-`build_lock' is defined. Since the restraint holds for entire builds,
-the lock is specified in the builder with `'locks':
-[build_lock.access('counting')]'.
-
- ---------- Footnotes ----------
-
- (1) See http://en.wikipedia.org/wiki/Read/write_lock_pattern for
-more information.
-
- (2) Deadlock is the situation where two or more slaves each hold a
-lock in exclusive mode, and in addition want to claim the lock held by
-the other slave exclusively as well. Since locks allow at most one
-exclusive user, both slaves will wait forever.
-
- (3) Starving is the situation that only a few locks are available,
-and they are immediately grabbed by another build. As a result, it
-may take a long time before all locks needed by the starved build are
-free at the same time.
-
-
-File: buildbot.info, Node: Build Factories, Prev: Interlocks, Up: Build Process
-
-6.3 Build Factories
-===================
-
-Each Builder is equipped with a "build factory", which is responsible
-for producing the actual `Build' objects that perform each build.
-This factory is created in the configuration file, and attached to a
-Builder through the `factory' element of its dictionary.
-
- The standard `BuildFactory' object creates `Build' objects by
-default. These Builds will each execute a collection of BuildSteps in
-a fixed sequence. Each step can affect the results of the build, but
-in general there is little intelligence to tie the different steps
-together. You can create subclasses of `Build' to implement more
-sophisticated build processes, and then use a subclass of
-`BuildFactory' (or simply set the `buildClass' attribute) to create
-instances of your new Build subclass.
-
-* Menu:
-
-* BuildStep Objects::
-* BuildFactory::
-* Process-Specific build factories::
-
-
-File: buildbot.info, Node: BuildStep Objects, Next: BuildFactory, Prev: Build Factories, Up: Build Factories
-
-6.3.1 BuildStep Objects
------------------------
-
-The steps used by these builds are all subclasses of `BuildStep'.
-The standard ones provided with Buildbot are documented later, *Note
-Build Steps::. You can also write your own subclasses to use in
-builds.
-
- The basic behavior for a `BuildStep' is to:
-
- * run for a while, then stop
-
- * possibly invoke some RemoteCommands on the attached build slave
-
- * possibly produce a set of log files
-
- * finish with a status described by one of four values defined in
- buildbot.status.builder: SUCCESS, WARNINGS, FAILURE, SKIPPED
-
- * provide a list of short strings to describe the step
-
- * define a color (generally green, orange, or red) with which the
- step should be displayed
-
- More sophisticated steps may produce additional information and
-provide it to later build steps, or store it in the factory to provide
-to later builds.
-
-* Menu:
-
-* BuildFactory Attributes::
-* Quick builds::
-
-
-File: buildbot.info, Node: BuildFactory, Next: Process-Specific build factories, Prev: BuildStep Objects, Up: Build Factories
-
-6.3.2 BuildFactory
-------------------
-
-The default `BuildFactory', provided in the
-`buildbot.process.factory' module, contains an internal list of
-"BuildStep specifications": a list of `(step_class, kwargs)' tuples
-for each. These specification tuples are constructed when the config
-file is read, by asking the instances passed to `addStep' for their
-subclass and arguments.
-
- When asked to create a Build, the `BuildFactory' puts a copy of
-the list of step specifications into the new Build object. When the
-Build is actually started, these step specifications are used to
-create the actual set of BuildSteps, which are then executed one at a
-time. This serves to give each Build an independent copy of each step.
-For example, a build which consists of a CVS checkout followed by a
-`make build' would be constructed as follows:
-
- from buildbot.steps import source, shell
- from buildbot.process import factory
-
- f = factory.BuildFactory()
- f.addStep(source.CVS(cvsroot=CVSROOT, cvsmodule="project", mode="update"))
- f.addStep(shell.Compile(command=["make", "build"]))
-
- (To support config files from buildbot-0.7.5 and earlier,
-`addStep' also accepts the `f.addStep(shell.Compile,
-command=["make","build"])' form, although its use is discouraged
-because then the `Compile' step doesn't get to validate or complain
-about its arguments until build time. The modern pass-by-instance
-approach allows this validation to occur while the config file is
-being loaded, where the admin has a better chance of noticing
-problems).
-
- It is also possible to pass a list of steps into the
-`BuildFactory' when it is created. Using `addStep' is usually
-simpler, but there are cases where is is more convenient to create
-the list of steps ahead of time.:
-
- from buildbot.steps import source, shell
- from buildbot.process import factory
-
- all_steps = [source.CVS(cvsroot=CVSROOT, cvsmodule="project", mode="update"),
- shell.Compile(command=["make", "build"]),
- ]
- f = factory.BuildFactory(all_steps)
-
- Each step can affect the build process in the following ways:
-
- * If the step's `haltOnFailure' attribute is True, then a failure
- in the step (i.e. if it completes with a result of FAILURE) will
- cause the whole build to be terminated immediately: no further
- steps will be executed, with the exception of steps with
- `alwaysRun' set to True. `haltOnFailure' is useful for setup
- steps upon which the rest of the build depends: if the CVS
- checkout or `./configure' process fails, there is no point in
- trying to compile or test the resulting tree.
-
- * If the step's `alwaysRun' attribute is True, then it will always
- be run, regardless of if previous steps have failed. This is
- useful for cleanup steps that should always be run to return the
- build directory or build slave into a good state.
-
- * If the `flunkOnFailure' or `flunkOnWarnings' flag is set, then a
- result of FAILURE or WARNINGS will mark the build as a whole as
- FAILED. However, the remaining steps will still be executed.
- This is appropriate for things like multiple testing steps: a
- failure in any one of them will indicate that the build has
- failed, however it is still useful to run them all to completion.
-
- * Similarly, if the `warnOnFailure' or `warnOnWarnings' flag is
- set, then a result of FAILURE or WARNINGS will mark the build as
- having WARNINGS, and the remaining steps will still be executed.
- This may be appropriate for certain kinds of optional build or
- test steps. For example, a failure experienced while building
- documentation files should be made visible with a WARNINGS
- result but not be serious enough to warrant marking the whole
- build with a FAILURE.
-
-
- In addition, each Step produces its own results, may create
-logfiles, etc. However only the flags described above have any effect
-on the build as a whole.
-
- The pre-defined BuildSteps like `CVS' and `Compile' have
-reasonably appropriate flags set on them already. For example, without
-a source tree there is no point in continuing the build, so the `CVS'
-class has the `haltOnFailure' flag set to True. Look in
-`buildbot/steps/*.py' to see how the other Steps are marked.
-
- Each Step is created with an additional `workdir' argument that
-indicates where its actions should take place. This is specified as a
-subdirectory of the slave builder's base directory, with a default
-value of `build'. This is only implemented as a step argument (as
-opposed to simply being a part of the base directory) because the
-CVS/SVN steps need to perform their checkouts from the parent
-directory.
-
-* Menu:
-
-* BuildFactory Attributes::
-* Quick builds::
-
-
-File: buildbot.info, Node: BuildFactory Attributes, Next: Quick builds, Prev: BuildFactory, Up: BuildFactory
-
-6.3.2.1 BuildFactory Attributes
-...............................
-
-Some attributes from the BuildFactory are copied into each Build.
-
-`useProgress'
- (defaults to True): if True, the buildmaster keeps track of how
- long each step takes, so it can provide estimates of how long
- future builds will take. If builds are not expected to take a
- consistent amount of time (such as incremental builds in which a
- random set of files are recompiled or tested each time), this
- should be set to False to inhibit progress-tracking.
-
-
-
-File: buildbot.info, Node: Quick builds, Prev: BuildFactory Attributes, Up: BuildFactory
-
-6.3.2.2 Quick builds
-....................
-
-The difference between a "full build" and a "quick build" is that
-quick builds are generally done incrementally, starting with the tree
-where the previous build was performed. That simply means that the
-source-checkout step should be given a `mode='update'' flag, to do
-the source update in-place.
-
- In addition to that, the `useProgress' flag should be set to
-False. Incremental builds will (or at least the ought to) compile as
-few files as necessary, so they will take an unpredictable amount of
-time to run. Therefore it would be misleading to claim to predict how
-long the build will take.
-
-
-File: buildbot.info, Node: Process-Specific build factories, Prev: BuildFactory, Up: Build Factories
-
-6.3.3 Process-Specific build factories
---------------------------------------
-
-Many projects use one of a few popular build frameworks to simplify
-the creation and maintenance of Makefiles or other compilation
-structures. Buildbot provides several pre-configured BuildFactory
-subclasses which let you build these projects with a minimum of fuss.
-
-* Menu:
-
-* GNUAutoconf::
-* CPAN::
-* Python distutils::
-* Python/Twisted/trial projects::
-
-
-File: buildbot.info, Node: GNUAutoconf, Next: CPAN, Prev: Process-Specific build factories, Up: Process-Specific build factories
-
-6.3.3.1 GNUAutoconf
-...................
-
-GNU Autoconf (http://www.gnu.org/software/autoconf/) is a software
-portability tool, intended to make it possible to write programs in C
-(and other languages) which will run on a variety of UNIX-like
-systems. Most GNU software is built using autoconf. It is frequently
-used in combination with GNU automake. These tools both encourage a
-build process which usually looks like this:
-
- % CONFIG_ENV=foo ./configure --with-flags
- % make all
- % make check
- # make install
-
- (except of course the Buildbot always skips the `make install'
-part).
-
- The Buildbot's `buildbot.process.factory.GNUAutoconf' factory is
-designed to build projects which use GNU autoconf and/or automake. The
-configuration environment variables, the configure flags, and command
-lines used for the compile and test are all configurable, in general
-the default values will be suitable.
-
- Example:
-
- # use the s() convenience function defined earlier
- f = factory.GNUAutoconf(source=s(step.SVN, svnurl=URL, mode="copy"),
- flags=["--disable-nls"])
-
- Required Arguments:
-
-`source'
- This argument must be a step specification tuple that provides a
- BuildStep to generate the source tree.
-
- Optional Arguments:
-
-`configure'
- The command used to configure the tree. Defaults to
- `./configure'. Accepts either a string or a list of shell argv
- elements.
-
-`configureEnv'
- The environment used for the initial configuration step. This
- accepts a dictionary which will be merged into the buildslave's
- normal environment. This is commonly used to provide things like
- `CFLAGS="-O2 -g"' (to turn off debug symbols during the compile).
- Defaults to an empty dictionary.
-
-`configureFlags'
- A list of flags to be appended to the argument list of the
- configure command. This is commonly used to enable or disable
- specific features of the autoconf-controlled package, like
- `["--without-x"]' to disable windowing support. Defaults to an
- empty list.
-
-`compile'
- this is a shell command or list of argv values which is used to
- actually compile the tree. It defaults to `make all'. If set to
- None, the compile step is skipped.
-
-`test'
- this is a shell command or list of argv values which is used to
- run the tree's self-tests. It defaults to `make check'. If set to
- None, the test step is skipped.
-
-
-
-File: buildbot.info, Node: CPAN, Next: Python distutils, Prev: GNUAutoconf, Up: Process-Specific build factories
-
-6.3.3.2 CPAN
-............
-
-Most Perl modules available from the CPAN (http://www.cpan.org/)
-archive use the `MakeMaker' module to provide configuration, build,
-and test services. The standard build routine for these modules looks
-like:
-
- % perl Makefile.PL
- % make
- % make test
- # make install
-
- (except again Buildbot skips the install step)
-
- Buildbot provides a `CPAN' factory to compile and test these
-projects.
-
- Arguments:
-`source'
- (required): A step specification tuple, like that used by
- GNUAutoconf.
-
-`perl'
- A string which specifies the `perl' executable to use. Defaults
- to just `perl'.
-
-
-
-File: buildbot.info, Node: Python distutils, Next: Python/Twisted/trial projects, Prev: CPAN, Up: Process-Specific build factories
-
-6.3.3.3 Python distutils
-........................
-
-Most Python modules use the `distutils' package to provide
-configuration and build services. The standard build process looks
-like:
-
- % python ./setup.py build
- % python ./setup.py install
-
- Unfortunately, although Python provides a standard unit-test
-framework named `unittest', to the best of my knowledge `distutils'
-does not provide a standardized target to run such unit tests. (Please
-let me know if I'm wrong, and I will update this factory.)
-
- The `Distutils' factory provides support for running the build
-part of this process. It accepts the same `source=' parameter as the
-other build factories.
-
- Arguments:
-`source'
- (required): A step specification tuple, like that used by
- GNUAutoconf.
-
-`python'
- A string which specifies the `python' executable to use. Defaults
- to just `python'.
-
-`test'
- Provides a shell command which runs unit tests. This accepts
- either a string or a list. The default value is None, which
- disables the test step (since there is no common default command
- to run unit tests in distutils modules).
-
-
-
-File: buildbot.info, Node: Python/Twisted/trial projects, Prev: Python distutils, Up: Process-Specific build factories
-
-6.3.3.4 Python/Twisted/trial projects
-.....................................
-
-Twisted provides a unit test tool named `trial' which provides a few
-improvements over Python's built-in `unittest' module. Many python
-projects which use Twisted for their networking or application
-services also use trial for their unit tests. These modules are
-usually built and tested with something like the following:
-
- % python ./setup.py build
- % PYTHONPATH=build/lib.linux-i686-2.3 trial -v PROJECTNAME.test
- % python ./setup.py install
-
- Unfortunately, the `build/lib' directory into which the
-built/copied .py files are placed is actually architecture-dependent,
-and I do not yet know of a simple way to calculate its value. For many
-projects it is sufficient to import their libraries "in place" from
-the tree's base directory (`PYTHONPATH=.').
-
- In addition, the PROJECTNAME value where the test files are
-located is project-dependent: it is usually just the project's
-top-level library directory, as common practice suggests the unit test
-files are put in the `test' sub-module. This value cannot be guessed,
-the `Trial' class must be told where to find the test files.
-
- The `Trial' class provides support for building and testing
-projects which use distutils and trial. If the test module name is
-specified, trial will be invoked. The library path used for testing
-can also be set.
-
- One advantage of trial is that the Buildbot happens to know how to
-parse trial output, letting it identify which tests passed and which
-ones failed. The Buildbot can then provide fine-grained reports about
-how many tests have failed, when individual tests fail when they had
-been passing previously, etc.
-
- Another feature of trial is that you can give it a series of source
-.py files, and it will search them for special `test-case-name' tags
-that indicate which test cases provide coverage for that file. Trial
-can then run just the appropriate tests. This is useful for quick
-builds, where you want to only run the test cases that cover the
-changed functionality.
-
- Arguments:
-`source'
- (required): A step specification tuple, like that used by
- GNUAutoconf.
-
-`buildpython'
- A list (argv array) of strings which specifies the `python'
- executable to use when building the package. Defaults to just
- `['python']'. It may be useful to add flags here, to supress
- warnings during compilation of extension modules. This list is
- extended with `['./setup.py', 'build']' and then executed in a
- ShellCommand.
-
-`testpath'
- Provides a directory to add to `PYTHONPATH' when running the unit
- tests, if tests are being run. Defaults to `.' to include the
- project files in-place. The generated build library is frequently
- architecture-dependent, but may simply be `build/lib' for
- pure-python modules.
-
-`trialpython'
- Another list of strings used to build the command that actually
- runs trial. This is prepended to the contents of the `trial'
- argument below. It may be useful to add `-W' flags here to
- supress warnings that occur while tests are being run. Defaults
- to an empty list, meaning `trial' will be run without an explicit
- interpreter, which is generally what you want if you're using
- `/usr/bin/trial' instead of, say, the `./bin/trial' that lives
- in the Twisted source tree.
-
-`trial'
- provides the name of the `trial' command. It is occasionally
- useful to use an alternate executable, such as `trial2.2' which
- might run the tests under an older version of Python. Defaults to
- `trial'.
-
-`tests'
- Provides a module name or names which contain the unit tests for
- this project. Accepts a string, typically `PROJECTNAME.test', or
- a list of strings. Defaults to None, indicating that no tests
- should be run. You must either set this or `useTestCaseNames' to
- do anyting useful with the Trial factory.
-
-`useTestCaseNames'
- Tells the Step to provide the names of all changed .py files to
- trial, so it can look for test-case-name tags and run just the
- matching test cases. Suitable for use in quick builds. Defaults
- to False.
-
-`randomly'
- If `True', tells Trial (with the `--random=0' argument) to run
- the test cases in random order, which sometimes catches subtle
- inter-test dependency bugs. Defaults to `False'.
-
-`recurse'
- If `True', tells Trial (with the `--recurse' argument) to look
- in all subdirectories for additional test cases. It isn't clear
- to me how this works, but it may be useful to deal with the
- unknown-PROJECTNAME problem described above, and is currently
- used in the Twisted buildbot to accomodate the fact that test
- cases are now distributed through multiple
- twisted.SUBPROJECT.test directories.
-
-
- Unless one of `trialModule' or `useTestCaseNames' are set, no
-tests will be run.
-
- Some quick examples follow. Most of these examples assume that the
-target python code (the "code under test") can be reached directly
-from the root of the target tree, rather than being in a `lib/'
-subdirectory.
-
- # Trial(source, tests="toplevel.test") does:
- # python ./setup.py build
- # PYTHONPATH=. trial -to toplevel.test
-
- # Trial(source, tests=["toplevel.test", "other.test"]) does:
- # python ./setup.py build
- # PYTHONPATH=. trial -to toplevel.test other.test
-
- # Trial(source, useTestCaseNames=True) does:
- # python ./setup.py build
- # PYTHONPATH=. trial -to --testmodule=foo/bar.py.. (from Changes)
-
- # Trial(source, buildpython=["python2.3", "-Wall"], tests="foo.tests"):
- # python2.3 -Wall ./setup.py build
- # PYTHONPATH=. trial -to foo.tests
-
- # Trial(source, trialpython="python2.3", trial="/usr/bin/trial",
- # tests="foo.tests") does:
- # python2.3 -Wall ./setup.py build
- # PYTHONPATH=. python2.3 /usr/bin/trial -to foo.tests
-
- # For running trial out of the tree being tested (only useful when the
- # tree being built is Twisted itself):
- # Trial(source, trialpython=["python2.3", "-Wall"], trial="./bin/trial",
- # tests="foo.tests") does:
- # python2.3 -Wall ./setup.py build
- # PYTHONPATH=. python2.3 -Wall ./bin/trial -to foo.tests
-
- If the output directory of `./setup.py build' is known, you can
-pull the python code from the built location instead of the source
-directories. This should be able to handle variations in where the
-source comes from, as well as accomodating binary extension modules:
-
- # Trial(source,tests="toplevel.test",testpath='build/lib.linux-i686-2.3')
- # does:
- # python ./setup.py build
- # PYTHONPATH=build/lib.linux-i686-2.3 trial -to toplevel.test
-
-
-File: buildbot.info, Node: Status Delivery, Next: Command-line tool, Prev: Build Process, Up: Top
-
-7 Status Delivery
-*****************
-
-More details are available in the docstrings for each class, use a
-command like `pydoc buildbot.status.html.WebStatus' to see them.
-Most status delivery objects take a `categories=' argument, which can
-contain a list of "category" names: in this case, it will only show
-status for Builders that are in one of the named categories.
-
- (implementor's note: each of these objects should be a
-service.MultiService which will be attached to the BuildMaster object
-when the configuration is processed. They should use
-`self.parent.getStatus()' to get access to the top-level IStatus
-object, either inside `startService' or later. They may call
-`status.subscribe()' in `startService' to receive notifications of
-builder events, in which case they must define `builderAdded' and
-related methods. See the docstrings in `buildbot/interfaces.py' for
-full details.)
-
-* Menu:
-
-* WebStatus::
-* MailNotifier::
-* IRC Bot::
-* PBListener::
-* Writing New Status Plugins::
-
-
-File: buildbot.info, Node: WebStatus, Next: MailNotifier, Prev: Status Delivery, Up: Status Delivery
-
-7.1 WebStatus
-=============
-
-The `buildbot.status.html.WebStatus' status target runs a small web
-server inside the buildmaster. You can point a browser at this web
-server and retrieve information about every build the buildbot knows
-about, as well as find out what the buildbot is currently working on.
-
- The first page you will see is the "Welcome Page", which contains
-links to all the other useful pages. This page is simply served from
-the `public_html/index.html' file in the buildmaster's base
-directory, where it is created by the `buildbot create-master'
-command along with the rest of the buildmaster.
-
- The most complex resource provided by `WebStatus' is the
-"Waterfall Display", which shows a time-based chart of events. This
-somewhat-busy display provides detailed information about all steps of
-all recent builds, and provides hyperlinks to look at individual build
-logs and source changes. By simply reloading this page on a regular
-basis, you will see a complete description of everything the buildbot
-is currently working on.
-
- There are also pages with more specialized information. For
-example, there is a page which shows the last 20 builds performed by
-the buildbot, one line each. Each line is a link to detailed
-information about that build. By adding query arguments to the URL
-used to reach this page, you can narrow the display to builds that
-involved certain branches, or which ran on certain Builders. These
-pages are described in great detail below.
-
- When the buildmaster is created, a subdirectory named
-`public_html/' is created in its base directory. By default,
-`WebStatus' will serve files from this directory: for example, when a
-user points their browser at the buildbot's `WebStatus' URL, they
-will see the contents of the `public_html/index.html' file. Likewise,
-`public_html/robots.txt', `public_html/buildbot.css', and
-`public_html/favicon.ico' are all useful things to have in there.
-The first time a buildmaster is created, the `public_html' directory
-is populated with some sample files, which you will probably want to
-customize for your own project. These files are all static: the
-buildbot does not modify them in any way as it serves them to HTTP
-clients.
-
- from buildbot.status.html import WebStatus
- c['status'].append(WebStatus(8080))
-
- Note that the initial robots.txt file has Disallow lines for all of
-the dynamically-generated buildbot pages, to discourage web spiders
-and search engines from consuming a lot of CPU time as they crawl
-through the entire history of your buildbot. If you are running the
-buildbot behind a reverse proxy, you'll probably need to put the
-robots.txt file somewhere else (at the top level of the parent web
-server), and replace the URL prefixes in it with more suitable values.
-
- If you would like to use an alternative root directory, add the
-`public_html=..' option to the `WebStatus' creation:
-
- c['status'].append(WebStatus(8080, public_html="/var/www/buildbot"))
-
- In addition, if you are familiar with twisted.web _Resource
-Trees_, you can write code to add additional pages at places inside
-this web space. Just use `webstatus.putChild' to place these
-resources.
-
- The following section describes the special URLs and the status
-views they provide.
-
-* Menu:
-
-* WebStatus Configuration Parameters::
-* Buildbot Web Resources::
-* XMLRPC server::
-* HTML Waterfall::
-
-
-File: buildbot.info, Node: WebStatus Configuration Parameters, Next: Buildbot Web Resources, Prev: WebStatus, Up: WebStatus
-
-7.1.1 WebStatus Configuration Parameters
-----------------------------------------
-
-The most common way to run a `WebStatus' is on a regular TCP port. To
-do this, just pass in the TCP port number when you create the
-`WebStatus' instance; this is called the `http_port' argument:
-
- from buildbot.status.html import WebStatus
- c['status'].append(WebStatus(8080))
-
- The `http_port' argument is actually a "strports specification"
-for the port that the web server should listen on. This can be a
-simple port number, or a string like `tcp:8080:interface=127.0.0.1'
-(to limit connections to the loopback interface, and therefore to
-clients running on the same host)(1).
-
- If instead (or in addition) you provide the `distrib_port'
-argument, a twisted.web distributed server will be started either on a
-TCP port (if `distrib_port' is like `"tcp:12345"') or more likely on
-a UNIX socket (if `distrib_port' is like `"unix:/path/to/socket"').
-
- The `distrib_port' option means that, on a host with a
-suitably-configured twisted-web server, you do not need to consume a
-separate TCP port for the buildmaster's status web page. When the web
-server is constructed with `mktap web --user', URLs that point to
-`http://host/~username/' are dispatched to a sub-server that is
-listening on a UNIX socket at `~username/.twisted-web-pb'. On such a
-system, it is convenient to create a dedicated `buildbot' user, then
-set `distrib_port' to
-`"unix:"+os.path.expanduser("~/.twistd-web-pb")'. This configuration
-will make the HTML status page available at `http://host/~buildbot/'
-. Suitable URL remapping can make it appear at
-`http://host/buildbot/', and the right virtual host setup can even
-place it at `http://buildbot.host/' .
-
- The other `WebStatus' argument is `allowForce'. If set to True,
-then the web page will provide a "Force Build" button that allows
-visitors to manually trigger builds. This is useful for developers to
-re-run builds that have failed because of intermittent problems in
-the test suite, or because of libraries that were not installed at
-the time of the previous build. You may not wish to allow strangers
-to cause a build to run: in that case, set this to False to remove
-these buttons. The default value is False.
-
- ---------- Footnotes ----------
-
- (1) It may even be possible to provide SSL access by using a
-specification like
-`"ssl:12345:privateKey=mykey.pen:certKey=cert.pem"', but this is
-completely untested
-