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)
Serveur SVN /var/svn/projet1 /var/svn/projet2
...
Client1 SVN
~/svn/projet1
Client2 SVN
~/svn/projet2
Login : user2 MDP : p4ssw0rd2 Login : user1
MDP : p4ssw0rd1
Met à disposition les dépôts projet1 et projet2
Peut récupérer projet1 Peut récupérer et modifier
projet1 et projet2 Écoute sur le
port 3690 par défaut
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 :
■ subversion
■ Apache + WebDAV
■ Côté client :
■ 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)
■ Installer les paquets
(root@debian) (~) # aptitude update
(root@debian) (~) # aptitude install subversion kdesvn kompare (formation@debian) (~) $ su -
Password: formation (root@debian) (~) #
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
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.
client serveur
Utilisateur svn Circule en clair
Mot de passe stocké en cache Démon svnserve
3690
Préparation d'un utilisateur svn
Préparation du groupe et de l'utilisateur svn :
Nous allons maintenant préparer le script de démarrage...
(root@debian) (~) # addgroup svn --system
(root@debian) (~) # adduser svn --system --home /var/svn
(root@debian) (~) # nano /etc/init.d/svn
http://doc.ubuntu-fr.org/subversion#configuration
#!/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
On peut rajouter l'option : --listen-port=3690 pour préciser le port sur lequel le serveur svn écoute
Préparation du script de démarrage
Correction des droits
Pour lancer, stopper ou redémarrer le service svn :
■ Nouvelle syntaxe
■ 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) (~) # chmod +x /etc/init.d/svn
(root@debian) (~) # service svn start (root@debian) (~) # service svn stop (root@debian) (~) # service svn restart
(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
Configuration du dépôt projet1 :
(root@debian) (~) # svnadmin create /var/svn/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 :
Correction des droits
(root@debian) (~) # nano /var/svn/projet1/conf/passwd [users]
# login = mot_de_passe user1 = p4ssw0rd1
user2 = p4ssw0rd2
(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
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
(root@debian) (~) # nano /var/svn/projet1/conf/authz
[/]* =
user1 = r user2 = rw
Vérifier que le serveur tourne
On lance le serveur pour que ceci soit pris en compte :
Vérifier que le serveur SVN tourne et écoute sur le port 3690 :
(root@debian) (~) # service svn start
(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
Premières opérations avec le client en mode texte
■ Checkout
■ Update
(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.
(formation@debian) (~/svn/projet1) $ svn update À la révision 0.
(formation@debian) (~) $ mkdir svn (formation@debian) (~) $ cd svn (formation@debian) (~/svn) $
Client svn : tests (2/2)
Création de quelques fichiers
Ajout des fichiers à la prochaine révision
Validation de la nouvelle révision
■ On peut vérifier que user1 ne pourra pas faire de commit (r)
■ Par contre user2 peut faire un commit (rw)
(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
(formation@debian) (~/svn/projet1) $ svn add toto.txt (formation@debian) (~/svn/projet1) $ svn add titi.txt (formation@debian) (~/svn/projet1) $ svn add tata.txt
(formation@debian) (~/svn/projet1) $ svn commit
Petite visite côté serveur
/var/svn/projet1/
■ conf/ : configuration du dépôt
■ 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
■ db/
■ 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
svn+ssh
client serveur
Utilisateur svn Circule en clair
Mot de passe stocké en cache Démon svnserve
3690
client serveur
Utilisateur linux (ssh) Chiffré
Éventuellement, clé ssh
Démon sshd
(pas de démon svnserve) 22
Mise en place
Installation
■ Côté serveur
■ Côté 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...
(root@debian) (~) # aptitude install openssh-server (root@debian) (~) # service ssh start
(root@debian) (~) # netstat -ntlp | grep 22
(root@debian) (~) # aptitude install openssh-client
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
Côté client :
$ svn co svn+ssh://svnuser@localhost/projet1 (root@debian) (~) # adduser svnuser
(root@debian) (~) # addgroup svnuser svn
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 :
■ On ajoute ce qui est en gras : (attention à ne pas rajouter ou enlever d'espace)
■ 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 (root@debian) (~) # nano ~toto/.ssh/authorized_keys
command="/usr/bin/svnserve -t -r /var/svn/ --tunnel-user=svnuser",no- port-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
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
svn sur https
client serveur
Utilisateur svn Circule en clair
Mot de passe stocké en cache Démon apache2
80
client serveur
Utilisateur svn Chiffré (ssl)
Mot de passe+certificat stockés en cache
Démon apache2 + module ssl 443
Installation
Installation des paquets :
On vérifie qu'apache2 tourne :
■ Processus et socket :
■ 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
(root@debian) (~) # aptitude install apache2 libapache2-svn
(root@debian) (~) # ps aux | grep apache2 (root@debian) (~) # netstat -ntlp | grep 80
Utilisateurs
On créé /etc/apache2/dav_svn.passwd et un premier utilisateur :
On rajoute quelques utilisateurs (attention : ne pas mettre le -c !)
Ce fichier contient les mots de passe chiffrés des 3 utilisateurs :
Ce fichier est sensible, donc on restreint les droits d'accès :
(root@debian) (~) # htpasswd -cs /etc/apache2/dav_svn.passwd user1
(root@debian) (~) # chown root:www-data /etc/apache2/dav_svn.passwd (root@debian) (~) # chmod 640 /etc/apache2/dav_svn.passwd
(root@debian) (~) # htpasswd -s /etc/apache2/dav_svn.passwd user2 (root@debian) (~) # htpasswd -s /etc/apache2/dav_svn.passwd user3
user1:{SHA}3qousqtDg/tMPXuvmiMDX5LWOjI=
user2:{SHA}gSnY8uDaL4aO8yf25DsYsKZYgy8=
user3:{SHA}lHRMpRJTr6cdmDe8r+VYs1UDIE8=
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
On ajoute www-data au groupe svn pour qu'apache ait les droits en écriture sur le dépôt.
[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
(root@debian) (~) # addgroup www-data svn
Configuration du module
Dans /etc/apache2/mods-available/dav_svn.conf on met :
On relance apache2 :
… et on vérifie que ça fonctionne : http://localhost/svn/projet1
<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>
(root@debian) (~) # a2enmod dav_svn
(root@debian) (~) # service apache2 force-reload
(root@debian) (~) # nano /etc/apache2/mods-available/dav_svn.conf
Tester avec le client svn
Récupérer le projet1 :
■ On fait un checkout avec le client svn
■ En cas d'erreur de segmentation :
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
(formation@debian) (~/svn) $ svn checkout --username=user1 http://localhost/svn/projet1
(formation@debian) (~/svn) $ rm -rf projet1
(formation@debian) (~/svn) $ svn checkout --username=user1 http://localhost/svn/projet1
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
Activer le module SSL
(root@debian) (~) # aptitude install ssl-cert openssl
(root@debian) (~) # make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/localhost.pem
(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)
Si ce n'est pas le cas, c'est sans doute que ce port n'a pas été activé dans /etc/apache2/ports.conf :
(root@debian) (~) # netstat -ntlp | grep 443
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
Activer le site ssl :
… puis tester : https://localhost/svn/projet1
(root@debian) (~) # a2ensite ssl
(root@debian) (~) # service apache2 restart
(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>
Tests
Essayons à présent de faire un checkout via https
■ 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
(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
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...
■ 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...
(formation@debian) (~) $ /sbin/ifconfig
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
On peut éventuellement compresser le dump
■ 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
(root@debian) (~) # svnadmin dump /var/svn/projet1 > ~/projet1.bdb
(root@debian) (~) # gzip -9 ~/projet1.bdb
Restauration
Renommons le repository actuel pour tester notre dump
Si on doit recréer le dépôt (ici ce n'est pas le cas) :
On restaure le dump :
Et on remet des droits corrects :
(root@debian) (~) # gunzip ~/projet1.bdb.gz
(root@debian) (~) # cat ~/projet1.bdb | svnadmin load -q /var/svn/projet1
(root@debian) (~) # svnadmin verify /var/svn/projet1 (root@debian) (~) # mv /var/svn/projet1/db ~/db.backup
(root@debian) (~) # svnadmin create /var/svn/projet1
(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
■ Choisir un mot de passe root pour la base de données et le mémoriser
Installer redmine
Nous pourrions faire tourner redmine sur mongrel (un serveur web orienté ruby) mais nous allons continuer à utiliser apache2 :
(root@debian) (~) # aptitude install mysql-server
(root@debian) (~) # aptitude install redmine-mysql redmine
(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
Référencer redmine (puis relancer apache2) :
(root@debian) (~) # ln -s /usr/share/redmine/public /var/www/redmine
(root@debian) (~) # nano /etc/apache2/sites-enabled/ssl
<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
Relancer redmine... donc apache !
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
(root@debian) (~) # cp /usr/share/redmine/config/email.yml.example /etc/redmine/default/email.yml
(root@debian) (~) # service apache2 restart production:
delivery_method: :smtp smtp_settings:
address: smtp.orange.fr port: 25
domain : monentreprise.fr
Attention à respecter les
espaces
scrupuleusement !
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)
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
(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
Mise en place (2/2)
#!/bin/sh REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
# 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
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)
Envoie ce message
au client si le test est déclenché Il faut l'envoyer sur /dev/stderr ! Échoue si aucune ligne ne
comporte de caractère alphanumérique
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.
Préparons une première release
■ On copie le trunk dans tags
(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
(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
Ajoutons le contenu de 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"
(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.
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)
■ Par exemple il s'agit de la révision 4 (et non 6) qui correspond à la dernière révision.
(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"
(formation@debian) (~/work) $ svn info branches/1.0/
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 !
Le principe est le même pour les scénarios évoqués en introduction
(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"