1 Introduction
Repositories are useful in managing software projects, mainly because they provide a means of source code collaboration. There are various forms of repositories, though this post will talk about
Mercurial, which is a distributed version control system. Mercurial is typically used in situations where a software project is managed in a team, with various users developing on the same code base. A source control management system can be internal which means that it is only available on the local machine or local area network. The internal solution is ideal for personal projects work, though for more open work an external solution is necessary to allow for accessibility from any Internet connection. This guide will detail the process of setting up an external solution since it requires much more work then an internal set up. To do this Mercurial will be set up behind an
Apache HTTP Server that is configured to provide external access.
2 System Setup
Due to the popularity of
Ubuntu, and personal usage of
Arch Linux both commands will be outlined when needed. The commands will begin with either
ubuntu#
or
arch#
for the specific distribution, otherwise just a
#
will be used when both are applicable. In addition, most Linux distributions are fairly similar which means that the installations of packages will be the same for the majority. The release for Arch Linux is 2009.08, and the release for Ubuntu is 10.04, both on 32-bit architecture.
For Ubuntu, just perform the following to acquire and setup Apache, PHP and MySQL. Then skip to section 3.
ubuntu# sudo apt-get install lamp-server^
2.1 Install Apache
Install the Apache package.
arch# sudo pacman -S apache
Apache should work right now, a quick test using the following command should start Apache.
arch# sudo /etc/rc.d/httpd start
To confirm it works browse to
http://localhost/. Then close down Apache for now.
arch# sudo /etc/rc.d/httpd stop
Make the Apache service starts on boot, the httpd deamon will be added to the
/etc/rc.conf
file.
DEAMONS=(... httpd ...)
2.2 Install PHP
Install the required PHP packages.
arch# sudo pacman -S php php-apache
Add the following to the
/etc/httpd/conf/httpd.conf
file at the end of the LoadModule list.
LoadModule php5_module modules/libphp5.so
Add the following to the
/etc/httpd/conf/httpd.conf
file at the end of it.
Include conf/extra/php5_module.conf
Change the following line in the
/etc/httpd/conf/httpd.conf
file to include the bold word.
Options Indexes FollowSymLinks Includes
To test that PHP is operational first make a test file
/srv/http/test.php
with the following text.
<? php phpinfo(); ?>
Restart/start Apache back up.
arch# sudo /etc/rc.d/httpd start
To confirm it works browse to
http://localhost/test.php and PHP information should be visible.
3 Mercurial Repositories
This section is dedicated to making Mercurial repositories accessible externally from the server. The first thing is to first install the Mercurial packages.
ubuntu# sudo apt-get install mercurial
--or--
arch# sudo pacman -S mercurial
3.1 Create Folder for Mercurial Repositories
A directory that is not located directly in the web server needs to be created to hold just the repositories (done so that repositories are not exposed). For me Redmine is being used, so ideally the repositories can be placed in there. The following directory needs to be created:
# sudo mkdir /srv/redmine/extra/hg
3.2 Create Folder for Mercurial Scripts
A directory in the web server folder needs to be created to hold the CGI scripts to allow mercurial to be accessible via the web server. The following directory needs to be created:
arch# sudo mkdir /srv/http/cgi-bin
--or--
ubuntu# sudo mkdir /var/www/cgi-bin
3.3 Create hgweb.config File
Within the previously created folder
cgi-bin
, the file
hgweb.config
needs to be created. This file directs where the Mercurial repositories are located. It needs to be created with the following contents:
[collections]
/srv/redmine/extra/hg/ = /srv/redmine/extra/hg/
The created file is the bare-minimum required for this set up to function. The paths should be set correctly to the system's file structure. In the case where a more fine-tuned file is needed, please consult the mercurial support page.
3.4 Create hgwebdir.cgi File
Within the previously created folder
cgi-bin
, the file
hgwebdir.cgi
needs to be created. This file is used to enable interaction from the external connection on the Mercurial repositories. It needs to be created with the following contents:
#!/usr/bin/env python
from mercurial import demandimport; demandimport.enable()
import cgitb
cgitb.enable()
import os
os.environ["HGENCODING"] = "UTF-8"
from mercurial.hgweb.hgwebdir_mod import hgwebdir
import mercurial.hgweb.wsgicgi as wsgicgi
application = hgwebdir('hgweb.config')
wsgicgi.launch(application)
The created file is the bare-minimum required for this set up to function. In the case where a more fine-tuned file is needed, please consult the Mercurial support page.
3.5 Configure Permissions
The web server need to have executable permissions on the
hgwebdir.cgi
file to allow for proper functionality. This can be set by being in the correct directory and executing the following command in terminal:
# sudo chmod a+x /path/to/hgwebdir.cgi
3.6 Configure Apache Access to the Repositories
A file is needed to configure Apache to direct certain HTTP requests to act towards the mercurial repositories. This is done by editing/adding the following to the
httpd.conf
, the file is located at:
arch# /etc/httpd/conf/httpd.conf
--or--
ubuntu# /etc/apache2/httpd.conf
The following contents is what should be included in the file (note the paths need to be configured according to the system):
ScriptAliasMatch ^/hg(.*) /path/to/cgi-bin/hgwebdir.cgi$1
<Directory /path/to/cgi-bin/>
Options ExecCGI FollowSymLinks
AllowOverride None
</Directory>
<Location /hg>
AuthType Digest
AuthName "mercurial"
AuthDigestProvider file
AuthUserFile /srv/redmine/extra/hg/hgusers
Require valid-user
</Location>
The idea is that for security reasons the authentication type used will be digest and it will only transmit the MD5 hash of the passwords. The authentication name must be consistent with the generation of the password(the
realm), and acts as an additional salt value (pick what ever you will remember, since you will need it for every user you will create). The authentication file will be located beside the repositories and in this example is called
hgusers
. This file needs to be created and managed using the
htdigest
command (a script to simplify this is attached to this guide). This configuration also will only allow for the repositories to be accessed if the user is authenticated. For additional configurations please refer to the Mercurial website's instructions.
In addition, due to the use of the digest authentication method Apache requires the appropriate modules. For Arch Linux the modules should already be enabled by default, if not by chance you just need to enable the following modules:
auth_digest
In Ubuntu that module must be moved from the
/etc/apache2/mods-available/
to
/etc/apache2/mods-enabled/
4 Services Available
There are now a few services available on this server:
- Functioning Apache web server
- PHP and MySQL enabled on the web server
- Protected Mercurial repositories available externally
With these services it become possible to host a website to indicate the location of the Mercurial repositories or possibly to a different tool (such as Redmine). MySQL is a useful service to have available regardless since there are various applications out there that can benefit from a standard database such as MySQL.
Mercurial now exists on the system and so users are able to perform the basic Mercurial functions. Cloning from any Mercurial repository, as well as being able to start local repositories are now possible. In addition there is always the possible of creating an hosting externally accessible repositories such as how this guide as instructed.
5 Conclusion
By the end of this guide Mercurial should be completely set up along with Apache and PHP. Repositories are externally available and a greater understanding on how to manage it should have been acquired. If in doubt there is plenty of resources available online. There is also the
mercurial-helper.sh
script that I made to help with user and repository management (I will post about this script eventually).
5.1 Key Notes
For the remote repositories to automatically update (using the hooks) the owner of the repository must be what runs the web service. In most cases this is the
www-data
user, if ever in doubt you can always use these commands to reset the owner and modes.
# sudo chown -R www-data /srv/redmine/extra/hg/
--then--
# sudo chmod -R 755 /srv/redmine/extra/hg/
Additionally, a typical
./project/.hg/hgrc
configuration would looks like:
[paths]
default = /srv/redmine/extra/hg/project/
[web]
allow_push = user
contact = user
description = Fill me out (in ./project/.hg/hgrc)
push_ssl = false
style = gitweb
[trusted]
users = *
groups = *
[hooks]
changegroup = hg update
These settings are used to allow users (which have to be authenticated using the
hgusers
file) to push back to the externally located repository. The reasoning for the hook section is to have the external repository to update when it receives a change set from a user. The trusted section is used to ensure that regardless of the users and groups using the repository (locally) that the pushes will still carry through. The rest of these settings can be found in the Mercurial documentation.