A few days ago I was configuring Subversion on one of my linux servers and I started looking for a way to dynamically expose the repositories complete with a separate users database. I was hoping to make it totally dynamic so that I could just add a new repository, configure the permissions (see my earlier post on per-directory access controls) and create the accounts. I tried something like this:
<VirtualHost virtual-host-1:80> ServerName svn.domain.tld SetEnvIf Request_URI "/([^/]+)(?:/?|/.*)?" REPOSITORY_NAME=$1 <Location /> DAV svn SVNPath /path/to/svnrepositories/${REPOSITORY_NAME} AuthzSVNAccessFile /path/to/svnrepositories/${REPOSITORY_NAME}/conf/httpd.access AuthUserFile /path/to/svnrepositories/${REPOSITORY_NAME}/conf/httpd.passwd Require valid-user AuthType Basic AuthName "Subversion Repository" </Location> </VirtualHost>
The key is this line: SetEnvIf Request_URI "/([^/]+)(?:/?|/.*)?" REPOSITORY_NAME=$11. If you browse to http://svn.domain.tld/someRepository it conditionally sets an Apache environment variable to someRepository which you can use to reference a specific repository, password file and access list. Perfect, right?
Unfortunately it's not that easy – you can't use dynamically set environment variable in any directive arguments. Crap! There are some other solutions out there like mod_macro, but I've had some issues with that in the past. mod_perl and a <Perl> tag might work, but I've never used that before and I want to keep my configuration simple (and minimize the time spent on this).
I decided to take the easy way out and sacrifice some functionality. The SVNParentPath directive allows you to define a path under which any directories will be assumed to be SVN repositories. Now I can add new repositories on the fly without restarting Apache, but I still don't have multiple user files.
In the end having distinct user files isn't that big of a deal, especially if you aren't worried about username conflicts and because you can control permissions on a per-repository basis in your user file. Here's a sample access file:
[groups] group1 = bill, joe [/] # By default no one except corey has permissions at the root level * = corey = rw [Some_Project:/] # grant all members of group1 full permissions on Some_Project # corey will inherit permissions from / @group1 = rw
My final Apache configuration looked like this:
<VirtualHost virtual-host-1:80> ServerAdmin webmaster@domain.tld DocumentRoot /home/domain/public_html ServerName svn.domain.tld <Location /> DAV svn SVNParentPath /home/domain/svn AuthzSVNAccessFile /home/domain/svnauth/httpd.access AuthUserFile /home/domain/svnauth/httpd.passwd Require valid-user AuthType Basic AuthName "Subversion Repository" </Location> </VirtualHost>
As always, the book Version Control with Subversion (buy it from Amazon) was a big help.
- If you want to use parenthesized expressions with SetEnvIf you'll need Apache 2.0.51 or newer. [back]




