Synchroniser svn et le répertoire de visualisation
J'ai été confronté à un petit challenge aujourd'hui. Je travaille en collaboration avec plusieurs équipes actuellement. Mon client possède un serveur de développement linux et je voulais mettre en place un dépôt SVN pour que les différentes équipes puissent travailler et "commiter" les données à un même emplacement.
Maintenant, plus que de simplement partager les données, le but final était de pouvoir synchroniser les commits utilisateurs ainsi que la racine web permettant de visualiser le site. En gros : un utilisateur synchronise le SVN et envoie ses modifications, les modifications seront directement visibles sur le serveur HTTP.
La première chose à faire est de créer la racine HTTP. Pour ça, je me connecte sur le serveur en SSH, je retrouve le répertoire d'installation Apache et je vais créer un nouveau virtualHost. J'ai déjà donné ce genre d'explication lors de l'installation de mon serveur multimédia, je ne m'attarderai pas sur le sujet. Il faut simplement savoir que j'ai rajouté les lignes suivantes dans la config de mon virtualHost afin que personne ne puisse avoir accès aux répertoires .svn qui seront dans chaque répertoire du site :
<DirectoryMatch "^/.*/\.svn/"> Order deny,allow Deny from all </DirectoryMatch>
Je crée un répertoire qui va correspondre au répertoire de base de la racine web.
mkdir /usr/home/apache2/dev.mydomain.com chown www:www /usr/home/apache2/dev.mydomain.com
Il faut néanmoins savoir que le virtualHost pointera sur
/usr/home/apache2/dev.mydomain.com/www
mais nous verrons ça un peu plus tard.
Je vais ensuite créer un nouveau dépôt. Ce nouveau dépôt va se trouver à l'emplacement suivant : /usr/home/svn/rev09.mydomain.
Dans /usr/home/svn, il y a un répertoire "conf" qui contient la configuration "globale" du SVN : un fichier authz, un fichier passwd ainsi qu'un fichier svnserve-standard.conf
svnserve-standard.conf :
[general] anon-access = none auth-access = write password-db = /usr/home/svn/conf/passwd authz-db = /usr/home/svn/conf/authz passwd : (user = password) [users] svn = ****** titouille = ****** user1 = ****** user2 = ****** user3 = ******
authz :
[groups] group1 = user1,user2 group2 = user3 owner = titouille,svn [rev09.mydomain:/] @owner = rw @group1 = rw @group2 = rw * =
J'ai donc plusieurs utilisateurs qui sont répertoriés dans des groupes, et ces groupes ont tous un accès en lecture/écriture au futur dépôt rev09.mydomain.
Je crée maintenant le dépôt et je spécifie que le propriétaire est svn:svn :
cd /usr/home/svn svnadmin create rev09.mydomain chown -R svn:svn rev09.mydomain
Je vais ensuite faire un lien symbolique du fichier /usr/home/svn/conf/svnserve.standard.conf pour remplacer le fichier /usr/home/svn/rev09.mydomain/conf/svnserve.conf :
rm /usr/home/svn/rev09.mydomain/conf/svnserve* ln -s /usr/home/svn/conf/svnserve.standard.conf /usr/home/svn/rev09.mydomain/conf/svnserve.conf chown svn:svn /home/svn/rev09.mydomain/conf/svnserve.conf
Maintenant que j'ai créé et configuré correctement mon dépôt, je vais tout d'abord essayer de m'y connecter avec éclipse via subclipse. Je démarre éclipse, j'affiche la vue "SVN Repositories" et je tente une connexion en faisant un click droit, new repository location, et je rentre l'adresse "svn://ip.de.mon.serveur/rev09.mydomain".
Si il me demande un login et mot de passe, j'insère mes infos de connexion SVN. La connexion s'effectue, j'en profite pour créer un répertoire "www" qui correspondra à la racine web (j'en ai parlé au début du billet).
Une fois que c'est fait, je reviens en mode console et je vais maintenant faire un checkout de mon projet vers la racine web, afin de faire en sorte que le répertoire de base de la racine web soient une copie de travail :
svn checkout svn://ip.de.mon.serveur/rev09.mydomain /usr/home/apache2/dev.mydomain.com
qui me renvoie la réponse suivante :
root# svn checkout svn://ip.de.mon.serveur/rev09.mydomain/ /usr/home/apache2/dev.mydomain.com Authentication realm: <svn://ip.de.mon.serveur:PORT> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Password for 'root': Authentication realm: <svn://ip.de.mon.serveur:PORT> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Username: titouille Password for 'titouille': ----------------------------------------------------------------------- ATTENTION! Your password for authentication realm: <svn://ip.de.mon.serveur:PORT> xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx can only be stored to disk unencrypted! You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/root/.subversion/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)? yes A /usr/home/apache2/dev.mydomain.com/www Checked out revision 1. root#
A priori, la première révision est passée correctement (l'ajout du répertoire www via eclipse).
et enfin je vais rendre www:www propriétaire de tous les fichiers qui sont dans la racine web :
chown -R www:www /usr/home/apache2/dev.mydomain.com
Maintenant que c'est fait, je vais commencer à m'atteler au travail de synchronisation.
Premièrement, je vais importer le projet dans éclipse : perspective PHP, click droit dans l'explorateur, Import. Je choisis "SVN -> Checkout projects from SVN" dans la boite de dialogue qui se présente et je clique sur "Next". Je sélectionne ensuite le dépôt correspondant et je clique encore sur "Next". Je sélectionne maintenant le répertoire "www" dans la hiérarchie du dépôt et je clique sur "Next". Je clique enfin sur "Finish" pour configurer un nouveau projet à l'aide de l'assistant de création de projets éclipse. Je sélectionne PHP Project, Next, j'insère le nom de mon projet : "rev09" et "Finish".
Dans mon nouveau projet, je vais créer un fichier "phpinfo.php" standard, qui va simplement contenir :
<?php phpinfo(); ?>
Je vais sauvegarder le fichier, puis click droit sur le projet, Team, Synchronise with repository. La perspective "Team synchronisation" s'ouvre et je peux voir la hiérarchie de mon projet avec les fichiers à commiter. Je vois mon fichier phpinfo.php. Click-droit, commit et le fichier est envoyé sur le SVN.
Je repasse en mode console, je tappe la ligne suivante :
root# ls -l /usr/home/apache2/dev.mydomain.com/www total 2 drwxr-xr-x 6 www www 512 Apr 2 13:12 .svn root#
Bien entendu, pour le moment, pas de synchronisation des fichiers, puisque je n'ai rien configuré à ce sujet.
Je vais maintenant créer un fichier "post-commit" qui va permettre de synchroniser les fichiers du svn vers la racine web. Ce fichier va se placer dans le répertoire /usr/home/svn/rev09.mydomain/hooks et contiendra les lignes suivantes :
#!/bin/sh SUDO=/usr/local/bin/sudo SVN=/usr/local/bin/svn $SUDO -u www $SVN update /usr/home/apache2/dev.mydomain.com --username svn --password ****** exit 0
Je vais rendre ce fichier exécutable et faire en sorte que svn:svn en soit le propriétaire :
chmod +x /usr/home/svn/rev09.mydomain/hooks/post-commit chown svn:svn /usr/home/svn/rev09.mydomain/hooks/post-commit
Puis je vais exécuter ce fichier pour être sûr que la synchronisation se fait correctement, au moins en mode console :
root# ./post-commit A /usr/home/apache2/dev.mydomain.com/www/phpinfo.php Updated to revision 2. root#
Yes, il a bien envoyé le fichier phpinfo.php vers le répertoire web "www". ça s'annonce bien.
Je vais finalement faire un test via éclipse directement. Je crée un nouveau fichier "test1.php" que je vais commiter vers le serveur.
En mode console :
root# ls -l /usr/home/apache2/dev.mydomain.com/www/ total 6 drwxr-xr-x 6 www www 512 Apr 2 13:33 .svn -rw-r--r-- 1 www www 33 Apr 2 13:31 phpinfo.php -rw-r--r-- 1 www www 9 Apr 2 13:33 test1.php root#
C'est bon, mes fichiers "phpinfo.php" et "test1.php" sont bien présent dans le répertoire "www".
Tout semble avoir fonctionné sans problèmes Smile (je dis ça mais j'ai bien galéré au départ pour trouver la bonne manière de faire Wink)
Il y a un autre problème maintenant :
Admettons que notre site web puisse créer de par son propre chef des fichiers sur la racine web, par exemple upload d'images, etc...
Vu que c'est une copie de travail, on doit pouvoir faire le processus de commit tout comme on le fait généralement depuis sa copie de travail local. Malheureusement, ça n'a pas l'air d'être le cas. J'ai rajouté un fichier "info.php" dans la racine web directement par FTP, puis tenté ceci :
root# svn commit /usr/home/apache2/dev.mydomain.com/www/info.php svn: Commit failed (details follow): svn: '/usr/home/apache2/dev.mydomain.com/www/info.php' is not under version control
Il y a donc un problème de synchronisation dans le sens inverse... Ma racine web a beau être une copie de travail, le processus devrai utiliser "svn add" pour que les fichiers soient ajoutés correctement, mais ce n'est pas le cas...
J'ai trouvé une réponse ici :
svn status |grep '\?' |awk '{print $2}'| xargs svn add
Il suffit ensuite de faire un commit comme ceci :
cd /usr/home/apache2/dev.mydomain.com svn commit -m "commentaire pour le submit"
Et ça fonctionne. Un "svn commit" tout simple ne fonctionne pas sur le serveur, car la commande sans l'argument -m est sensé ouvrir un éditeur permettant d'insérer le commentaire de commit et déclenche l'erreur suivante dans mon cas :
svn commit /usr/home/apache2/dev.mydomain.com/www vi: No terminal database found svn: Commit failed (details follow): svn: system('vi svn-commit.tmp') returned 256
ABE !
source : Backup / restore d'un dump svn