<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" 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>
    <programlisting language="bash">
services.httpd.enable = true;
services.httpd.adminAddr = ...;
networking.firewall.allowedTCPPorts = [ 80 443 ];
</programlisting>
    <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
      <literal>.authz</literal> file describing access permission, and
      <literal>AuthUserFile</literal> to the password file.
    </para>
    <programlisting language="bash">
services.httpd.extraModules = [
    # note that order is *super* important here
    { name = &quot;dav_svn&quot;; path = &quot;${pkgs.apacheHttpdPackages.subversion}/modules/mod_dav_svn.so&quot;; }
    { name = &quot;authz_svn&quot;; path = &quot;${pkgs.apacheHttpdPackages.subversion}/modules/mod_authz_svn.so&quot;; }
  ];
  services.httpd.virtualHosts = {
    &quot;svn&quot; = {
       hostName = HOSTNAME;
       documentRoot = DOCUMENTROOT;
       locations.&quot;/svn&quot;.extraConfig = ''
           DAV svn
           SVNParentPath REPO_PARENT
           AuthzSVNAccessFile ACCESS_FILE
           AuthName &quot;SVN Repositories&quot;
           AuthType Basic
           AuthUserFile PASSWORD_FILE
           Require valid-user
      '';
    }
</programlisting>
    <para>
      The key <literal>&quot;svn&quot;</literal> is just a symbolic name
      identifying the virtual host. The
      <literal>&quot;/svn&quot;</literal> in
      <literal>locations.&quot;/svn&quot;.extraConfig</literal> 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>
    <programlisting>
$ svn create REPO_NAME
</programlisting>
    <para>
      Repository files need to be accessible by
      <literal>wwwrun</literal>:
    </para>
    <programlisting>
$ chown -R wwwrun:wwwrun REPO_PARENT
</programlisting>
    <para>
      The password file <literal>PASSWORD_FILE</literal> can be created
      as follows:
    </para>
    <programlisting>
$ htpasswd -cs PASSWORD_FILE USER_NAME
</programlisting>
    <para>
      Additional users can be set up similarly, omitting the
      <literal>c</literal> flag:
    </para>
    <programlisting>
$ htpasswd -s PASSWORD_FILE USER_NAME
</programlisting>
    <para>
      The file describing access permissions
      <literal>ACCESS_FILE</literal> will look something like the
      following:
    </para>
    <programlisting language="bash">
[/]
* = r

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