Tag: apache

  • Installing Mercurial and Hosting Repositories with CentOS

    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