<chapter xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         version="5.0"
         xml:id="module-services-subversion">
  <title>Subversion</title>

 <para>
  <link xlink:href="https://subversion.apache.org/">Subversion</link>
  is a centralized version-control system.  It can use a <link
  xlink:href="http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.serverconfig.choosing">variety
  of protocols</link> for communication between client and server.
 </para>
 <section xml:id="module-services-subversion-apache-httpd">
  <title>Subversion inside Apache HTTP</title>

   <para>
   This section focuses on configuring a web-based server on top of
   the Apache HTTP server, which uses
   <link xlink:href="http://www.webdav.org/">WebDAV</link>/<link
   xlink:href="http://www.webdav.org/deltav/WWW10/deltav-intro.htm">DeltaV</link>
   for communication.
   </para>

   <para>For more information on the general setup, please refer to
   the <link
   xlink:href="http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.serverconfig.httpd">the
   appropriate section of the Subversion book</link>.
   </para>

   <para>To configure, include in
   <literal>/etc/nixos/configuration.nix</literal> code to activate
   Apache HTTP, setting <xref linkend="opt-services.httpd.adminAddr" />
   appropriately:
   </para>

    <para>
<programlisting>
  services.httpd.enable = true;
  services.httpd.adminAddr = ...;
  networking.firewall.allowedTCPPorts = [ 80 443 ];
</programlisting>
    </para>

    <para>For a simple Subversion server with basic authentication,
    configure the Subversion module for Apache as follows, setting
    <literal>hostName</literal> and <literal>documentRoot</literal>
    appropriately, and <literal>SVNParentPath</literal> to the parent
    directory of the repositories,
    <literal>AuthzSVNAccessFile</literal> to the location of the
    <code>.authz</code> file describing access permission, and
    <literal>AuthUserFile</literal> to the password file.
    </para>
    <para>
<programlisting>
services.httpd.extraModules = [
    # note that order is *super* important here
    { name = "dav_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_dav_svn.so"; }
    { name = "authz_svn"; path = "${pkgs.apacheHttpdPackages.subversion}/modules/mod_authz_svn.so"; }
  ];
  services.httpd.virtualHosts = {
    "svn" = {
       hostName = HOSTNAME;
       documentRoot = DOCUMENTROOT;
       locations."/svn".extraConfig = ''
           DAV svn
           SVNParentPath REPO_PARENT
           AuthzSVNAccessFile ACCESS_FILE
           AuthName "SVN Repositories"
           AuthType Basic
           AuthUserFile PASSWORD_FILE
           Require valid-user
      '';
    }
</programlisting>
    </para>

    <para>
    The key <code>"svn"</code> is just a symbolic name identifying the
    virtual host.  The <code>"/svn"</code> in
    <code>locations."/svn".extraConfig</code> is the path underneath
    which the repositories will be served.
    </para>

    <para><link
              xlink:href="https://wiki.archlinux.org/index.php/Subversion">This
    page</link> explains how to set up the Subversion configuration
    itself.  This boils down to the following:
    </para>
    <para>
      Underneath <literal>REPO_PARENT</literal> repositories can be set up
      as follows:
    </para>
    <para>
<screen>
<prompt>$ </prompt> svn create REPO_NAME
</screen>
    </para>
    <para>Repository files need to be accessible by
    <literal>wwwrun</literal>:
    </para>
    <para>
<screen>
<prompt>$ </prompt> chown -R wwwrun:wwwrun REPO_PARENT
</screen>
    </para>
    <para>
      The password file <literal>PASSWORD_FILE</literal> can be created as follows:
    </para>
    <para>
<screen>
<prompt>$ </prompt> htpasswd -cs PASSWORD_FILE USER_NAME
</screen>
    </para>
    <para>
    Additional users can be set up similarly, omitting the
    <code>c</code> flag:
    </para>
    <para>
<screen>
<prompt>$ </prompt> htpasswd -s PASSWORD_FILE USER_NAME
</screen>
    </para>
    <para>
      The file describing access permissions
      <literal>ACCESS_FILE</literal> will look something like
      the following:
    </para>
    <para>
<programlisting>
[/]
* = r

[REPO_NAME:/]
USER_NAME = rw
</programlisting>
    </para>
    <para>The Subversion repositories will be accessible as <code>http://HOSTNAME/svn/REPO_NAME</code>.</para>
 </section>
</chapter>
