Hudson love
Some time ago I tried having a separate build machine performing continuous builds every time I checked my project sources into Subversion and I was quickly hooked. It’s a very simple idea but I always found it a little hard to fully appreciate the benefits before I tried it in a real project.
While having a build machine really shines with unit tests, it has a place even when you don’t have any unit testing at all in place. Firstly, you catch those time-consuming errors not having added all files to the version control system. Breaking a build wastes time for the entire team. Secondly, you have an incentive to keep the build process sane since the system gets built all the time. Building a system really should be as simple as checking the sources out and running a single command. Performing automated builds can help simply because setting up the builds becomes troublesome otherwise!
So here’s a suggestion for you existing project that does not have any unit tests: setup a build machine that builds the project every time someone checks something in. Then create a single unit test and have it run as part of the continuous build process. That’s it. You will now know that your project can be built and that it at least passes some simple test. Moving forward, you can for example make a point of creating a unit test for all new bug reports from customers. You decide, but knowing that your project builds alone can be worth quite a lot.
There are several applications for continuous integration to choose from. Most of them seem to have been developed within the Java community, but they are capable of running much more than Java builds and JUnit tests. The first build system I tried was CruiseControl because it seemed an obvious choice at the time. It has performed very well, though I remember it was a little cumbersome to set up. Since I recently needed to set up CruiseControl from scratch I figured I might just as well try Hudson out.
For me, the major advantage of Hudson, besides the much neater interface, is the packaging and running behavior. Hudson is delivered as a WAR file that you can deploy on any Java servlet container, but it also contains Winstone, a lightweight servlet container so that you can actually run Hudson “self-hosted” by simply going:
$ java -jar hudson.war
Starting a self-hosted Hudson on a Linux box as a daemon, typically requires an System V init.d script. I can post a little information on how to write such a script and have Hudson start each time your System V machine boots if you wish; It’s not hard since Hudson will run as a single process, but a better solution might be to deploy Hudson to a servlet container, like Tomcat, JBoss or Glassfish.
A reasonable choice of servlet container for an Ubuntu box is Tomcat, simply because it is available as an Ubuntu package. Installation requires you to enable the universe and multiverse repositories. Details on how to do that can be found here. Once those repositories are enabled, you can install Tomcat and Hudson on an Ubuntu box by following these steps:
We start by installing Java and Tomcat.
# apt-get install sun-java6-jdk
# apt-get install tomcat5.5
Sun’s Java should be the default but if it is not, you can select the default Java by:
# update-alternatives --config java
Tomcat on Ubuntu comes with the security manager enabled by default and this will cause Hudson not to run. You can disable the security manager by editing the /etc/default/tomcat5.5 file.
Next we need to set the home directory for hudson. Add the following line to /etc/tomcat5.5/context.xml
<Environment name="HUDSON_HOME" value="/srv/hudson"
type="java.lang.String" override="false"/>
As you can see, I choose /srv/hudson as the home directory. See the FHS for details on that choice. Whichever directory you choose, create the directory and set the ownership so that the tomcat55 user can use it and restart Tomcat:
# mkdir /srv/hudson # chown tomcat55.nogroup /srv/hudson/ # /etc/init.d/tomcat restart
Now, simply deploy Hudson by copying the hudson.war file into the /var/lib/tomcat5.5/webapps/ directory. Tomcat will notice the new file and deploy it automatically. Verify that it all works by pointing your browser to http://hostname:8180/hudson/ To update Hudson simply copy the new hudson.war file to the same location, overwriting the old.
If you wish to restrict access to Hudson, add the following two lines to /etc/tomcat5.5/tomcat-users.xml:
<role rolename="admin"/>
<user username="hudson-admin" password="secret" roles="admin"/>
Restart Tomcat and enable security in the Hudson System Configuration panel. Users not logged in will still be able to access builds but cannot adjust the settings or force new builds.
Update 2008-12-28:
I just verified that the installation instructions are still valid on Ubuntu 8.10 using Tomcat 6. All you have to do is replace tomcat55 with tomcat6 above; also, the port seem to have changed from 8180 to 8080. Here’s an updated installation summary:
Install Java and Tomcat.
# apt-get install sun-java6-jdk
# apt-get install tomcat6
Configure or disable the security manager:
# vi /etc/default/tomcat6
Set the home directory for Hudson by adding the follwowing line to /etc/tomcat6/context.xml
<Environment name="HUDSON_HOME" value="/srv/hudson"
type="java.lang.String" override="false"/>
Create the home directory, set the permissions and restart Tomcat
# mkdir /srv/hudson
# chown tomcat6.nogroup /srv/hudson/
# /etc/init.d/tomcat6 restart
Deploy Hudson by copying the hudson.war file into the /var/lib/tomcat6/webapps/ directory. Verify that it works by pointing your browser to http://hostname:8080/hudson/
May 9th, 2008 at 1:12
Great post. Helped me set up Hudson in Tomcat on Ubuntu. Now it’s time for some building.
December 18th, 2008 at 14:02
I installed tomcat following your instructions, but installing tomcat ver 6.0, and did everything else as i’m told. I got to “Verify that it all works by pointing your browser to http://hostname:8180/hudson/“. Nope. Tried at port 8080, so i saw:
”
HTTP Status 404 -
type Status report
message
description The requested resource () is not available.
Apache Tomcat/6.0.18
”
and i still can’t solve it.
December 19th, 2008 at 10:01
LymphoCite T, I’ll have a look at installing Tomcat version 6 and see if anything changed regarding my instructions above. I’ll post an update as soon as I can manage.
December 27th, 2008 at 23:41
Re: LymphoCite T
I had a similar problem on a fresh install of Ubuntu Heron; and ended up disabling TOMCAT security in my startup script. e.g. TOMCAT6_SECURITY=no
You might find the following article (for Tomcat 5.5 but still relevant) useful
http://suereth.blogspot.com/2008/08/ubuntu-dev-server-hudson.html
December 28th, 2008 at 14:51
LymphoCite T, I just verified that the installation instructions indeed seem to work fine with Tomcat 6. I updated the post so that you can see exactly what I did. Did you remember to disable the security manager as Julian suggested? What does your Tomcat log say? (/var/log/tomcat6/catalina.*.log)
Are you running on a minimal installation? I can really recommend Ubuntu Jeos, now part of the standard server ISO image. Having your build server running a minimal OS installation is something that I can really recommend, for many reasons.
April 7th, 2009 at 14:40
Instead of disabling tomcat security, a better way is to add, in file /etc/tomcat6/policy.d/50local.policy, the lines:
grant codeBase “file:/var/lib/tomcat6/webapps/hudson/WEB-INF/-” {
permission java.security.AllPermission;
};
August 17th, 2009 at 11:15
Thanks a lot for all your contribs.
In return, let me share my config files:
============================
/etc/tomcat6/policy.d/99hudson.policy (for both extraction and runtime)
————————————————–
grant codeBase “file:/var/lib/tomcat6/webapps/hudson/-” {
permission java.security.AllPermission;
};
grant codeBase “file:/srv/hudson/-” {
permission java.security.AllPermission;
};
============================
/etc/tomcat6/Catalina/localhost/hudson.xml (custom location of .war)
————————————————–
============================
In /etc/tomcat6/server.xml, add URIEncoding=”UTF-8″ to Connector port otherwise, hudson will complain about URI resolution for non-ascii characters. Any other idea to make it hudson specific?
============================
Dor ssh connections, I had to create a populated .ssh directory in /usr/share/tomcat6. Any other idea to make it hudson specific?
Regards.
August 17th, 2009 at 11:17
Oops, sth wa missing in previsous post:
============================
/etc/tomcat6/Catalina/localhost/hudson.xml (custom location of .war)
————————————————–
August 17th, 2009 at 11:20
OK, seems it was due to the presence of the xml version & encoding. Removed them so you can finally see the content:
============================
/etc/tomcat6/Catalina/localhost/hudson.xml (custom location of .war)
————————————————–
August 17th, 2009 at 11:24
Hum…
============================
/etc/tomcat6/Catalina/localhost/hudson.xml (custom location of .war)
————————————————–
<?xml version=’1.0′ encoding=’utf-8′?>
<Context
docBase=”/srv/hudson/hudson.war”
privileged=”true”
path=”/hudson”
allowLinking=”true”
swallowOutput=”true”
>
<Environment name=”HUDSON_HOME” value=”/srv/hudson” type=”java.lang.String” override=”false”/>
</Context>
August 17th, 2009 at 11:26
Re-hum…
============================
/etc/tomcat6/Catalina/localhost/hudson.xml (custom location of .war)
————————————————–
<?xml version=’1.0′ encoding=’utf-8′?>
<Context
docBase=”/srv/hudson/hudson.war”
privileged=”true”
path=”/hudson”
allowLinking=”true”
swallowOutput=”true”
>
<Environment
name=”HUDSON_HOME”
value=”/srv/hudson”
type=”java.lang.String”
override=”false”/>
</Context>
August 17th, 2009 at 11:28
Sorry for the multiple posts but WordPress doesn’t seem to allow refactoring
September 14th, 2009 at 23:32
The setup here works for me mostly but when I try to run groovy scripts or set up hudson managed security or anything that runs a groovy script i get a ClassNotFoundException for the groovy classes. Everything works perfectly if i disable the security manager in tomcat so I must still be missing some security setting. Anyone know how to fix this error?