In the previous post I discussed some things to consider when publishing mercurial repositories. Here I explain the steps I took to setup and configure Mercurial repository publishing via SSH and HTTPS on CentOS 5.5 x64.
Prerequisites
These are the prereqs for my setup. Most of these instructions will probably work on other distros and web servers, but the exact commands and details will vary.
- CentOS 5.5
- Apache 2.x (Installed and Configured)
- root or sudo access on the server
- Internet Connection during installation (yes, some of us do development on offline networks)
Download and Install Packages
The mercurial packages that are available directly out of the CentOS repositories and RPMForge for CentOS 5.5 were too old for my liking. I downloaded the latest RPMs (at the time of writing) directly. Update 2011/03/30: Mercurial 1.8.x is now in RPMForge for EL5 so you can get it directly via yum.
sudo yum install python-docutils python-setuptools mercurial mercurial-hgk mercurial-ssh
I ran into an dependency resolution issue because I have the EPEL repo enabled with a higher priority than RPMForge. I added the following line to the [epel] entry in /etc/yum.repos.d/epel.repo to force yum to look for mercurial elsewhere so it pulled from RPMForge.
exclude=mercurial,mercurial-hgk,mercurial-ssh
Create an hg Group
I find it useful to create a group for all of the version control users on the server because I want to support both HTTPS and SSH access. If you are using HTTPS access only, then you don’t need a group here since it will all be done via apache. I used hg here but you could use anything you want like vcs or versioncontrol.
sudo groupadd hg
# Add all committers to the hg group using usermod
Create and Configure a Repo
Note that I go through a few extra hoops here to allow multiple-committers since I want to support both SSH and HTTPS access.
# Create your new Hg repo (or copy the existing one) in /srv/hg
sudo hg init /srv/hg/
# Make the repo writable by the group for a multiple-committers environment
cd /srv/hg/
sudo chgrp hg .hg .hg/* .hg/store/*
sudo chmod g+w .hg .hg/* .hg/store/*
sudo chmod g+s .hg .hg/* .hg/store/data
# Give ownership of Hg repos to the apache user
sudo chown -R apache /srv/hg/
# Setup your .hgignore file to handle files you don't want under version control
# Add your project files to the repo
hg add
# Commit your project
hg commit
Setup HgWeb
There is great documentation on how to do this on the Mercurial Wiki but here are the steps I used.
# Setup Hgweb for HTTP access using mod_python
sudo mkdir /etc/hgweb
sudo mkdir /var/hg
sudo vim /var/hg/hgwebdir.py
########## BEGIN COPY BELOW THIS LINE ###########
#!/usr/bin/env python
#
import cgitb
cgitb.enable()
from mercurial.hgweb.hgwebdir_mod import hgwebdir
from mercurial.hgweb.request import wsgiapplication
import mercurial.hgweb.wsgicgi as wsgicgi
def make_web_app():
return hgwebdir("/etc/hgweb/hgwebdir.conf")
def start(environ, start_response):
toto = wsgiapplication(make_web_app)
return toto (environ, start_response)
############ END COPY ABOVE THIS LINE ############
sudo vim /etc/hgweb/hgwebdir.conf
######### COPY BELOW THIS LINE #############
[collections]
/srv/hg = /srv/hg
[web]
style = gitweb
allow_archive = bz2 gz zip
contact = Your Name, your.email@address.com
allow_push = *
push_ssl = true
######## END COPY ABOVE THIS LINE ###########
Setup modpython_gateway
We need a dynamic landing page to handle access to the collection of all repos available on the box rather. This way we don’t have to setup a static landing page for each and every repo we publish. I’m using the ever popular modpython_gateway script for this.
wget http://www.aminus.net/browser/modpython_gateway.py?format=raw
sudo mv modpython_gateway.py\?format\=raw /var/hg/modpython_gateway.py
# IMPORTANT! Only use the -c flag for the FIRST person you add, drop it for every add after that
sudo htdigest -c /etc/hgweb/users.htdigest "Zach's Mercurial Repository" burly
sudo vim /etc/httpd/conf.d/hgweb.conf
######### BEGIN COPY BELOW THIS LINE ########
PythonPath "sys.path + ['/var/hg']"
SetHandler mod_python
PythonHandler modpython_gateway::handler
PythonOption wsgi.application hgwebdir::start
AuthType Digest
AuthName "Zach's Mercurial Repository"
AuthDigestProvider file
AuthUserFile "/etc/hgweb/users.htdigest"
Require valid-user
# Redirect all non-SSL traffic automagically
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
####### END COPY ABOVE THIS LINE ##########
Configure Apache
We need to enable WSGI handling in apache and that we have all the right file permissions. If you don’t have a CA cert you’ll need to setup one up if you want to use SSL. Here is how to do that on CentOS.
sudo vim /etc/httpd/conf/httpd.conf
# Add the Following Lines in their Respective Locations in the Conf
####### BEGIN COPY BELOW THIS LINE ########
LoadModule wsgi_module modules/mod_wsgi.so
AddHandler wsgi-script .wsgi
####### END COPY ABOVE THIS LINE #########
sudo chown -R root.root /etc/hgweb
sudo chown apache.apache /etc/hgweb/users.htdigest
sudo chmod 400 /etc/hgweb/users.htdigest
sudo chown -R apache.apache /var/hg
sudo service httpd restart
Use your Repo!
You should now be able to view your repositories by pointing your browser at http://yermachinenameorip/hg and you should be prompted for the username and password created in your htdigest file from earlier (i.e. not your shell account credentials). Note that due to the re-write rule in our hgweb.conf file, you should automatically be redirected to the SSL version of the site.
You should now be able to clone your repo via https and your htdigest credentials via:
hg clone https://@yermachinenameorip/hg/reponame
or via SSH and your shell account credentials via:
hg clone ssh://@yermachinenameorip/srv/hg/reponame
Maintenance
#--------------------------
# Create a new project
#--------------------------
hg init /srv/hg/<reponame>
# Make the repo writable by the group for a multiple-committers environment
cd /srv/hg/<reponame>
sudo chgrp hg .hg .hg/* .hg/store/*
sudo chmod g+w .hg .hg/* .hg/store/*
sudo chmod g+s .hg .hg/* .hg/store/data
# Give ownership of Hg repos to the apache user
sudo chown -R apache /srv/hg/<reponame>
hg add
hg commit
#--------------------------
# Add a new user
#--------------------------
useradd -G hg
passwd
# Set the htaccess password for the user
htpasswd /etc/hgweb/users.htdigest
Additional Resources