Dynamic Subversion Backup Tool
As I said in this post I’ve been exploring and using Subverison a lot recently, and with plans to start a hosted subversion arm to the web hosting business I need to keep working on the web based management tool. As everyone knows backups are crucial, so the first step towards my web based subversion management tool is the backup side of things. This is the first version of the script, I’ve been running it nightly for about 2 weeks now and it’s behaved very well so far.
I started with the script provided by Mark Shead (Backing up Subverison Automatically) however with plans for expansion I didn’t want to end up with a backup script for each repository. In addition to this I wanted the script to integrate with my envisaged web based SVN management tool, that meant database integration. In setting up the above script I found this article very helpful.
I ran with several versions of Marks script all running via cron and sending the output as email for a few days, then decided that now was a good time to integrate the script to a database and backup all of the repositories in the database. For a guide to using the script via cron see the end of the article.
I would include a SQL dump from PHPMyAdmin - but wordpress won’t let me include that in the post -but you need a single table called repo with three fields (repo_id, repo_location and repo_prefix). Any questions or comments leave a comment or email me.
Watch out for the mis-spelled SE!!!L!!!ECT - wordpress also won’t let me save the post with that line (or this line!) for some reason. I’m looking into why.
#perl modules to use
use DBI;
use DBD::mysql
#DBI config values
$host = "localhost";
$database = "database_name";
$user = "user_name";
$password = "password";
#Data Source Name
$dsn = "dbi:mysql:$database:localhost:3306";
#Perl DBI Connect
$connect = DBI->connect($dsn, $user, $password) or die "Unable to connect: $DBI::errstr\n";
#write the query
#Perl DBI Connect
$connect = DBI->connect($dsn, $user, $password) or die "Unable to connect: $DBI::errstr\n";
#write the query
$query = "SE!!!Insert L!!!ECT repo_location, repo_prefix FROM repo";
$query_handle = $connect->prepare($query);
#run the query
$query_handle->execute();
$query_handle->bind_columns(undef, \$repo_location, \$repo_prefix);
while($query_handle->fetch()) {
#my $svn_repo = $repo_location;
my $bkup_dir = "/subversion/backup";
#my $bkup_file = $repo_prefix;
my $tmp_dir = "/subversion/tmp";
my $bkup_svr = "backup.green-host.co.uk";
my $bkup_svr_login = "root";
my $remote_path = "/home/green/svn_backup";
print "\n-------------\n";
print "Backing up Repository $repo_location";
print "\n-------------\n";
$bkup_file = $repo_prefix . `date -Is`;
chomp $bkup_file;
my $youngest = `svnlook youngest $repo_location`;
chomp $youngest;
my $dump_command = "svnadmin -q dump $repo_location > $bkup_dir/$bkup_file ";
print "\nDumping Subversion repo $repo_location to $bkup_file...\n";
print `$dump_command`;
print "Backing up through revision $youngest... \n";
print "\nCompressing dump file...\n";
print `gzip -9 $bkup_dir/$bkup_file\n`;
chomp $bkup_file;
my $zipped_file = $bkup_dir . "/" . $bkup_file . ".gz";
print "\nCreated $zipped_file\n";
print `scp $zipped_file $bkup_svr_login\@$bkup_svr:$remote_path`;
print "\n$bkup_file.gz transfered to $bkup_svr\n";
#Test Backup
print "\n-------------\n";
print "Testing Backup";
print "\n-------------\n";
print "Downloading $bkup_file.gz from $bkup_svr\n";
print `scp $bkup_svr_login\@$bkup_svr:$remote_path/$bkup_file.gz $tmp_dir/`;
print "Unzipping $bkup_file.gz\n";
print `gunzip $tmp_dir/$bkup_file.gz`;
print "Creating test repository\n";
print `svnadmin create $tmp_dir/test_repo`;
print "Loading repository\n";
print `svnadmin -q load $tmp_dir/test_repo < $tmp_dir/$bkup_file`;
print "Checking out repository\n";
print `svn -q co file://$tmp_dir/test_repo $tmp_dir/test_checkout`;
print "Cleaning up\n";
print `rm -f $tmp_dir/$bkup_file`;
print `rm -rf $tmp_dir/test_checkout`;
print `rm -rf $tmp_dir/test_repo`;
}