Mon CV

Synchroniser un répertoire local vers un volume FTP avec la librairie Perl “turbo-ftp-sync”

22 août 2013

Comme pas mal de monde, j’utilise FTP pour effectuer chaque jour une réplique d’un dossier sur un serveur dédié sur une machine accessible en FTP.

Il y a pas mal de solutions disponibles, et j’utilisais un script Bash maison exploitant la commande rsync.

Mais pour des raisons que je n’ai pas encore identifiées, le fait de monter un volume distant en FTP et synchroniser les données avec rsync n’était pas très fiable. J’ai cherché les causes, puis ne les trouvant pas, j’ai cherché à contourner le problème en utilisant une autre approche.

Cette fois je me suis tourné du côté des librairies Perl disponibles et j’ai trouvé chaussure à mon pied avec le script turbo-ftp-sync, qui promet une synchro rapide (“very fast with minimum network traffic”). Pour cela ce script n’interroge pas l’arborescence du volume FTP distant pour connaitre les dates de modification et taille de chaque fichier à chaque fois, mais il les stocke dans un base de donnée locale au format SQLite. Revers de la médaille, il ne sait travailler que dans un sens (ce qui n’est donc pas une véritable synchronisation) : depuis le stockage local vers le FTP. Pour moi cela correspondait à mon besoin.

Le script est disponible ici avec sa documentation.

 

1. Installer turbo-ftp-sync

Pour ma part j’ai choisi d’utiliser CPAN pour installer les modules Perl nécessaires.

Dans votre terminal, situez-vous dans le répertoire où vous souhaitez installer votre script (ici /usr/local/bin) avec

cd /usr/local/bin

puis entrez la commande :

perl -MCPAN -e shell

Cette commande vous permet d’ouvrir la console CPAN. Si c’est la première fois que vous lancez cette commande, répondez par défaut aux questions posées pour la configuration de l’interface.

Lancez l’installation des modules nécessaires depuis la console CPAN (en acceptant bien sur l’installation des dépendances nécessaires ou les upgrades de modules nécessaires) :

install Bundle::CPAN
reload cpan
install DBI
install Cwd
install base
install Exception::Class
install Exception::Class::Base
install Exception::Class::TryCatch
install ExtUtils::MakeMaker
install File::Find
install Net::FTP
install Net::Netrc
install strict
install Test::More
install warnings
install Net::FTPTurboSync

Pour quitter la console CPAN, il suffit de rentrer la commande :

exit

2. Tester le script

Dés à présent vous devez avoir dans votre dossier le script turbo-ftp-sync d’installé. Pour l’utiliser il suffit de le lançant à l’aide des paramètres nécessaires selon la syntaxe : turbo-ftp-sync [ options ] [ <localdir> <remoteURL> ]. Je vous renvoie à la documentation disponible pour toutes les options possibles.

Avant de passer à la suite, je vous conseille de faire vos tests depuis le terminal.

Selon vos besoins, vous pouvez vous arrêter à cette étape et lancer votre tâche depuis la crontab ainsi.

 

3. Mettre en place un fichier de configuration

De mon côté, ce qui m’intéressait c’était de pouvoir utiliser cette librairie en combinaison avec un fichier de configuration. Là c’est assez simple, il suffit de créer un fichier de configuration (ici stocké dans /etc/turbo-ftp-sync/) qui contienne vos paramètres. J’utilise nano pour créer et éditer ce fichier :

nano /etc/turbo-ftp-sync/synchro1.cfg

Entrez les paramètre nécessaires (un par ligne, que vous avez testé à l’étape 2 à l’aide des exemple et de la documentation). Ici, pour moi cela donne :

localdir=/home/user/www/monrep
ftpserver=mon.serveur.fr
ftpuser=turbo-ftp-sync
ftppasswd=monjolipassword
db=/var/turbo-ftp-sync/synchro1.db
maxerrors=0

Vous pouvez, bien entendu, utiliser toutes les options offertes par cette librairie. Une fois ceci entré dans l’éditeur nano, enregistrez la modification en faisant : [ctrl + x], puis y (yes), puis validez en tapant sur [entrée].

Vous pouvez ensuite tester que votre fichier de configuration soit fonctionnel en lançant la commande :

/usr/local/bin/turbo-ftp-sync cfg=/etc/turbo-ftp-sync/synchro1.cfg

 

4. Lancer le tout depuis un autre script

Pour pousser le vice, je souhaitais que le tout soit lancé par un script Bash appelé par une tâche cron. Vous me direz qu’on peu faire plus simple, mais c’est mon côté un peu psychorigide qui prend le dessus : je ne touche pas à la librairie, je stocke les paramètres dans le répertoire dédié aux configurations. Je voulais aussi faire un peu de “cosmétique” en journalisant et en m’envoyant un mail avec le résultat de cette synchronisation. C’est aussi plus facile ensuite d’utiliser mon script Shell en boucle sur x configurations.

A l’aide de votre éditeur favori, créez votre script (ici /usr/local/bin/turbo-ftp-sync.sh) :

#!/bin/bash

# nos variables
CURRENT_DIR=$(dirname $0)
LOG=$(mktemp /tmp/turbo_sync_ftp_log.XXXXX) # emplacement du log temporaire de la tâche
LOG_CUMUL="/var/log/turbo_sync_ftp_log.log" # pensez à personnaliser l'emplacement et le nom du journal
SCRIPT_PERL_EXPORT="$CURRENT_DIR/turbo-ftp-sync" # pensez à personnaliser le chemin de la librairie si elle n'est pas dans le même répertoire
MAIL_ADMIN="moi@moimoimoi.fr"
DATE_DU_JOUR=$(date)

if [ `whoami` != 'root' ]
	then
	echo "Ce script doit être utilisé par le compte root. Utilisez SUDO."
	exit 1
fi

# testons si un fichier de configuration est spécifié en paramètre
if [ $1 ]
	then
	CONFIGFILE=$1
else
	echo "Vous devez spécifier en paramètre le chemin d'un fichier de configuration valide."
	exit 1
fi

# testons si une connection internet est ouverte
dig +short myip.opendns.com @resolver1.opendns.com > /dev/null 2>&1
ERROR=$(echo $?)
if [ $ERROR -ne 0 ]
	then
	echo "ERROR myip.opendns.com : " $ERROR
	echo "Non connecté à internet. Nous quittons le script."
	exit 1
else
	# journalisation
	rm -f $LOG
	echo " " >> $LOG
	echo "****************************** $DATE_DU_JOUR ******************************" >> $LOG
	# préparons le dossier qui accueille le fichier database
	# recherche de la ligne contenant l'adresse
	grep db= $CONFIGFILE > /dev/null 2>&1
	RETOUR_GREP=$(echo $?)
	if [ ! -f $CONFIGFILE ] 
		then
		echo "Fichier de configuration $CONFIGFILE inexistant. Merci d'entrer en paramètre le chemin d'un fichier de configuration valide." >> $LOG
		echo "Reportez-vous à la documentation http://search.cpan.org/~yaitskov/Net-FTPTurboSync-0.07/scripts/turbo-ftp-sync." >> $LOG
		cat $LOG | mail -s "[FAILED] Rapport ERREUR script synchronisation (${0})" $MAIL_ADMIN 
		cat $LOG >> $LOG_CUMUL
		rm -f $LOG
		exit 1
	fi	
	if [ $RETOUR_GREP -ne 0 ]
		then
		echo "Erreur dans votre fichier de configuration $CONFIGFILE : nous ne trouvons pas la ligne commençant par db=" >> $LOG
		echo "Reportez-vous à la documentation http://search.cpan.org/~yaitskov/Net-FTPTurboSync-0.07/scripts/turbo-ftp-sync." >> $LOG
		cat $LOG | mail -s "[FAILED] Rapport ERREUR script synchronisation (${0})" $MAIL_ADMIN 
		cat $LOG >> $LOG_CUMUL
		rm -f $LOG
		exit 1
	else
		DB=$(grep db= $CONFIGFILE | sed 's/.\{3\}//')
		# Création par sécurité du dossier correspondant
		DIR_DB=$(dirname $DB)
		[ ! -d $DIR_DB ] && mkdir -p $DIR_DB
		# lançons le sous-script Perl (http://search.cpan.org/~yaitskov/Net-FTPTurboSync-0.07/)
		echo "Exécution du sous-script Perl $SCRIPT_PERL_EXPORT" >> $LOG
		echo " " >> $LOG
		/usr/bin/perl "$SCRIPT_PERL_EXPORT" cfg="$CONFIGFILE" >> $LOG 2>&1
		RETURN_CODE_PERL=$?
		echo "Code retour PERL : $RETURN_CODE_PERL" >> $LOG
		if [ $RETURN_CODE_PERL -eq 0 ]
			then 
			echo "Pas de problème détecté lors de la synchronisation." >> $LOG
			cat $LOG | sed '/^$/d' | mail -s "[OK] Rapport execution script import synchronisation (${0})" $MAIL_ADMIN 
			cat $LOG | sed '/^$/d' >> $LOG_CUMUL
			rm -f $LOG
			exit 0

			else
			echo "Problème détecté lors de la synchronisation." >> $LOG
			cat $LOG | sed '/^$/d' |  mail -s "[FAILED] Rapport ERREUR script synchronisation (${0})" $MAIL_ADMIN 
			cat $LOG | sed '/^$/d' >> $LOG_CUMUL
			rm -f $LOG
			exit 1
		fi
	fi
fi

N’oubliez pas de rendre exécutable votre script avec un

chmod +x /usr/local/bin/turbo-ftp-sync.sh

Pour tester votre script en faisant appel à votre fichier de configuration préalablement créé :

/usr/local/bin/turbo-ftp-sync.sh /etc/turbo-ftp-sync/synchro1.cfg

 

Il ne vous faut ensuite que programmer cette tâche dans votre crontab.

 

 

 

Posted in Unix et LinuxTags: