A collection of computer systems and programming tips that you may find useful.
Brought to you by Craic Computing LLC, a bioinformatics consulting company.

Tuesday, April 10, 2007

Setting up a Subversion Repository

Subversion (svn) is a leading software version control system that has a myriad of features. It is heavily documented, however the basic steps involved in setting it up and accessing it are somewhat obscured by descriptions of the many configuration choices.

Here is a concise description of setting a svn repository on a linux server (which I'll call remote) and accessing it from a client computer (local).

1: Creating a Repository

Download the software from http://subversion.tigris.org/ or, on a Fedora system :

[remote ~]#
yum install subversion.

Create a directory for the repository, with whatever name you choose

[remote ~]$ mkdir /proj/svn_repository

Create the svn repository in that directory

[remote ~]$ svnadmin create /proj/svn_repository

Create subdirectories for each project using svn (not regular mkdir!).
There are many ways to do this but a commmon approach is to have a svn directory for each project and three subdirectories called trunk, branches, tags - with trunk containing the primary version of your code.

[remote ~]$ svn mkdir file:///proj/svn_repository/project1 -m 'New directory'
[remote ~]$ svn mkdir file:///proj/svn_repository/project1/trunk -m 'New directory'
[remote ~]$ svn mkdir file:///proj/svn_repository/project1/branches -m 'New directory'
[remote ~]$ svn mkdir file:///proj/svn_repository/project1/tags -m 'New directory'

There is no need for a svn commit command. And, of course, you can add project directories at any time.

Import a test body of code from a directory on that server as a test of the installation

[remote ~]$ cd ~/mytestproj
[remote ~]$ svn import . file:///proj/svn_repository/project1/trunk

Check that the files are in the repository

[remote ~]$ svn list file:///proj/svn_repository/project1/trunk

2. Set up Remote Access to the Repository

There are several ways to do this. Assuming that your users have accounts on the server with the repository, then using svn+ssh is probably the easiest to setup and maintain.

First, install the svn client on the client(local) machine. Look for this on http://subversion.tigris.org/

Without making any changes to the server, connect to it using svn+ssh with the remote hostname and the full path to the repository directory.

[local ~]$ svn list svn+ssh://svn.craic.com/proj/svn_repository/project1/trunk

This will prompt you for your user account password on the server and then return the list of files in the repository. So this just works... but it will ask you for your password for every outgoing connection, which quickly becomes a royal pain.

To fix this you need to set up an RSA private/public key pair and copy the public key to your directory on the remote server. Key pairs may look a little cryptic but the basic is pretty simple.

(Note, that if you already have an RSA keypair for another purpose then you will need to give your new pair a different name - see below for the tweak needed to use this - for now I'll use the default name)

First, create the key pair on your client machine (Do NOT enter a passphrase when prompted - just hit Return)

[local ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/jones/.ssh/id_rsa): /Users/jones/.ssh/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/jones/.ssh/id_rsa.
Your public key has been saved in /Users/jones/.ssh/id_rsa.pub.
The key fingerprint is:

Create a .ssh directory in your home directory on the remote server if
it doesn't already exist, then copy the the public key (id_rsa.pub) to the remote machine that you want to connect to.

[local ~]$ scp .ssh/id_rsa.pub jones@svn.craic.com:/home/jones/.ssh/tmp.pub

Now go to the remote server and install the key in ~/.ssh.
[remote ~]$ cd .ssh

Look for a file called authorized_keys, create it if it does not exist
[remote .ssh]$ mv tmp.pub authorized_keys
Or append the new key on to the end of it.
[remote .ssh]$ cat tmp.pub >> authorized_keys

Now, back on the local client, you should be able to use the svn command I gave above without having to give a password.
[local ~]$ svn list svn+ssh://svn.craic.com/proj/svn_repository/project1/trunk

In addition, you can now ssh into the remote server without having to give a password. In some cases this is a nice side benefit, but some sites may wish to separate svn access from ssh access to a server. Doing this can have several benefits, especially if you have multiple private/public keypairs for different purposes, plus it lets you to simplify your svn client commands a little.

On the client, rename your private key to something that indicates it is specifically for svn.
[local ~]$ cd .ssh
[local ~]$ mv id_rsa id_rsa_svn

Add a line to your shell settings file, such as ~/.bashrc or ~/.bash_login, that tells svn which key to use when it runs ssh.

export SVN_SSH="ssh -i $HOME/.ssh/id_rsa_svn"

Now go back to the remote server and customize the authorized_keys file so that this public key can only be used with svn. Add the string
command='/usr/bin/svnserve -t -r /proj/svn_repository'
to the start of the line for the public key for your client, thus:

command='/usr/bin/svnserve -t -r /proj/svn_repository' ssh-rsa AAFaB3NzaC1[...]2oT+HQ== jones@client.craic.com

What this does is to start up an instance of the SVN server (svnserve) whenever you connect from your client via ssh. But more than that, the string
-r /proj/svn_repository specifies the root of the repository path. That means that the URL that you specify on your client becomes quite a bit shorter.

So instead of using this command to list files in a project:
[local ~]$ svn list svn+ssh://svn.craic.com/proj/svn_repository/project1/trunk

You can use this:
[local ~]$ svn list svn+ssh://svn.craic.com/project1/trunk

That is all you should need to access your remote repository. Check out the svn book and other resources for details on how you actually work with the files stored therein.

Thursday, April 5, 2007

Perl CPAN on Mac OSX

Two things to remember when using CPAN to install or upgrade a Perl module on a Mac OS X system:

1. Set FTP to use Passive Mode
Otherwise it will just spin its wheels trying to find a cpan repository that it can download from.

In your bash shell, or your ~/.bash_login file add this line:
export FTP_PASSIVE=1

2. Run the CPAN interface under sudo
You need root privileges to install the modules after they have compiled.
sudo perl -MCPAN -e "shell"

The CPAN may recommend updating your Bundle::CPAN module. While this is a good thing to do, it does take a long time to install/update all the supporting modules (10-15 minutes), so bear that in mind.

Archive of Tips