Subversion transparent proxy with svnsync + WebDAV proxy
This article describes a a master-slave setup of subversion, where the slave acts as a transparent proxy, in the sense that the user connecting to the slave server does not really know that he is talking to a slave server and not the master.
This setup integrates two modules, WebDAV proxy and svnsync to achieve its purpose. The following item list explains how they work together:
- The slave server has his own local repository and can serve read requests autonomously (WebDAV proxy)
- Write requests to the slave server get forwarded to the master server (WebDAV proxy)
- The slave repository has to be synchronised with the server's repository (svnsync)
- Slave configuration
- Master configuration
WebDAV proxy support is new in subversion 1.5. At the time of writing, v1.5 has not been released yet. This article does not describe how to build your own subversion binary. As a small hint: I compiled my version with the following line (if this does not help you, then it might be safe for you to wait for the final release of version 1.5):
./configure --prefix /usr/local/subversion \ --with-httpd --with-apxs=apxs2 --disable-mod-activation \ --without-berkeley-db --without-neon --with-serf=/usr
Slave Apache setup
In order to set up a WebDAV proxy server in Apache, all we need to do is to load the modules dav_module (mod_dav.so), dav_svn_module (mod_dav_svn.so) and proxy_module (mod_proxy.so). The configuration is straight-forward. Let's say we want to mirror a remote repository from https://svn.example.org/source/repos to the local path /path/to/local/repository, and this repository shall be accessible at the location /local/repository. All we need is to add the following Location directive in the Apache configuration file:
<Location /local/repository> DAV svn SVNPath /path/to/local/repository SVNMasterURI https://svn.example.org/source/repos </Location>
Slave repository setup
Now let's create the slave repository, accessible for the user svnsync:
svnadmin create /path/to/local/repository chown svnsync: /path/to/local/repository -R
Before svnsync update the data from the server, we have to manually create the file /path/to/local/repository/hooks/pre-revprop-change with the following content:
#!/bin/sh USER="$3" if [ "$USER" != "svnsync" ]; then echo >&2 "Only the svnsync user can change revprops" exit 1 fi exit 0
Let's make it executable with the following command and we're ready to go.
chmod +x /path/to/local/repository/hooks/pre-revprop-change
The slave repository is initialised by the following command line:
svnsync init --username svnsync file:///path/to/local/repository \ https://svn.example.org/source/repos
Once the repository is initialised, further updates need only the minimal command line:
svnsync sync file:///path/to/local/repository
Should the synchronisation fail and leave the repository locked, then the following line deletes. the lock. Please be aware that you can seriously screw your repository up if you delete the lock while svnsync is running!
svn pdel --revprop -r 0 svn:sync-lock file:///path/to/local/repository
The SVN slave sync script
The operations described in this section can be performed by the mighty SVN slave sync script.
The master server must run subversion 1.4 or higher in order to provide support for svnsync. Strictly speaking, no configuration is needed on the server to allow the slave to mirror a repository, but as soon as data is committed on the server, the slave's repository will get more and more out of date. We need thus a mechanism to trigger the replication from the master to the slave server. We can do this easily by editing the post-commit hook script on the master repository. That script might look like:
#!/bin/sh # # REPOS="$1" # REV="$2" ssh -l svnsync svn-slave.example.org "/path/to/svn-sync-slave.sh -r /path/to/local/repository"