Mercurial on OpenSolaris and GlassFish

I am working on rewriting a set of labs for our intermediate students at SJSU. Version control is something that everyone with a CS degree is pretty much expected to know these days, so I thought of digging up an old Subversion lab from my open source programming class.

But distributed version control systems such as Mercurial and Git are getting all the love these days. Some people said that it is actually easier to teach Mercurial than Subversion. This seemed unintuitive--wouldn't it be harder to deal with a bunch of repositories instead of having just one centralized one?

Actually, I now see the point. It is really easy to get going with Mercurial as a single user. The student has an instant benefit: The repository is a "time machine".

The instructor, if so inclined, has an instant benefit too: The repository makes it harder to cheat. How so? I'll require my students to commit before every test run, and have them submit the zipped repository. It is really easy to tell who made and fixed lots of errors over a period of time, and who mysteriously got their code working perfectly in one try.

Of course, for team work, we need a server. I installed Mercurial and the splendid mercurial-server onto a donated Sun server running OpenSolaris and GlassFish. Installation was a bit off the beaten track, so here are the directions.

Mercurial was easy enough—it's in the standard repos. But mercurial-server is only in contrib:

pfexec pkg set-publisher -O http://pkg.opensolaris.org/contrib  contrib
pfexec pkg install mercurial-server

That doesn't run the standard install script, so here is what I did by hand:

pfexec /usr/sbin/useradd -m -d /export/home/hg hg
pfexec passwd hg

(Give some password; it doesn't seem to work without one.)

pfexec mkdir /etc/mercurial-server/keys/root/cay
ssh-add -L > my-key
pfexec mv my-key /etc/mercurial-server/keys/root/cay/thinkpad
pfexec su hg
cd /usr/share/mercurial-server/init/
 ./hginit
chmod 700 /export/home/hg/.ssh
chmod 600 /export/home/hg/.ssh/authorized_keys
/usr/share/mercurial-server/refresh-auth   
exit

Then you can go on in the usual way, installing keys and adding repos remotely (with Mercurial, of course).

Next, I wanted to serve up the repos with GlassFish v3. There are some outdated instructions for GlassFish v2 here and here that got me started.

Make a WAR file with the following structure

Copy hgwebdir.fcgi from the Mercurial installation; to find its location, run

pkg contents SUNWmercurial | grep hgwebdir 

On my Solaris machine, the Python package for FastCGI wasn't installed. I got it like this:

wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py 
pfexec easy_install flup

Next, create two files, hgweb.config (whose format is documented here):

[paths]
/ = /export/home/hg/repos/*
[web]
baseurl = /mercurial/cgi-bin/hgwebdir.fcgi

And web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
      <servlet-name>cgi</servlet-name>
      <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
      <init-param>
         <param-name>cgiPathPrefix</param-name>
         <param-value>WEB-INF/cgi</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>cgi</servlet-name>
      <url-pattern>/cgi-bin/*</url-pattern>
   </servlet-mapping>
   <welcome-file-list>
      <welcome-file>
        cgi-bin/hgwebdir.fcgi/
      </welcome-file>
   </welcome-file-list>
</web-app>

An hour of my life went into discovering that the / at the end of the welcome file is essential.

Deploy the WAR in domains/domain1/autodeploy and point your browser to http://yourhost.dom:8080/mercurial.