djangoproject.com | nginx.org | python.org | linux.com
version seven.
  http://demongin.org
demongin.org - Serving Mercurial Repositories with Ubuntu is Hell of Easy

Serving Mercurial Repositories with Ubuntu is Hell of Easy

Seriously: setting this up is easier than falling down the stairs, especially if you're already serving other code repositories via HTTPS


Thursday, 2010-04-01 | Careerism, On the Internet, Programming

Our business in life is not to succeed but to continue to fail in high spirits.

Robert Louis Stevenson

Setting up the Repository

Assuming you're starting from utter scratch, the first thing you'll want to do is install mercurial:

toconnell@lana:~$ aptitude update && apt-get install mercurial
Now, decide where you want your repositories to live. I like to stick mine in /opt:
root@lana:/opt/hg/toconnell$ cd /
root@lana:/$ ls /opt
dump  share  svn
root@lana:/$ mkdir /opt/hg
root@lana:/$ cd /opt/hg/
Once the "root" of your repository is created, go ahead and create a repository.
root@lana:/opt/hg# mkdir toconnell
root@lana:/opt/hg# chown toconnell: toconnell/
root@lana:/opt/hg# su toconnell
toconnell@lana:/opt/hg$ cd toconnell/
toconnell@lana:/opt/hg/toconnell$ hg init 
Now that you've got a root and a repository, you're going to need to copy the cgi application that serves repositories into that directory. Find it and copy it like this:
toconnell@lana:/opt/hg/toconnell$ exit
root@lana:/opt/hg/toconnell# cd ..
root@lana:/opt/hg$ dpkg -S mercurial |grep hgwebdir
mercurial-common: /usr/share/doc/mercurial-common/examples/hgwebdir.cgi
mercurial-common: /usr/share/pyshared/mercurial/hgweb/hgwebdir_mod.py
root@lana:/opt/hg$ cp /usr/share/doc/mercurial-common/examples/hgwebdir.cgi .
Once it's there, make it executable by the apache user:
root@lana:/opt/hg# ls -l hgwebdir.cgi 
-rw-r--r-- 1 root root 2280 2010-04-01 12:53 hgwebdir.cgi
root@lana:/opt/hg# chmod +x hgwebdir.cgi
root@lana:/opt/hg# ls -l hgwebdir.cgi 
-rwxr-xr-x 1 root root 2280 2010-04-01 12:53 hgwebdir.cgi
Now you'll need to whip up a small config file that names your repos and provides their paths:
root@lana:/opt/hg# echo -e "[paths]\ntoconnell = /opt/hg/toconnell" > hgweb.config
...and then you create an hgrc file that specifies which users you want to be able to push to it:
root@lana:/opt/hg# echo -e "[paths]\nallow_push = toconnell" > toconnell/.hg/hgrc
And that's it. Once those meager pieces are in place, all that's left to do is edit or create an apache conf.

Configuring Apache

If you're already serving a subversion repository via SSL, all you've got to do is add about half a dozen lines and you're good to go. Say you've already got an apache config file like this in your /etc/apache/sites-enabled directory

root@lana:/etc/apache2/sites-enabled# cat 001-repositories 
<VirtualHost *:443>
        ServerName tyrannybelle.com
        ServerAdmin toconnell@tyrannybelle.com

        DocumentRoot /var/www/https
        ErrorLog /var/log/apache2/repo-error.log
        CustomLog /var/log/apache2/repo-access.log combined

        SSLEngine on
        SSLCertificateFile /path/to/ssl.pem

        RewriteEngine On
        RewriteCond %{HTTP_HOST} ^www\.tyrannybelle\.com$ [NC]
        RewriteRule ^(.*)$ https://tyrannybelle.com

        RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
        RewriteRule .* - [F]

        <Directory />
            Options Indexes FollowSymLinks MultiViews ExecCGI
            AllowOverride Limit Options FileInfo
            Order Allow,Deny
            Allow from All
        </Directory>

        <Location /toc-svn>
          DAV svn
          SVNPath /opt/svn/toconnell
          AuthType Basic
          AuthName "toconnell's private SVN repository"
          AuthUserFile /path/to/htpasswd.repositories
          Require valid-user
          SSLRequireSSL
        </Location>
</VirtualHost>
There are only two changes you'll need to make to the above file to rehabilitate it to serve your new mercurial repositories: If you haven't already got an SVN repo up and running on HTTPS, just go ahead and use the example above, eschewing the bit about SVN.

Once you've got a suitable apache config file, just restart apache and navigate to the ScriptAlias you've just created. In my case, this would be https://tyrannybelle.com/hg. After you pass HTTPS basic auth, you should see a nice view of your repositories.

Just to make sure everything is working, go ahead and do some stuff server-side:
toconnell@lana:/opt/hg$ cd toconnell/
toconnell@lana:/opt/hg/toconnell$ mkdir python_one-offs/
toconnell@lana:/opt/hg/toconnell$ hg add python_one-offs/
toconnell@lana:/opt/hg/toconnell$ hg commit python_one-offs/
Then, finally, on your local machine, just dial up the server and clone your repo down:
toconnell@esme:~$ hg clone https://tyrannybelle.com/hg/toconnell
http authorization required
realm: Mercurial repositories
user: toconnell
password: 
destination directory: toconnell
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
And that's that: easy-peasy.