Subversion backup script

Following up on the good work of Jean-Francois Roy, here’s my slightly extended version of his script to backup all Subversion repositories to a remote host.

How to use:

  1. Download backup-all-svn.sh
  2. chmod u+x path/to/backup-all-svn.sh
  3. ./backup-all-svn.sh -h target_host (can also set target port and user name)

Some features:

  • Works with plain /bin/sh, so it should work on any Linux / BSD distribution.
  • Works with repository names with spaces and non-ASCII characters.

backup-all-svn.sh

#!/bin/sh
#
# $Id: backup-all-svn.sh 387 2008-06-07 20:36:08Z vengmark $
#
# NAME
#    backup-all-svn.sh - Backup all Subversion repositories
#
# SYNOPSIS
#    backup-all-svn.sh [options]
#
# OPTIONS
#    -v     Verbose output
#    -h     Target host name (mandatory)
#    -p     Target host port
#    -u     Target host user name
#
# EXAMPLE
#    ./backup-all-svn.sh -v -h example.com -p 1234 -u johndoe
#
# DESCRIPTION
#    Backups all your subversion repositories to a remote machine.
#
#    The current user must have access to the subversion repositories.
#    To work around this, you should `sudo adduser <username> <svn-group>`
#    and `sudo chmod -R g+w /path/to/repos`.
#
#    To avoid having to type your password several times, you can setup SSH
#    keys - See e.g. https://help.ubuntu.com/community/SSHHowto
#
# BUGS
#    Email bugs to victor dot engmark at gmail dot com. Please include the
#    output of running this script in verbose mode (-v).
#
# COPYRIGHT AND LICENSE
#    Copyright (C) 2005 Jean-Francois Roy
#    Copyright (C) 2008 Victor Engmark
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################

# Init
ifs_original="$IFS" # Reset when done

PATH="/usr/bin:/bin"
cmdname=`basename $0`
directory=`dirname $0`

# Remote host
target_dir=".svn-backup/`date +%G-%m-%d`"
target_port=22
target_user=`whoami`

# Subversion
svn_root="/var/lib/svn"
svn_install_root="/usr/bin"

# Error messages from /usr/include/sysexits.h, recommended by
# http://www.faqs.org/docs/abs/HTML/exitcodes.html
EX_OK=0
EX_USAGE=64
EX_CANT_CREATE=73

# Custom errors
EX_NO_SUCH_DIR=91
EX_NO_SUCH_EXEC=92

usage_error()
{
	echo "Usage: ${cmdname} [-v] -h host [-p port] [-u user]" #Code 3 
	exit $EX_USAGE
}

# Process parameters
until [ $# -eq 0 ]
do
	case $1 in
		-v)
			verbose=1
			shift
			;;
		-h)
			if [ -z "$2" ]
			then
				usage_error
			fi
			target_host=$2
			shift 2
			;;
		-p)
			if [ -z "$2" ]
			then
				usage_error
			fi
			target_port=$2
			shift 2
			;;
		-u)
			if [ -z "$2" ]
			then
				usage_error
			fi
			target_user=$2
			shift 2
			;;
		*)
			#Unknown parameter
			usage_error
			;;
	esac
done

if [ -z ${target_host} ]
then
	usage_error
fi

# Use for mandatory directory checks
# $1 is the directory path
# $2 is the (optional) error message
check_directory()
{
	if [ ! -d $1 ]
	then
		echo "No such directory: '${1}'" >&2
		echo $2 >&2
		exit $EX_NO_SUCH_DIR
	fi
}

check_directory $svn_root "Please change \$svn_root to point to the directory where your Subversion repositories are."

check_directory $svn_install_root "Please change \$svn_install_root to point to the directory where Subversion is installed."

# Make sure an executable is available
# $1 is the path to the executable
# $2 is the (optional) error message
check_executable()
{
	if [ ! -x $1 ]
	then
		echo "No such executable: '${1}'" >&2
		echo $2 >&2
		exit $EX_NO_SUCH_EXEC
	fi
}

svn_install_missing="Please change \$svn_install_root to point to the directory where Subversion is installed."
check_executable ${svn_install_root}/svnlook $svn_software_missing
check_executable ${svn_install_root}/svnadmin $svn_software_missing

# Create the temporary folder
temp_dir=`mktemp -t -d ${cmdname}.XXXXXXXXXX` || exit $?

verbose_echo()
{
	if [ $verbose ]
	then
		echo "$*"
	fi
}

# Announce that we're running
verbose_echo "Running $cmdname at `date`."

# Create target directory
ssh -p ${target_port} ${target_user}@${target_host} "mkdir -p \"${target_dir}\"" || exit $?

# Loop over repositories
cd "${svn_root}"
IFS="
" # Make sure paths with spaces don't make any trouble when looping
for repository in *
do
	# Get the last revision
	revision=`${svn_install_root}/svnlook youngest "${repository}"`
	verbose_echo "Backing up repository \"${repository}\" revision ${revision}."

	# Make sure the repo is OK
	verbose_echo "Recovering the repository."
	${svn_install_root}/svnadmin recover --wait "${repository}" > /dev/null

	# Did the recover operation fail?
	if [ $? -ne 0 ]
	then
		echo "Backup failed because recovery failed." >&2
		break
	fi

	# Hotcopy
	verbose_echo "Hot-copying the repository."
	${svn_install_root}/svnadmin hotcopy --clean-logs "${repository}" "$temp_dir/${repository}"

	# Did the hotcopy fail?
	if [ $? -ne 0 ]
	then
		echo "Backup failed because hotcopy failed." >&2
		rm -Rf "$temp_dir"
		break
	fi

	# Compress the hotcopy
	verbose_echo "Compressing the repository in a tar.bz2 archive."
	archive="${repository}-r${revision}.tar.bz2"
	tar -cjpf "$temp_dir/${archive}" -C "$temp_dir" "${repository}"

	# Send it over
	verbose_echo "Copying repository archive to remote host."
	scp -P ${target_port} "$temp_dir/${archive}" "${target_user}@${target_host}:\"${target_dir}/${archive}\""

done

verbose_echo "Cleaning up."
rm -Rf $temp_dir
IFS="$ifs_original"

# End
verbose_echo "${cmdname} completed at `date`."

exit $EX_OK
Advertisements

2 thoughts on “Subversion backup script

  1. Pingback: Paperless - Aiming for information utopia » Subversion over HTTPS using Apache 2 on Ubuntu Hardy server howto

  2. Pingback: Subversion server using HTTPS on Ubuntu Hardy setup « Paperless

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