The following information resulted from several hours of battling with SELinux
and Apache, attempting to find some way of serving up my Mercurial repository
(now at http://hg.newartisans.com) over HTTP. In short, I found that cgi-bin
would not work at all with SELinux, for reasons I couldn’t figure out (it
didn’t generate any AVC messages once I extended Apache’s permissions – it
just wouldn’t serve any data).
But getting modpython to work turned out to be no picnic either. The data is out there, on the Web, but nothing from any one place worked for me. So after much effort, here’s what I discovered, boiled down into nice easy chunks for the tired reader.
Steps to follow
Install Mercurial. I’m using CentOS 5, and Mercurial was not available through
yum
. I installed it from Dag Wieers repository.Install modpython. This you can do through yum with
yum install mod_python
.Create a directory for your Mercurial projects in
/srv/hg
. My ledger project ended up having all the Mercurial files in/srv/hg/ledger/.hg
. Note that unlike systems like git, you do need the files in the.hg
subdirectory. The rest of the parent directory will remain empty. Make sure that the security context on all of these directories isuser_u:object_r:public_content_rw_t
, if you intend to allow others to post changes. Otherwise, make ituser_u:object_r:public_content_t
. The files will have to be readable and writable by Apache if you want to allow commits. To change the security context, you can use this command:chcon -R user_u:object_r:public_content_t /srv/hg
.Create a directory called
/etc/hgweb
. In it you will have two files,hgwebdir.conf
andusers.htdigest
. I’ll give you some example files in the appendices to this article. The security context for this directory and all the files in it should besystem_u:object_r:httpd_config_t
. Theusers.htdigest
file should be owned byapache
, and have permissions set to 400.Create a directory called
/var/hg
. It will have two files in it,hgwebdir.py
andmodpython_gateway.py
. Both of those are found below. The security context for this directory and its contents should besystem_u:object_r:httpd_sys_content_t
. It can be owned by root, just make sure it’s world readable.Configure your Apache server. I’m using a virtual host to serve pages on
hg.newartisans.com
. I leave it up to you to modify this for running on your main server. See below.I still can’t get pushes to work over HTTP (I’m using ssh). If you figure this out or have an answer, please send me a note!
/etc/hgweb/hgwebdir.conf
The only part of this you’ll need to change is the name and e-mail address of
the administrator. And change push_ssl
if you need to deliver encrypted data
(such as work-related sources). Note: if you change push_ssl
, you’re going to
have to configure Apache to use SSL for your host, which is beyond the scope
of this article.
[collections]
/srv/hg = /srv/hg
[web]
style = gitweb
allow_archive = bz2 gz zip
contact = John Wiegley, johnw@newartisans.com
push_ssl = false
/etc/hgweb/users.htdigest
You can make this file very easily. Here’s what I typed to create an entry for myself:
htdigest -c users.htdigest "New Artisans LLC" johnw
It will ask you for the password to use. You’ll need an entry for everyone who
will have commit access to your repository. If you are using the htdigest
command to make these entries, remove the -c
flag! That causes the file to get
created the first time.
/var/hg/hgwebdir.py
Strangely enough, there is no working version of this on the Web that I could find. But here’s what worked for me:
#!/usr/bin/env python
#
# An example CGI script to export multiple hgweb repos,
# edit as necessary
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):
= wsgiapplication(make_web_app)
toto return toto (environ, start_response)
/var/hg/modpython_gateway.py
This is quite a bit longer, so I’m just going to link to the copy of modpythongateway.py in my Downloads section.
changes to /etc/httpd/conf/httpd.conf
There are a couple of oddities in here: First, the rewrite rule. You’ll want
this. Ignore the fact that it contains the string hgwebdir.cgi
in it.
Apparently hgwebdir
depends on this and then ignores it, but since we’re
running with modpython it doesn’t actually do anything. If you get rid of it,
the errors you get will be rather hard to figure out!
Also, be careful with the AuthName
. This is the same exact string that you
have to pass to the htdigest
command (see above), or else user authentications
will fail.
ServerAdmin webmaster@newartisans.com
ServerName hg.newartisans.com
ErrorLog /var/log/httpd/error_log
CustomLog /var/log/httpd/access_log combined
RewriteEngine On
RewriteRule ^/(.*) /hgwebdir.cgi/$1
PythonPath "sys.path + ['/var/hg']"
SetHandler mod_python
PythonHandler modpython_gateway::handler
PythonOption wsgi.application hgwebdir::start
Order allow,deny
Allow from all
# authentication
AuthType Digest
AuthName "New Artisans LLC"
AuthDigestDomain hg.newartisans.com
AuthDigestProvider file
AuthUserFile "/etc/hgweb/users.htdigest"
Require valid-user