The distributed package is in the process of being merged into the core product.
This "distributed" contrib package for CruiseControl allows a master build machine to distribute build requests to other physical machines on which the builds are performed and to return the results to the master.
In order to extend CruiseControl without requiring that our distributed extensions be merged in with the core CruiseControl code, we decided to add our code as a new contrib package. This complicates configuration a bit, but carefully following the following steps should have you distributing builds in no time. You should, however, already be familiar with CruiseControl if you expect to succeed with this more complex arrangement.
The distributed extensions make use of Jini for the service lookup and RMI features it provides. In addition to the usual CruiseControl startup the user will have to start up a Jini service registrar and HTTP class server. Also, each build agent machine will need to have code installed locally and will need to start up and register their availability with the registrar. Once a federation of one or more agents is registered with a running registrar, CruiseControl has the ability to distribute builds through a new DistributedMasterBuilder that wraps an existing Builder in the CC configuration file. Examples are given below. Doing distributed builds is seamless in CruiseControl and the user has the option of only distributing builds for projects they choose to distribute.
If you will be distributing builds in an environment which includes Build Agents from CruiseControl version 2.6 or earlier, please see Upgrade Notes.
ant
. The default target will build the distributed extensions.ANT_HOME
environment variable set, and a junit.jar available to to ant. Junit ant tasks don't work unless junit.jar is on ant's "boot" classpath. You can either copy a junit.jar file into your ANT_HOME/lib
directory, or define the ANT_ARGS
environment variable with a "-lib" directive pointing to a junit.jar. For example:
export ANT_HOME=~/devtools/apache-ant-1.6.5 export ANT_ARGS="-lib ~/devtools/cruisecontrol/main/lib/junit-3.8.2.jar"You might need to set the
JAVA_HOME
environment variable if the JNLP API (javaws.jar) can not be located otherwise.contrib/ conf/... (Shared configuration files - some of which are copied into dist sub dirs) dist/ (New directory created by builing distributed extensions) agent/... (*Build Agent) builder/... (DistributedMasterBuilder class, used by master build loop). core/... lookup/... (*Lookup Service - aka: Registrar) util/... (*General utilites, including Agent Utility)
cruise.build.dir
should be set to the directory the build agent should consider its build directory. It will be treated as a temporary directory, though some caching may occur.cruise.run.dir
typically works, but can be set to the root directory for the master copy of the code and build results. That is, if you follow the canonical CC configuration, this should be the parent directory of your checkout, logs, and output directories. The logs and output directories will be automatically populated by the results sent back from the build agents.<plugin name="distributed" classname="net.sourceforge.cruisecontrol.builders.DistributedMasterBuilder"/>
<cruisecontrol> <project> <schedule> <distributed>
Execute the nested Builder on a remote Build Agent and optionally return build artifacts after the build completes.
The standard CruiseControl properties passed to builders are available from within the nested Builder
Attribute | Required | Description |
---|---|---|
entries | No | A semicolon-delimited list (key1=value1;key2=value2) used to find a matching agent on which to perform this build. |
agentlogdir | No | Build artifacts directory on remote Agent. All content of this directory is returned to the Master, and deleted after the build completes. |
masterlogdir | No | Build artifacts directory on Master into which Agent artifacts will be moved. Typically included in log merge |
agentoutputdir | No | Another artifacts directory on the remote Agent. All content of this directory is returned to the Master, and deleted after the build completes. |
masteroutputdir | No | Another artifacts directory on Master into which Agent artifacts will be moved. Typically included in log merge |
showProgress | No (defaults to true) | If true or omitted, the distributed builder will provide progress messages, as will the nested builder if it supports this feature (assuming the nested builder's own showProgress setting is not false). If false, no progress messages will be shown by the distributed builder or nested builder - regardless of the nested builder's showProgress setting. If any parent showProgress is false, then no progress will be shown, regardless of the distributed or nested builder settings. |
Element | Cardinality | Description |
---|---|---|
<builder> | 1 | The nested <builder> to be executed on the remote Build Agent. See <composite> to execute multiple Builders. |
<remoteResult> | 0 .. * | Specifies additional artifacts directory. All content of this directory is returned to the Master, and deleted from the Agent after the build completes.
The element has two required attributes: "agentDir" and "masterDir". The "masterDir" is typically included in log merge Example: <remoteResult agentDir="target/site" masterDir="target/site"/>
|
<schedule interval="30"> <ant antscript="ant.bat" antworkingdir="C:/cruise-control/checkout/BasicJavaProject" > </ant> </schedule>wrap the ant builder configuration with a
<distributed>
tag like this:
<schedule interval="30"> <distributed> <ant antscript="ant.bat" antworkingdir="C:/cruise-control-agent/checkout/BasicJavaProject" > </ant> </distributed> </schedule>Note: antscript and antworkingdir attributes now refer to locations on your agent. All agents must conform to these same settings.
key=value
", without the quotes). In the CC configuration file an attribute can be added to the <distributed> tag containing semicolon-delimited entries used to match this agent with the projects that should be built on it. For instance, changing the example above to:
<schedule interval="30"> <distributed entries="agent.name=number2"> <ant antscript="ant.bat" ...will ensure an agent with
agent.name=number2
in its user-defined.properties file will be the recipient of this project's build requests. If multiple agents match a given set of entries, it is indeterminate which will receive the build request. For an agent to be considered a match, the agent must have at least all the entries defined for <distributed entries="...">. A matching agent may have more entries than those defined for <distributed entries="...">.os.name
, java.vm.version
(which may show the hotspot version in java 1.6.0_04+), and java.version
, containing the Java system properties of the same names, and hostname
containing the hostname on which the agent is running. A more useful example than the previous one might be:
<distributed entries="os.name=Windows XP">or
<distributed entries="os.name=Linux">By configuring one project twice, with two different
os.name
properties, you could ensure that your project builds correctly on two different operating systems with only one instance of CruiseControl running. This requires two <project> configurations in your config.xml. Here's a more complex example:
<distributed entries="os.name=Windows XP;dotnet.version=1.1;fixpack=SP2">
<project ...> <schedule ...> <distributed entries="..."> <composite> <ant (build 1)...> <ant (build 2)...>The exampe below will cause a set of builds to be performed sequentially on the different agents (each with a different OS). Both the Windows and Linux builds must complete successfully before the entire Composite Build is considered successful.
<project ...> <schedule ...> <composite> <distributed entries="os.name=Windows XP"> <ant (build 1)...> <distributed entries="os.name=Linux"> <ant (build 1)...>
<distributed agentlogdir="agent/log" masterlogdir="master/log" agentoutputdir="agent/output" masteroutputdir="master/output"> ... </distributed>After a remote build, any files on the agent machine in dir "agent/log" will be copied back to the master machine into dir "master/log". The "logs" and "output" dirs will be deleted on the Agent after the build finishes.
# This is NOT jini friendly. #127.0.0.1 localhost.localdomain localhost ubuntudan 127.0.0.1 localhost.localdomain localhost # actual host ip address and host name 10.6.18.51 ubuntudan
ant
. The default target should start the registrar and class server.ant
. The default target should start the build agent and register it with the Lookup Service. Note: while there is no reason you couldn't have an agent running in your build master, additional agents will require you to copy the cc-agent.zip to each machine, unzipping and configuring for each of them. Another option is to use the webstart BuildAgent features - see Java Web Start deployment of build agents for details.JiniLookUpUtility
. In contrib/distributed/dist/util run ant test-jini
. After 5 seconds you should see a list of services that have been registered with Jini. Since the Jini Lookup Service itself is a Jini service you should have com.sun.jini.reggie.ConstrainableRegistrarProxy
listed even if you have no agents running. If you do have agents running, however, you should see a Proxy
service listed for each of them, with BuildAgentService
listed as the type. You can also test the availability of services (Lookup and BuildAgents) by using the Agent Utility InteractiveBuildUtility
. This allows you to test your configuration without starting CruiseControl. In contrib/distributed/dist/util run ant manual-build
. If the distributed tag in your configuration file does not contain any entries, you'll be prompted to enter them. These are optional, however, and pressing ENTER at the prompt will pick up whatever agent is available. Note that you can pass in the path to your CruiseControl configuration file as an argument to the InteractiveBuildUtility
and save a step when running it. (Note: This ant target is not working [reading input from the command prompt isn't working in ant - any fixes?], but the class should work outside of ant.)CCDIR
environment variable to your CruiseControl/main
directory before launching the contrib/distributed/cruisecontrol.bat/.sh file.log4j.rootCategory=INFO,A1,FILE,Mail ... # Mail is set to be a SMTPAppender log4j.appender.Mail=org.apache.log4j.net.SMTPAppender log4j.appender.Mail.BufferSize=100 log4j.appender.Mail.From=ccbuild@yourdomain.com log4j.appender.Mail.SMTPHost=yoursmtp.mailhost.com log4j.appender.Mail.Subject=CC has had an error!!! log4j.appender.Mail.To=youremail@yourdomain.com log4j.appender.Mail.layout=org.apache.log4j.PatternLayout log4j.appender.Mail.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %-5p [%x] [%c{3}] %m%n
<system> <configuration> <threads count="5" /> </configuration> </system>where 5 would be replaced with your expected number of build agents.
contrib/distributed/ant war-agent
will use the file contrib/distributed/build-sign.properties to sign agent jars and bundle them into a deployable .war
file (dist/cc-agent.war).
Be sure you update build-sign.properties appropriately to use your signing information/certificate.contrib/distributed/dist/util/ant agent-util
(from inside the contrib/distributed/dist/util dir) will launch a Build Agent monitoring utility. The Agent Utility can also be used to kill (and if the agent was launched via webstart - restart) Build Agents.
As of version 2.8, CruiseControl will automatically load a JMX Build Agent Utility into the JMX Control Panel if CCDist classes are available. See the -agentutil command line argument to disable the JMX Build Agent Utility if needed.-Djava.awt.headless=true
or -skipUI
to the Build Agent during startup (either via command line or as a webstart jnlp parameter).registry.url
in the agent.properties file and set it's value to the url of the Lookup Service. If you need multiple unicast URL's, use a comma separated list of Unicast Lookup Locaters (URL's) as the property value (see example below). This can be useful in environments where multicast is not working or practical, or if multicasts are disabled, but should be used only after checking out other things (like the localhost issue). registry.url=jini://ubuntudan,jini://10.6.18.51
<distributed entries="sound=hardwaremixable"> ... </distributed>Deploy and launch all your agents, without modifying entries in user-defined.properties. You can now add a new 'Entry Override' (ie:
sound=hardwaremixable
) to only those agents running on the correct hardware. Do this via the Build Agent UI or the Build Agent Utility. This new Agent entry will persist across Agent restarts.cruise.build.dir
could be used on the agent, removing the requirement for any user configuration. The agent.properties file could have cruise.build.dir
commented out so users would see they had the option to configure their own build location.This code was initially donated to the CruiseControl community by SolutionsIQ, Bellevue, WA.
The folks at SolutionsIQ responsible for this code include Jeff Ramsdale, Rand Huso, Pinak Mengle, and Mehruf Meherali
Maintained by Dan Rollo