Showing posts with label mercurial. Show all posts
Showing posts with label mercurial. Show all posts

Sunday, June 6, 2010

Mercurial Helper Script

Explanation

This is the current version of the mercurial-helper script that I have created. The general purpose of this script is to aid users in creating and adding users to the password file hgusers (typically called that), as well as setting up a repository.

Unfortunately I have not added any functionality to remove users from the password file, though this is not a difficult task to carry out. Users should be able to change/update their passwords in the hgusers file just by re-entering their credentials. A second problem is that script requires sudo access to make sure that the directories and permissions can be altered correctly.

How to Use

Acquire the script by creating a file called mercurial-helper.sh and pasting in the following section's code into it. Then place this file where the mercurial repositories are going to be found (if the earlier blog entries were followed that would be /srv/redmine/extra/hg/). Now to execute it:
# sudo sh mercurial-script.sh

Then the script should guide you through the rest of the steps to create and add users to the password file, as well as creating a repository.

mercurial-script.sh

#!/bin/bash
#-----------------------
# Author: Kevin Jalbert
# Date: June 6th, 2010
#-----------------------

# Variables that are used
choice=4
name="----"
passwordFile="----"
realm="----"
repository="----"

# Present the user with potential options
echo "1. Add/Change User"
echo "2. Create New Repository"
echo "3. Exit"
echo -n "Please choose an option [1,2, or 3]? "

# Keep looping till a valid choice is made
while [ $choice -eq 4 ]; do

 read choice

 # Adding/changing a user
 if [ $choice -eq 1 ] ; then

  echo "--Adding/changing a user--"

  # Acquire the name
  echo "Enter the user's account name"
  read name

  # Acquire repository's realm
  echo "Enter the repository's realm (should be mercurial)"
  read realm

  # Acquire file's name
  echo "Enter name of password file (should be hgusers)"
  read passwordFile

  # Check to see if this file already exists, and perform appropriate action
  if [ -e $passwordFile ]; then
   echo `htdigest $passwordFile $realm $name`
  else
   echo `htdigest -c $passwordFile $realm $name`
  fi

  echo "User [$name] has been added/changed within password file [$passwordFile]"

 # Creating a new repository
 elif [ $choice -eq 2 ] ; then

  echo "--Creating a new repository--"

  # Acquire the repository's name
  echo "Enter the repository's name"
  read repository

  # Acquire the users involved in this repository
  echo "Enter the users involved in this repository (Comma Separated Values)"
  read name

  # Set up the repository
  echo `hg init $repository`
  echo `touch ./$repository/.hg/hgrc`
  echo "[paths]
default = $PWD/$repository/

[web]
allow_push = $name
contact = $name
description = Fill me out (in ./project/.hg/hgrc)
push_ssl = false
style = gitweb

[trusted]
users = *
groups = *

[hooks]
changegroup = hg update" > ./$repository/.hg/hgrc

  # Change the ownership permissions
  echo `chown -R www-data ./$repository/`
  echo `chmod -R 755 ./$repository`

  echo "The repository is created. The configuration file located at ./$repository/.hg/hgrc
  needs to be edited to ensure that the path to this repository is set as well as any
  additional changes that are desired."

 # Exiting
 elif [ $choice -eq 3 ] ; then

  echo "Exiting"
  exit;

 # Script input mismatch
 else

  $choice=4
  echo "Incorrect input, try again"
  echo "1. Add/Change User"
  echo "2. Create new Repository"
  echo "3. Exit"
  echo -n "Please choose an option [1,2 or 3]? "

 fi
done

Monday, May 31, 2010

Mercurial Setup Guide

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.