Wednesday, May 16, 2012

Configure FreeNAS To Be Your Subversion Repository



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.”
    Screenshot of NFS shared path configuration in FreeNAS
    Figure 1
    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:
    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:
    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:
    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:
    ###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):
    sudo apt-get install subversion
    And created an svn repository at the root of the shared path:
    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):
    anon-access = none
    auth-access = write
    password-db = passwd
    Then I added myself as an authenticated user to the /media/svn/conf/passwd file:
    # 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:
    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#! /bin/sh
    2### BEGIN INIT INFO
    3# Provides:          svnserve
    4# Required-Start:
    5# Required-Stop:
    6# Default-Start:     2 3 4 5
    7# Default-Stop:      0 1 6
    8# Short-Description: svnserve init script
    9# Description:       This file is used to start, stop, restart,
    10#                    and determine status of the svn server daemon.
    11# Author:            iceflatline <iceflatline@gmail.com>
    12### END INIT INFO
    13 
    14### START OF SCRIPT
    15set -e
    16# PATH should only include /usr/* if it runs after the mountnfs.sh script
    17PATH=/sbin:/usr/sbin:/bin:/usr/bin
    18DESC="svnserve"
    19NAME=svnserve
    20DAEMON=/usr/bin/$NAME
    21# Make sure the path in DAEMON_ARGS
    22# reflects the location of the svn repository
    23DAEMON_ARGS="-d -r /media/svn"
    24SCRIPTNAME=/etc/init.d/$NAME
    25 
    26# Exit if the subversion package is not installed
    27[ -x "$DAEMON" ] || exit 0
    28 
    29# Load the VERBOSE setting and other rcS variables
    30. /lib/init/vars.sh
    31 
    32# Define LSB log_* functions.
    33# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
    34. /lib/lsb/init-functions
    35 
    36# The function that starts the svnserve daemon
    37start() {
    38    start-stop-daemon --start --quiet \
    39    --exec $DAEMON -- $DAEMON_ARGS
    40}
    41 
    42# The function that stops the svnserve daemon
    43stop() {
    44    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
    45    --exec $DAEMON
    46}
    47 
    48case "$1" in
    49  start)
    50    log_daemon_msg "Starting $DESC"
    51    start
    52    case "$?" in
    53        0) log_end_msg 0 ;;
    54        1) log_end_msg 1 ;;
    55    esac
    56    ;;
    57  stop)
    58    log_daemon_msg "Stopping $DESC"
    59    stop
    60    case "$?" in
    61        0) log_end_msg 0 ;;
    62        1) log_end_msg 1 ;;
    63    esac
    64    ;;
    65  restart|force-reload)
    66    log_daemon_msg "Restarting $DESC"
    67    stop
    68    case "$?" in
    69      0|1)
    70        start
    71        case "$?" in
    72            0) log_end_msg 0 ;;
    73            1) log_end_msg 1 ;;
    74        esac
    75        ;;
    76    esac
    77    ;;
    78    status)
    79    status_of_proc "$DAEMON" "$NAME"
    80    ;;
    81  *)
    82    echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}"
    83    ;;
    84esac
    85exit 0
    86### 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:
    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:
    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”:
    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
    http://tldp.org/LDP/abs/html/abs-guide.html
    https://help.ubuntu.com/community/Subversion

    No comments:

    Post a Comment