Subversion

Subversion

From Consultancy.EdVoncken.NET

Jump to: navigation, search

Contents

Installing Subversion

On my 64-bit CentOS server, Subversion is easy to install:

 yum install subversion.x86_64

Note the trailing ".x86_64" - this ensures that Yum only installs 64-bit software.

Subversion Web Access

If you want to use Subversion over the Web (i.e. use the HTTP protocol with Subversion), you should install Apache with the mod_dav_svn module:

 yum install mod_dav_svn

Check /etc/httpd/conf.d/subversion for configuration settings.

Multi-protocol Subversion access

The repositories can be accessed using various network protocols.

  • For HTTP access, the repositories must be writable by the apache user.
  • For SSH access, the repositories must be owned by a group that contains all Subversion users.

To accommodate both HTTP and SSH, set up permissions and ownership as follows:

 groupadd svnusers
 usermod -a -G svnusers apache
 usermod -a -G svnusers ed
 
 chown -R apache.svnusers /var/www/svn
 find /var/www/svn -type d -exec chmod g+sw {} \;
 chmod g+w /var/www/svn/*/db/write-lock /var/www/svn/*/db/txn-current*

The last line makes the write-lock file writable for the svnusers group. Without it, you would get errors like:

 svn: Can't open file '/var/www/svn/reponame/db/write-lock': Permission denied

HTTP

The Subversion URL looks like this:

 http://server.example.com/repos/config

SSH

The Subversion URL looks like this:

 svn+ssh://server.example.com/var/www/svn/config

Subversion Replication

On the primary host we have several repositories, including:

 /var/www/svn/config

All repositories are accessible over our network using HTTP (http://primary.server.local/repos/config etc.).

Using svnsync, we can make a read-only replica available on a secondary server. The process consists of 3 steps:

Prepare the Replica
Create user accounts in Subversion. Set up empty repositories on the secondary host.
Initialize the Replica
Set up an svnsync relationship between primary and secondary.
Update the Replica
Synchronization can be started manually, but we can also set up the replication so that any change on the primary automatically triggers a sync operation to the secondary.

Prepare the Replica

Note: We need a Subversion user on both repositories to execute the synchronization. In this example, a dedicated user named "syncuser" was added to /etc/subversion/httpd.users on both primary and secondary.

To set up a new (read only!) replica, create an empty repository on the secondary:

 mkdir /var/www/svn
 svnadmin create /var/www/svn/config
 chown -R apache.svnusers /var/www/svn
 find /var/www/svn -type d -exec chmod g+sw {} \;
 chmod g+w /var/www/svn/*/db/write-lock

We now have an empty repository, ready to be synchronized.

Finally, we must ensure that a Subversion hook named "pre-revprop-change" is present on the secondary (this is an executable shell script, /var/www/svn/config/hooks/pre-revprop-change):

 #!/bin/sh
 #
 # This hook ensures that syncuser can make modifications during svnsync
 
 USER="$3"
 if [ "$USER" = "syncuser" ]; then exit 0; fi
 
 echo "Only syncuser may change revision properties" >&2
 exit 1
 
 # EOF

If you forget this step, you will get the following error message during "svnsync init" in the next step:

 svnsync: Repository has not been enabled to accept revision propchanges;
 ask the administrator to create a pre-revprop-change hook

Initialize the Replica

Log on to the secondary host, and set up the destination repository for synchronization:

 svnsync init --username syncuser \
         http://secondary.server.local/repos/config \
         http://primary.server.local/repos/config

Update the Replica

Manual Synchronization

Enter the following command:

 svnsync synchronize --username syncuser http://secondary.server.local/repos/config

Automatic Synchronization

Ideally, the secondary should automatically be kept in sync with the primary. There are two good ways of accomplishing this:

  1. Set up a cron-job
  2. Set up a post-commit hook on the primary repository

The advantage of a post-commit hook is that every commit to the primary repository is immediately reflected on the secondary. The post-commit hook is an executable shell-script /var/www/svn/config/hooks/post-commit:

 #!/bin/sh
 #
 # Push new commits to our replica repositories
 
 REPOS="$1"
 
 replica_url="http://secondary.server.local/repos"
 reponame=`/bin/basename ${REPOS}`
 
 /usr/bin/svnsync sync --non-interactive --username syncuser --password TheSecret ${replica_url}/${reponame}
 
 # EOF

Here, we have directly specified the username and password in the script. There are security implications, it would be slightly better to use the "--config-dir" option.

We will also need a post-revprop-change hook on the primary:

 #!/bin/sh
 #
 # Push revision property changes to our replicas
 
 REPOS="$1"
 
 replica_url="http://secondary.server.local/repos"
 reponame=`/bin/basename ${REPOS}`
 
 /usr/bin/svnsync sync --non-interactive --username syncuser --password TheSecret ${replica_url}/${reponame}
 
 # EOF

For good measure, you may also want to set up an svnsync cron-job to make sure no commits are missed.

SELinux considerations

I ran into several problems trying to get svnsync to work on my SELinux-enabled hosts. For debugging, I disabled SELinux for HTTP as follows:

 setsebool -P httpd_disable_trans=1
 service httpd restart

Note: You should not do this on an Internet-facing webserver; defense in depth is your best friend.

Backup

The following script (/etc/cron.daily/svndump) dumps all Subversion repositories into /var/backup so they can be backed up in a consistent state:

 #!/bin/sh
 #
 # Dump all Subversion repositories
 #   Output is written to /var/backup/YYYY/MM/reponame-YYYYMMDD-HHMMSS.svndump.gz
 
 timestamp=$(/bin/date +%Y%m%d-%H%M%S)
 backupdir="/var/backup/$(/bin/date +%Y)/$(/bin/date +%m)"
 
 /bin/mkdir -p ${backupdir}
 if [ ! -d ${backupdir} ];
 then
   echo "Backup directory ${backupdir} does not exist"
   exit 2
 fi
 
 cd /var/www/svn || exit 1
 for repo in *
 do
   svnadmin dump -q /var/www/svn/${repo} |gzip > ${backupdir}/${repo}-${timestamp}.svndump.gz
 done
 
 # EOF

Additional Tools

svnX
An OS X open source GUI for most features of the svn client binary.
Subcommander
A cross platform (MacOSX, Windows & Linux) general purpose graphical subversion client with diff and merge tool.

References