Formation subversion (svn) Marc-Olivier Buob
Partie 1 : introduction Introduction État de l'art Définitions Installation
Problématique Besoin : Plusieurs personnes interviennent simultanément sur les mêmes fichiers. Ex : développement logiciel collaboratif Comment synchroniser et fusionner leur travail? Solution : utiliser un VCS (Version Control System) VCS = logiciel de gestion de version Il stocke un ensemble de fichiers et maintient leur chronologie... Chaque version est appelée révision. Quels fichiers ont été modifiés? Quand? Comment? Pour cela, le VCS maintient comment passer d'une version à l'autre Un VCS peut être distribué ou basé sur un modèle client serveur. Note : un VCS n'est pas adapté pour synchroniser de gros volumes binaires (photos...). Voir rsync etc...
SVN (subversion) SVN est un VCS libre Basé sur un modèle client serveur Conçu pour remplacer Concurrent Version System (CVS). Distribué sous licence apache et BSD. VCS concurrents :... CVS (libre, client serveur) git (libre, distribué) Révisions locales Plus adapté pour de gros projets que SVN Poussées périodiquement sur un serveur centralisé Team Foundation Serveur (Microsoft) http://fr.wikipedia.org/wiki/logiciel_de_gestion_de_versions
Rappels préliminaires Rappels en administration système : Utilisateurs (root, formation, svn,...) Pourquoi est-il important de définir une politique de droits restrictive? Rappels sur les droits UNIX (propriétaire, groupe, droits rwx) Organisation des fichiers sous Linux. Rappels en réseau : Qu'est-ce qu'un serveur? Qu'est-ce qu'un client mysqld / mysql apache2 / firefox, chromium, IE sshd / ssh, scp, konqueror, winscp Qu'est-ce qu'un port? Qu'est-ce qu'un protocole sécurisé? Pourquoi doit-on privilégier un protocole sécurisé?
Architecture SVN (client / serveur) Met à disposition les dépôts projet1 et projet2 Écoute sur le port 3690 par défaut Login : user1 MDP : p4ssw0rd1 Serveur SVN /var/svn/projet1 /var/svn/projet2... Login : user2 MDP : p4ssw0rd2 Client1 SVN ~/svn/projet1 Client2 SVN ~/svn/projet2 Peut récupérer projet1 Peut récupérer et modifier projet1 et projet2
Définitions Dépôt (repository) : arborescence associée à un projet Exemple : /var/svn/projet1 Base du serveur SVN : répertoire contenant l'ensemble des dépôts Exemple : /var/svn par exemple Révision : nouvelle version du projet mise à disposition sur le serveur Principales opérations côté client : checkout : récupérer la dernière version (première utilisation) update : action de récupérer la dernière révision add : ajoute un fichier à la prochaine révision delete : retire un fichier de la prochaine révision commit : publier une nouvelle révision revert : revenir dans une révision antérieure http://fr.wikipedia.org/wiki/subversion_%28logiciel%29#les_principales_commandes_de_subversion
Méthodologie côté client La première fois qu'on récupère un projet : svn checkout Avant de commencer à travailler : S'assurer qu'on travaille avec la dernière révision : svn update Avant de publier une mise à jour : S'assurer qu'on travaille avec la dernière révision : svn update Ajout de fichier svn add Suppression d'un fichier svn delete Modification d'un fichier rien : svn le verra au commit :-) Validation svn commit
Outils classiques Sous GNU/Linux Côté serveur : Côté client : subversion Apache + WebDAV svn (mode texte) + éventuellement colorsvn (coloration syntaxique) kdesvn (konqueror, KDE) RabbitVCS (nautilus, GNOME) Sous Microsoft Windows Côté client : Tortoise SVN (libre, licence GNU/GPL) Remarque : de la même façon il existe Tortoise git, Tortoise CVS...
URL SVN Base du serveur : svn://nom_du_serveur svn+ssh://nom_du_serveur (svn / ssh) http://nom_du_serveur/svn (svn + apache + module dav_svn) Le module base svn crée une arborescence dans le répertoire «svn» Adresse d'un dépôt SVN : svn://nom_du_serveur/nom_du_projet http://nom_du_serveur/svn/nom_du_projet
Installation des outils Pour cette formation, nous allons travailler sous Debian Les serveurs sont souvent sous GNU/Linux Linux est un environnement pratique pour le développement logiciel Certaines commandes sont propres à Debian et aux distributions qui en dérive (ubuntu...). Les autres distributions ont des équivalents. aptitude, service, update-rc.d On installe les paquets associés à SVN Passer en root (profil administrateur) (formation@debian) (~) $ su - Password: formation (root@debian) (~) # Installer les paquets (root@debian) (~) # aptitude update (root@debian) (~) # aptitude install subversion kdesvn kompare
Les différentes installations Il existe plusieurs manières de mettre en place un serveur svn Partie 2 : svn Tâche en arrière plan (démon) qui écoute sur le port svn (3690) Pas chiffré Partie 3 : svn+ssh ssh est couramment utilisé sous linux ssh permet de faire circuler du trafic de manière sécurisée (basé sur ssl) Partie 4 : apache2 et dav_svn en http et en https apache2 est un serveur web fréquemment utilisé sous linux dav_svn est le module qui permet d'interfacer apache et svn mais plus compliqué à mettre en place
Partie 2 : configuration du serveur Préparation de l'utilisateur svn Préparation du script de démarrage Préparation d'un dépôt
Introduction svn 3690 client serveur Utilisateur svn Circule en clair Mot de passe stocké en cache Démon svnserve svn et SASL SASL est un mécanisme d'authentification qui permet de chiffrer les échanges de mots de passe Nous ne l'arborderons pas, nous proposerons une solution équivalente basée sur ssh.
Préparation d'un utilisateur svn Préparation du groupe et de l'utilisateur svn : (root@debian) (~) # addgroup svn --system (root@debian) (~) # adduser svn --system --home /var/svn Nous allons maintenant préparer le script de démarrage... (root@debian) (~) # nano /etc/init.d/svn
http://doc.ubuntu-fr.org/subversion#configuration On peut rajouter l'option : --listen-port=3690 pour préciser le port sur lequel le serveur svn écoute #!/bin/sh set -e if [ -x /usr/bin/svnserve ] ; then HAVE_SVNSERVE=1 else echo "Svnserve not installed." exit 0 fi. /lib/lsb/init-functions case "$1" in start) log_action_begin_msg "Starting SVN server" /sbin/start-stop-daemon --start --chuid svn:svn --exec /usr/bin/svnserve -- -d -r /var/svn log_action_end_msg $? ;; stop) log_action_begin_msg "Stopping SVN server" /sbin/start-stop-daemon --stop --exec /usr/bin/svnserve log_action_end_msg $? ;; force-reload restart) $0 stop $0 start ;; *) echo "Usage: /etc/init.d/svn {start stop restart force-reload}" exit 1 ;; esac exit 0
Préparation du script de démarrage Correction des droits (root@debian) (~) # chmod +x /etc/init.d/svn Pour lancer, stopper ou redémarrer le service svn : Nouvelle syntaxe (root@debian) (~) # service svn start (root@debian) (~) # service svn stop (root@debian) (~) # service svn restart Par le passé, on aurait écrit /etc/init.d/svn start (etc...) Ajout de svnserve à la liste des services lancés au démarrage (root@debian) (~) # update-rc.d svn defaults
Préparation d'un dépôt (1/3) Création d'un dépôt «projet1» : ceci engendre l'apparition d'un squelette de fichiers de configuration dans /var/svn/projet1 (root@debian) (~) # svnadmin create /var/svn/projet1 Configuration du dépôt projet1 : (root@debian) (~) # nano /var/svn/projet1/conf/svnserve.conf [general] # Niveau d'autorisation pour un accès anonyme # (none read write) anon-access = none # Niveau d'autorisation si authentification réussie # (none read write) auth-access = write password-db = passwd authz-db = authz realm = projet1
Préparation d'un dépôt (2/3) Création des mots de passe utilisateurs pour ce dépôt : (root@debian) (~) # nano /var/svn/projet1/conf/passwd [users] # login = mot_de_passe user1 = p4ssw0rd1 user2 = p4ssw0rd2 Correction des droits (root@debian) (~) # chown -R svn:svn /var/svn/projet1 (root@debian) (~) # chmod -R u+rw /var/svn/projet1 (root@debian) (~) # chmod -R g+rw /var/svn/projet1 (root@debian) (~) # chmod -R o-rwx /var/svn/projet1
Préparation d'un dépôt (3/3) Correction des permissions utilisateur pour le dépôt projet1 (root@debian) (~) # nano /var/svn/projet1/conf/authz [/] * = user1 = r user2 = rw Signification : * = : pour tout le monde aucun droit user1 = r : user1 a un accès en lecture seule user2 = rw : user2 a un accès en lecture écriture
Vérifier que le serveur tourne On lance le serveur pour que ceci soit pris en compte : (root@debian) (~) # service svn start Vérifier que le serveur SVN tourne et écoute sur le port 3690 : (root@debian) (~) # ps aux grep svnserve svn 4886... 0:00 /usr/bin/svnserve -d -r /var/svn root 4937... 0:00 grep svnserve (root@debian) (~) # netstat -ntlp grep 3690 tcp 0 0 0.0.0.0:3690 0.0.0.0:* LISTEN 4886/svnserve
Client svn : tests (1/2) Préparation du répertoire d'accueil (formation@debian) (~) $ mkdir svn (formation@debian) (~) $ cd svn (formation@debian) (~/svn) $ Premières opérations avec le client en mode texte Checkout (formation@debian) (~/svn) $ svn checkout --username=user1 svn://localhost/projet1 Domaine d'authentification : <svn://localhost:3690> projet1 Mot de passe pour 'user1' : p4ssw0rd1 Révision 0 extraite. Update (formation@debian) (~/svn/projet1) $ svn update À la révision 0.
Client svn : tests (2/2) Création de quelques fichiers (formation@debian) (~) $ cd ~/svn/projet1 (formation@debian) (~/svn/projet1) $ nano toto.txt (formation@debian) (~/svn/projet1) $ nano titi.txt (formation@debian) (~/svn/projet1) $ nano tata.txt Ajout des fichiers à la prochaine révision (formation@debian) (~/svn/projet1) $ svn add toto.txt (formation@debian) (~/svn/projet1) $ svn add titi.txt (formation@debian) (~/svn/projet1) $ svn add tata.txt Validation de la nouvelle révision (formation@debian) (~/svn/projet1) $ svn commit On peut vérifier que user1 ne pourra pas faire de commit (r) Par contre user2 peut faire un commit (rw)
Petite visite côté serveur /var/svn/projet1/ conf/ : configuration du dépôt db/ authz : droits définis sur ce dépôt passwd : mot de passe associés à ce dépôt svnserve.conf : comportement du dépôt revs/0/0 : branche 0, création revs/0/1 : branche 0, révision 1 hooks/ : permet de déclencher un script à un moment précis Avant un commit, après un commit etc... Attention : Il ne faut jamais «bidouiller» un dépôt à la main car on risque de le corrompre. Il faut passer autant que possible par svnadmin.
Partie 3 : svn+ssh Installation côté serveur Préparation d'une clé ssh Tuning sur la clé ssh Manipulations côté client
Introduction svn 3690 client serveur Utilisateur svn Circule en clair Mot de passe stocké en cache Démon svnserve svn+ssh 22 client serveur Utilisateur linux (ssh) Chiffré Éventuellement, clé ssh Démon sshd (pas de démon svnserve)
Mise en place Installation Côté serveur (root@debian) (~) # aptitude install openssh-server (root@debian) (~) # service ssh start (root@debian) (~) # netstat -ntlp grep 22 Côté client (root@debian) (~) # aptitude install openssh-client On utilisera un utilisateur linux sur le serveur capable de se connecter en ssh (par exemple «svnuser»). On bénéficie de tous les avantages liés à ssh Communication sécurisée...
Côté client On a pas besoin de faire tourner svnserve On ne passe que par ssh Côté serveur : créer l'utilisateur svnuser et le mettre dans le groupe svn pour qu'il puisse accéder au dépôt (root@debian) (~) # adduser svnuser (root@debian) (~) # addgroup svnuser svn Côté client : $ svn co svn+ssh://svnuser@localhost/projet1
Installation d'une clé ssh Afin d'éviter d'avoir à chaque le mot de passe ssh (et retrouver le mécanisme de cache apporté par un client svn), nous allons créer une clé ssh. Afin de limiter ce que peut faire via ssh l'utilisateur svnuser grâce à cette clé, nous allons restreindre son contexte d'utilisation Afin d'alléger la syntaxe, nous allons modifier la clé pour taper svn+ssh://svnuser@localhost/projet1 et non svn+ssh://svnuser@localhost/var/svn/projet Une fois la clé fonctionnelle, root peut modifier le mot de passe de svnuser (voire désactiver ce mot de passe) http://prendreuncafe.com/blog/post/2005/08/29/262-installer-sa-cle-ssh-sur-un-serveur-distant
Restriction de la clé ssh Une fois la clé installé pour svnuser on restreint sa portée Côté serveur : (root@debian) (~) # nano ~toto/.ssh/authorized_keys On ajoute ce qui est en gras : (attention à ne pas rajouter ou enlever d'espace) command="/usr/bin/svnserve -t -r /var/svn/ --tunnel-user=svnuser",noport-forwarding,no-pty,no-agent-forwarding,no-x11-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJrzaTaORxmlSdme/JZKThniqzTT0QVUSwgP8h8rrYN/CJMITC +ADZctsco8g4f9EaV0Z0IliaI5j72HmvTZic4BOTcrNmgqRoTX/Xd5NNgXn3NDn4N+SrqN POjT6J8e7dSrotvq7T9eiGiPLufnTd+CQ3oYhS47wS8oRTiB/LutAAAAFQChbxsMp3LVFA 8IVuy2wsFZXILMYQAAAIB+wmBJXmMLhP6ZNJenwAPvzAS3vLcIQau1R12RWS0F13Y/7w7z alil2wflcxgbaz3kvvapttaig87n1gp0lieknfziqbt7i0twcodh4ydaoxciboglml3gjg F7Z37BY74lHLtArn47vc/sF92c4bl0V8CNpXLyGoJqpVUqow8D2gAAAIA0PEzwMUxcwh3L TNswCIG02YuJJJV/1d3OTawIcfWuYx7492cxt7H/rNlbHtjBJUXQgFqIjR+LCNCd3Ejwxb R3HXoyFwOANXeRhg7KYYJq/1csWT9h2XFzrdslxbb+9mj9sGL6Rc6LHsdbpvMD3Zzfp2mH 5WNSGvWgXz5eoKGYxQ== formation@debian On peut même restreindree la provenance, la commande qui a été lancée sur ssh etc... http://troy.jdmz.net/rsync/index.html Si besoin : ajouter svnuser dans le fichier /var/svn/projet1/conf/authz
Partie 4 : svn et apache Installation du serveur apache Installation du module dav_svn Préparation du site Préparation des profils et des dépôts Sécurisation avec SSL
Introduction svn sur http 80 client serveur Utilisateur svn Circule en clair Mot de passe stocké en cache Démon apache2 svn sur https 443 client serveur Utilisateur svn Chiffré (ssl) Mot de passe+certificat stockés en cache Démon apache2 + module ssl
Installation Installation des paquets : (root@debian) (~) # aptitude install apache2 libapache2-svn On vérifie qu'apache2 tourne : Processus et socket : (root@debian) (~) # ps aux grep apache2 (root@debian) (~) # netstat -ntlp grep 80 Avec un navigateur : http://localhost Avant de configurer dav_svn, nous allons configurer Les utilisateurs : /etc/apache2/dav_svn.passwd Les permissions : /etc/apache2/dav_svn.authz Chaque dépôt : projet1 : /var/svn/projet1/conf/svnserve.conf
Utilisateurs On créé /etc/apache2/dav_svn.passwd et un premier utilisateur : (root@debian) (~) # htpasswd -cs /etc/apache2/dav_svn.passwd user1 On rajoute quelques utilisateurs (attention : ne pas mettre le -c!) (root@debian) (~) # htpasswd -s /etc/apache2/dav_svn.passwd user2 (root@debian) (~) # htpasswd -s /etc/apache2/dav_svn.passwd user3 Ce fichier contient les mots de passe chiffrés des 3 utilisateurs : user1:{sha}3qousqtdg/tmpxuvmimdx5lwoji= user2:{sha}gsny8udal4ao8yf25dsyskzygy8= user3:{sha}lhrmprjtr6cdmde8r+vys1udie8= Ce fichier est sensible, donc on restreint les droits d'accès : (root@debian) (~) # chown root:www-data /etc/apache2/dav_svn.passwd (root@debian) (~) # chmod 640 /etc/apache2/dav_svn.passwd
Permissions Les permissions sont définies dans /etc/apache2/dav_svn.authz Attention : supprimer les commentaires ou les mettre sur une ligne dédiée, sans quoi dav_svn ne lira pas correctement la ligne! [groups] groupe1 = user1, user3 [/] * = # Par défaut, accès refusé [projet1:/] * = # Par défaut, accès refusé user1 = r # user1 pourra juste consulter le dépôt user2 = rw # user2 pourra lire ET écrire [projet1:/trunk/sources/] user3 = r # user3 aura accès en lecture seule à ce dossier [projet2:/] * = # Par défaut, accès refusé @groupe1 = r # "@" indique qu'on parle d'un groupe user2 = rw # Autorisations en lecture ET écriture pour user2 (root@debian) (~) # chown root:www-data /etc/apache2/dav_svn.authz (root@debian) (~) # chmod 640 /etc/apache2/dav_svn.authz
Configuration svn par dépôt Dans /var/svn/projet1/conf/svnserve.conf Tester si Cyrus SASL est actif : svnserve --version [general] anon-access = none # Pas d'accès anonyme auth-access = write # Un accès authentifié peut lire/écrire # password-db = passwd # À commenter! # authz-db = authz # À commenter! realm = projet1 # Titre du dépôt [sasl] # use-sasl = true # Si on utilise Cyrus SASL On ajoute www-data au groupe svn pour qu'apache ait les droits en écriture sur le dépôt. (root@debian) (~) # addgroup www-data svn
Configuration du module Dans /etc/apache2/mods-available/dav_svn.conf on met : (root@debian) (~) # nano /etc/apache2/mods-available/dav_svn.conf <Location /svn> # http://localhost/svn/ DAV svn SVNParentPath /var/svn # Racine du serveur SVN SVNListParentPath On # Plusieurs dépôts AuthType Basic AuthName "Mes depots" # Titre des dépôts AuthUserFile /etc/apache2/dav_svn.passwd AuthzSVNAccessFile /etc/apache2/dav_svn.authz Require valid-user # Authentification imposée </Location> On relance apache2 : (root@debian) (~) # a2enmod dav_svn (root@debian) (~) # service apache2 force-reload et on vérifie que ça fonctionne : http://localhost/svn/projet1
Tester avec le client svn Récupérer le projet1 : On fait un checkout avec le client svn (formation@debian) (~/svn) $ svn checkout --username=user1 http://localhost/svn/projet1 En cas d'erreur de segmentation : (formation@debian) (~/svn) $ rm -rf projet1 (formation@debian) (~/svn) $ svn checkout --username=user1 http://localhost/svn/projet1 Le client svn ne demande le mot de passe que la première fois Il le redemande si le mot de passe a été changé Le mot de passe est sauvé en cache dans ~/.subversion Tenter d'ajouter un fichier et de faire un commit en user1 Que constate-t'on? Idem avec user2
Sécurisation avec SSL (1/3) Nous allons générer un certificat SSL (https) Connexion sécurisée entre le client svn et le serveur apache On utilisera un certificat SSL auto signé Gratuit Mais pas reconnu par les navigateurs (root@debian) (~) # aptitude install ssl-cert openssl (root@debian) (~) # make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/localhost.pem Activer le module SSL (root@debian) (~) # a2enmod ssl (root@debian) (~) # service apache2 force-reload
Sécurisation avec SSL (2/3) Vérifier qu'apache2 écoute sur le port 443 (https) (root@debian) (~) # netstat -ntlp grep 443 Si ce n'est pas le cas, c'est sans doute que ce port n'a pas été activé dans /etc/apache2/ports.conf : NameVirtualHost *:80 Listen 80 <IfModule mod_ssl.c> Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule> (root@debian) (~) # service apache2 force-reload
Sécurisation avec SSL (3/3) Générer la configuration du site ssl On peut repartir de /etc/apache2/sites-available/default-ssl (root@debian) (~) # nano /etc/apache2/sites-available/ssl <VirtualHost *:443> ServerAdmin webmaster@localhost SSLEngine On SSLCertificateFile /etc/ssl/private/localhost.pem ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> Activer le site ssl : (root@debian) (~) # a2ensite ssl (root@debian) (~) # service apache2 restart puis tester : https://localhost/svn/projet1
Tests Essayons à présent de faire un checkout via https (root@debian) (~) # openssl x509 -in /etc/ssl/private/localhost.pem -noout -fingerprint SHA1 Fingerprint=26:45:C0:15:63:51:45:36:2C:2C:BD:CA:C8:A2:5F:59:A6:E9:B2:FF En cas d'erreur de segmentation, supprimer le projet partiellement téléchargé et recommencer le checkout. (formation@debian) (~/svn) $ svn co https://localhost/svn/projet1 Erreur de validation du certificat du serveur pour 'https://localhost:443' : - Le certificat n'est pas signé pas une autorité de confiance. Valider le certificat manuellement! Informations du certificat : - nom d'hôte : localhost - valide de Thu, 20 Jan 2011 12:36:26 GMT à Sun, 17 Jan 2021 12:36:26 GMT - signataire : localhost - empreinte : 26:45:c0:15:63:51:45:36:2c:2c:bd:ca:c8:a2:5f:59:a6:e9:b2:ff (R)ejet, acceptation (t)emporaire ou (p)ermanente? p Domaine d'authentification : <https://localhost:443> Mon depot Mot de passe pour 'formation' : (appuyer sur entrée) Domaine d'authentification : <https://localhost:443> Mon depot Nom d'utilisateur : user2 Mot de passe pour 'user2' : p4ssw0rd2 Connecting to deprecated signal QDBusConnectionInterface::serviceOwnerChanged(QString,QString,QString) Erreur de segmentation (formation@debian) (~/svn) $ rm -rf projet1 (formation@debian) (~/svn) $ svn co https://localhost/svn/projet1
Partie 5 : un client svn : kdesvn Introduction Présentation de l'interface Commit / update dans konqueror Exploiter kompare
Introduction Un client SVN peut être utilisé dans différents contextes Update : récupérer la dernière révision Commit : publier une nouvelle révision Revert : revenir en arrière dans le développement quand on a fait fausse route depuis plusieurs révisions Fork dans un projet (création d'une nouvelle branche) Merge dans un projet (fusion de plusieurs branches) Diff : comparer ce qui a évolué entre deux révisions Voir qui a contribué, à quels endroits et à quel moment dans les logs Il peut donc être utilisé par un développeur qu'un chef de projet. Rappel : il existe plusieurs clients SVN : kdesvn, svn, tortoisesvn... Ici nous allons utiliser un client SVN graphique pour plus de confort Dans les slides qui suivent nous avons mis l'interface en anglais pour retrouver la terminologie SVN, mais kdesvn est traduit en français.
KdeSVN KdeSVN est intégré dans konqueror ou dolphin (l'explorateur de fichiers) et dispose d'une interface dédiée. Voyons cette interface. Il en est de même pour tortoisesvn sous windows. Barre de menus Connexion Déconnexion à un dépôt SVN Opérations SVN Vue dossiers Vue fichiers Logs SVN Propriétés
kdesvn : tests Connexion au dépôt Open (ouvrir) : https://localhost/svn/projet1 Saisir le login et le mot de passe (user2, p4ssw0rd2) Enregistrer en favori Fonctionne sur le même principe qu'un favori dans un navigateur Internet Se connecter au dépôt à enregistrer Bookmarks (favoris), add bookmark Le dépôt apparaît désormais directement dans le menu bookmark.
kdesvn : checkout Subversion > checkout a repository Source : https://localhost/svn/projet1 Target : /home/formation/svn/ Téléchargé dans /home/formation/svn/projet1 START = révision 0 HEAD = dernière révision
kdesvn : update/commit Désormais on peut travailler directement dans l'explorateur de fichiers (konqueror ou dolphin) Update : clic droit dans le dossier projet1, update Ajoutez un fichier ayant pour nom votre prénom dans /home/formation/svn/projet1 Modifiez un fichier existant (celui-ci va apparaître en vert) Commit : clic droit dans le dossier projet1, commit
kdesvn + kompare : diff Pour le moment le diff n'est pas très lisible. Nous allons arranger ça grâce à kompare. Dans kdesvn : Configuration > Configure KdeSVN > Diff & Fusion cochez les cases comme indiqué ci-dessous
Illustration de kompare (1/2) Créez un fichier plop.c (cadre de gauche) puis faites un commit. Corrigez ce fichier selon le cadre de droite, puis faites un commit. #include <stdio.h> void dire_bonjour(){ printf("bonjour\n"); } int main(){ dire_bonjour(); return 0; } #include <stdio.h> void dire_bonjour(){ printf("bonjour\n"); } void ecrire_message( FILE *fp, const char *msg ){ fprintf(fp, "%s\n", msg); } int main(){ ecrire_message(fp, "Bonjour\n"); return 0; }
Illustration de kompare (2/2) Dans kdesvn, faites un clic droit sur plop.c pour afficher ses dernières modifications. Kompare s'ouvre et affiche ceci :
Sous Windows : tortoisesvn Si vous faites les TPs dans une machine virtuelle Linux qui tourne sous virtualbox pour windows : Stoppez la VM Dans les propriétés réseaux, mettez la machine en accès NAT Redémarrez la VM et vérifiez que vous avez une IP qui n'est pas en 10.0.2... (formation@debian) (~) $ /sbin/ifconfig Si c'est le cas, votre VM est visible par les autres machines Installez TortoiseSVN sous windows Créez un fichier à ajouter au dépôt (vous pouvez travailler tous sur le même dépôt pour voir les interactions). Modifications / créations simultanées (merge) etc...
Partie 6 : backup svn Sauvegarde Restauration
Sauvegarde On a intérêt à faire des sauvegardes (dump) régulièrement : Idéalement le dump doit être sauvé sur un autre PC Pour de petits volumes sur un autre support (clé USB, ) On passe par svnadmin pour être sûr que le dump soit correct (pas de lock...) Attention : la configuration svn n'est pas dumpée (root@debian) (~) # svnadmin dump /var/svn/projet1 > ~/projet1.bdb On peut éventuellement compresser le dump (root@debian) (~) # gzip -9 ~/projet1.bdb Convertir projet1.bdb en projet1.bdb.gz Pour décompresser un fichier «.gz» on peut utiliser la commande gunzip On peut automatiser les backups avec cron (+anacron) ou fcron http://doc.ubuntu-fr.org/cron http://doc.ubuntu-fr.org/fcron
Restauration Renommons le repository actuel pour tester notre dump (root@debian) (~) # mv /var/svn/projet1/db ~/db.backup Si on doit recréer le dépôt (ici ce n'est pas le cas) : (root@debian) (~) # svnadmin create /var/svn/projet1 On restaure le dump : (root@debian) (~) # gunzip ~/projet1.bdb.gz (root@debian) (~) # cat ~/projet1.bdb svnadmin load -q /var/svn/projet1 (root@debian) (~) # svnadmin verify /var/svn/projet1 Et on remet des droits corrects : (root@debian) (~) # chown svn:svn /var/svn/projet1/db (root@debian) (~) # chmod -R u+rw /var/svn/projet1/db (root@debian) (~) # chmod -R g+rw /var/svn/projet1/db
Partie 7 : redmine Introduction Installation Utilisation
Introduction Redmine est un système Open Source de gestion de projet en mode web. Il est développé en ruby grâce au framework ruby on rails. Trac est une solution concurrente écrite en python, mais il est moins complet que trac Pas de GANTT Contrairement à redmine, trac ne sait pas gérer des dépôts distants Dans cette formation nous allons nous concentrer sur redmine.
Fonctionnalités Gestion multi-projets Gestion fine des droits utilisateurs définis par des rôles Rapports de bugs, demandes d'évolutions Wiki et forums multi-projets Notifications par email / RSS / ATOM Gestion de feuilles de route, diagramme de Gantt, calendrier Historique Intégration avec divers suivis de versions : SVN, CVS, Mercurial, Git,... Identification possible via LDAP Multilingue (25 langues disponibles pour la 0.7.0) Support de plusieurs bases de données : MySQL, PostgreSQL ou SQLite.
Installation Redmine a besoin d'une base de données pour fonctionner Nous allons utiliser ici MySQL (root@debian) (~) # aptitude install mysql-server Choisir un mot de passe root pour la base de données et le mémoriser Installer redmine (root@debian) (~) # aptitude install redmine-mysql redmine Nous pourrions faire tourner redmine sur mongrel (un serveur web orienté ruby) mais nous allons continuer à utiliser apache2 : (root@debian) (~) # aptitude install libapache2-mod-passenger (root@debian) (~) # a2enmod passenger (root@debian) (~) # service apache2 restart
Référencer redmine dans apache2 Il ne reste plus qu'à dire à apache de mettre à disposition les pages web associées à redmine (root@debian) (~) # ln -s /usr/share/redmine/public /var/www/redmine (root@debian) (~) # nano /etc/apache2/sites-enabled/ssl Référencer redmine (puis relancer apache2) : <VirtualHost *:443> ServerAdmin webmaster@localhost SSLEngine On SSLCertificateFile /etc/ssl/private/localhost.pem DocumentRoot /var/www RailsEnv production RailsBaseURI /redmine <Directory /usr/share/redmine/public/> Options FollowSymLinks AllowOverride None Order deny,allow Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Premiers tests On se connecte à redmine https://localhost/redmine Login : admin, MDP : admin En cas de «permission denied» Vérifiez que vous êtes bien en https (on a configuré redmine uniquement pour https) Vérifiez que les paquets redmine sont correctement installés Vérifiez que le lien /var/www/redmine est correct (en cyan)
Configuration préliminaire Administration > Settings > General : https On peut configurer qui peut créer un compte, forcer l'authentification Administration > Settings > Authentification Cocher «authentification requiered» Désactiver «self-registration» et «autologin» Arrangeons le profil «admin». Dans «Mon compte» : Corriger la langue si besoin Corriger l'adresse mail
Prise en charge des dépôts SSL Problématique : Le certificat SSL n'est pas accepté à ce stade par www-data. Il n'est pas accepté par défaut par redmine (self-signed) www-data n'a pas les droits pour écrire son profil dans ~www-data = /var/www-data redmine plantera au moment d'indexer le dépôt! Pour ça nous allons créer un profil client svn à www-data à la main et faire accepter le certificat à www-data (root@debian) (~) # mkdir /var/www/.subversion (root@debian) (~) # chown www-data:www-data /var/www/.subversion (root@debian) (~) # su www-data $ svn info --username=user2 https://localhost/svn/projet1 Accepter en permanence le certificat (Ctrl d) (Ctrl d)
Création du projet Création d'un projet Projects > New project Donner un nom au projet, une description, et un identifiant (de son choix), une éventuelle page web associée au projet, cocher les modules à activer Par défaut : accès anonyme = accès en lecture seule Ajout d'un dépôt svn Settings > Repository > ajouter les infos du dépôt svn Note : le nombre de points associés au mot de passe peut varier mais c'est normal. Regarder le contenu du dépôt Aller dans Repository (au même niveau que Settings)
Configuration de l'envoi d'email Configurer l'envoi d'email (root@debian) (~) # cp /usr/share/redmine/config/email.yml.example /etc/redmine/default/email.yml production: delivery_method: :smtp smtp_settings: address: smtp.orange.fr port: 25 domain : monentreprise.fr Attention à respecter les espaces scrupuleusement! Relancer redmine... donc apache! (root@debian) (~) # service apache2 restart Vérifier dans Administration > Settings > Email notifications que est correct Penser à corriger localhost/redmine:3000 en l'ip ou le nom de la machine Préciser https
Création des utilisateurs Pour créer un compte : Administration > User > New user Dans «Mon compte» : Corriger la langue si besoin Corriger l'adresse mail On ne peut pas supprimer un utilisateur (on peut juste le verrouiller)
Wiki Projet1 > Wiki Redmine permet de maintenir un wiki par projet Syntaxe wiki : voir exemple ci-contre Lorsqu'on crée un lien, cliquer dessus permet de créer la page associée Wiki h1. Titre 1 h2. Titre 2 h3. Titre 3 <pre> Ceci est du code </pre> Des puces * puce1 * puce2 Une énumération # enum1 # enum2 Voici deux liens : [[DocumentationUtilisateur]] [[DocumentationUtilisateur Cliquez ici]]
Redmine : diff SVN Sélectionner le projet à examiner Dans «Accueil», cliquer sur projet1 Aller dans «Dépôt» Sélectionner les deux révisions à comparer puis cliquer sur «Afficher les différences» ajout suppression
Gestion des tickets Création d'un ticket d'incident Il faut être identifié dans un profil qui peut émettre une demande Cliquer sur «Nouvelle demande» Attribution d'un ticket La personne à laquelle est attribuée le ticket le verra au moment de s'identifier Modification / résolution d'un ticket Cliquer sur le numéro de la demande Changer le statut et enregistrer
Diagramme de Gantt Un diagramme de Gantt permet de planifier et d'ordonnancer de manière optimale les différentes tâches dans un projet. Permet de visualiser l'avancement d'un projet, ses retards Légende : En bleu : réalisé En gris : à réaliser En rouge : deadline dépassé ou en retard (réalisation / temps écoulé)
Partie 8 : les hooks svn Introduction Contexte d'utilisation Exemples
Introduction Un hook est une opération exécutée automatiquement par le serveur SVN à un moment donné : Avant une opération (pre) : vérifications... Après une opération (post) : reporting, statistiques... Exemples : pre-commit et post-commit Exemples : Vérifier qu'un commit est commenté Déployer lors d'un commit l'arborescence svn sur un serveur de production On peut imaginer n'importe quel script de vérification (cf google) Les hooks sont configurés pour chaque projet. /var/svn/projet1/hooks Contient un fichier par hook actif (portant le nom du hook) Le hook s'active quand le fichier est rendu exécutable
Hooks pre-lock : déclenché lorsqu un utilisateur essaye déverrouiller un fichier. Souvent utilisé pour gérer les droits d accès sur les verrous au niveau utilisateur. post-lock : déclenché lorsqu'un verrouillage a réussi. Souvent utilisé pour envoyer un email lors d un lock. pre-unlock, post-unlock. : même principe lors du retrait d'un verrou pre-commit : exécuté avant un commit. Utilisé pour contrôler le ou les fichiers publiés (ex : message de commit obligatoire ). post-commit : exécuté après un commit réussi Généralement utilisé pour envoyer un mail à un administrateur. pre-revprop-change : déclenché lors de changement de révision svn. post-revprop-change : notification d un changement de propriétés. Remarque : Ce hook ne peut fonctionner que si le hook pre-revprop-change est lui aussi mis en place. start-commit : appelé avant même que l opération de commit ne soit créée. Il sert la plupart du temps à vérifier les droits d un utilisateur.
Mise en place (1/2) Lors de la création du svn, un certain nombre de squelettes (templates, ie des squelettes) ont été générés (/var/svn/projet1/hooks/*tmpl) Si le serveur est sous Windows, ces fichiers sont inutilisables (les réécrire en.bat) (root@debian) (/var/svn/projet1/hooks) # cp pre-commit.tmpl pre-commit (root@debian) (/var/svn/projet1/hooks) # chown root:svn pre-commit (root@debian) (/var/svn/projet1/hooks) # chmod 750 pre-commit Les droits sont établis comme suit 7 : root peut lire (4), modifier (2), exécuter le hook (1) (7 = 4+2+1) 5 : le groupe svn peut le lire (4) et l'exécuter (1) (mais pas le modifier) 0 : les autres ne peuvent rien faire Un hook n'est qu'un script shell (il faut donc qu'il soit lisible et exécutable pour être utilisable) Il peut invoquer n'importe quoi, par exemple un script perl Les messages doivent être écrits sur la sortie d'erreur standard (>&2) pour être visible par le client SVN
Mise en place (2/2) #!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook Échoue si aucune ligne ne comporte de caractère alphanumérique # Vérifier que le commit est commenté $SVNLOOK log -t "$TXN" "$REPOS" grep "[a-za-z0-9]" > /dev/null if [ $? -ne 0 ] ; then echo "Veuillez commenter votre commit!" >&2 exit 1 fi # Ici on peut rajouter d'autres règles # All checks passed, so allow the commit. exit 0 Envoie ce message au client si le test est déclenché Il faut l'envoyer sur /dev/stderr! Quitte le hook avec succès (0) En cas d'erreur le hook retourne une valeur non nulle (différente pour chaque cas d'erreur)
Partie 9 : les branches svn Introduction Exemple concret
Introduction Le concept de branche SVN se met en place en hiérarchisant correctement le dépôt svn. Par convention trunk : répertoire dans lequel on travaille (version en développement, le HEAD) tags : contient des snapshots de versions stabilisées (releases) Dans svn les tags n'existent contrairement à dans cvs branches : permet de faire évoluer des branches parallèles au trunk en espérant merger à terme avec le trunk. Exemple : Dans trunk la version 1.5 est en développement. Dans tags, on a mis la release 1.4 On doit effectuer une correction sur la version 1.4 Alors on copie tags/1.4 vers branches/1.4.x Une fois les corrections terminées, on peut mettre branches/1.4.x dans tags/1.4.1
Préparation d'un dépôt de test Nous allons faire ce TP cours avec un dépôt de test créé en local. Les commandes ci-dessous créent un squelette svn conforme à ce que nous venons de voir. (formation@debian) (~) $ mkdir rep work (formation@debian) (~) $ svnadmin create rep (formation@debian) (~) $ svn co file:///home/formation/rep work (formation@debian) (~) $ svn mkdir work/branches work/tags work/trunk (formation@debian) (~) $ svn commit -m "Mise en place" work/
Release À ce stade le projet est encore unifié, on travaille donc dans le trunk. (formation@debian) (~) $ cd ~/work/trunk (formation@debian) (~/work/trunk) $ touch prgm.txt (formation@debian) (~/work/trunk) $ svn add prgm.txt (formation@debian) (~/work/trunk) $ svn commit Préparons une première release On copie le trunk dans tags (formation@debian) (~/work) $ svn copy trunk tags/release_1 (formation@debian) (~/work) $ svn commit -m "Création release 1"
Branches Imaginons que prgm.txt n'est pas correctement architecturé Ceci constitue la première branche La version alternative sera dans la seconde branche (formation@debian) (~/work) $ svn copy trunk branches/1.0 (formation@debian) (~/work) $ svn mkdir branches/2.0 (formation@debian) (~/work) $ svn commit -m "Ajout des branches" Ajoutons le contenu de la seconde branche (formation@debian) (~/work/branches/2.0) $ touch model.txt view.txt controller.txt (formation@debian) (~/work/branches/2.0) $ svn add * (formation@debian) (~/work/branches/2.0) $ cd ~/work (formation@debian) (~/work) $ svn commit -m "Développement de la 2e branche (architecture MVC)"
Concilier la 1ère branche et le tronc Supposons que certains développeurs continuent de travailler et de résoudre des bugs dans le tronc. (formation@debian) (~/work/trunk) $ echo "patch" > prgm.txt (formation@debian) (~/work/trunk) $ touch addons.txt (formation@debian) (~/work/trunk) $ cd ~/work/ (formation@debian) (~/work) $ svn commit -m "Correction bug28" La branche 1.0 n'en a pas bénéficié! Nous allons faire un merge mais au préalable il faut récupérer le numéro de version de la dernière modification (et non la version) (formation@debian) (~/work) $ svn info branches/1.0/ Par exemple il s'agit de la révision 4 (et non 6) qui correspond à la dernière révision.
Le merge On propage la révision 4 HEAD sur la première branche Le but est d'appliquer les mises à jours effectuées jusqu'à maintenant sur le trunk depuis qu'on a créé la branche 1.0 et d'appliquer ces modifications à la branche! (formation@debian) (~/work) $ svn merge -r 4:HEAD file:///home/formation/rep/trunk/ branches/1.0/ (formation@debian) (~/work) $ svn commit -m "Merge du trunk et de la branche 1.0" Le principe est le même pour les scénarios évoqués en introduction