Vous êtes ici : Accueil / Debian GNU/Linux / Serveurs / Développement / Installer un serveur Subversion sur Debian

Installer un serveur Subversion sur Debian

Par Pierre-Yves Landuré Dernière modification 22/04/2014 11:19

Subversion est un outil de gestion de code source. Il d'historise les différentes évolutions du code source d'un logiciel, et gère les éventuels conflits entre les modifications effectuées par plusieurs développeurs. USVN est une interface Web d'administration de Subversion. Elle facilite l'administration des utilisateurs, groupes, et dépôts du serveur SVN. Ce guide vous aide à installer Subversion et USVN sur Debian.

Ce guide est testé sur:

  • Debian 6.0 Squeeze
  • Debian 7.0 Wheezy

Ce guide est testé avec ces versions de USVN:

  • 1.0.6

Prérequis

Ce guide nécessite:

Paramètres

Renseignez le nom de domaine où sera disponible l'application:

USVN_DOMAIN="usvn.domaine-exemple.fr"

Renseignez le nom de domaine où seront disponibles les dépôts SVN:

SVN_DOMAIN="svn.domaine-exemple.fr"

Renseignez le nom d'hôte du serveur MySQL:

MYSQL_HOST="localhost"

Si le serveur MySQL n'est pas local, l'outil mysql-tools essaiera de s'y connecter avec le client MySQL, ou, en cas d'échec de connexion, via une connexion SSH.

Renseignez le nom du certificat SSL à utiliser pour chiffrer l'application USVN avec HTTPS (créé via la procédure Créer un certificat SSL / TLS sur Debian) (optionnel, recommandé):

USVN_SSL_KEY_NAME="${USVN_DOMAIN}"

Renseignez le nom du certificat SSL à utiliser pour chiffrer l'application USVN avec HTTPS (créé via la procédure Créer un certificat SSL / TLS sur Debian) (optionnel, recommandé):

SVN_SSL_KEY_NAME="${SVN_DOMAIN}"

Installation

Déterminez le chemin d'installation:

INSTALL_PATH="/opt/usvn/${USVN_DOMAIN}"

Détectez le protocole utilisé:

SVN_PROTOCOL="http"
command test -n "${SVN_SSL_KEY_NAME}" -a -e "/etc/ssl/private/${SVN_SSL_KEY_NAME}.key" && SVN_PROTOCOL="https"

Déterminez le chemin des données:

DATA_PATH="/var/lib/usvn/${USVN_DOMAIN}"

Créez les dossiers:

command mkdir --parent "${INSTALL_PATH}"

Préparation de l'environnement

Installez les logiciels nécessaires:

command apt-get install subversion libapache2-svn \
    php5-mysql php5-cli apg mysql-client apache2-utils

Activez les modules d'Apache 2 nécessaires à l'application (le module de réécriture d'URL et le module du serveur Subversion):

command a2enmod rewrite
command a2enmod dav_svn
command a2enmod authz_svn

Rechargez la configuration de PHP et d'Apache 2:

test -x /etc/init.d/php5-fpm && /etc/init.d/php5-fpm force-reload
test -x /etc/init.d/apache2 && /etc/init.d/apache2 force-reload
test -x /etc/init.d/lighttpd && /etc/init.d/lighttpd force-reload
test -x /etc/init.d/nginx && /etc/init.d/nginx force-reload

Mise en place de l'application

Récupérez l'URL de la dernière version de l'application:

SOURCE_URL="$(command wget --quiet --output-document=- "http://www.usvn.info/download.html" \
    | command grep 'tar.gz' | command tail -n 1 \
    | command sed -e 's|.*href="\([^"]*\)".*|\1|')"

Récupérez le numéro de version à partir de l'URL des sources:

VERSION="$(command echo "${SOURCE_URL}" \
| command sed 's|.*archive/\([^+]*\)\+.tar.gz|\1|')"

Téléchargez les sources:

command wget --no-check-certificate "${SOURCE_URL}" \
    --output-document="/tmp/usvn.tgz"

Décompressez l'archive:

command tar --directory "${INSTALL_PATH}" --strip 1 -xzf "/tmp/usvn.tgz"

Corrigez les permissions par défaut des dossiers:

command chown -R root:root "${INSTALL_PATH}"

Supprimez le fichier téléchargé:

command rm "/tmp/usvn.tgz"

Mise en conformité avec la LSB

Mettez en place une architecture de dossier conforme à la LSB. Créez le dossier destiné à recevoir les fichiers du dépôt Subversion, ainsi que quelques fichiers de configuration:

command mkdir --parent "${DATA_PATH}/svn"
command chown -R www-data:www-data "${DATA_PATH}"

Création de la base de données

Créez la base de données:

MYSQL_PARAMS="$(command mysql-tools --server="${MYSQL_HOST}" --with-ssh \
--auto-hosts --db-prefix="usvn" --create "${USVN_DOMAIN}")"

Récupérez les paramètres de la nouvelle base de données:

MYSQL_DB="$(echo "${MYSQL_PARAMS}" | command grep -e "^MYSQL_DB" \
    | command cut --delimiter="=" --fields="2-")"
MYSQL_USER="$(echo "${MYSQL_PARAMS}" | command grep -e "^MYSQL_USER" \
    | command cut --delimiter="=" --fields="2-")"
MYSQL_PASSWORD="$(echo "${MYSQL_PARAMS}" | command grep -e "^MYSQL_PASSWORD" \
    | command cut --delimiter="=" --fields="2-")"
echo "${MYSQL_PARAMS}"

Générez un préfixe de table aléatoire:

MYSQL_PREFIX="$(command apg -q -a 0 -n 1 -M NCL)_"

Initialisez le contenu de la base de données:

command cat "${INSTALL_PATH}/library/SQL/mysql.sql" \
    | command sed -e "s/usvn_/${MYSQL_PREFIX}/g" \
-e 's/type =/engine =/g' \ | command mysql --user="${MYSQL_USER}" --password="${MYSQL_PASSWORD}" \ --host="${MYSQL_HOST}" "${MYSQL_DB}"

Configuration

Choisissez un mot de passe pour le compte d'administration:

ADMIN_PASSWORD="$(command apg -q -a 0 -n 1 -M NCL)"

Créez le fichier htpasswd de votre serveur Subversion:

command htpasswd -cbm "${DATA_PATH}/${SVN_DOMAIN}.htpasswd" "admin" "${ADMIN_PASSWORD}"

Ajustez les permissions du nouveau fichier:

command chown www-data:www-data "${DATA_PATH}/${SVN_DOMAIN}.htpasswd"

Récupérez la version chiffrée du mot de passe du compte admin:

ADMIN_SECRET="$(command grep "admin" "${DATA_PATH}/${SVN_DOMAIN}.htpasswd" \
  | command cut --delimiter=":" --fields="2-")"

Créez le compte d'administration:

command echo "INSERT INTO ${MYSQL_PREFIX}users (users_login, users_password,
        users_lastname, users_firstname, users_email,
        users_is_admin, users_secret_id)
      VALUES ('admin', '${ADMIN_SECRET}',
        'Systeme', 'Administrateur', 'root@localhost',
        1, '$(command apg -q -m 32 -x 32 -a 1 -n 1 -M NL)');" \
    | command mysql --user="${MYSQL_USER}" --password="${MYSQL_PASSWORD}" \
      --host="${MYSQL_HOST}" "${MYSQL_DB}"

Créez la configuration de USVN:

command cp "${INSTALL_PATH}/config/config.ini.example" "${INSTALL_PATH}/config/config.ini"
command sed -i -e 's|^url.base.*$|url.base = ""|' \
    -e "s|system.locale.*$|system.locale = \"${LANG}\"|" \
    -e "s|template.name.*$|template.name = \"usvn\"|" \
    -e "s|site.ico.*$|site.ico = \"medias/usvn/images/logo_small.tiff\"|" \
    -e "s|site.logo.*$|site.logo = \"medias/usvn/images/logo_trans.png\"|" \
    -e "s|subversion.path.*$|subversion.path = \"${DATA_PATH}\"|" \
    -e "s|subversion.passwd.*$|subversion.passwd = \"${DATA_PATH}/${SVN_DOMAIN}.htpasswd\"|" \
    -e "s|subversion.authz.*$|subversion.authz = \"${DATA_PATH}/${SVN_DOMAIN}.authz\"|" \
    -e "s|subversion.url.*$|subversion.url = \"${SVN_PROTOCOL}://${SVN_DOMAIN}/\"|" \
    -e "s|database.adapterName.*$|database.adapterName = \"PDO_MYSQL\"|" \
    -e "s|database.prefix.*$|database.prefix = \"${MYSQL_PREFIX}\"|" \
    -e "s|database.options.host.*$|database.options.host = \"${MYSQL_HOST}\"|" \
    -e "s|database.options.username.*$|database.options.username = \"${MYSQL_USER}\"|" \
    -e "s|database.options.password.*$|database.options.password = \"${MYSQL_PASSWORD}\"|" \
    -e "s|database.options.dbname.*$|database.options.dbname = \"${MYSQL_DB}\"|" \
-e "s|^version.*$|version = \"${VERSION}\"|" \ "${INSTALL_PATH}/config/config.ini" echo 'update.checkforupdate = "1" update.lastcheckforupdate = "0"' >> "${INSTALL_PATH}/config/config.ini"

Mettez en place le fichier htaccess:

command echo '<Files *.ini>
  Order Allow,Deny
  Deny from all
</Files>

<IfModule mod_php.c> php_flag short_open_tag on php_flag magic_quotes_gpc off </IfModule>
RewriteEngine on #RewriteCond RewriteBase "/" RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L]' \ > "${INSTALL_PATH}/public/.htaccess"

Mettez en place la configuration d'Apache 2 pour l'application web:

if [ -e "/etc/ssl/private/${USVN_SSL_KEY_NAME}.key" ]; then
command a2tools --overrides="Limit FileInfo Options" \
--ssl="${USVN_SSL_KEY_NAME}" \
"${USVN_DOMAIN}" "${INSTALL_PATH}/public/"
command a2tools --template="redirect" "${USVN_DOMAIN}" "https://${USVN_DOMAIN}/"
else
command a2tools --overrides="Limit FileInfo Options" \
"${USVN_DOMAIN}" "${INSTALL_PATH}/public/"
fi

Déterminez l'option SSL:

if [ -e "/etc/ssl/private/${SVN_SSL_KEY_NAME}.key" ]; then
  SSL_OPTION="--ssl=${SVN_SSL_KEY_NAME}"
command a2tools --template="redirect" "${SVN_DOMAIN}" "https://${SVN_DOMAIN}/"
fi

Mettez en place la configuration du serveur Subversion:

command a2tools --template="custom" ${SSL_OPTION} "${SVN_DOMAIN}" "
# This Location directives allow users to access to the proxyfied contents.
# Do not remove this if you want your site to work :).
<Location />
Order deny,allow
Allow from all
ErrorDocument 404 default
DAV svn
#SSLRequireSSL
Require valid-user
SVNParentPath ${DATA_PATH}/svn
SVNListParentPath off
AuthType Basic
AuthName \"USVN\"
AuthUserFile ${DATA_PATH}/${SVN_DOMAIN}.htpasswd
AuthzSVNAccessFile ${DATA_PATH}/${SVN_DOMAIN}.authz
</Location>"

Nettoyez le dossier USVN en retirant les fichiers liés à l'installation:

command rm "${INSTALL_PATH}/public/dot.htaccess"
command rm "${INSTALL_PATH}/public/install.php"

Connectez-vous à l'application en utilisant les paramètres affichés par:

command echo "Les identifiants de connexion à l'administration d'USVN sont:
* URL d'accès  : http://${USVN_DOMAIN}
* Identifiant  : admin
* Mot de passe : ${ADMIN_PASSWORD}"

Sauvegardes

Sauvegardez l'installation avec Backup Manager (voir Installer et configurer Backup Manager sur Debian):

command backup-manager-tools add "${INSTALL_PATH}"
command backup-manager-tools add "${DATA_PATH}"

N'oubliez pas de sauvegarder la base de données (voir Installer et configurer MySQL sur Debian).

Il est nécessaire de sauvegarder les dépôts Subversion gérés par USVN. Comme leur nombre peut varier en fonction de votre utilisation, configurez Backup Manager pour obtenir automatiquement la liste des dépots présents:

command sed -i -e "s|\\(BM_SVN_REPOSITORIES=\\).*$|\\1\$(command find ${DATA_PATH}/svn/ -mindepth 1 -maxdepth 1 -type d)|" \
    "/etc/backup-manager.conf"

Activez la sauvegarde des dépôts Subversion:

command sed -i -e 's/[#]*\(.*BM_ARCHIVE_METHOD=.*".*\)"$/\1 svn"/' \
         "/etc/backup-manager.conf"

Mise à jour

Renseignez le domaine de l'installation obsolète:

USVN_DOMAIN="usvn.domaine-exemple.fr"

Déterminez le chemin d'installation:

INSTALL_PATH="/opt/usvn/${USVN_DOMAIN}"

Récupérez l'URL de la dernière version de l'application:

SOURCE_URL="$(command wget --quiet --output-document=- "http://www.usvn.info/download.html" \
    | command grep 'tar.gz' | command tail -n 1 \
    | command sed -e 's|.*href="\([^"]*\)".*|\1|')"

Récupérez le numéro de version à partir de l'URL des sources:

VERSION="$(command echo "${SOURCE_URL}" \
| command sed 's|.*archive/\([^+]*\)\+.tar.gz|\1|')"

Téléchargez les sources:

command wget --no-check-certificate "${SOURCE_URL}" \
    --output-document="/tmp/usvn.tgz"

Décompressez l'archive:

command tar --strip 1 --directory "${INSTALL_PATH}" -xzf "/tmp/usvn.tgz"

Corrigez les permissions par défaut des dossiers:

command chown -R root:root "${INSTALL_PATH}"

Nettoyez le dossier USVN en retirant les fichiers liés à l'installation:

command rm "${INSTALL_PATH}/public/dot.htaccess"
command rm "${INSTALL_PATH}/public/install.php"

Corrigez le numéro de version du fichier de configuration:

command sed -i -e "s|^version.*$|version = \"${VERSION}\"|" \
  "${INSTALL_PATH}/config/config.ini"

Supprimez le fichier téléchargé:

command rm "/tmp/usvn.tgz"

Subversion et reverse proxy

En utilisant un reverse proxy Apache 2 HTTPS pour accéder au serveur Subversion sur HTTP, des problèmes apparaissent lors des commits. Pour palier à cela, il existe des règles complexes de réécriture de requêtes.

Paramètres

Connectez-vous au shell du serveur reverse proxy Apache 2.

Renseignez le nom de domaine du serveur Subversion HTTPS (le reverse proxy):

SVN_DOMAIN="svn.domaine-exemple.fr"

Renseignez le nom de domaine du serveur Subversion HTTP (le serveur lui-même):

LOCAL_DOMAIN="subversion.domaine.lan"

Renseignez le nom du certificat SSL à utiliser pour chiffrer l'application USVN avec HTTPS (créé via la procédure Créer un certificat SSL / TLS sur Debian) (optionnel, recommandé):

SVN_SSL_KEY_NAME="${SVN_DOMAIN}"

Mise en place

Activez le module headers de Apache 2:

command a2enmod headers

Utilisez l'outil a2tools pour mettre en place la configuration du Reverse proxy:

command a2tools --template="custom" --ssl="${SVN_SSL_KEY_NAME}" "${SVN_DOMAIN}" "
 <IfModule mod_rewrite.c> <IfModule mod_proxy.c> # Do not ever never comment this line ! # This line prevent your web server to be used # as a proxy server by lurkers and other lamers. ProxyRequests Off # This little option pass the hostname to the proxyfied server. # This allow you to setup virtual hosts on the proxyfied server. # Yay ! This can be a life saver, so trust me, you want this option On. ProxyPreserveHost On
# Turn this on if the site behind the reverse proxy is on HTTPS.
SSLProxyEngine Off

# Declare the current request protocol.
RequestHeader set X-Forwarded-Proto "https"
# We use a HTTP subversion server behind a HTTPS reverse proxy ? # We need to fix the Destination header. # For details, please visit : http://silmor.de/49 # This configuration need the mod headers : a2enmod headers. # We replace all https in destination hearder by http. RequestHeader edit Source ^https: http: early RequestHeader edit Destination ^https: http: early # This do the same thing as over but allow Destination url to be different from the frontend ones. # RewriteCond %{HTTP:Destination} http[s]?://[^/]*/(.*\$) # RewriteRule ^/.* - [E=MyDestination:http://${SVN_DOMAIN}/%1,PT] # RequestHeader set Destination %{MyDestination}e env=MyDestination # RewriteCond %{HTTP:Source} http[s]?://[^/]*/(.*\$) # RewriteRule ^/.* - [E=MySource:http://${SVN_DOMAIN}/%1,PT] # RequestHeader set Source %{MySource}e env=MySource # Here is the magic that proxyfy the LAN server. # The first line is .... i don't remember what... # but trust me, it is usefull ;p. # The second line is a rewrite rule that do the proxy # magic. I was used to use a ProxyPass rule to do this work, but it # turned out that sometimes ProxyPass give you a 503 error when under # heavy load. The RewriteRule does not have this flow. ProxyPassReverse / http://${LOCAL_DOMAIN}/ RewriteRule ^/(.*) http://${LOCAL_DOMAIN}/\$1 [P,L]
# Uncomment the two lines below to enable URL rewrite debugging. # RewriteLog /var/log/apache2/${SVN_DOMAIN}-rewrite.log # RewriteLogLevel 9 </IfModule> </IfModule> # This Location directives allow users to access to the proxyfied contents. # Do not remove this if you want your site to work :). <Location /> # This allow SVN protocol specific methods. Without this, the reverse proxy reject svn commands. <Limit OPTIONS PROPFIND GET REPORT MKACTIVITY PROPPATCH PUT CHECKOUT MKCOL MOVE COPY DELETE LOCK UNLOCK MERGE> Order deny,allow Allow from all Satisfy Any </Limit> </Location> "

Migration vers le nouveau serveur

Cas simple : organisation similaire

Si vous disposiez déjà d'un serveur Subversion organisé de manière à ce qu'à chaque projet corresponde un dépôt, la migration se fait très simplement.

  1. La première étape est de recréer vos projets via l'interface USVN, en prenant bien garde de décocher l'option de création des répertoires standards (/trunk, /branches et / tags).
  2. Une fois tous vos projets créés, ouvrez une ligne de commande sur l'ancien serveur SVN, et créez une sauvegarde du contenu de chacun de vos dépôt en exécutant autant de fois que nécessaire la commande:
    command svnadmin dump "/path/to/repository/for/project" | command gzip -9 - > "project.dump.gz"
  3. Copiez les fichiers de sauvegarde ainsi obtenus sur le nouveau serveur (scp est votre ami :)).
  4. Sur le nouveau serveur, importez les sauvegardes en exécutant autant de fois que nécessaire la commande:
    su www-data -c "command zcat 'project.dump.gz' | svnadmin load '${DATA_PATH}/svn/project'"
  5. Une fois l'import terminé, vérifiez que tout s'est bien déroulé en récupérant votre projet, et en vérifiant que tout s'y trouve:
    command svn checkout 'http://svn.domaine.com/project' './project'

Remarque: Si vous disposez d'une copie de travail qui utilise l'ancien dépôt, vous pouvez la faire pointer vers le nouveau dépôt à l'aide de la commande:

command svn switch --relocate 'http://svn.vieux-server.com/project/trunk' 'http://svn.domaine.com/project/trunk'

Source: Merci à Ned Batchelder pour son article How to move a subversion repository.

Cas complexe : modification de l'organisation

C'est un cas que j'ai rencontré. L'ancien serveur SVN possédait une organisation de projet basée non pas sur "un dépôt par projet", mais sur "un dossier par projet".

Dans ce cas, il est nécessaire de modifier l'organisation de ce dépôt pour la faire correspondre à la méthode "un dépôt par projet".

  1. La première étape est de recréer vos projets via l'interface USVN, en prenant bien garde de décocher l'option de création des répertoires standards (/trunk, /branches et / tags).
  2. Une fois tous vos projets créés, ouvrez une ligne de commande sur l'ancien serveur SVN, et créez une sauvegarde du contenu de chacun de vos dépôt en exécutant autant de fois que nécessaire la commande:
    command svnadmin dump '/path/to/repository' \
        | command svndumpfilter include '/folder/for/project/' \
        | command gzip -9 - > 'project.dump.gz'
    

    Remarque: La commande svndumpfilter ne conserve que les changements effectués dans le dossier spécifié. CEPENDANT, elle ne supprime pas les révisions vides , c'est à dire ne contenant aucun changements dans le dossier spécifié. Si vous souhaitez supprimer les révisions vides, et renuméroter les révisions sauvegardées, utilisez la commande suivante pour la sauvegarde du projet:

    command svnadmin dump '/path/to/repository' \
        | command svndumpfilter include --drop-empty-revs --renumber-revs '/folder/for/project/' \
        | command gzip -9 - > 'project.dump.gz'
  3. Copiez les fichiers de sauvegarde ainsi obtenus sur le nouveau serveur (scp est votre ami :)).
  4. Il vous faut maintenant préparer l'import de votre dossier dans le nouveau serveur Subversion. Pour ce faire, 2 solutions s'offrent à vous.
    • Solution simple: Conserver le même emplacement dans le nouveau serveur, et déplacer après import. Pour ce faire, si le dossier de votre projet sur l'ancien dépôt était /folder/for/project/, il vous faut recréer l'arborescence /folder/for/ sur le nouveau serveur (on ne crée pas le dossier "project". Cela peut se faire simplement avec la commande:
      command svn mkdir -m "* Recréation de l'arborescence." "http://svn.domaine.com/folder/"
      command svn mkdir -m "* Recréation de l'arborescence." "http://svn.domaine.com/folder/for/"
    • Solution complexe: Si vous ne souhaitez pas déplacer vos dossiers importés après l'import, vous pouvez modifier manuellement le fichier de dump pour obtenir le résultat souhaité. Par exemple, pour placer le contenu du dossier "project" à la racine du nouveau dépôt SVN, vous pouvez utiliser la commande suivante (résultats non garantis):
      command zcat 'project.dump.gz' \
      | command sed -e 's|folder/for/project/||g' \
      | command gzip -9 - > 'moved-project.dump.gz'
  5. Sur le nouveau serveur, importez les sauvegardes en exécutant autant de fois que nécessaire la commande:
    su www-data -c "command zcat 'project.dump.gz' | command svnadmin load '/var/lib/subversion/svn/project'"
    
  6. Une fois l'import terminé, vérifiez que tout s'est bien déroulé en récupérant votre projet, et en vérifiant que tout s'y trouve:
    command svn checkout 'http://svn.domaine.com/project' './project'

Sources:

Remarque: si vous souhaitez passer de l'organisation "un dépot par projet" à une organisation "un dossier par projet", cela se fait très simplement grâce à l'option de --parent-dir de svnadmin load:

command zcat 'project.dump.gz' \
| command svnadmin load --parent-dir '/dossier/dans/projet' '/var/lib/subversion/svn/project'

Remerciements