Getting Started


This installation guide is for administrators planning on using SVNGroup for implementing Subversion access control lists. Those using the svngroup client for manipulation of these ACLs only need to install the svngroup-client package.

The first step is download the latest SVNGroup installation package from SourceForge.

Installing Prerequisites


It is recommended that all of the prerequisite software for SVNGroup is installed prior to installing SVNGroup itself.

You will need all of the following software packages:
If you're using a Linux distribution, the simplest way to get these packages is with your distribution software package manager tools, i.e., emerge, apt-get, or yum.

Most distributions come with Python pre-installed. If yours does not then you will need to install Python 2.4.1 or higher.

And of, course, you'll need Subversion.

Unpacking and Installing


If you are upgrading an existing installation of SVNGroup continue to the Upgrade instructions. Do not follow the remaining steps in this section or you will overwrite an existing SVNGroup database.

Move the svngroup tarball package to /usr/src and unpackage it with tar -xzvf svngroup-x.y.z.tar.gz. cd to the created directory, svngroup-x.y.z.

Now is a good time to review the Makefile and change any variables. Most installations will work with provided Makefile, but if your Subversion binaries are located somewhere other than /usr/bin you will want to change:
  • SVNLOOK
  • SVN

to point to the appropriate locations for the svnlook and svn binaries.

SQLObject

By default the SVNGroup installer will try to install SQLObject, the ORM software used to map Python code to SQL statements. If you already have SQLObject installed on your computer, set INSTALL_SQLOBJECT to FALSE.

Creating a Server Key and Certificate

An SSL socket is used between the SVNGroup client and server, and thus, a server private key and certificate are required. By default the Makefile will prompt for information to place in the certificate. If you already have a key and certificate you'd like to use then set CREATE_KEYANDCERT to FALSE.

Installation

First, type make. If you are prompted for certificate information go ahead and enter it.

Assuming everything is generated properly, type make install. If this is the first time you've installed SQLObject on this system it may go off and try to download additional required software.

SVNGroup does its best to detect what flavor of Linux you're running (that is, it checks for /etc/distribution-release) and installs a runlevel script in the appropriate location.

Database Initialization

Only run this step if you're installing SVNGroup for the first time or you are certain you want to wipe out any previous database installation.

make install-database

Upon initialization the installation will have a default user, admin with administrative privileges (the ability to create users, groups, etc.).

Starting the Server

The server's runlevel script will be in the appropriate location for your system (e.g., /etc/rc.d/init.d) and all versions should respond to start and stop:

/etc/init.d/sgserver start

The SVNGgroup server log file is at /var/log/sgserver. Current versions have a high level of logs (debug level) and it is isn't currently configurable (unless you edit the source to turn down the log level). Future versions will make this configurable.

Determining Connectivity

The server installation also installs the svngroup client. Typing svngroup with no arguments will produce something similar to:

hardcore:~$ svngroup
svngroup version 0.9.5
Current user:    
Current server:  
        
Go ahead and point svngroup to the running server.

hardcore:~$ svngroup setserver localhost
Server name changed
hardcore:~$ svngroup setuser admin admin
Password changed locally
        
You should now be able to query the system for all of the available users:

hardcore:~$ svngroup listusers
Username                 Administrator
------------------------ -------------------
admin                                    Yes
        
SVNGroup is now installed and running on your Subversion server, but it currently has no means by which to communicate with Subversion to provide access controls. It's time to update the pre-commit hook of the repository (or repositories) to provide this functionality.

Adding the Pre-commit Hook


Note: This section, and really, this entire software package, assumes that you are familiar with and have probably edited Subversion pre-commit scripts. If you haven't, it is suggested you create a test repository first and read the Subversion chapter on repository hooks before continuing any further. Errors in pre-commit scripts can prevent anyone from checking in to the repository.

The script /usr/lib/svngroup/hooks/svngroup-precommit.sh is created as a part of the server installation process. This script is intended to be called by the pre-commit hook for your repository in the following fashion:

# Check that the author of this commit has the rights to perform the commit
# on the files and directories being modified with svngroup.
SVNGROUP_HOOK=/usr/lib/svngroup/hooks/svngroup-precommit.sh
$($SVNGROUP_HOOK "$REPOS" "$TXN") >&2  || exit 1

This hook snippet can be placed anywhere in the pre-commit hook in your Subversion repository (before the final exit 0 statement that is). This snippet must be added to the pre-commit script for all repositories you want to enable svngroup on.

Test Drive

The following example a basic test to ensure the pre-commit hook is properly installed and the SVNGroup server is enforcing access control lists.

In this example a repository has been created with svnadmin in /var/svn/repositories:

hardcore:/var/svn/repositories$ svnadmin create test
        

Since this is a new repository the pre-commit script will have to be created from the pre-commit.tmpl template file.

hardcore:/var/svn/repositories/test/hooks$ cp pre-commit.tmpl pre-commit
hardcore:/var/svn/repositories/test/hooks$ chmod +x pre-commit

Now, edit the pre-commit script and comment out the default commit-access-control.pl script from executing and add the SVNGroup pre-commit snippet.

Now, let's import an initial project shell into the repository. This can be done easily by creating a directory called shell and inside this directory issuing:

mkdir branches tags trunk
        

and then while still in the shell directory type:

hardcore:/tmp/shell$ svn import . file://localhost/var/svn/repositories/test/calc -m"Initial import"
Adding         trunk
Adding         branches
Adding         tags
        

If you look at the sgserver logs you will see an XML message similar to:

<svngroup majorVersion="0" minorVersion="9" patchVersion="5">
  <user password="" username="" />
  <svninfo branch="" reporoot="file://localhost/var/svn/repositories/test"
           repourl="file://localhost/var/svn/repositories/test"
           repouuid="8798d2f7-d30b-4b4c-9296-2c0d9984fb7c" />
  <command name="validatepaths">
    <username>root</username>
    <path name="calc/" type="path" />
    <path name="calc/branches/" type="path" />
    <path name="calc/tags/" type="path" />
    <path name="calc/trunk/" type="path" />
  </command>
</svngroup>

Every path that is being committed to the repository now goes through the SVNGroup process. If you look at the continuation of the logs you will see the logic that SVNGroup goes through to determine whether or not the commit will be authorized:

For each path in the submission:
  Is the path owned by a group?
    If no, then this particular path is authorized
    If yes, then
      Is the given user a owner of the group to which the path belongs or do
      they have a grant for the group?
        If no, then this particular path is not authorized
        If yes, then this particular path is authorized 
Were all the paths examined authorized?
  If yes, then the submission is authorized and can proceed.
  If no, then the submission is not authorized, and rejected. 

In this case the paths were new and groups have been created. Let's add a group and place the calc/trunk directory under access control.

Most of the svngroup commands work best when issued in a Subversion working copy. Many can have the repository information supplied to them with --repository, but it's far easier to be in a working copy.

In /tmp we'll check out the calc/trunk branch.

hardcore:/tmp$ svn co file://localhost/var/svn/repositories/test/calc/trunk calc
Checked out revision 1.

Now, as the admin user let's create a group, issuing this command in the working copy at the top-level of calc/trunk. This is important because svngroup will detect what branch to create the group for.

hardcore:/tmp/calc$ svngroup addgroup calc_root 
Group calc_root created for URL file://localhost/var/svn/repositories/test/calc/trunk
(repository identified by 8798d2f7-d30b-4b4c-9296-2c0d9984fb7c) on branch calc/trunk

Note that because we issued the command in the top of the working copy svngroup was able to accurately detect what branch we intend this group to belong to.

We can now look at the details of the group:

hardcore:/tmp/calc$ svngroup list calc_root
Group:      calc_root
Repository: 8798d2f7-d30b-4b4c-9296-2c0d9984fb7c
Base URL:   file://localhost/var/svn/repositories/test/calc/trunk
Branch:     calc/trunk
Owners:  
Paths:

There are no paths and no owners in the group. Let's add a path, the "dot" path, meaning, the calc/trunk directory itself. Without the dot-path the group would not control submissions in the calc/trunk directory.

Before adding this path we need to let admin own the group (at least temporarily). This is a known annoyance. Future versions will allow the administrator to add paths to any group regardless of whether the administrator is an owner.

hardcore:/tmp/calc$ svngroup addowner calc_root admin
User 'admin' added as an owner to group 'calc_root'

hardcore:/tmp/calc$ svngroup addpath calc_root .
Path '.' has been added to group 'calc_root'

Now, let's say I'm ready to add and check something in to the calc/trunk directory.

hardcore:/tmp/calc$ svn add README
A         README
hardcore:/tmp/calc$ svn commit README
Adding         README

The user trying to make the submission (root) is not authorized! SVNGroup reports back:

svn: 'pre-commit' hook failed with error output:
SVNGroup commit failure:  
NOAUTH:Path calc/trunk/README is not a member of any authorized group (belongs to group calc_root for branch calc/trunk)
svn: Your commit message was left in a temporary file:
svn:    '/tmp/calc/svn-commit.tmp'

To remedy the situation we need to do two things: add a userid for root to SVNGroup, and second, allow root to submit to the calc_root group by giving him or her a grant.

Again, as the admin user (the ROOT in all caps is root's initial svngroup password):

hardcore:/tmp/calc$ svngroup adduser root ROOT
User 'root' created as normal user

Now, a grant. We want root to able to submit their changes, but they've indicated that there is only one change and they are going to do it within the hour. So we create a grant that expires an hour from now (at the time of this writing, approximately 3:22AM):

hardcore:/tmp/calc$ svngroup addgrant --expires 2008-06-08T03:22 calc_root root
User root granted submission permissions on group calc_root until 2008-06-08 03:22:00

The format for the grant expiration is in ISO8601 format minus the seconds field.

We can see root can now submit to the calc_root group:

hardcore:/tmp/calc$ svngroup listgrants --user root
Grants for root:
Group                    Branch                           Expires On
------------------------ -------------------------------- -------------------
calc_root                calc/trunk                       2008-06-08 03:22:00

root tries the commit again:

hardcore:/tmp/calc$ sudo svn commit README
Adding         README
Transmitting file data .
Committed revision 2.

Looking at the svngroup logs reveals:

2008-06-08 02:26:16,814 sgserver 181 INFO Processing validatepaths
2008-06-08 02:26:16,817 sgservercommands 971 INFO User root is authorized for group calc_root on branch calc/trunk
2008-06-08 02:26:16,820 sgservercommands 1013 INFO Built all possible paths user root is authorized for
2008-06-08 02:26:16,820 sgservercommands 1014 DEBUG ['calc/trunk']
2008-06-08 02:26:16,821 sgservercommands 1033 DEBUG calc/trunk/README normalized to calc/trunk/README
2008-06-08 02:26:16,821 sgservercommands 1057 DEBUG Path calc/trunk/README is authorized
2008-06-08 02:26:16,822 sgserver 202 DEBUG Server response:  OK:  All given paths are valid

SVNGroup determined that the root user could indeed submit to calc/trunk and allowed the submission of the README file. The grant does not expire after the submission however, but it will at the stated expiration.

Upgrading to a New Server Version



New with version 0.9.6 is a single command to upgrade an existing server installation:

make upgrade
        

make upgrade will automatically stop a running server, upgrade all of the appropriate files, and then restart the server.

If you are running Ubuntu or Debian (or any installation that has an /etc/lsb-release file), you may need to explicitly terminate a running server (0.9.3 to 0.9.5) due to a defect in the runlevel script (this has been fixed in the 0.9.6 version and should be unnecessary when upgrading to 0.9.7).

make upgrade will not attempt to reinstall SQLObject or generate a new private key or certificate for the server. If you would like to perform these steps then stop the server through the runlevel script and use make ; make install. make upgrade will also not manipulate the existing database unless it needs to perform a schema migration. Versions that perform schema migrations will be marked as such.

It is recommended you install 0.9.6, but for previous releases you can use the following steps:

Upgrading the SVNGroup server is straightforward. Although you don't have to take the Subversion repository offline during this process, it is advised to do this procedure during a maintenance or low-activity window as the pre-commit hook of the repository will automatically fail if it can not communicate with the SVNGroup server. No one will be able to submit during this window.

Use the appropriate runlevel script to offline the server:

/etc/init.d/sgserver stop
        

Any commands issued by svngroup that require communication with the server will now report back an error indicating that the server is unavailable.

Unpack the new server installation package and edit the Makefile to change CREATE_KEYANDCERT and INSTALL_SQLOBJECT to FALSE (since there is already a server key and certificate installed, as well as SQLObject).

Type make followed by make install. Do not type make install-database as it will overwrite your existing installed database (with all of its installed users and group information).

Restart the server, and that's it.

For all 0.9.x versions of SVNGroup there are no client-server incompatibilities. Users of a 0.9.5 client should be able to use a 0.9.6 or higher server, and 0.9.6 or higher clients should able to use a 0.9.5 server. The version information of the client and server are embedded in the request/response messages to provide fallback mechanisms if there is an introduced incompatability.