Où l’on va voir plusieurs façon d’avoir une sauvegarde des dépôts SVN
Le contexte
Certains développeurs de ma connaissance utilisent encore SVN1. Il est bien évident que les dépôts sont sauvagardés toutes les nuits.
Les dépôts d’une société de 5 ans et de 20 développeurs commencent à être conséquents. La sauvegarde complète à coup de # svnadmin dump n’est plus envisageable dans le courant de la nuit2.
La sauvegarde incrémentale
La première solution mise en place est la sauvegarde incrémentale.
Le principe est simple :
- on commence par une sauvegarde complète ;
- avec la commande svnlook youngest on obtient la dernière révision, on met cette information dans un fichier ;
- la sauvegarde partielle commence à la révision stockée précédemment ;
- la sauvegarde complète suivante génère un nouveau fichier youngest.
Nous avons donc ces sauvegardes sur une semaine complète :
- Samedi → complète ;
- Dimanche → les commits du dimanche ;
- Lundi → les commits du dimanche plus ceux de lundi ;
- Mardi → les commits du dimanche plus ceux de lundi et mardi ;
- Mercredi → les commits du dimanche plus ceux de lundi, mardi et mercredi ;
- Jeudi → les commits du dimanche plus ceux de lundi, mardi, mercredi et jeudi ;
- Vendredi → les commits du dimanche plus ceux de lundi, mardi, mercredi, jeudi et vendredi.
La restauration se fait donc avec la dernière sauvegarde complète plus la dernière sauvegarde partielle.
Plongeons dans le script
Le script est assez simple. Je vais vous donner les deux fonctions de sauvegarde partielle et complète et la boucle de gestion, je vous laisserais broder autour pour l’envoi d’un message ou la copie de la sauvegarde sur une autre machine.
Définition de variables
Nous allons définir quelques variables, comme le répertoire d’accueil de nos sauvegardes, la date courante, le chemin vers le fichier de trace :
|
|
Les noms des variables sont assez parlant pour ne pas avoir besoin d’explication.
Le cœur du script, la boucle
Le cœur du script est une boucle sur les listes des dépôts, définie dans la variable REPOLIST.
|
|
- Nous faisons une boucle sur le contenu de REPOLIST, le nom du dépôt en cours de traitement est stocké dans la variable REPO. La variable CURRENTREPO est le chemin absolu vers le dépôt ;
- nous comptons le nombre de sauvegardes complètes qui se trouvent dans le répertoire d’accueil des sauvegardes ;
-
- si nous avons plu de zéro sauvegarde, il est possible de faire une sauvegarde partielle ;
-
- nous vérifions si nous ne sommes pas un dimanche
-
-
- un jour de semaine, nous appelons la fonction de sauvegarde partielle ;
-
-
- nous sommes dimanche, nous appelons la fonction de sauvegarde complète
- nous n’avons pas de sauvegarde complète, nous appelons la fonction de sauvegarde complète.
La fonction de sauvegarde complète
|
|
- nous faisons une sauvegarde complète du dépôt courant dans le répertoire d’accueil des sauvegardes em mettant dans le nom du fichier de sauvegarde la date courante ;
- avec la commande svnlook youngest nous obtenons la dernière révision du dépôt que nous stockons dans un fichier au nom de dépot.latest dans le répertoire d’accueil des sauvegardes ;
- nous compressons (au format bzip2) le fichier de sauvegarde du dépôt ;
- nous supprimons le fichier de sauvegarde non compressé.
La fonction de sauvegarde partielle
|
|
- nous cherchons un fichier .latest.txt au nom du dépôt dans le répertoire d’accueil des sauvegardes ;
- si le fichier existe, nous peuplons la variable latest avec son contenu ;
-
- nous faisons une sauvegarde incrémentale du dépôt en partant de la révision stockée dans latest jusqu’à la révision courante (nommée HEAD dans SVN) ;
-
- nous compressons le fichier de sauvegarde ;
-
- nous supprimons le fichier de sauvegarde non compressé ;
- si le fichier n’existe pas
-
- il est impossible de faire la sauvegarde partielle
Il reste à enrober tout cela de tests (vérifier l’existence du répertoire d’accueil des sauvegardes), envoyer le fichier de trace par mail, mais l’essentiel est là.
C’est bien, mais pas satisfaisant
Cela fonctionne et même plutôt bien. La restauration se fait facilement en créant un nouveau dépôt, en important la dernière sauvegarde complète puis en important la dernière sauvegarde partielle
|
|
Le problème n’est pas dans la méthode ou la complexité, mais dans le temps prit pour la restauration. Un petit dépôt de 5000 commits, peut être remis sur pied en 30 minutes. Mais un gros dépôt, avec plus de 30 000 commits, certains fichiers binaires (ou c’est mal, mais cela arrive) peut prendre beaucoup plus de temps (1 ou 2 jours parfois). Pendant ce temps-là, les développeurs cessent de travailler.
Il nous faut une solution plus réactive. Cette solution existe, c’est la synchronisation de dépôt.
La synchronisation de dépôt
Le principe est simple. Sur une autre machine, nous allons créer des dépôts qui seront synchronisés avec le serveur principal. Toutes les heures, nous faisons tourner un script qui met à jour le miroir. En cas de pépin sur la machine principale, il faut basculer sur l’autre machine. Un changement dans le DNS suffit.
Les éléments nécessaires
Il nous faut un serveur SVN principal (normalement, nous l’avons déjà), une autre machine avec suffisamment de place pour avoir une copie des dépôts de la première machine. Ces deux machines doivent pouvoir dialoguer entre elles. Un utilisateur dédié à la tache de synchronisation.
Nous n’aurons pas beaucoup de manipulation à faire sur la machine qui héberge le serveur principal. La création de l’utilisateur de synchro3 et l’autorisation de réécrire dans le dépôt de destination.
Autorisation d’écriture
Nous devons, sur le serveur principal, faire en sorte que notre utilisateur de synchro puisse écrire sur le serveur de secours. Je sais, c’est tordu. Nous allons faire ça pour chaque dépôt (que nous voulons synchroniser). Dans le répertoire depot/hooks nous allons ajouter un script pre-revprop-change dans lequel nous allons mettre ceci :
|
|
Une fois sauvegardé, faites en sorte que ce script soit exécutable :
|
|
À moins d’une erreur, nous n’aurons plus besoin d’intervenir sur le serveur principal, le reste des manipulations se faisant sur la machine de secours.
Création des dépôts de secours
Nous allons maintenant travailler sur la machine de secours. Sur celle-ci nous allons commencer par créer les dépôts que nous allons synchroniser. Faisons cela d’un jet pour nos trois dépôts :
|
|
Nos dépôts sont créés.
Initialisation des dépôts
C’est cette étape qui va permettre d’indiquer au dépôt de sauvegarde ou se trouve sa source.
|
|
svnsync va vous demander le nom et le mot de passe de l’utilisateur. C’est celui que nous avons créé plus haut qu’il faut indiquer4.
Il faut bien sûr réaliser cette étape pour nos trois dépôts.
Synchronisation des dépôts
Il est temps de synchroniser réellement nos dépôts :
|
|
Si tout se passe bien, la synchronisation se fait presque magiquement. C’est dément non ? Si vous n’avez pas sauvegardé4 le mot de passe, celui-ci vous sera demandé.
Attention : Si votre dépot est gros, la première synchronisation sera longue. Aussi longue en fait qu’un checkout de dépot.
Un script pour automatiser tout ça
Nous allons réaliser un petit script pour automatiser la synchronisation. C’est un script tout aussi simle que le script de sauvegarde, plus simple même.
Une boucle sur la liste des dépôts et la synchronisation :
|
|
Voilà, le script est fini. On en change les droits pour le rendre exécutable et non visible par le commun des mortel :
|
|
Des finitions
J’avais envie de rendre mon script plus sympa. Avec des couleurs et des [OK] ou [FAILED], comme les scripts de démarrage de Linux.
Commençons par définir les couleurs (cette partie se place avant ou après la définition des variables) :
|
|
Et modifions la boucle pour tester le code retour de la commande de synchronisation :
|
|
Et voilà le résultat (sauf que l’on de voit pas les couleurs) :
|
|
Reste à mettre tout ça dans un fichier de trace et à l’envoyer par courrier électronique et le lancer régulièrement (toutes les heures par exemple)
-
non, dans l’entreprise on ne peut pas changer de système de gestion de version d’un coup de tête. Il faut être sûr de conserver l’historique. N’oublions pas le coût de la formation et les réticences d’un passage à git (par exemple). ↩︎
-
si la nuit existe toujours. En effet, une société qui dispose de développeurs à Paris, New York et Tokyo, ne connaît pas de période de non-activité hors du week-end. ↩︎
-
Si vous utilisez LDAP, faites un utilisateur dans votre base LDAP. ↩︎
-
En fonction de votre configuration, il est possible que l’on vous demande si vous voulez stocker le mot de passe de l’utilisateur de synchro en clair. Je n’ai pas encore de solution pour le stocker de façon sure. Je ne l’ai pas sauvegardé, je préfère le mettre dans le script en ayant des droits stricts dessus. ↩︎ ↩︎