Mercurial repository publication

From ImageWeb

Jump to: navigation, search

Procedure for installing Mercurial software on Linux for repository sharing.

These notes describe installation of Mercurial on Ubuntu Linux 8.04 (Hardy Heron). The software was installed from source in this case as the version available for APT from the Ubuntu repositories is very old.

Mercurial is being chosen over Subversion for two main reasons:

  • it does not create extra files in the working directories, making it more suitable for versioning arbitrary parts of a directory tree, hence possibly suitable for versioning research data, and
  • it supports distributed versioning, allowing developers to make frequent commits to a local repository, and then push the result back to a shared repository when all tests pass: this is a better match for agile, test-led development than the working styles using Subversion.

See also:

Contents

Install Mercurial software

cd ~
wget http://mercurial.selenic.com/release/mercurial-1.4.2.tar.gz
tar xvfz mercurial-1.4.2.tar.gz 
cd mercurial-1.4.2/
sudo apt-get install python-dev
sudo make install
sudo nano /etc/mercurial/hgrc.d/hgext.rc 
nano ~/.hgrc
hg debuginstall

Content of ~/.hgrc (use appropriate name and email address):

[ui]
username = Graham Klyne <gk@domain>

Content of /etc/mercurial/hgrc.d/hgext.rc is pretty much per distribution. I needed to comment out hgext.imerge and hgext.interhg, as these are now built-in to the Mercurial core, not add-ons as ther werein earlier versions:

# mercurial configuration file for upstream hg extensions
# See hgrc(5) for more information

[extensions]

# changeset access control for mercurial
# hgext.acl=

# allow user-defined command aliases
# hgext.alias=

# bugzilla integration for mercurial
# hgext.bugzilla=

# show the children of the given or working dir revision
# add the 'children' command
hgext.children=

# create a graph showing who changed the most lines
# add the 'churn' command
hgext.churn=

# Foreign SCM converter
# add the 'convert' and 'debugsvnlog' commands
hgext.convert=

# external diff program support for mercurial
# hgext.extdiff=

# pull and merge remote changes
# add the 'fetch' command
hgext.fetch=

# GnuPG signing extension for Mercurial
# add the 'sign', 'sigcheck' and 'sigs' commands
hgext.gpg=

# ASCII graph log extension for Mercurial
# add the 'glog' command
hgext.graphlog=

# Dichotomic search in the DAG of changesets
# add the 'bisect' command
# hgext.hbisect=

# allows browsing the history of a repository in a graphical way
# add the 'view' command
hgext.hgk=

# lets you split a merge into pieces
# add the 'imerge' command
# hgext.imerge=

# allows you to change changelog and summary text
# hgext.interhg=

# patch queues for mercurial
# add the 'q*' commands
hgext.mq=

# email notifications for mercurial
# hgext.notify=

# make it easy to refer to the parent of a revision
# hgext.parentrevspec=

# send changes as series of email patches
# add the 'email' command
hgext.patchbomb=

# removes files not known to mercurial
# add the 'purge' and 'clean' commands
hgext.purge=

# interactive change selection during commit
# add the 'record' command
hgext.record=

# Patch transplanting extension for Mercurial
# add the 'transplant' command
hgext.transplant=

# add filters so automatically convert end-of-line between Windows and Unix
# world.
# hgext.win32text=

Publish repository via Apache web server

sudo cp ~/mercurial-1.4.2/hgwebdir.cgi /var/www/
sudo nano /var/www/hgweb.config
sudo chmod +x /var/www/hgwebdir.cgi 
sudo nano /etc/apache2/sites-available/mercurial.conf
sudo a2ensite mercurial.conf
sudo /etc/init.d/apache2 reload
sudo mkdir /usr/files/hg
sudo chown www-data: /usr/files/hg
# Create a repository
sudo -u www-data hg init /usr/files/hg/sysconfig

Content of /var/www/hgweb.config (use repository name and path to suit):

[paths]
sysconfig = /usr/files/hg/sysconfig

Content of /etc/apache2/sites-available/mercurial.conf:

# Use script for accessing Mercurial repositories
ScriptAlias /hg "/var/www/hgwebdir.cgi"

Browse to /hg on target host to see list of repositories.

Enable digest authentication for repository updates (push)

sudo nano /etc/apache2/sites-available/mercurial.conf
sudo htdigest -c /etc/apache2/hgusers mercurial graham
sudo a2enmod auth_digest 
sudo /etc/init.d/apache2 reload
sudo htdigest /etc/apache2/hgusers mercurial graham

Revised content of /etc/apache2/sites-available/mercurial.conf:

# Use script for accessing Mercurial repositories
ScriptAlias /hg "/var/www/hgwebdir.cgi"

<Location /hg>
    AuthType Digest
    AuthName "mercurial"
    AuthDigestDomain /hg 
    AuthDigestProvider file
    AuthUserFile /etc/apache2/hgusers
    <LimitExcept GET>
        Require valid-user
    </LimitExcept>
</Location>


Enable Apache SSL access

sudo a2enmod ssl
sudo nano /etc/apache2/sites-available/default
sudo openssl genrsa -des3 -out server.key 1024  # with passphrase
sudo openssl genrsa -out server.key 1024  # without p[assphrase
sudo openssl req -new -key server.key -out server.csr
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
sudo cp server.crt /etc/ssl/certs
sudo cp server.key /etc/ssl/private
sudo /etc/init.d/apache2 force-reload
cat /etc/apache2/ports.conf  # Check for listen on port 443 
sudo ufw allow 443 # allow access through firewall

Content of /etc/apache2/sites-available/default:

NameVirtualHost *
#ServerName luggage.atuin.ninebynine.org
ServerName localhost
DocumentRoot /var/www/

ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined

<VirtualHost *>
    ServerName luggage.atuin.ninebynine.org
        DocumentRoot /var/www/
        ServerAdmin webmaster@localhost

        SSLEngine on
        SSLOptions +StrictRequire
        SSLCertificateFile /etc/ssl/certs/server.crt
        SSLCertificateKeyFile /etc/ssl/private/server.key

         :

</VirtualHost>

Note that the virtual host configures as described above may no longer accept non-SSL requests on port 80. One option is to redirect port 80 requests to https: on port 443. Another is to use a dedicated virtual host for the mercurial repository: I have removed the SSL directives from the <virtualhost *> section, and have a file /etc/apache2/sites-available/mercurial.conf that looks like this:

# Use script for accessing Mercurial repositories

ScriptAlias /hg "/var/www/hgwebdir.cgi"

<Location /hg>
    AuthType Digest
    AuthName "mercurial"
    AuthDigestDomain /hg
    AuthDigestProvider file
    AuthUserFile /etc/apache2/hgusers
    <LimitExcept GET>
        Require valid-user
    </LimitExcept>
</Location>

<VirtualHost hg.atuin.ninebynine.org:443>
    ServerName hg.atuin.ninebynine.org
    DocumentRoot /var/www/
    ServerAdmin webmaster@localhost

    SSLEngine on
    SSLOptions +StrictRequire
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key

    ScriptAlias /hg "/var/www/hgwebdir.cgi"

    <Location /hg>
        AuthType Digest
        AuthName "mercurial"
        AuthDigestDomain /hg
        AuthDigestProvider file
        AuthUserFile /etc/apache2/hgusers
        <LimitExcept GET>
            Require valid-user
        </LimitExcept>
    </Location>
</VirtualHost>

This setup allows http: for read access, and https: for updates when directed to host hg.atuin.ninebynine.org. It does require that hg.atuin.ninebynine.org is resolved appropriately by DNS.

Notes

According to http://httpd.apache.org/docs/2.2/vhosts/name-based.html, the various directives interact thus:

  • NameVirtualHost (top-level): specifies the IP address (not name!) and optionally the port on which the HTTP server will listen for name-based virtual host requests.
  • <virtualhost> blocks are created for each different named host to be served. The argument to the <VirtualHost> directive must match a defined NameVirtualHost directive.
  • ServerName directives are used within a <VirtualHost> block to indicate the HTTP request host name whose handling is defined by other directives within the same block.
  • ServerAlias, DocumentRoot, ScrioptAlias and other directives within a <VirtualHost> block are used to define how requests for a particular virtual host are served.

(Having read this, I think it may be possible to configure the http: and https: protocols to work side-by-side for a given hostname by defining something along these lines:

ServerName localhost
DocumentRoot /var/www/

NameVirtualHost *:80
<VirtualHost *:80>
    ServerName luggage.atuin.ninebynine.org
    DocumentRoot /var/www/

     :

</VirtualHost>

NameVirtualHost *:443
<VirtualHost *:443>
    ServerName luggage.atuin.ninebynine.org
    DocumentRoot /var/www/

    SSLEngine on
    SSLOptions +StrictRequire
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key

     :

</VirtualHost>

Allow web push to repository

sudo nano /etc/mercurial/hgrc

or

sudo nano <repository-path>/.hg/hgrc


Content of /etc/mercurial/hgrc:

# system-wide mercurial configuration file
# See hgrc(5) for more information
[web]
allow_push = *
Personal tools
Oxford DMP online
MIIDI
Claros