Mercurial on CentOS 6.2

For pure server tasks there is probably no better free distribution than CentOS. What is then more natural than use it as a Mercurial server?

I will assume that CentOS 6.2 is already installed (at least minimal) and DHCP (if used) is already set up. Simplest test would be connecting via SSH. If you can connect, you are ready.

First step would be to install our web server. There is no doubt (ok, there is some) that Apache is way to go here.

yum install httpd
service httpd start
chkconfig httpd on

After installation we need to adjust firewall and test out setup by pointing our browser to whichever address our server has (in my case that would be 192.168.56.101). When you get Apache test page, you can continue further. Until that time, fiddle with settings.

There is already a Mercurial package included within CentOS repository but it is rather old version (1.4). We will go with newest and greatest. At time of writing that would be Mercurial 2.2.2.

rpm -Uvh http://pkgs.repoforge.org/mercurial/mercurial-2.2.2-1.el6.rfx.i686.rpm

Now let’s create directory structure:

mkdir -p /srv/hg/cgi-bin
cp /usr/share/doc/mercurial-2.2.2/hgweb.cgi /srv/hg/cgi-bin/.

Next we need to edit /srv/hg/cgi-bin/hgweb.cgi. Find line that has config parameter and replace value with “/srv/hg/cgi-bin/hgweb.config”. Then create /srv/hg/cgi-bin/hgweb.config and write:

[collections]
/srv/hg/ = /srv/hg/

[web]
allow_push = *
push_ssl = false

Those settings will allow for HTTP-only operation where everybody (authorized) can push changes. For small networks this might be suitable, but you should probably be looking into at least enabling HTTPS. Guides for that can be found all around. You can find even (Ubuntu-specific) https guide on these pages so feel free to adjust and configure.

Last change will be to /etc/httpd/conf/httpd.conf. At the very bottom we will add following text:

NameVirtualHost *
<VirtualHost *>
    DocumentRoot /srv/hg/cgi-bin/
    ScriptAliasMatch (.*) /srv/hg/cgi-bin/hgweb.cgi/$1
    <Directory "/srv/hg/cgi-bin/">
        SetHandler cgi-script
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog /var/log/httpd/hg.log
    <Location />
        AuthType Basic
        AuthName "Mercurial"
        AuthUserFile  /srv/hg/.htpasswd
        Require valid-user
    </Location>
</VirtualHost>

Short restart later (another service httpd restart) you should be greeted with 403 forbidden.

Turns out that there are few more things to do. First one would be to create new user (testuser).

htpasswd -c /srv/hg/.htpasswd testuser
 New password:
 Re-type new password:

After that is sorted out, we need to adjust directory rights:

chown -R apache:apache /srv/hg/
chmod a+x /srv/hg/cgi-bin/hgweb.cgi

Last setup step would be to adjust SELinux security a bit. Easiest way would be to disable it completely (check /etc/sysconfig/selinux). Proper way would be to just load module which allows actions that we need. While you can troubleshoot this yourself, I have also prepared pre-compiled SELinux module (only httpd-mercurial.pp is really needed, other file is for reference). After unpacking, just execute:

semodule -i httpd-mercurial.pp

And that is it. Now you will be able to access your repositories at 192.168.56.101 (replace IP with yours) and do with them as you please.

P.S. To create repository all you need is to:

cd /srv/hg/
hg init TestRepo
chown -R apache:apache TestRepo