Saturday, June 6, 2009

SVN+SSH and the post-commit hook

To aid my Python programming, I have recently set up a subversion (SVN) repository on one of the spare computers in the office. SVN is basically a way of maintaining versions (or revisions) of a particular project. Messages/comments can be added to files or updates that are "committed" to the repository and differences between revisions can also be viewed making it particularly suited for programming projects. I set up SVN to also use SSH as a secure method of accessing the code available on the computer. However, on its own, SVN isn't terribly exciting so to jazz things up, I added a Trac interface to the repository. Trac maintains tickets (for correcting or adding parts to the project), project components (useful for modularising a project) and has an in-built wiki which could contain documentation for the code. Trac can also close and create references to tickets by reading the commit messages when a user commits code to the repository. This is done through hooks which form part of the SVN repository and hooks are executed on particular events such as before files are committed and after files are committed. I made available the post-commit shell script, copied the documented Trac scripts and made it available to run on the server, but the Trac database would never update with tickets that were closed or referenced.

My SVN process was always running as a root user, so permissions aren't exactly a problem for it. The post-commit file had execution permissions enabled for the user and group (set to Apache and a user group actively using SVN). I had even added a line to temporarily store the Python egg scripts it uses, but still it wouldn't update the Trac database. To top things off, running as the Apache user to 'check' revision 100 (sudo -u apache env - /svn/repo/MyRepo/hooks/post-commit /svn/repo/MyRepo/ 100) would return no errors and complete the database update successfully.

I was about to give up when I remembered that most people I saw demonstrate the post-commit were reliant on using a SVN username or were doing this through Apache's WebDAV (so the Apache user). As I was using SVN+SSH as the protocol of choice, we were logging in through our own user accounts. It is through our user accounts that the post-script is activated and, thus, meaning that the group would need sufficient permissions to run this file. However, as stated earlier, the post-commit script had the sufficient privileges to execute, but as it called the Python script "trac-post-commit-hook", that too needed to have the appropriate group execute and read privileges. This was amended, but still didn't update the Trac database.

I thus ran the post-commit script under my username where I received a few error messages. It was here I saw the offending error: the Trac database couldn't be written to. The solution here was to make the Trac database (defaults to trac.db) and its working directory have write permissions to all users that use the SVN. Upon making this change, the Trac database now updates.