Bringing-up CruiseControl

by Sebastien Mirolo on Thu, 7 Jul 2011

CruiseControl is a continuous build application written in Java, using a jsp web framework. It is not as straightforward to setup as running "aptitude install cruisecontrol". So while the 73Mb cruisecontrol-src-2.8.4.zip file was downloading from the website, I started to read through a good introduction to cruisecontrol.

Well, let's back up a little. Cruisecontrol is a jsp webapp so we will need to install a jsp http server. Since I don't plan to get rid of apache as the primary http server, that means installing a connector. I used tomcat as a jsp server and the associated tomcat-apache connector.

# Installing the jsp server and connector
# cd /var/lib
$ tar zxvf apache-tomcat-7.0.16.tar.gz
$ tar zxvf tomcat-connectors-1.2.31-src.tar.gz
$ pushd tomcat-connectors-1.2.31-src
$ cd native
$ ./configure --with-apxs=/usr/sbin/apxs # (or where ever the apxs/apxs2 is)
$ make
$ sudo make install
$ cd jkstatus
$ ant -Dcatalina.build=/var/lib/apache-tomcat-7.0.16
$ popd

# Configuring apache to forward jsp request through the connector
$ cat > /etc/apache2/other/jk_mod.conf
LoadModule jk_module libexec/apache2/mod_jk.so

JkWorkersFile /var/lib/apache-tomcat-7.0.16/conf/workers.properties
JkShmFile /var/lib/apache-tomcat-7.0.16/logs/mod_jk.shm
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

NameVirtualHost 127.0.0.1:80

<VirtualHost 127.0.0.1:80>
        ServerAdmin webmaster@localhost
        ServerName cruisecontrol.localhost 
        DocumentRoot /var/lib/apache-tomcat-7.0.16/webapps
        ErrorLog /var/log/cruisecontrol_error_log
        CustomLog /var/log/apache2/cruisecontrol_access_log common

       # We need relative links in jsp pages to refer inside the tomcat 
       # workarea and not the Apache DocumentRoot. We do that by redirecting
       # all traffic for /cruisecontrol to the connector.
       JkMount /cruisecontrol/* ajp13
       <LocationMatch ".*WEB-INF.*">
                AllowOverride None
                deny from all
        </LocationMatch>
        <Directory "/var/lib/apache-tomcat-7.0.16/webapps">
                AllowOverride None
                Options SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
</VirtualHost>

$ cat > /var/lib/apache-tomcat-7.0.16/conf/workers.properties
worker.list=ajp13
worker.ajp13.type=ajp13
worker.ajp13.host=localhost
worker.ajp13.port=8009
^D

# Starting the jsp server followed by Apache
sudo /usr/sbin/apachectl stop
/var/lib/apache-tomcat-7.0.16/bin/startup.sh
sudo /usr/sbin/apachectl start

At this point, we should be able to access both your site as previously ((http://localhost) and tomcat through the connector (http://localhost/cruisecontrol/index.jsp). Of course, we will get an error from tomcat but we can see it is coming from tomcat and not apache. It is time to setup cruise control.

# Building the web app
$ unzip cruisecontrol-src-2.8.4.zip
$ pushd cruisecontrol-src-2.8.4/reporting/jsp
$ cat > override.properties
user.log.dir=/var/lib/cruisecontrol-2.8.4/workarea/logs
user.build.status.file=buildstatus.txt
cruise.build.artifacts.dir=/var/lib/cruisecontrol-2.8.4/workarea/artifacts
^D
$ chmod +x ./build.sh
$ mkdir dist
$ ./build.sh war

# Copy the war file et al. inside the jsp web server and fix permissions
# Cruisecontrol will be available at http://localhost/cruisecontrol/index.jsp
$ cd webcontent && jar xvf ../dist/cruisecontrol.war
$ pushd /var/lib/apache-tomcat-7.0.16
$ mkdir -p webapps/cruisecontrol
$ cp -rf ../cruisecontrol-2.8.4/reporting/jsp/webcontent/* webapps/cruisecontrol
$ rm webapps/cruisecontrol/WEB-INF/lib/servlet-api-2.5.jar \
     webapps/cruisecontrol/WEB-INF/lib/jsp-api-2.1.jar \
     webapps/cruisecontrol/WEB-INF/lib/el-api.jar
$ find ./webapps -type d -exec chmod 777 {} +
$ sudo chown -R username work 
$ find ./work -type d -exec chmod 777 {} +

# Restarting the jsp server followed by Apache
sudo /usr/sbin/apachectl stop
/var/lib/apache-tomcat-7.0.16/bin/startup.sh
sudo /usr/sbin/apachectl start

We know have the cruise control web front-end running and we are ready to bring the second half of the continuous build system, that is the build daemon proper.

$ pushd /var/lib/cruisecontrol-2.8.4/main
$ chmod +x ./build.sh
$ ./build.sh
$ chmod +x bin/cruisecontrol.sh
$ bin/cruisecontrol.sh

# Setting-up the cruise control working area
$ cd ..
$ mkdir -p workarea/reps workarea/logs workarea/artifacts
$ popd

Almost ready to roll. That is where we create a config.xml in the workarea with the specifics of the projects to build. I used something like the following as a start.

$ cat > /var/lib/cruisecontrol-2.8.4/workarea/config.xml
<cruisecontrol>
  <project name="worlds">
    <schedule interval="7200">
      <exec command="dws" 
            args="build http://hostname/worlds.git"
            workingdir="/var/lib/cruisecontrol-2.8.4/workarea" />
    </schedule>
  </project>
</cruisecontrol>
^D

With a config.xml at hand, we are ready to launch the cruisecontrol build daemon proper.

$ /var/lib/cruisecontrol-2.8.4/main/bin/cruisecontrol.sh

Side notes

The cruisecontrol build daemon opens up a port and responds to HTTP request on it, i.e. the JMX interface. That is how you can force build and access the daemon status through the web interface. At first, I could not get this to work properly because the default port was already in use by another process. I did the following to fix this.

$ diff -u apache-tomcat-7.0.16/webapps/cruisecontrol/WEB-INF/web.xml.prev \
          apache-tomcat-7.0.16/webapps/cruisecontrol/WEB-INF/web.xml
     <context-param>
       <param-name>cruisecontrol.jmxport</param-name>
+      <param-value>8000</param-value>
-      <param-value>8787</param-value>

$ /var/lib/cruisecontrol-2.8.4/main/bin/cruisecontrol.sh -jmxport 8787

After looking around and getting used to tomcat and cruisecontrol, you will certainly realize that some annoying default settings do not interact nicely with your monitoring and backup services. For example, logs are not stored in /var/log by default. It is often possible to quickly fix this by editing either apache-tomcat-7.0.16/conf/server.xml and apache-tomcat-7.0.16/webapps/cruisecontrol/WEB-INF/web.xml.

You might also like to read A continuous-integration build server with CruiseControl from Mark Wilkinson. It contains a lot of pointers and useful information about CruiseControl.