Home : Linux resources : Subversion server
This recipe was used to set my server up initially on SuSE 9.0 (where the shipped RPM edition of Subversion is so old as to be completely useless, so I built Subversion 1.3.0 from the tarball), and again when I migrated it to new hardware running openSUSE 10.2 (which comes with Subversion 1.4.0).
[But according to the openSUSE project "Lifetime" page, openSUSE 10.2 has been obsolete for more than 12 years now. Some of this may still work, but I haven't had reason to test it myself for quite some time, so take it with a huge grain of salt. -- rgr, 29-Jan-21.]
openssl req -x509 -newkey rsa:1024 -sha1 -days 90 -keyout key.pem -out req.pemBe sure to specify -sha1; if you don't, you will get MD5. The -x509 is what makes openssl req generate a self-signed certificate. Specifying -days 90 produces a cert valid for 90 days; the default is thirty (and this is ignored if you generate a proper signing request instead of a self-signature). This recipe is based on the "req(1)" man page, which explains what all the options mean.
In all cases, it is probably desirable to replace the word "server" with something specific to the server in question -- just be sure you do the same for the SSL config file.
OS key.pem (private key) req.pem (certificate) OpenSUSE /etc/apache2/ssl.key/server.key /etc/apache2/ssl.crt/server.crt CentOS /etc/pki/tls/private/server.key /etc/pki/tls/certs/server.crt
Note that this recipe installs the Subversion binaries into the default /usr/local/bin/ location. In order to use the backup script described below, you may need to add /usr/local/bin/ to $PATH.
CFLAGS=`apxs2 -q CFLAGS` ./configure --enable-shared \ --with-ssl --with-apxs=`which apxs2` --disable-mod-activationThese options have the following effect:
# Subversion server setup. -- rgr, 20-Mar-06. <Location /svn> DAV svn # any "/svn/foo" URL will map to a repository /shared/svn/foo SVNParentPath /shared/svn # how to authenticate. AuthType Basic AuthName "Subversion repository at rgrjr.dyndns.org" AuthUserFile /etc/svn-auth-file # require authentication for anything beyond read access. <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
# Subversion server setup. -- rgr, 13-Dec-07. <Location /svn> DAV svn # any "/svn/foo" URL will map to a repository /shared/svn/foo SVNParentPath /shared/svn # access control policy file. AuthzSVNAccessFile /etc/svn-access.conf # try anonymous access first, resort to real # authentication if necessary. Satisfy Any Require valid-user # how to authenticate. AuthType Basic AuthName "Subversion repository at rgrjr.dyndns.org [new]" AuthUserFile /etc/svn-auth-file </Location>The difference between this and the previous <Location> recipe is that the <LimitExcept> part is is replaced by top-level "Require valid-user" and "Satisfy Any" options, and the AuthzSVNAccessFile identifies an access file. Note that user credentials are still defined with htpasswd2 in /etc/svn-auth-file as before.
# Subversion authentication. See # http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html # for details. [/] # Allow everyone to read the entire repository, unless overridden. * = r # Give write permission to rogers and rgr. rogers = rw rgr = rw [lap-config:/] # This is private, so we need "* =" to revoke anonymous reads, and # "rogers = rw" to reinstate write permission. * = rogers = rwThe "[/]" paragraph reinstates the anonymous read/authenticated write policy of the previous section for all directories of all repositories, and the final paragraph restricts all access to the lap-config repository to rogers.
rogers@rgr> svn ls https://rgrjr.dyndns.org/svn/rgr-hacks/ branches/ tags/ trunk/ rogers@rgr>This is the expected output for a repository created by cvs2svn; if you look in trunk/, you will see the version-controlled files in the top-level directory.
svn co https://rgrjr.dyndns.org/svn/rgr-hacks/trunk rgr-hacksand look at the new working copy in the rgr-hacks subdirectory.
To find binary files in a CVS working copy:
rogers@rgr> cd ~/emacs/rgr-hacks rogers@rgr> find . -type f -name Entries \ | xargs -e egrep -n -e '\.(png|jpg|gif)/' \ | fgrep -v /-kb/To fix them:
rogers@rgr> cvs admin -kb *.jpg rogers@rgr> cvs updateNote that cvs admin operates on the repository immediately; the cvs update is only needed to update the working copy, but that is useful for subsequent searches.
Somewhat more problematic are files that are supposed to have DOS-style "CRLF" line endings, regardless of which OS they are checked out on. Even if marked "-kb", cvs2svn still treats these as "text/plain" and initializes their svn:eol-style to "native".
To find CRLF files (approximately) in a CVS working copy:
rogers@rgr> find . -type f | fgrep -v /CVS/ | xargs fgrep -l '\r'Since these often have "*.text" or other file extensions that are also used for files that should have "native" EOL style, there is no good way for cvs2svn to tell them apart, so I just fix them after the conversion (see below).
See also "How do I fix up end-of-line translation problems?" in the cvs2svn FAQ.
# svnadmin create /shared/svn/rgr-hacks # chown -R rogers /shared/svn/rgr-hacks
rogers@rgr> cvs2svn --existing-svnrepos -s /shared/svn/rgr-hacks/ /shared/cvsroot/rogers/emacs/rgr-hacks/Note that by default, cvs2svn will stuff everything that is not a branch into a trunk/ subdirectory.
# chown -R wwwrun /shared/svn/rgr-hacks
rogers@rgr> xargs svn propset svn:eol-style CRLF < dos-eol-files.text rogers@rgr> xargs perl -pi.bk -e 's/$/\r/;' < dos-eol-files.textAfter testing, do:
rogers@rgr> svn ci -m 'Fix svn:eol-style on DOS-like files.' rogers@rgr> find . -name '*.bk' | xargs rmto commit and clean up.
rogers@rgr> cd .. rogers@rgr> mv rgr-hacks rgr-hacks.cvs rogers@rgr> svn co https://rgrjr.dyndns.org/svn/rgr-hacks/trunk rgr-hacks rogers@rgr> diff -ur rgr-hacks.cvs rgr-hacksNote that diff will find many trivial differences in $Id:$ tags. If image files are reported to be different, then you probably need to go back to step 1.
rgrjr:~ # svnadmin create /shared/svn/lap-config rgrjr:~ # chown -R wwwrun.www /shared/svn/lap-config rgrjr:~ #
rogers@lap> mkdir -p tmp/trunk rogers@lap> cd tmp/trunk rogers@lap> tar xzf source-of-files.tgz rogers@lap> cd ../.. rogers@lap> ls tmp/trunk/ fstab.mgi hosts.random README.text.~1~ routes.rgrjr fstab.random ntp.conf.mgi resolv.conf.mgi site-setup HOSTNAME.mgi ntp.conf.random resolv.conf.rgrjr ssh_config hosts.mgi README.text routes.mgi sshd_config rogers@lap>Note that Subversion will not include README.text.~1~, knowing that it is an old version of the README.text file.
rogers@lap> svn import tmp https://rgrjr.dyndns.org/svn/lap-config -m "Initial import (SuSE 9.1)" Adding tmp/trunk Adding tmp/trunk/hosts.random Adding tmp/trunk/README.text Adding tmp/trunk/ssh_config Adding tmp/trunk/resolv.conf.rgrjr Adding tmp/trunk/sshd_config . . . Committed revision 1. rogers@lap> svn list https://rgrjr.dyndns.org/svn/lap-config trunk/ rogers@lap>
rogers@lap> rm -fr tmp
rogers@lap> svn co https://rgrjr.dyndns.org/svn/lap-config/trunk lap-config A lap-config/hosts.random A lap-config/README.text A lap-config/ssh_config A lap-config/resolv.conf.rgrjr A lap-config/sshd_config A lap-config/HOSTNAME.mgi A lap-config/routes.mgi A lap-config/ntp.conf.mgi A lap-config/site-setup A lap-config/ntp.conf.random A lap-config/routes.rgrjr A lap-config/resolv.conf.mgi A lap-config/fstab.mgi A lap-config/hosts.mgi A lap-config/fstab.random Checked out revision 1. rogers@lap> cd lap-config/ rogers@lap> ls fstab.mgi hosts.mgi ntp.conf.random resolv.conf.rgrjr site-setup fstab.random hosts.random README.text routes.mgi ssh_config HOSTNAME.mgi ntp.conf.mgi resolv.conf.mgi routes.rgrjr sshd_config rogers@lap>This creates a normal working copy.
# Back up Subversion repositories daily at 00:50. This is ten minutes before # the normal /home partition backup time. 50 0 * * * cd /home/rogers/projects/svn-dump && svn-dump.pl /shared/svn/*Since all mod_dav_svn repositories on my server are subdirectories of /shared/svn/, this catches everything with a single command. The files that are created look like this:
rogers@rgr> ls -lt /home/rogers/projects/svn-dump total 5468 -rw-r--r-- 1 rogers users 79596 06-29 00:50 web-site-213-235.svndump -rw-r--r-- 1 rogers users 19269 06-29 00:50 rgr-hacks-397-414.svndump -rw-r--r-- 1 rogers users 24044 06-29 00:50 kea-cl-558-568.svndump -rw-r--r-- 1 rogers users 172628 05-16 00:50 web-site-164-212.svndump -rw-r--r-- 1 rogers users 3210 04-14 00:50 hacks-4-4.svndump -rw-r--r-- 1 rogers users 56310 03-31 00:50 kea-cl-523-557.svndump -rw-r--r-- 1 rogers users 2264449 03-16 00:50 web-site-0-163.svndump -rw-r--r-- 1 rogers users 4476 03-03 00:50 rgr-hacks-392-396.svndump -rw-r--r-- 1 rogers users 903 02-05 00:50 rgr-hacks-391-391.svndump . . .Most files with only a few revisions are quite small, since each file records only the incremental changes since the last dump. The web-site-0-163.svndump file is large since that is the first dump since converting this repository from CVS.
Periodically, in order to reduce the clutter of small *.svndump files, I delete the most recent files, and the next time the svn-dump.pl cron job runs, these files are consolidated into a single new *.svndump file.
rogers@home> svnadmin dump /shared/svn/rgr-hacks/ > rgr-hacks.svndump * Dumped revision 0. . . . * Dumped revision 469. * Dumped revision 470. * Dumped revision 471. rogers@home>In this case, an 8.6MB file was generated for a repository that is only 5.7MB. If dumping creates a file that is unmanageably large, you might want to use the --deltas option of svnadmin dump. Note that svnadmin dump requires a path to the repository, not a URL, so this must be done on the original server. Note also that this command only writes to standard output, hence the redirection.
rogers@home> scp rgr-hacks.svndump rgrjr.com: rgr-hacks.svndump 100% 8652KB 540.7KB/s 00:16 rogers@home>
# svnadmin create /var/www/subversion/rgr-hacks #
# svnadmin load /var/www/subversion/rgr-hacks < rgr-hacks.svndump <<< Started new transaction, based on original revision 1 . . . <<< Started new transaction, based on original revision 471 * editing path : trunk/rgr-perl-hacks.el ... done. ------- Committed revision 471 >>> #(svnadmin load is even more verbose than svnadmin dump, so this transcript is even more severely truncated.)
# chown -R wwwrun.www /var/www/subversion/rgr-hacks #
svn switch --relocate https://rgrjr.dyndns.org/svn/rgr-hacks/ https://www.rgrjr.com/svn/rgr-hacks/The --relocate option means to move the working copy to the same version of the same repository but in a different location, so svn switch only needs to rewrite the URLs. In particular, this means the working copy doesn't need to be up-to-date, nor do any modified files need to be committed. It's also quite fast.