Thanks, Vinayan!
I've been working on a Ruby script to automate the whole process. Here's what I have. It seems to work for me, but your mileage may vary.
First is svn_setup.rb, which you execute as yourself. Usage:
ruby svn_setup.rb repo_name
# OR
ruby svn_setup.rb repo_name remove
Here's the script:
# svn_setup.rb
my_domain = 'example.com' # Do not include http://
php_username = 'svn_admin'
php_password = 'a very strong password'
rw_users = ['first_svn_username', 'second_svn_username', 'etc'] # These all need to be present in ~/authfiles/svn-htpasswd
repo_name = ARGV[0]
action = (ARGV.length > 1 and ARGV[1] == 'remove') ? :remove : :create
my_username = `whoami`.chomp
require 'net/http'
begin
# Temporarily relax permissions so the webserver can get in there
puts 'Relaxing permissions on ~/svn and ~/.subversion'
File.chmod 0777, "/home/#{my_username}/svn"
File.chmod 0777, "/home/#{my_username}/.subversion"
# Run the PHP script to create the repo
puts 'Sending request to PHP script'
url = "http://#{my_domain}/svn_setup.php?username=#{php_username}&password=#{php_password}&repo_name=#{repo_name}&action=#{action.to_s}"
puts "--Begin output from PHP script"
puts Net::HTTP.get(URI.parse(url))
puts "--End output from PHP script"
# Give permissions to our SVN users
if action == :create
puts 'Adding entries to svn-access.conf'
access_conf = File.open("/home/#{my_username}/authfiles/svn-access.conf", 'a+')
access_conf << "\n[#{repo_name}:/]\n* = \n"
rw_users.each do |user|
access_conf << "#{user} = rw\n"
end
end
ensure
# Tighten up permissions
puts 'Tightening permissions on ~/svn and ~/.subversion'
File.chmod 0755, "/home/#{my_username}/svn"
File.chmod 0755, "/home/#{my_username}/.subversion"
# Reminder to the user
if action == :remove
puts "\nYou'll have to manually remove the entries from ~/authfiles/svn-access.conf. (For safety, we'd rather not do any automatic deletion from that file!)"
end
end
Next is svn_setup.php, which executes as nobody. Be sure to put this in ~/public_html or make it web-accessible in some other way (e.g. with a symlink).
// svn_setup.php
<?php
// Using GET for this is technically not correct, but in this context, it probably doesn't matter
$my_username = 'example'; // your HostingRails account username
$username = 'svn_admin';
$password = 'a very strong password';
if ($_GET['username'] == $username and $_GET['password'] == $password) {
if (!isset($_GET['repo_name']) or strlen($_GET['repo_name']) == 0) {
echo 'No repo name specified';
} else {
if (isset($_GET['action']) and $_GET['action'] == 'remove') {
$cmd = "rm -rf /home/{$my_username}/svn/{$_GET['repo_name']}";
} else {
$cmd = "svnadmin create --config-dir /home/{$my_username}/.subversion /home/{$my_username}/svn/{$_GET['repo_name']}";
}
system($cmd);
echo "Ran '$cmd'";
}
} else {
echo 'Incorrect username or password';
}
?>