Subversion backup script
Following up on the good work of Jean-Francois Roy, here's my slightly extended version of his script (Update: sorry, the link is dead) to backup all Subversion repositories to a remote host.
How to use:
- Download backup-all-svn.sh
-
chmod u+x path/to/backup-all-svn.sh
-
./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> <div>`
# 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
No webmentions were found.