Centre de Ressources Informatiques Université Paul Verlaine - Metz Ile du Saulcy BP 80794 57012 Metz Cedex 1

Subversion / svn


L'installation d'un serveur svn pour un groupe de travail avec des projets publics , privés et authentfication ldap n'est pas tout à fait trivial.

Installation

Classique
apt-get install subversion subversion-tools libapache2-svn viewcvs

Configuration

Par défaut on utilise apache1.3 sur cette machine, subversion à besion de dav pour apache2.
L'accès https à svn est réalisé par un serveur frontend apache1.3 en virtualhost avec mod_proxy.
<VirtualHost 195.220.226.57:443>
ServerName  svn.univ-metz.fr
DocumentRoot /home/svn/html
ServerAdmin crium-reseau@univ-metz.fr
#-- SSL
SSLEngine on
SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL:+SSLv3

SSLCertificateFile ssl/svn.crt
SSLCertificateKeyFile ssl/svn.key

#   SSL Protocol Adjustments:
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown 
 downgrade-1.0 force-response-1.0

 ProxyPass      / http://svn.univ-metz.fr:8081/
 ProxyPassReverse   / http://svn.univ-metz.fr:8081/

  CustomLog /var/log/apache/wssl_access.log combined
  ErrorLog /var/log/apache/wssl_error.log
  TransferLog /var/log/apache/wssl_access.log
</VirtualHost>

attention à désactiver les alias de doc/ ou icons/ qui seront différent sur apache2 sinon on obtient ce type de message : client denied by server configuration: proxy:http (astuce pour google)

Le premier piège : l'accès html ne doit pas recouvrire les "location" svn
la structure sera alors
/home/svn
        |_htlm
        |_pub     (projets publics)
        |_cri     (projets privé)


Second problème : limiter l'accès par viewcvs.

dans la conf de viewcvs (/etc/viewcvs/viewcvs.conf) on associe un nom de projet à un dossier dans svn_roots.
Par convention les projets protégés commenceront par cri_.
en utilisant root_as_url_component = 1 dans viewcvs.conf et LocationMatch dans la conf apache2 (cf ci-dessous) on limite l'accès en lecture aux projets dont le nom viewcvs commence par cri_

ATTENTION pour apache2.2 il faut ajouter aux directives ldap
AuthBasicProvider ldap
AuthzLDAPAuthoritative off


Voilà la conf pour apache2 :
NameVirtualHost svn.univ-metz.fr

<VirtualHost svn.univ-metz.fr>
    ServerAdmin crium-reseau@univ-metz.fr
    DocumentRoot /home/svn/html
    # DocumentRoot could not overlap svn Location
    # else http://subversion.tigris.org/faq.html#301-error
    #
    <Directory />
        Options FollowSymLinks Indexes
        AllowOverride All
    </Directory>

    # defined in conf.d
    # take care with "Alias /doc/ ..." in https conf
    # Alias /doc/viewcvs/ /usr/share/viewcvs/

    # viewcvs script see /etc/viewcvs/viewcvs.conf
   ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

   # "/usr/lib/cgi-bin" could be changed to whatever your ScriptAliased
   # CGI directory exists, if you have that configured.
   #
   <Directory /usr/lib/cgi-bin/>
       AllowOverride None
       Options ExecCGI
       Order allow,deny
       Allow from all
       AddDefaultCharset UTF-8
   </Directory>

   # To use CGI scripts:
   AddHandler cgi-script .cgi

    # Public read repository
    <Location /pub>
        Options FollowSymLinks Indexes
        AllowOverride All
        DAV svn
        SVNParentPath /home/svn/pub

        AuthType Basic
        AuthName "LDAP"
        AuthLDAPURL ldap://ldap.univ.fr:389/ou=people,dc=univ,dc=fr??sub?Mgroup=cr
        AuthLDAPBindDN "cn=*****,ou=applis,dc=univ,dc=fr"
        AuthLDAPBindPassword ******

        order allow,deny
        allow from all
        <LimitExcept GET PROPFIND OPTIONS REPORT>
            Require valid-user
        </LimitExcept>
    </Location>

    # Private repository
    <Location /cri>
        Options FollowSymLinks Indexes
        AllowOverride All
        DAV svn
        SVNParentPath /home/svn/cri

        AuthType Basic
        AuthName "LDAP"
        AuthLDAPURL ldap://ldap.univ.fr:389/ou=people,dc=univ,dc=fr??sub?Mgroup=cri
        AuthLDAPBindDN "cn=*****,ou=applis,dc=univ,dc=fr"
        AuthLDAPBindPassword *****

        order allow,deny
        allow from all
        Require valid-user
    </Location>

    # Protect viewcvs access
    # - use root_as_url_component = 1 in viewcvs.conf
    # - names are defined in viewcvs.conf
    #
    <LocationMatch "/cgi-bin/viewcvs.cgi/cri_*">
        AuthType Basic
        AuthName "LDAP"
        AuthLDAPURL ldap://ldap.univ.fr:389/ou=people,dc=univ,dc=fr??sub?Mgroup=crium
        AuthLDAPBindDN "cn=*****,ou=applis,dc=univ,dc=fr"
        AuthLDAPBindPassword *******

        order allow,deny
        allow from all
        Require valid-user
    </LocationMatch>

    ErrorLog /var/log/apache2/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/log/apache2/access.log combined
    ServerSignature On

</VirtualHost>


On peut également mixer les authentifications par exemple un groupe ldap + des utilisateurs d'un fichier htpasswd
on utilise alors AuthBasicProvider ldap file avec AuthBasicAuthoritative off pour pouvoir changer de module d'identification si l'utilisateur n'existe pas dans le premier mode d'identification et on l'applique sur un LocationMatch

    # allow users from htpass file on catisurvey
    <LocationMatch /pub/catisurvey/*>
        AuthType Basic
        AuthName "LDAP"
        # don't forget 'ldap' and 'file'
        AuthBasicProvider ldap file
        AuthLDAPURL ldap://ldap.univ.fr:389/ou=people,dc=univ,dc=fr??sub?Mgroup=cri
        AuthLDAPBindDN "cn=*****,ou=admins,dc=univ,dc=fr"
        AuthLDAPBindPassword ******
        AuthLDAPGroupAttribute uid
        AuthLDAPGroupAttributeIsDN off

        AuthUserFile /var/www/htpass_cati_users
        AuthBasicAuthoritative off

        AuthzLDAPAuthoritative off

        order allow,deny
        allow from all
        <LimitExcept GET PROPFIND OPTIONS REPORT MKCOL>
            Require valid-user
        </LimitExcept>

        SetHandler               perl-script
    </LocationMatch>



Dernier problème : il y a un problème entre mod_proxy et dav, lorsqu'on fait des svn copy pour taguer ( erreur : 502 Bad Proxy )
Il faut ajouter un handler perl pour corriger à la volé.

NEW Si on utilise uniquement apache2, ce handler n'est plus nécessaire

package ProxyDav;

use strict;

use Apache2::RequestRec ();
use APR::Table ();
use URI;

use Apache2::Const -compile => qw(OK);

sub handler {
	my $r = shift;

  my $method = $r->method();
	if ($method eq 'MOVE' || $method eq 'COPY') {
	  my $destination = $r->headers_in()->get('Destination');
		my $new_destination = URI->new($destination);
		$new_destination->scheme('http');
		$r->headers_in()->set('Destination', $new_destination);
	}
  return Apache2::Const::OK;
}

1;

__END__

<Location /svn>
  SetHandler               perl-script
  PerlHeaderParserHandler  ProxyDav
</Location>

Merci : http://blog.bitflux.ch/archive/tag/subversion/

Pour finir

Utilisation de svn

Migration de Berkeley à FSFS


Lors de la migration de Lenny à Squeeze, subversion n'accepte plus l'ancien format BDB. Il faut convertir les anciens dépôts à FSFS.

On obtient des messages d'erreur de ce type :
DB_VERSION_MISMATCH: Database environment version mismatch:
bdb: Program version 4.8 doesn't match environment version 4.6
ou
Couldn't open a repository: Unable to open an ra_local session to URL:
Unable to open repository  file:/... Berkeley DB error for filesystem

La conversion ne pose pas vraiment de problème :
# conversion au dernier format
svnadmin recover /home/svn/pub/utils
# dump
svnadmin dump /home/svn/pub/utils > utils.dump
cp /home/svn/pub/utils/hooks/post-commit utils.post-commit
# nouveau depot
rm -rf /home/svn/pub/utils
svnadmin create /home/svn/pub/utils --fs-type fsfs
# load
svnadmin load /home/svn/pub/utils < utils.dump
cp utils.post-commit /home/svn/pub/utils/hooks/post-commit