To take full advantage of Warehouse’s features, we now weave it into svnserve and get both systems working together. First we will make svnserve hooks that update our warehouse repositories and then we will have Warehouse create our authz and passwd files for svnserve to use.
Hooks
Svnserve has a nice system of hooks that let you execute any script you want at certain moments of a commit. Warehouse has a set of command line actions that let you synchronize the changesets so let’s make a hook which happens after a commit to synchronize the latest changes.
post-commit file
Let’s create the post-commit script:
cd ~/repositories
nano post-commit
Here’s the contents of the script:
#!/bin/sh
cd /home/demo/public_html/warehouse
rake warehouse:post_commit RAILS_ENV=production REPO_PATH=$1 REVISION=$2
As long as the repository and the subfolder have the same name, the repo is automatically chosen by Warehouse so to make things easy and to be able to use this same post-commit file everywhere, let’s keep those names consistent.
Now make the script executable:
chmod +x post-commit
hook your repositories
Finally, we’ll make a symbolic link to the post-commit hook from each of the repos’ hooks directories just like we did with the svnserve.conf files. Be sure to do this for any future repos you create.
ln -fs /home/demo/repositories/post-commit project1/hooks
ln -fs /home/demo/repositories/post-commit project2/hooks
Test it out
Let’s give the automatic syncing a try. Make some changes to your local copy of the repository and make a commit. This should behave normally but now when you revisit your repo in Warehouse, it will have magically been updated with the latest changes. Neat!
SVN Access Files
Let’s get Warehouse to create both our SVN access files (authz) and user/password files (passwd) automatically when changes are made from the web interface. Let’s start with the easy one…
Build authz configuration file
Warehouse let’s you set per-directory access rules on every repo it manages. This allows you to fine tune access for any and all of your users easily. It will also output these rules to a file which svnserve can read and understand to limit access for commits and checkouts, etc.
Let’s set this up, visit the admin settings tab at http://code.example.com/admin/settings. Set the “Shell command to run when permissions are updated” to:
rake warehouse:build_config RAILS_ENV=production CONFIG=/home/demo/repositories/authz
All this does is tell Warehouse to write the permissions we configure in Warehouse to the authz file in our repositories folder.
Re-enable authz-db in svnserve
Now we must tell svnserve to actually use this authz file so hop back into the svnserve.conf file and make the change by uncommenting the authz-db line. It should now look like this:
[general]
anon-access = none
auth-access = write
password-db = /home/demo/repositories/passwd
authz-db = /home/demo/repositories/authz
realm = Example Repository
That’s it! Now you can manage repository access right from the Warehouse GUI. Give it a try by changing a permission from the Access pane and seeing if the authz file gets updated correctly.
Note that the default access for new repos in Warehouse is read-only for the primary user so be sure to update that as needed.
Write the passwd file
Warehouse has a mechanism to write to htpassword files (appropriately called rake warehouse:build_htpasswd). These files look just like the passwd file we created in Act I except they don’t include the [users] header. The [users] header is necessary for svnserve to read the file so we must coax Warehouse to add this header. Additionally, Warehouse is configured to write passwd files in a hashed form but svnserve requires plaintext files. So let’s fix this.
Enable Plain Text passwords
Hop back into the Settings pane of the Admin page. Click on “More settings…” at the bottom left and look for the “Authentication Scheme” drop down under the Password Settings section. Choose “Plain” from the drop down and save the new settings. Now you must change your user passwords to make sure they are saved in plain text this time around.
Change Warehouse’s htpasswd method
Now we will actually edit the Warehouse app to get the functionality we want. This isn’t too hard, but unfortunately any updates will temporarily break the password mechanism. So be sure to change this file again if you ever update/change Warehouse. Let’s get to the right file first:
cd ~/public_html/warehouse
cd lib/warehouse
edit command.rb file
Open up the command.rb file:
nano command.rb
and look for the following method (line 98):
def write_users_to_htpasswd(users, htpasswd_path = nil)
if htpasswd_path.nil?
htpasswd_path = users
users = connection[:users]
end
users = users.select(:login, :crypted_password) if users.is_a?(Sequel::Dataset)
open htpasswd_path, 'w' do |f|
users.each do |user|
next if user[:login].to_s == '' || user[:crypted_password].to_s == ''
f.write("%s:%s\n" % [user[:login], user[:crypted_password]])
end
end
puts "Wrote htpasswd file to '#{htpasswd_path}'"
end
This baby handles the writing of the htaccess file so we simply tell it to write a [users] line before cycling through each user and password. Simply add the following code:
f.write("[users]\n")
To the “open htpasswd_path” loop like this:
open htpasswd_path, 'w' do |f|
f.write("[users]\n")
users.each do |user|
next if user[:login].to_s == '' || user[:crypted_password].to_s == ''
f.write("%s:%s\n" % [user[:login], user[:crypted_password]])
end
end
save and restart
Now save the file and restart Warehouse.
sudo /etc/init.d/thin restart
test it out
And that’s it. Let’s give it a try by running the following command:
cd ~/public_html/warehouse
rake warehouse:build_htpasswd RAILS_ENV=production CONFIG=/home/demo/repositories/passwd
Now check the passwd file and ensure that it is written correctly with the [users] header and that your username and password appear:
cat ~/repositories/passwd
...
[users]
admin:password
All together now
Sweet! Warehouse can now dynamically write our authz and passwd files in a format that svnserve understands. This means svnserve is “receiving” instructions from Warehouse on how to behave and is securing your repositories as needed.
The final step is to tell Warehouse to execute that htpasswd command when users are modified. Go back into the Settings of the Admin tab and add the command:
rake warehouse:build_htpasswd RAILS_ENV=production CONFIG=/home/demo/repositories/passwd
to the “Shell command to run when someone’s password is updated.” option. From now on, when you add or update a user, the passwd file will be changed accordingly.
Finale
Phew! That was some decent work up there. But it is worth it. Your Subversion slice is running smoothly with no user/repository restrictions. You have about 8 GB of usable space for your content which is more than any of the SVN hosts out there provide. And with bandwidth cheaper than ever, you shouldn’t break more than $15 a month.
In general, this system covers the needs of the majority of users out there, but for the rest there are a couple of tweaks that might be helpful. In future parts, I will detail how to switch from Nginx to Apache and serve SVN through mod_svn which will increase our security options. There’s also a few other Warehouse tricks that might be helpful to some users. Stay in tune!

© 2009