Serving Mercurial repositories from OpenVMS

Monday, 16 November 2009 08:51

I have just completed configuring the Mercurial repositories that hold the open source software served by Kednos.  It is now possible to use the hg client to fetch and build MMK (The Halls Of ZK and MX will follow very soon) from http://hg.kednos.com.  The following demonstrates a successful clone of the MMK repository.

hg clone http://hg.kednos.com/mmk
destination directory: mmk
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 44 changes to 44 files
updating working directory
44 files updated, 0 files merged, 0 files removed, 0 files unresolved

So, how did I get this all set up?  Well that is the topic of this post.  I have spent a bit of time tinkering around, reading the Mercurial documentation as well as some snippets of configuration files here and there.  The first part was installing Mercurial.  Mercurial has been ported by Jean-François Piéronne as part of his efforts in porting Python to OpenVMS.  The Mercurial distribution is included on the Python logical disk and is not available as a PCSI (or other) kit.  I chose to move the Mercurial distribution to our own physical disks and used the following commands to do so:

$ LD CONNECT <python-ld>
%I, Allocated device is $7$LDA5:
$ MOUNT/OVERRIDE=IDENTIFICATION LDA5:
$ BACKUP LDA5:[Mercurial...]*.* ddcu:[dir...]

As I said, this step is not necessary and entirely up to the user, I just like it this way.  I then tweaked my login procedure to include the following commands to ensure I always have the relevant foreign symbols configured:

$ IF (F$SEARCH("PYTHON_ROOT:[VMS]SETUP.COM") .NES. "") THEN -
    @PYTHON_ROOT:[VMS]SETUP
$ IF (F$SEARCH("MERCURIAL_ROOT:[VMS]SETUP.COM") .NES. "") THEN -
    @MERCURIAL_ROOT:[VMS]SETUP

Once Mercurial had been installed and was running correctly, I began work on setting up the webpage that can be seen at http://hg.kednos.com.  To serve the Mercurial repository we use (as we do for all our web facing needs) WASD.  After some searching round on the 'net I found a couple snippets of WASD configuration file here and here.  So, using these as a base I began to fiddle around with our setup.

Firstly, I needed somewhere to store the CGI procedure that handles all incoming connections as well as the repositories.  I created the logical MERCURIAL_HOME.  Although it seems to be the norm to use the abbreviation "hg" I found that to be troublesome in our setup as we also use Hunter Goatley's HGFTP for all our FTP needs.  So, I created a directory and copied/created the relevant files and created the first repository like so:

$ CREATE/DIRECTORY ddcu:[MERCURIAL]
$ DEFINE/SYSTEM/EXECUTIVE_MODE/TRANSLATION_ATTRIBUTES=CONCEALED -
   MERCURIAL_HOME ddcu:[MERCURIAL.]    ! Don't forget to put this one in SYLOGICALS.COM too.
$ SET DEFAULT MERCURIAL_HOME:[000000]
$ COPY MERCURIAL_ROOT:[VMS]HGCGIPLUS.COM MERCURIAL_HOME:[000000]
$ CREATE LOGIN.COM
$ EXITT 1^Z
$ CREATE HGWEB.CONFIG
[web]
style = gitweb

[paths]
mmk = mmk^Z
$ hg init mmk
$ CREATE [.mmk.^.hg]hgrc.
[web]
style = gitweb
description = MMK Make Utility
contact = Tim E. Sneddon <tsneddon@kednos.com>
name = mmk
allow_archive = gz zip bz2^Z

I ended up tweaking our version of hgcgiplus.com as we have a number of different version of OpenVMS running in our cluster.  As a result of that we have three different PYRTE images.  So, after a number of seemingly random HTTP 502 errors and some tinkering with WASD's WATCH facility I finally recalled what had been done for MoinMoin ( we used it before VWcms) and added in the pre-amble that picks up the correct image.

So, with all the files in the right place and a fresh repository waiting to be filled I began configuring WASD.  First up was the configuration of the service.  I added the following two lines to HTTPD$SERVICE.

[[http://hg.kednos.com]]
[[https://hg.kednos.com]]

That was no trouble, so now it's time to add the mapping rules to HTTPD$MAP, like so.

[[hg.kednos.com]]
pass /static/* /mercurial_root/mercurial/templates/static/*
pass /mmk/static/* /mercurial_root/mercurial/templates/static/*
pass /*/-/* /ht_root/runtime/*/* cache=perm
pass /ht_root/runtime/* /ht_root/runtime/*
script+ * /mercurial_home/hgcgiplus* \
    map=once ods=5 script=syntax=unix script=query=none \
    script=as=mercurial throttle=1,,,30 \
    script=param=PYRTE=/WSGI=BUFFER

This is a little more involved.  The first couple lines ensure that all the static data references, like images and CSS for the template, are available.  The next is a special rule added for the purpose of  showing the Mercurial FastCGI procedure for this post.  The next two lines ensures that the HTTP error message help pages all work correctly.  Lastly, the line that allows everything to run.

The final rule ensures that everything not matched by the preceding pass rules is treated as a query string to be processed by Mercurial.  All path names are translated to the POSIX/UNIX format.  According to the WASD PyRTE documentation the final line causes a 4x improvement in speed.

The final step in the configuration is to set up the MERCURIAL user that the hgcgiplus.com script executes under.  I simply copied the HTTP$NOBODY user that is created as part of the WASD installation.  I used the following commands:

UAF> COPY HTTP$NOBODY MERCURIAL/OWNER="Mercurial Server"/UIC=[ggg,uuu]

With the MERCURIAL user created the protections can be set on the hgcgiplus.com procedure, like so:

$ SET SECURITY/ACL=((IDENTIFIER=WASD_HTTP_NOBODY,ACCESS=READ+EXECUTE), -
                    (IDENTIFIER=*,ACCESS=NONE)) -
              /OWNER=MERCURIAL MERCURIAL_HOME:[000000]HGCGIPLUS.COM

Now that everything is configured I told WASD to re-read its configuration and show me what I had created.

$ HTTPD == "$HT_EXE:HTTPD"
$ HTTPD/DO=DCL=PURGE/CLUSTER
$ HTTP/DO=MAP/CLUSTER

Voila!  Now we have a working Mercurial repository.  For the moment it is pull only.  All modifications to the repository are handled locally.  In the not to distant future I intend to get the push functionality up and running.  When I do so, I'll post about that and how to configure the security necessary when providing the push facility.

Now, wouldn't it be wonderful if it had been that easy?  Of course this is the shortened version with everything in the correct order and neatly written out.  I spent a while playing  around trying to get things working changing configurations, putting them back again and so on.  Hopefully everything above will save somone the hassle of figuring it out for themselves also.

Did I miss anything?  Post a comment below and let me know.

[PRINT]  [PRINT]