Local storage publishing with Mercurial and Apache

To be able to access your local storages directly with a Mercurial client, you can follow this instructions.

Generating a Self-Signed Certificate

First of all, you need a SSL (Secure Socket Layer) certificate.

The first step is to create your RSA Private Key. This key is a 1024 bit RSA key which is encrypted using Triple-DES. We also need a private key without pass-phrase (.pem) for Apache.

$ openssl genrsa -des3 -rand /etc/passwd -out server.key 1024
$ openssl rsa -in server.key -out server.pem

Once the private key is generated, a Certificate Signing Request can be generated.

$ openssl req -new -key server.key -out server.csr

At this point you will need to generate a self-signed certificate.

$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

Finally, install these files in Apache configuration directory.

$ sudo mkdir /etc/apache2/ssl
$ sudo cp server.crt server.pem /etc/apache2/ssl/
$ sudo chmod og-r /etc/apache2/ssl/server.pem

Installing Mercurial Configuration Files

Create a directory for Mercurial configuration for pfinstance:

$ su pfinstance
$ mkdir Mercurial

Add in Mercurial/ directory a hgwebdir.conf file such as:

[web]
style = gitweb
allow_archive = gz, zip, bz2
allow_push = *
push_ssl = false

[paths]
/ = /home/pfinstance/PubliForge/Storages/*

And complete with a hgwebdir.wsgi file like:

from mercurial import demandimport
from mercurial.hgweb.hgwebdir_mod import hgwebdir
from os import environ

demandimport.enable()
environ['VIRTUAL_ENV'] = '/usr/local/virtualenv'
environ['HGENCODING'] = 'UTF-8'
application = hgwebdir('/home/pfinstance/Mercurial/hgwebdir.conf')

The last thing to do in Mercurial/ directory is to create a users file with htpasswd utility:

$ cd Mercurial
$ htpasswd -s -c users user1
$ htpasswd -s users user2

Configuring Apache

In this section, we assume you have installed Apache with module mod_ssl.

Activate module SSL:

$ sudo a2enmod ssl

Now, in /etc/apache2/sites-available, create or complete a pfinstance file with the following content:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName hg.pfinstance.org
    DocumentRoot /home/pfinstance/PubliForge/Storages
    CustomLog  ${APACHE_LOG_DIR}/access_pfinstance.log combined

    SSLEngine on
    SSLCertificateFile    /etc/apache2/ssl/server.crt
    SSLCertificateKeyFile /etc/apache2/ssl/server.pem

    <Location />
      Allow from all
      SSLRequireSSL

      AuthType Basic
      AuthName "PFInstance - Mercurial"
      AuthUserFile /home/pfinstance/Mercurial/users
      Require valid-user
    </Location>

    WSGIDaemonProcess hginstance \
       user=pfinstance group=pfinstance \
       home=/home/pfinstance/PubliForge/Storages \
       processes=1 threads=15 maximum-requests=1000 \
       python-path=/usr/local/virtualenv/lib/python2.7/site-packages \
       python-eggs=/home/pfinstance/PubliForge/Cache/Tmp

    WSGIScriptAlias / /home/pfinstance/Mercurial/hgwebdir.wsgi
    <Directory /home/pfinstance/Mercurial>
      WSGIProcessGroup hginstance
      Require all granted
    </Directory>

    # SSL Protocol Adjustments for MSIE
    BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown \
        downgrade-1.0 force-response-1.0
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
</IfModule>

Lastly, activate your new Apache configuration and reload Apache:

$ sudo a2ensite pfinstance
$ sudo service apache2 reload

Now, your PubliForge storages with local version control system are reachable as Mercurial repository. You can use a Mercurial client to clone them with URL such as https://hg.pfinstance.org/MyStorageID.