Skip to content

Instantly share code, notes, and snippets.

@MechMK1
Created December 25, 2014 00:38
Show Gist options
  • Select an option

  • Save MechMK1/8efa583d6aec0c41e387 to your computer and use it in GitHub Desktop.

Select an option

Save MechMK1/8efa583d6aec0c41e387 to your computer and use it in GitHub Desktop.
Quickly create a new SVN repository and make it accessible via WebDAV
#!/bin/bash
#CFG
#Paths to directories must NOT end with /
SVNPARENT="/var/svn"
APACHECFG="/etc/apache2"
APACHESVN="/etc/apache2/svn"
USEMASTER=false #Prefer individual set to true to always use master or use -m to change individually
MASTERPASSWD="${APACHESVN}/master.passwd"
MASTERREALM="REALM" #Change
DEFAULTUSER=USER #Change
#TMP
FORCERUN=false
VERBOSE=false
REPONAME=
REPOLOCATION=
SVNREALM=
SVNPASSWD=
MASTERCONFIG=
#functions
function verbose {
if [ "$VERBOSE" == "true" ]
then echo "VERBOSE: $1"
fi
}
#Check parameters
while test $# -gt 0; do
case "$1" in
-h|--help)
echo "Usage: $0 [options] reponame"
echo " "
echo "Options:"
echo " -f, --force Run even if user is not root"
echo " Only do this if your current user has write access to all directories"
echo ""
echo " -m, --master Prefer using a master password file and realm over individual files/realms"
echo ""
echo " -v, --verbose Give verbose output"
exit 0
;;
-f|--force)
export FORCERUN=true
echo "Warning! Forcing to run this as non-root is generally not a good idea. But hey, I'm sure you know what you're doing."
shift
;;
-m|--master)
export USEMASTER=true
shift
;;
-v|--verbose)
export VERBOSE=true
shift
;;
*)
if [ $# -gt 1 ]
then echo "Using '$1' as repository name. Discarding the rest"
fi
export REPONAME="$1"
export REPOLOCATION="${SVNPARENT}/${REPONAME}"
export APACHESVNCFG="${APACHESVN}/${REPONAME}"
export MASTERCONFIG="${APACHESVN}/master.conf"
break
;;
esac
done
verbose "Check if the scipt should be run"
verbose "User must be root or force unprivileged use"
verbose "User id is $(id -u) and FORCERUN is $FORCERUN"
if ! ([ $(id -u) == 0 ] || [ $FORCERUN == "true" ])
then verbose "Display warning and exit"
echo "Must be run as root or with -f" && exit 1
else verbose "User is root or usage is forced. Continue!"
fi
verbose "Create repository base directory at $REPOLOCATION"
if ! mkdir "${REPOLOCATION}"
then verbose "mkdir failed! Exiting!"
echo "Could not create directory at ${REPOLOCATION}. Exiting!"
exit 1
else verbose "Creation successful!"
fi
verbose "Use svnadmin to create the repository barebones"
if ! svnadmin create --pre-1.6-compatible "${REPOLOCATION}"
then verbose "svnadmin failed! Exiting!"
echo "Could not create repository barebones at ${REPOLOCATION}. Exiting!"
verbose "Removing ${REPOLOCATION} before exiting"
rm -rf "${REPOLOCATION}"
exit 1
else verbose "Bareboning successful!"
fi
verbose "Create SVN config directory for apache"
if ! mkdir "${APACHESVNCFG}"
then verbose "mkdir failed! Exiting!"
echo "Could not create directory at ${APACHESVNCFG}. Exiting!"
verbose "Removing ${REPOLOCATION} before exiting"
rm -rf "${REPOLOCATION}"
exit 1
else verbose "Creation successful!"
fi
verbose "Determine if master or individual passwd/realm should be used"
if [ "$USEMASTER" == "true" ]
then verbose "Master"
if ! cat << EOFMASTER >> "${APACHESVNCFG}/${REPONAME}.conf"
<Location /svn/$REPONAME>
DAV svn
SVNPath /var/svn/$REPONAME
AuthType Basic
AuthName "$MASTERREALM"
AuthUserFile $MASTERPASSWD
Require valid-user
</Location>
EOFMASTER
then verbose "Fail Master"
echo "Could not create config file. Cleaning up and exiting"
verbose "Removing ${REPOLOCATION} before exiting"
rm -rf "${REPOLOCATION}"
verbose "Removing ${APACHESVNCFG}/${REPONAME} before exiting"
rm -rf "${APACHESVNCFG}/${REPONAME}"
exit 1
else verbose "Success Master"
fi
else verbose "Individual"
if ! cat << EOFINDIV >> "${APACHESVNCFG}/${REPONAME}.conf"
<Location /svn/$REPONAME>
DAV svn
SVNPath /var/svn/$REPONAME
AuthType Basic
AuthName "$REPONAME"
AuthUserFile /etc/apache2/svn/$REPONAME/$REPONAME.passwd
Require valid-user
</Location>
EOFINDIV
then verbose "Fail Individual"
echo "Could not create config file. Cleaning up and exiting"
verbose "Removing ${REPOLOCATION} before exiting"
rm -rf "${REPOLOCATION}"
verbose "Removing ${APACHESVNCFG} before exiting"
rm -rf "${APACHESVNCFG}"
exit 1
else verbose "Success Individual"
if ! htpasswd -c "${APACHESVNCFG}/${REPONAME}.passwd" "$DEFAULTUSER"
then verbose "Failed to create passwd file"
verbose "Removing ${REPOLOCATION} before exiting"
rm -rf "${REPOLOCATION}"
verbose "Removing ${APACHESVNCFG}} before exiting"
rm -rf "${APACHESVNCFG}"
exit 1
fi
fi
fi
verbose "Adding repository to master list"
if ! echo "Include svn/$REPONAME/$REPONAME.conf" >> "${MASTERCONFIG}"
then verbose "Could not add repository to master list"
echo "Could not write to master config file. Cleaning up and exiting"
verbose "Removing ${REPOLOCATION} before exiting"
rm -rf "${REPOLOCATION}"
verbose "Removing ${APACHESVNCFG} before exiting"
rm -rf "${APACHESVNCFG}"
exit 1
else verbose "Successfully written master config"
fi
verbose "Restarting apache"
if ! service apache2 restart
then verbose "Could not restart apache. Exiting without cleanup for forensics reasons"
echo "Could not restart. Exiting without cleanup"
exit 1
else verbose "Successfully written master config"
fi
@MechMK1
Copy link
Author

MechMK1 commented Dec 25, 2014

Currently, this script has only been tested on apache2 on Ubuntu. It requires a working vhost which includes the master config file (in my case, located at /etc/apache2/svn/master.conf)

A quick documentation of all files involved:

File/Directory Description
/etc/apache2/ Apache's config directory
/etc/apache2/svn/ Directory which contains all metadata about SVN repositories (but not the repositories themselves)
/etc/apache2/svn/master.conf Contains "Include svn/REPO/REPO.conf" for every added repository
/etc/apache2/svn/master.passwd Simple htpasswd file which contains usernames and hashes of all users which are able to authenticate to master repositories (see note1)
/etc/apache2/svn/REPO/ Directory which contains metadata about the REPO repository
/etc/apache2/svn/REPO/REPO.conf Contains the WebDAV configuration
/etc/apache2/svn/REPO/REPO.passwd Simple htpasswd file which contains usernames and hashes of all users who are able to authenticate to the REPO repository
/etc/apache2/sites-enabled/*.conf Any vhost declaration which at some point includes /etc/apache2/svn/master.conf
/var/svn/ Base directory which contains all svn repositories
/var/svn/REPO/ SVN repository

Note1 - Master vs. Individual mode.
If a repository is created in individual mode (default), then a new .passwd file and realm is created. This means, a new user and potentially a new password is used to authenticate with this password. Use this if you work with lots of different people and don't want them to be able to access other repositories than they should be able to.
If a repository is created in master mode (-m, --master), one single .passwd file (master.passwd) is used. Use this if you have a lot of private repositories to which only you and anyone you add to the master.passwd file have access. This generally saves lots of time, but is less secure as passwords are shared between all master repositories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment