Subversion backups

At work I have been given the job of administering our Subversion repository for the project.  I am also the “official” expert and go-to guy for Subversion–that ought to be interesting!  I’m no expert on servers and administration, and I only casually use Subversion. The other engineers have not used source code revision yet it seems.  I suppose I will learn as I go.

The subversion repository server is actually just an unused Windows XP workstation that is also acting as a file server.  Since we only need to allow access to the server over the corporate LAN, I decide to use the SVNSERVE to simplify administration and configuration.  I really don’t want to dig into configuring a web server, and I think SVNSERVE will work for us as the team size is still small (about 10 engineers). Because the server is just a regular workstation, I wanted to create a backup system so that if anything happens due to careless mistakes, I can easily bring the repository back to its latest state.

I decided on using a weekly full backup and daily incremental backup system.  I utilized the task scheduling feature of Windows XP to automatically run my backup system in the wee hours of the morning.  It can be accessed and configured to run tasks although a wizard in the Control Panel.  I created one task that will run on Saturday that will perform a full backup of our Subversion repository, and I created another task that will run incremental backups of the Subversion repository on weekdays.

I turned to my trusted tool for doing anything that I find troublesome (repetitive tasks or system administration): Perl.  I ran into early trouble though when I tested the task scheduler with perl.  I used the command “perl.exe -w C:\Perl\scripts\test.pl” with the scheduler, and the scheduled task would run, but my test script did not output to a file to prove that it had run.  I made sure that my %PATH% variable had the Perl binary directory too.  After scratching my head awhile I decided to create a Windows BAT file to execute the perl script.  The BAT file is really simple and looks like this:

@echo off
C:
cd C:\Perl\scripts
@perl.exe -w full_svn_backup.pl

That BAT file did the trick!  I created two BAT files, one that executes a full backup script and one that executes an incremental backup script.  I registered the BAT files with Windows XP task scheduler and then all that was left was to write the backup glue code in the perl scripts. For full backups, one simply has to execute svnadmin dump to backup the entire repository.  The full backup script looks like this:

######################################
# SVN repository full backup script
######################################

use strict;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
use Time::localtime;

# determine the current time
my ($day, $month, $year);
my $tm = localtime;
($day, $month, $year) = ($tm->mday, $tm->mon, $tm->year);
$year = $year + 1900;
$month = $month + 1;

# create variables to represent the paths and filenames to the repository and backups
my $repos_dir   = “C:\\svnrepos”;
my $backup_dst  = “C:\\subversion\\backup”;
my $backup_file = “full-backup.” . $year . $month . $day;

# determine the latest revision in the repositry
my $latest_rev = `svnlook youngest $repos_dir`;
chomp($latest_rev);

# execute the svnadmin dump command
my $cmd = “svnadmin dump –revision 0:$latest_rev $repos_dir > $backup_dst\\$backup_file”;
`$cmd`;

# create a ZIP archive of the repository backup to store on backup media
my $zip = Archive::Zip->new();
my $archive = $zip->addFile( “$backup_dst\\$backup_file” );
$zip->writeToFileNamed(“$backup_dst\\$backup_file” . “.zip”);

# save the latest revision number for use by incremental backup script
open(FDREV, “>revinfo.txt”) or die “$!”;
print FDREV $latest_rev . “\n”;
close(FDREV);

I’m not a perl guru who excels at writing greatl perl code, but I know enough to get the job done.  I then created a similar script for performing incremental backups.  Incremental backups are performed by using the –incremental flag with svnadmin dump.

###########################################
# SVN repository incremental backup script
###########################################

use strict;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
use Time::localtime;

# determine the current time
my ($day, $month, $year);
my $tm = localtime;
($day, $month, $year) = ($tm->mday, $tm->mon, $tm->year);
$year = $year + 1900;
$month = $month + 1;

# create variables to represent the paths and filenames to the repository and backups
my $repos_dir   = “C:\\svnrepos”;
my $backup_dst  = “C:\\subversion\\backup”;
my $backup_file = “inc-backup.” . $year . $month . $day;

# save the latest full backup revision number for use by incremental back script
open(FDREV, “<revinfo.txt”) or die “$!”;
my $last_rev = <FDREV>;
chomp($last_rev);
close(FDREV);

# determine the latest revision in the repositry
my $latest_rev = `svnlook youngest $repos_dir`;
chomp($latest_rev);

if($latest_rev eq $last_rev){
exit 0;
}

# execute the svnadmin dump command
my $start = $last_rev + 1;
my $end = $latest_rev;
my $cmd = “svnadmin dump –incremental –revision $start:$end $repos_dir > $backup_dst\\$backup_file”;
`$cmd`;

# create a ZIP archive of the repository backup to store on backup media
my $zip = Archive::Zip->new();
my $archive = $zip->addFile( “$backup_dst\\$backup_file” );
$zip->writeToFileNamed(“$backup_dst\\$backup_file” . “.zip”);

# save the latest backup revision number for use by incremental back script
open(FDREV, “>revinfo.txt”) or die “$!”;
print FDREV $latest_rev . “\n”;
close(FDREV);

These two scripts, coupled with BAT files for launching the scripts and Windows XP task scheduler, allow for a convenient backup solution that is really hands off.

Perl – making my life easier since 1999.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s