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

11 thoughts to “Mercurial on CentOS 6.2”

  1. Starting httpd: Syntax error on line 1013 of /etc/httpd/conf/httpd.conf:
    Invalid command ‘<VirtualHost’, perhaps misspelled or defined by a module not included in the server configuration

  2. hg init software
    Traceback (most recent call last):
    File “/usr/bin/hg”, line 38, in
    mercurial.dispatch.run()
    File “/usr/lib/python2.6/site-packages/mercurial/dispatch.py”, line 27, in run
    sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
    File “/usr/lib/python2.6/site-packages/mercurial/dispatch.py”, line 40, in dispatch
    req.ui = uimod.ui()
    File “/usr/lib/python2.6/site-packages/mercurial/ui.py”, line 43, in __init__
    for f in scmutil.rcpath():
    File “/usr/lib/python2.6/site-packages/mercurial/scmutil.py”, line 430, in rcpath
    _rcpath = osrcpath()
    File “/usr/lib/python2.6/site-packages/mercurial/scmutil.py”, line 402, in osrcpath
    path = systemrcpath()
    File “/usr/lib/python2.6/site-packages/mercurial/scmutil.py”, line 455, in systemrcpath
    path.extend(rcfiles(os.path.join(p, root)))
    File “/usr/lib/python2.6/site-packages/mercurial/scmutil.py”, line 440, in rcfiles
    for f, kind in osutil.listdir(rcdir)
    File “/usr/lib/python2.6/site-packages/mercurial/demandimport.py”, line 86, in __getattribute__
    self._load()
    File “/usr/lib/python2.6/site-packages/mercurial/demandimport.py”, line 58, in _load
    mod = _origimport(head, globals, locals)
    ImportError: /usr/lib/python2.6/site-packages/mercurial/osutil.so: wrong ELF class: ELFCLASS32
    -bash-4.1# semodule -i httpd-mercurial.pp
    semodule: Failed on httpd-mercurial.pp!

Leave a Reply

Your email address will not be published. Required fields are marked *