In a previous post, you might have read that I was given a mission to set up a Mercurial code repository for users within a private network, to be accessed via passwords. What this meant was, use Apache web server to serve up a Mercurial repository as a live URL, with basic HTTP authentication via passwords.
Normally I access things stored in Mercurial through ssh protocol, not HTTP, so this was something I hadn't tried in a long time. My memory doesn't stretch back more than six months! So, I wrote down what I had to do to achieve this. I needed to make Mercurial, Apache, mod_wsgi and Python play nicely together.
I thought I would share the things I did to get things going. I'm assuming that you already know something about:
- Apache HTTP server
- Linux, the command line and apt for packages
- Python and WSGI
- Mercurial version control system (cloning)
If you're interested, the server was running slightly older versions of things: Ubuntu 10.04 and Python 2.6x. That's why I went with the slightly old mod_wsgi for Apache. Even though I did this on Ubuntu, I dare say these instructions would be almost identical for someone using Linux Mint, Crunchbang or Debian.
Here are the steps to follow, for a project named "booklister"
On the server
Make sure you have copied your project's source files over to the server first,
e.g. by zipping them and using scp
Install Apache and Mercurial
e.g. by zipping them and using scp
Install Apache and Mercurial
apt-get install apache2 mercurial
Install the mod_wsgi interface for Python
apt-get install libapache2-mod-wsgi
Restart Apache
/etc/init.d/apache2 restart
Install the mod_wsgi interface for Python
apt-get install libapache2-mod-wsgi
Restart Apache
/etc/init.d/apache2 restart
Install the Python module for Mercurial
pip install mercurial
Create an "hgusers" group for all users who will be working with the repository
groupadd hgusers
Add users into the group, using this format:
usermod -a -G GROUPNAME USERNAME
usermod -a -G hgusers scott
usermod -a -G hgusers anotheruser
Add users into the group, using this format:
usermod -a -G GROUPNAME USERNAME
usermod -a -G hgusers scott
usermod -a -G hgusers anotheruser
You can view the users in the new group:
cat /etc/group
Setup password access for Mercurial via Apache: create user passwords for Apache authentication using the htpasswd utility
htpasswd -cb /etc/apache2/hgpasswd scott scottspassword
htpasswd -b /etc/apache2/hgpasswd anotheruser anotherpassword
Create a directory which will hold the Mercurial repositories.
Set permissions on it for the Apache user and the hgusers group
cd /var/lib
mkdir hg_repos
chown -R www-data:hgusers hg_repos
chmod -R g+rwx hg_repos
Initialise a Mercurial repository, and copy source project files into it. Add them all into version control.
hg init booklister
cd booklister
cp -r /home/scott/temp/booklister/* .
hg add
cat /etc/group
Setup password access for Mercurial via Apache: create user passwords for Apache authentication using the htpasswd utility
htpasswd -cb /etc/apache2/hgpasswd scott scottspassword
htpasswd -b /etc/apache2/hgpasswd anotheruser anotherpassword
Create a directory which will hold the Mercurial repositories.
Set permissions on it for the Apache user and the hgusers group
cd /var/lib
mkdir hg_repos
chown -R www-data:hgusers hg_repos
chmod -R g+rwx hg_repos
Initialise a Mercurial repository, and copy source project files into it. Add them all into version control.
hg init booklister
cd booklister
cp -r /home/scott/temp/booklister/* .
hg add
Create an hgrc file (for Mercurial) in the repository's .hg directory
vim .hg/hgrc
[ui]
username = "scott@mycompany.com"
[trusted]
groups = hgusers
users = scott, anotheruser
[web]
allow_read = scott, anotheruser
allow_push = scott, anotheruser
allow_archive = gz, zip, bz2
push_ssl=False
Create an hgweb.wsgi file (for mod_wsgi) in the repository directory
vim hgweb.wsgi
#!/usr/bin/env python
""" File for Mercurial, Apache and mod_wsgi http access.
Enable demandloading to reduce startup time.
"""
from mercurial import demandimport
from mercurial.hgweb import hgweb
# Path to repo or hgweb config to serve (see 'hg help hgweb')
config = "/var/lib/hg_repos/booklister"
demandimport.enable()
application = hgweb(config)
Make an initial commit for the new files, with a comment
hg commit -m "First commit"
#!/usr/bin/env python
""" File for Mercurial, Apache and mod_wsgi http access.
Enable demandloading to reduce startup time.
"""
from mercurial import demandimport
from mercurial.hgweb import hgweb
# Path to repo or hgweb config to serve (see 'hg help hgweb')
config = "/var/lib/hg_repos/booklister"
demandimport.enable()
application = hgweb(config)
Make an initial commit for the new files, with a comment
hg commit -m "First commit"
Correct permissions on the repository files that may be new or changed
cd /var/lib/hg_repos
chown -R www-data:hgusers booklister
chmod -R g+rwx booklister
cd /var/lib/hg_repos
chown -R www-data:hgusers booklister
chmod -R g+rwx booklister
Edit the Apache config file (or a virtual host file). Add Directory and Location blocks.
vim /etc/apache2/apache2.conf
WSGIScriptAlias /booklister /var/lib/hg_repos/booklister/hgweb.wsgi
WSGIDaemonProcess booklister user=www-data group=hgusers threads=1 processes=10
<Directory /var/lib/hg_repos/booklister>
Options ExecCGI FollowSymlinks
AddHandler wsgi-script .wsgi
AllowOverride None
Order deny,allow
deny from all
allow from vvv.ww.xxx.y/zz
</Directory>
ScriptAlias /booklister "/var/lib/hg_repos/booklister/hgweb.wsgi"
<Location /booklister>
AuthType Basic
AuthUserFile /etc/apache2/hgpasswd
AuthName "Book Lister project repo"
Require valid-user
</Location>
Restart Apache
/etc/init.d/apache2 restart
vim /etc/apache2/apache2.conf
WSGIScriptAlias /booklister /var/lib/hg_repos/booklister/hgweb.wsgi
WSGIDaemonProcess booklister user=www-data group=hgusers threads=1 processes=10
<Directory /var/lib/hg_repos/booklister>
Options ExecCGI FollowSymlinks
AddHandler wsgi-script .wsgi
AllowOverride None
Order deny,allow
deny from all
allow from vvv.ww.xxx.y/zz
</Directory>
ScriptAlias /booklister "/var/lib/hg_repos/booklister/hgweb.wsgi"
<Location /booklister>
AuthType Basic
AuthUserFile /etc/apache2/hgpasswd
AuthName "Book Lister project repo"
Require valid-user
</Location>
Restart Apache
/etc/init.d/apache2 restart
Locally
Clone the remote repository in a desired location. You'll now have a local copy!
cd /home/scott/ws/py
hg clone http://myserver/booklister
-Enter user name and password
scott
scottspassword
Create a local rc file for Mercurial. You can do this in your home ~ directory,
or in the clone project's folder. I usually put mine in the project's folder.
cd booklister
vim .hg/hgrc
[ui]
username = Scott Davies <scott@mycompany.com>
password = scottspassword
[paths]
default = http://myserver://booklister
Try making a change to file, then try to push the change to the repository
hg commit -m "Test change"
hg push
pushing to http://myserver//booklister
http authorization required
realm: Book Lister project repo
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
cd /home/scott/ws/py
hg clone http://myserver/booklister
-Enter user name and password
scott
scottspassword
Create a local rc file for Mercurial. You can do this in your home ~ directory,
or in the clone project's folder. I usually put mine in the project's folder.
cd booklister
vim .hg/hgrc
[ui]
username = Scott Davies <scott@mycompany.com>
password = scottspassword
[paths]
default = http://myserver://booklister
Try making a change to file, then try to push the change to the repository
hg commit -m "Test change"
hg push
pushing to http://myserver//booklister
http authorization required
realm: Book Lister project repo
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
Thanks for publishing this, it was a great help.
ReplyDelete