Making your own FreeBSD Subversion repository mirror
Not long ago it was announced that the FreeBSD ports tree will cease exporting its Subversion repository to CVS, and subsequently any use of CVSup for updating the ports tree will be discontinued by February 28th 2013.
FreeBSD’s main source tree repository has been served by Subversion since late May 2008 with every commit done in the Subversion repository being exported to the old CVS repository, but no date has been announced when that Subversion to CVS transfer will be shut down. Stay tuned for more information.
Nonetheless, this is a Good Time™ to begin the transition from CVSup to Subversion once and for all. And why not set up your own FreeBSD Subversion repository mirror for both the main source tree and the ports tree well ahead of the transition?
For more official information, you should consult the FreeBSD’s Committer’s Guide chapter on Subversion and the FreeBSD Handbook‘s list of official FreeBSD Subversion repository mirrors.
On one of my own computers I have previously installed and set up Subversion for serving the repositories I chose to share with the rest of the world. All Subversion repositories (usually) live in /home/svn/svnroot
. In this case /home/svn/svnroot
is a separate ZFS file system. The same is true for /home/svn
. I don’t feel it’s necessary for me to backup the FreeBSD Subversion mirrors, so I chose to create a separate ZFS file system for these two FreeBSD repository mirrors, namely /home/svn/svnroot/freebsd
.
Here’s the command I used:
zfs create -o compression=gzip-9 enterprise_zdata/home/svn/svnroot/freebsd
What happens next is dependent on how much time and bandwidth you are willing to spend. You could start off by using a seed file available from ftp://ftp.freebsd.org/pub/FreeBSD/development/subversion/
and synchronize the missing revisions afterwards, or you could start fresh by downloading each and every revision. I chose the latter which involves a lot more work, testing my patience.
Next, I logged in as the svn
user and prepared two skeleton Subversion repository on which we will dump the contents from one of the official FreeBSD Subversion mirrors.
cd ~svn/svnroot/freebsd svnadmin create base svnadmin create ports
Some surgery is necessary before we can proceed with svnsync
.
First, allow for anonymous read access by editing the conf/svnserve.conf
file. The line:
# anon-access = read
in the [general]
section, usually at line no. 19, should read:
anon-access = read
Copy the edited svnserve.conf
file to the ports repository:
cp -p svnserve.conf ../../ports/conf/svnserve.conf
Second, and most important(!), the pre-commit hook for revprop changes must exist and be executable. Thus, copy the hooks/pre-revprop-change.tmpl
file to hooks/pre-revprop-change
, add execute permissions, and edit the script to exit with exit status zero.
cd ~svn/svnroot/freebsd/base/hooks cp -p pre-revprop-change.tmpl pre-revprop-change chmod a+x pre-revprop-change
The first few lines of the pre-revprop-change
file should read:
#!/bin/sh exit 0 # PRE-REVPROP-CHANGE HOOK # # The pre-revprop-change hook is invoked before a revision property # is added, modified or deleted. Subversion runs this hook by invoking # a program (script, executable, binary, etc.) named 'pre-revprop-change' # (for which this file is a template), with the following ordered # arguments:
Copy the edited pre-revprop-change
file to the hooks
directory for the ports repository mirror:
cp -p pre-revprop-change ../../ports/hooks/pre-revprop-change
Now, we need to make sure the repositories are ready for receiving the contents from one of the official FreeBSD Subversion mirrors. I chose to use the svn0.us-east.freebsd.org
mirror, but you may opt to use the svn0.us-west.freebsd.org
mirror, or the svn0.eu.freebsd.org
mirror. It is also possible to use the main FreeBSD Subversion repository at svn.freebsd.org
, but that may change in the future.
svnsync init file:///home/svn/svnroot/freebsd/base svn://svn0.us-east.freebsd.org/base svnsync init file:///home/svn/svnroot/freebsd/ports svn://svn0.us-east.freebsd.org/ports
The next two commands are both time consuming and bandwidth hungry when executed for the first time:
svnsync sync file:///home/svn/svnroot/freebsd/base svnsync sync file:///home/svn/svnroot/freebsd/ports
In my case, the first command ran for 39 hours and 20 minutes. The second command ran for 55 hours and 38 minutes.
If you at some time later want to change which mirror you are updating your own mirror from, then study these commands:
svn propset svn:sync-from-url --revprop -r 0 svn://svn0.us-west.freebsd.org/base file:///home/svn/svnroot/freebsd/base svn propset svn:sync-from-url --revprop -r 0 svn://svn0.us-west.freebsd.org/ports file:///home/svn/svnroot/freebsd/ports
To make it easy for people to simply migrate from using one of the official mirrors to my mirror, we need to mimick the UUIDs of the main FreeBSD Subversion repositories.
svnadmin setuuid /home/svn/svnroot/freebsd/base ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f svnadmin setuuid /home/svn/svnroot/freebsd/ports 35697150-7ecd-e111-bb59-0022644237b5
The two commands above allows every user to simply execute the following commands:
cd /usr/src svn relocate svn://svn.ximalas.info/freebsd/base/stable/9 cd /usr/ports svn relocate svn://svn.ximalas.info/freebsd/ports/head
I’m assuming you are already a Subversion user and that you are following the stable/9
line. As a result you are now syncronizing your working copies from my FreeBSD Subversion mirror.
This would be no good if my mirror is not synchronizing itself with the chosen official mirror, so let’s set up a crontab
file for the svn
user enabling synchronization every two hours.
SHELL=/bin/sh PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin HOME=/home/svn MAILTO=svn # #minute hour mday month wday command # 0 */2 * * * svnsync sync -q file:///home/svn/svnroot/freebsd/base 0 */2 * * * svnsync sync -q file:///home/svn/svnroot/freebsd/ports
This file is expected to have tabs between each field, mind you.
Save the file as .crontab
in the home directory of your svn
user, and let the cron
utility know what to do using the command:
crontab .crontab
If you are new to FreeBSD, you may choose to checkout RELENG_9
aka stable/9
, and the ports collection, by using these commands, tailor them to suit your needs:
svn co svn://svn.ximalas.info/freebsd/base/stable/9 /usr/src svn co svn://svn.ximalas.info/freebsd/ports/head /usr/ports
On the other hand, you might be better off using one of the official FreeBSD Subversion mirrors, svn0.us-west.freebsd.org
, or svn0.us-east.freebsd.org
, or even svn.freebsd.org
. It’s entirely up to you.
Here are some select items from ZFS’ statistics, i.e. a command like zfs get all enterprise_zdata/home/svn/svnroot/freebsd
, updated on 2013-03-24:
PROPERTY |
VALUE |
---|---|
used |
14.2G |
compressratio |
2.76x |
recordsize |
128K |
checksum |
fletcher4 |
compression |
gzip-9 |
exec |
on |
setuid |
off |
logicalused |
23.2G |
The base
repository mirror consumes roughly 5.1 GiB, while the ports
repository consumes roughly 8.8 GiB, both as reported by the du
command.
The reason for these weird numbers stems from the fact that I use hard drives with 4K disc block sizes and have enabled compression. The lesson is simply don’t do that.
I whipped up this small shell script to create my own seed files, much like the seed files available at ftp://ftp.freebsd.org/pub/FreeBSD/development/subversion/
. In effect the seed files are an online backup of my repository mirror.
#!/bin/sh # Shell script for creating seed files for the FreeBSD Subversion repository mirror. # Copyright © 2012, Trond Endrestøl <Trond.Endrestol@ximalas.info> # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. FREEBSD_SVN_REPO_MIRROR_DIR="/home/svn/svnroot/freebsd" FREEBSD_SVN_REPO_MIRROR_FS="enterprise_zdata/home/svn/svnroot/freebsd" FREEBSD_SVN_REPO_SEEDFILE_DIR="/home/svn/tmp" LOCAL_MIRROR_HOSTNAME="svn.ximalas.info" PATH=/bin:/sbin:/usr/bin:/usr/local/bin export PATH SNAPSHOTNAME=`date +%Y%m%dT%H%M%S` SNAPSHOT="${FREEBSD_SVN_REPO_MIRROR_FS}@${SNAPSHOTNAME}" zfs snapshot ${SNAPSHOT} cd ${FREEBSD_SVN_REPO_MIRROR_DIR}/.zfs/snapshot/${SNAPSHOTNAME} # Samples from manual execution: # -rw-r--r-- 1 svn svn - 1,2G 11 sep 19:01 svnmirror-base-r240363.svn.ximalas.info.tar.xz # -rw-r--r-- 1 svn svn - 714M 11 sep 22:26 svnmirror-ports-r301235.svn.ximalas.info.tar.xz BASE_REVISION_NUMBER=`tail -2 base/db/revprops/0/0 | head -1` PORTS_REVISION_NUMBER=`tail -2 ports/db/revprops/0/0 | head -1` gtar cJf ${FREEBSD_SVN_REPO_SEEDFILE_DIR}/svnmirror-base-r${BASE_REVISION_NUMBER}.${LOCAL_MIRROR_HOSTNAME}.tar.xz base gtar cJf ${FREEBSD_SVN_REPO_SEEDFILE_DIR}/svnmirror-ports-r${PORTS_REVISION_NUMBER}.${LOCAL_MIRROR_HOSTNAME}.tar.xz ports cd / zfs destroy ${SNAPSHOT} exit 0
Update 2013-03-24
Those who are still using CVS/CVSup for updating their ports tree will see messages like these:
"/usr/ports/Mk/bsd.port.mk", line 4: warning: ACTION REQUIRED "/usr/ports/Mk/bsd.port.mk", line 5: warning: You are using a ports file that originated from CVS!! "/usr/ports/Mk/bsd.port.mk", line 6: warning: The FreeBSD project has switched from CVS to SubVersion. "/usr/ports/Mk/bsd.port.mk", line 7: warning: This CVS repository is NO LONGER UPDATED! If you see this "/usr/ports/Mk/bsd.port.mk", line 8: warning: message then your tree is STALE and you need to follow "/usr/ports/Mk/bsd.port.mk", line 9: warning: the update instructions to receive any more updates. "/usr/ports/Mk/bsd.port.mk", line 10: warning: Original announcement: "/usr/ports/Mk/bsd.port.mk", line 11: warning: http://lists.freebsd.org/pipermail/freebsd-ports/2012-September/078099.html "/usr/ports/Mk/bsd.port.mk", line 12: warning: Reminder: "/usr/ports/Mk/bsd.port.mk", line 13: warning: http://lists.freebsd.org/pipermail/freebsd-announce/2013-January/001451.html "/usr/ports/Mk/bsd.port.mk", line 14: warning: UPDATE INSTRUCTIONS: "/usr/ports/Mk/bsd.port.mk", line 15: warning: http://wiki.freebsd.org/CvsIsDeprecated
Switch to the FreeBSD ports Subversion repository using either devel/subversion
or net/svnup
. The latter is recommended if you’re short on disk space or don’t want to waste additional disk space due to the .svn
control directory.
To access the FreeBSD ports Subversion repository mirror on my server using (a recent version of) svnup
, you would use a command like this one:
svnup current -b freebsd/ports/head -f -h svn.ximalas.info -l /usr/ports -p svn -v 2
svnup
is a bit too primitive since it deletes files and directories it should leave in place:
####### Fetching revision: 315115 - /usr/ports/INDEX-9.db - /usr/ports/INDEX-9 - /usr/ports/distfiles/Net-SSLeay-1.54.tar.gz - /usr/ports/distfiles/IO-Socket-SSL-1.84.tar.gz - /usr/ports/distfiles/Net-HTTP-6.06.tar.gz - /usr/ports/distfiles/LWP-Protocol-https-6.03.tar.gz - /usr/ports/distfiles/Crypt-SSLeay-0.64.tar.gz - /usr/ports/distfiles/libwww-perl-6.05.tar.gz - /usr/ports/distfiles/Mail-SpamAssassin-3.3.2.tar.gz - /usr/ports/distfiles/spamass-milter-0.3.2.tar.gz - /usr/ports/distfiles
You can make up for this deficiency by creating separate directories for distfiles and packages, and optionally a directory for workdirs, like this:
mkdir /usr/ports-distfiles mkdir /usr/ports-packages mkdir /usr/ports-workdirs
Next, add the following variables to the /etc/make.conf
file:
DISTDIR=/usr/ports-distfiles PACKAGES=/usr/ports-packages WRKDIRPREFIX=/usr/ports-workdirs
If you keep local stuff in /usr/ports/local
, then you’d better store that stuff in CVS or in some other SCM system and be prepared to check out those files after each svnup run.
While the preceding paragraphs on how to run snvup
are sound advice, the latest version of svnup
, currently at 0.99, is a great improvement over its predecessors, and it no longer deletes excess files not originating from the Subversion repositories unless told to do so.