Viewing Category: Subversion  [clear category selection]

Updating Subversion Repositories to Berkeley DB 4.3

While copying various old repositories to a new server, I found that some of them needed to be updated to the current version of Berkeley DB. If the new svnadmin is used on an old repository, it outputs an error like so:

svnadmin: Berkeley DB error for filesystem 'project/db' while opening environment: svnadmin: DB_VERSION_MISMATCH: Database environment version mismatch svnadmin: bdb: Program version 4.3 doesn't match environment version

The new server is CentOS 5.2, which comes with Subversion 1.4.2, using Berkeley DB 4.3. The system had compat-db-4.2.52 installed, providing /usr/bin/db42_*. To perform the upgrade I needed to install the db4-utils package. After searching the interwebs for solutions, I cobbled the following script together:

#!/bin/bash REPOS=${1:-_} if [ "$REPOS" == _ ]; then echo "Usage: `basename $0` repository" exit 1 fi if ! echo "$REPOS" | grep -qE '^/'; then REPOS="$PWD/$REPOS" fi if [ ! -d "$REPOS" ]; then echo "Error: $REPOS does not exist." exit 1 fi if [ ! -d "$REPOS/db" ]; then echo "Error: $REPOS does not look like a Subversion repository." exit 1 fi if [ ! -z `lsof -t +D "$REPOS"` ]; then echo "Error: there seem to be open files in the repository." exit 1 fi read -n 1 -p "About to update repository to Berkely DB 4.3. Continue? (y/n): " echo if [ $REPLY != "y" -a $REPLY != "Y" ]; then exit 2 fi cd $REPOS/db /usr/bin/db42_checkpoint -1 /usr/bin/db42_recover /usr/bin/db42_archive /usr/bin/svnlook youngest .. /usr/bin/db_archive -d /usr/bin/svnadmin verify .. echo "Finished. File permissions have changed."

Obviously, you'd want to make a complete backup of your current repository before trying the upgrade. It's worked on the repositories that I've used it on so far. Even for a small repository, it can take a while to run. Remember that if the repository is being accessed through mod_dav_svn, the permissions will need to be set back to the Apache user and group after the upgrade.

Creating a Subversion Server

I've been moving servers around recently, and I've tried to document the installation procedure for future reference. The information might help others, and I've tried to make sure it's accurate and reproducible. This describes a fairly generic Subversion server accessible through HTTPS. The authorization is done with a simple Apache password file, although it's easy enough to use LDAP instead.

Install the software packages and create a user account. It seems that UID/GID 44 is typical for a Subversion system account. It doesn't matter if you choose another number.

yum install httpd mod_dav_svn mod_ssl subversion groupadd -g 44 svn useradd -u 44 -g svn -r -m -s /sbin/nologin -d /home/svn svn

Create a project repository. Set the environment variable PROJECT as appropriate. For mod_dav_svn to work properly, the web server user account must own the repository. Because Subversion creates file locks when running transactions, the repository should be on a local filesystem rather than NFS.

PROJECT=project su -l svn -s /bin/sh -c "mkdir repositories" su -l svn -s /bin/sh -c "svnadmin create repositories/$PROJECT" chown -R apache:apache /home/svn/repositories/$PROJECT

Configure HTTPS access by creating a self-signed SSL certificate. Generate a certificate authority key, if one doesn't exist. Then create the CA certificate.

openssl genrsa -des3 -out /etc/pki/CA/private/ca.key 1024 chmod 400 /etc/pki/CA/private/ca.key openssl req -new -x509 -days 365 \ -key /etc/pki/CA/private/ca.key -out /etc/pki/CA/ca.crt

Create the private key for the Subversion server. Then create the certificate signing request.

openssl genrsa -out /etc/pki/tls/private/svn.key 1024 chmod 400 /etc/pki/tls/private/svn.key openssl req -new -key /etc/pki/tls/private/svn.key -out ~/svn.csr

Finally, create the Subversion server certificate.

openssl x509 -req -days 365 -set_serial 01 \ -CA /etc/pki/CA/ca.crt -CAkey /etc/pki/CA/private/ca.key \ -in ~/svn.csr -out /etc/pki/tls/certs/svn.crt

In configuring Apache, I've chosen to put the server on a non-default port because it prevents using up an IP on my server. Feel free to use 443 if you can. Use a FQDN your server name.

Listen *:10044 <VirtualHost *:10044> ServerName svn-server SSLEngine on SSLCACertificateFile /etc/pki/CA/ca.crt SSLCertificateFile /etc/pki/tls/certs/svn.crt SSLCertificateKeyFile /etc/pki/tls/private/svn.key DocumentRoot /home/svn/webroot CustomLog /home/svn/logs/access_log combined LogLevel warn ErrorLog /home/svn/logs/error_log <Location /svn> DAV svn SVNParentPath /home/svn/repositories SVNPathAuthz on <LimitExcept GET PROPFIND OPTIONS REPORT> AuthType Basic AuthName "Subversion Repository" AuthUserFile /home/svn/etc/passwd Require valid-user </LimitExcept> </Location> </VirtualHost>

Create the directories needed for the svn account. I recommend putting an HTML document in the web root that lists the repositories available.

su -l svn -s /bin/sh -c "mkdir webroot logs etc"

Create a user account with access to the repository.

su -l svn -s /bin/sh -c "htpasswd -c etc/passwd $USERNAME"

Finally, test it out with a Subversion client.

SVNROOT="https://svn-server/svn/$PROJECT" svn mkdir -m "Initial setup." $SVNROOT/branches $SVNROOT/tags $SVNROOT/trunk

Because the client won't be able to verify the SSL certificate, you'll need to manually approve its use.