Recently I had the pleasure of building a Network Attached Storage (“NAS”) server based on FreeNAS. Since then, this device has more than fulfilled my initial requirements for reliable file storage and media server in my network. In a previous post, I described how I configured FreeNAS to store web files and serve as a document root for the Apache http server implemented in my Ubuntu server. Using a similar approach, this post will describe how I configured FreeNAS to host my Subversion (“svn”) repository.
Software versions used in this post were as follows:
- FreeNAS v0.7.1 Shere (revision 5127)
- Ubuntu Server v10.04 LTS (x64)
- Subversion 1.6.6dfsg-2ubuntu1
- nfs-common v1:1.2.0-4ubuntu4
- portmap v6.0.0-1ubuntu2
Configuring the FreeNAS Server
I began by creating the directory svn on /mnt/files, an existing mount point on my FreeNAS server. This directory would serve as the location for my svn repository. Then I enabled the Network File System (“NFS”) service so that /mnt/files/svn could be accessed from the Ubuntu server. To do this, navigate to Services->NFS->Settings and make sure that the check box for enabling NFS is checked and specify the number of servers that will run (the default value of four should easily handle dozens of users). Now select “Save and Restart.” Next, navigate to Services->NFS->Shares and select the “+” icon, where you are presented with the configuration screen for creating a new NFS share. Enter the path to be shared; the network that is authorized to access this shared path; and, make sure that the “All dirs” checkbox selected. The remaining options can retain their defaults (See Figure 1). Now select “Add” then “Apply changes.”
Configuring the Ubuntu Server
In order to mount the NFS shared path without error, I needed to add a couple of packages. The nfs-common package is needed when a host acts as an NFS client, and includes a number of processes that ensure a particular NFS connection is allowed and may proceed. Also, because NFS relies upon remote procedure calls to function, the package portmap is needed in order to map RPC requests to the NFS service:
1 |
sudo apt-get install nfs-common portmap |
After these requisite packages were added, I created a directory to mount the NFS shared path. In this command, you must include the IP address of the FreeNAS server as well as the path to the directory created on it previously:
1 2 |
sudo mkdir /media/svn sudo mount 192.168.10.5:/mnt/files/svn /media/svn |
Then I made sure the permissions for this directory were set correctly:
1 |
sudo chmod 755 /media/svn |
Next, I added the following lines to /etc/fstab in order for the shared path to mount automatically at boot time:
1 2 3 4 5 6 |
###Start iceflatline #Mount the FreeNAS directory /mnt/files/svn for use as a Subversion repository 192.168.10.5:/mnt/files/svn /media/svn nfs defaults 0 0 ###End iceflatline |
Then I installed Subversion. The Subversion package for Ubuntu includes the Subversion client, tools to create a Subversion repository (svnadmin), and a custom protocol to make the repository I create on FreeNAS available over my network (svnserve):
1 |
sudo apt-get install subversion |
And created an svn repository at the root of the shared path:
1 |
svnadmin create /media/svn |
Next, I removed anonymous access to the repository and established write privileges for authenticated users. To do this, open /media/svn/conf/svnserve.conf and uncomment the following lines (Note: The svnserve.conf file is sensitive to white spaces, so make sure to not leave a space preceding the line when removing the hash (#) symbol):
1 2 3 |
anon-access = none auth-access = write password-db = passwd |
Then I added myself as an authenticated user to the /media/svn/conf/passwd file:
1 2 3 |
# harry = harryssecret # sally = sallyssecret iceflatline = <my password> |
I plan to use svn’s custom protocol for access to the repository so I need to start the svn server. One way to start it is to use the svnserve command:
1 |
svnserve -d -r /media/svn |
However, I wanted the svn server to start up at boot time, as well as have stop and restart capabilities while it was running, so I created the following simple init script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
#! /bin/sh ### BEGIN INIT INFO # Provides: svnserve # Required-Start: # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: svnserve init script # Description: This file is used to start, stop, restart, # and determine status of the svn server daemon. # Author: iceflatline <iceflatline@gmail.com> ### END INIT INFO ### START OF SCRIPT set -e # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="svnserve" NAME=svnserve DAEMON=/usr/bin/$NAME # Make sure the path in DAEMON_ARGS # reflects the location of the svn repository DAEMON_ARGS="-d -r /media/svn" SCRIPTNAME=/etc/init.d/$NAME # Exit if the subversion package is not installed [ -x "$DAEMON" ] || exit 0 # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # The function that starts the svnserve daemon start() { start-stop-daemon --start --quiet \ --exec $DAEMON -- $DAEMON_ARGS } # The function that stops the svnserve daemon stop() { start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \ --exec $DAEMON } case "$1" in start) log_daemon_msg "Starting $DESC" start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; esac ;; stop) log_daemon_msg "Stopping $DESC" stop case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; esac ;; restart|force-reload) log_daemon_msg "Restarting $DESC" stop case "$?" in 0|1) start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; esac ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" ;; esac exit 0 ### END OF SCRIPT |
To use the script, I saved it to my home directory as svnserve and made it executable. Then moved it to /etc/init.d:
1 2 3 |
cd ~ chmod +x svnserve sudo mv svnserve /etc/init.d/ |
Then added the svnserve script to all of Ubuntu server’s multi-user run levels (2-5) and started the svn server:
1 |
sudo update-rc.d svnserve defaults && sudo /etc/init.d/svnserve start |
Now, if for some reason the Ubuntu server is rebooted, the svn server will fire up automatically.
With the svn server now running, I created a root-level directory in subversion for a project called “code”:
1 |
svn mkdir svn://192.168.10.5/code |
After creating the project in subversion I can now use the standard svn commands or applications such Tortoise, RapidSVN and others to checkout the project or otherwise interact with the repository.
Conclusion
This concludes the post on how to configure a FreeNAS server for use as an svn repository. Sure, I could have installed the subversion package directly on FreeBSD, the underlying operating system for FreeNAS, but that approach adds processes that are not native to the FreeNAS implementation. By using the approach outlined in this post, I was able to place the repository on a solid, reliable and centralized storage system, and provide good logical and physical separation between the svn repository and the svn server functionality.
References
Hi,
you still can create a chroot or jail on you NAS, so you can seperate “additional services” from the “basic services”. Since a NAS often idle most of the time why not?