Sauvegardes
Sauvegarde des fichiers de confs de backupninja
Ce script fonctionne sur sirex et permet de copier les fichiers de confs de backupninja se trouvant dans les sauvegardes des machine dans un seul répertoire.
- sauvegardes-backupninja.sh
#!/bin/bash root=/home/sauvegardes confdir=etc/backup.d/ store=/home/sauvegardes/00-confs-sauvegardes logfile=var/log/backupninja.log ## Pour les machines sauvegardées sur sirex : for rep in $(ls ${root} | grep -v 00); do for sauv in $(ls ${root}/${rep}); do for file in $(ls ${root}/${rep}/${sauv}/${confdir}/); do cp ${root}/${rep}/${sauv}/${confdir}/${file} ${store}/${sauv}-${file} ; done cp ${root}/${rep}/${sauv}/${logfile} ${store}/logs/${sauv}.log done done ## Pour sirex : for file in $(ls /${confdir}); do cp /${confdir}/${file} ${store}/sirex-${file} ; done cp /${logfile} ${store}/logs/sirex.log ; ## Listing des horaires de sauvegarde : cd ${store} && grep -r "when =" *.rdiff > horaires/horaires-rdiff && grep -r "when =" *.sys > horaires/horaires-sys ;
Automatiser ce script : copier cette ligne dans le fichier /etc/crontab
:
####### Listing des sauvegardes 01 19 * * * root /root/bin/confs-sauvegardes
Sauvegardes Davical
Un script permet de sauvegarder les données de Davical.
Pour que cela fonctionne en temps qu'utilisateur lambda, il faut donner les droits sur la base :
su postgres psql CREATE USER pec WITH PASSWORD 'xxxxxxx'; GRANT ALL PRIVILEGES ON DATABASE davical TO pec; \c davical; GRANT ALL ON caldav_data TO pec; \q
Voici le script avec les commentaires :
- sauv-davical.sh
#!/bin/bash # répertoire de sauvegarde des contacts dans le /home : SAUV=$HOME/sauvegardes-davical # fichier d'annuaire d'importation pour le téléphone IP : GIGASET="${SAUV}/repertoire-gigaset.vcf" # répertoire contenant les listes des calendriers et annuaires : LISTE=$HOME/bin/confs # répertoire de backup sur un autre disque : DIST=/media/data/perso/ ## fonctions : # Si le répertoire de sauvegarde n'existe pas, on le crée createdir(){ if [ -d $SAUV ] then echo "le repertoire existe" else mkdir $SAUV fi } # Extraction d'un calendrier ou d'un annuaire pour l'utilisateur julpec dump(){ davicaldump -d $SAUV -C $LISTE/liste-sauv-calendriers -A $LISTE/liste-sauv-annuaires -u julpec } # Conversion de deux annuaires pour en faire des annuaires téléphoniques tel(){ $HOME/bin/vcf2tel -u julpec -a contacts -r $SAUV -p -t /home/pec/bin/confs/conf-tel-tex echo "conversion en annuaire contacts effectuée" $HOME/bin/vcf2tel -u julpec -a travail -r $SAUV echo "conversion en annuaire travail effectuée" } # Création d'un fichier d'annuaire compatible avec le téléphone IP Gigaset C530IP pour import repertoire(){ rm $GIGASET echo "--> Création du répertoire pour le téléphone Gigaset" for input in $(ls ${SAUV}/*.csv); do IFS=, tail -n +2 "$input" | while read nom cell home ; do echo -ne "BEGIN:VCARD\x0d\x0aVERSION:2.1\x0d\x0aN:${nom};\x0d\x0a"; if [ ! -z ${home} ] ; then echo -ne "TEL;HOME:$(echo ${home} | sed 's/ //g')\x0d\x0a"; fi if [ ! -z ${cell} ] ; then echo -ne "TEL;CELL:$(echo ${cell} | sed 's/ //g')\x0d\x0a"; fi echo -ne "END:VCARD\x0d\x0a" ; done >> $GIGASET ; done } # Backup de cette sauvegarde sur un autre disque backup(){ cp -R $SAUV $DIST/$USER/ && cp $SAUV/tel* $DIST/$USER/. } # Passage à l'action : enchaînement des 5 fonctions createdir && dump && tel && repertoire && backup
Pour fonctionner, ce script a besoin d'autres scripts :
Davicaldump
Ce script permet d'extraire des agendas et annuaires de la base de donnée de
Davical, le serveur caldav/cardav. Pour savoir comment l'utiliser, il suffit de
lancer sans arguments avec la commande ./davicaldump
- davicaldump.sh
#!/bin/bash usage(){ echo -e " usage: $0 options Ce script exporte un(des) annuaire(s) et un(des) calendrier(s) Davical d'un·e utilisateur·trice. L'export se fait au format vcf pour les annuaires et ics pour les calendriers OPTIONS : -h affiche ce message -u <user> nom d'utilisateur·trice de davical -d <répertoire> chemin vers le répertoire d'export -A <fichier> chemin vers un fichier listant les annuaires à exporter -C <fichier> chemin vers un fichier listant les calendriers à exporter -a <annuaire> nom d'un annuaire à exporter -c <calendrier> nom d'un calendrier à exporter " } extract(){ echo "exporting $COLLECTION" psql davical -Atc "SELECT array_to_string(array(SELECT caldav_data FROM caldav_data WHERE dav_name LIKE '/$NOM/$COLLECTION%'),'');" > $DIR/$COLLECTION-$NOM } if [ $# -eq 0 ]; then usage fi while getopts "hu:d:C:A:c:a:" option; do case $option in h) usage; exit 1 ;; u) NOM=$OPTARG ;; d) DIR=$OPTARG ;; C) CAL_FILE=$OPTARG ;; A) CARD_FILE=$OPTARG ;; c) CAL=$OPTARG ;; a) CARD=$OPTARG ;; esac done if [ -z $NOM ]; then echo "il manque le nom d'utilisateur·trice" echo "tappez davicaldump -h pour plus d'options" exit 0 fi if [ -z $DIR ]; then echo "il manque le répertoire de sauvegarde" echo "tappez davicaldump -h pour plus d'options" exit 0 fi if [ ! -d $DIR ]; then echo "le répertoire de sauvegarde n'est pas valide, on le crée !" mkdir $DIR fi if [[ $CAL_FILE ]]; then if [ ! -f $CAL_FILE ]; then echo "le fichier d'agendas ($CAL_FILE) n'existe pas" exit 0 fi for COLLECTION in $(cat $CAL_FILE); do extract && mv $DIR/$COLLECTION-$NOM $DIR/$COLLECTION-$NOM.ics done fi if [[ $CARD_FILE ]]; then if [ ! -f $CARD_FILE ]; then echo "le fichier d'annuaires ($CARD_FILE) n'existe pas" exit 0 fi for COLLECTION in $(cat $CARD_FILE); do extract && mv $DIR/$COLLECTION-$NOM $DIR/$COLLECTION-$NOM.vcf done fi if [[ $CAL ]]; then COLLECTION=$CAL extract && mv $DIR/$COLLECTION-$NOM $DIR/$COLLECTION-$NOM.ics fi if [[ $CARD ]]; then COLLECTION=$CARD extract && mv $DIR/$COLLECTION-$NOM $DIR/$COLLECTION-$NOM.vcf fi
Vcf2tel
Ce script permet de compiler tous les contacts d'un annuaire contenant des numéros de téléphone et en faire la conversion en différents formats : csv, html, pdf.
Pour qu'il fonctionne il faut installer LateX ainsi que le support français :
apt-get install texlive-latex-base texlive-latex-recommended texlive texlive-lang-french
Pour connaître son fonctionnement, il suffit de le lancer sans arguments : ./vcf2tel.sh
- vcf2tel.sh
#!/bin/bash function usage(){ echo -e " Ce script permet de convertir un fichier vcf extrait d'une base de donnée Davical et contenant des numéros de téléphone en différents fichiers permettant de créer des annuaires téléphoniques : csv, html, tex, pdf Il faut renseigner différents paramètres : -u <user> Nom d'utilisateur présent dans le fichier vcf extrait de la base de donnée de davical -a <annuaire> Nome de l'annuaire à traiter -r <répertoire> Chemin du répertoire de sauvegarde davical contenant le fichier vcf -p Pour dire si on veut générer un pdf -t <fichier de conf latex> Chemin vers le fichier de configuration LateX pour générer le pdf " } function transvcf(){ sed -i \ -e '1iBEGIN:VCARD\nEND:VCARD' \ -e 's/X-EVOLUTION-UI-SLOT=[12];//' \ $rep$vcf } function vcf2csv(){ vcf2csv-tel.py -i $rep$vcf -o $temp -d comma -q } function transcsv(){ if [ -f $temp ] then cat $temp | sed '1d' | sort -n | sed -e '1iNom,Portable,Fixe' -e '/","",""/d' -e 's/"//g' -e 's/..$//' > $csv && rm $temp fi } function csv2html(){ echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"ggttp://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> <html lang=\"fr-FR\"><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/> <title>Téléphones $USER</title> <meta name=\"robots\" content=\"noindex,nofollow\"/> </head>" > $html if [ -f $csv ]; then (echo "<table>\ <tr align=center><td>Nom</td><td>Portable</td><td>Fixe</td></tr>" ; while read INPUT ; do echo "<tr><td>${INPUT//,/</td><td style=\"text-align:center;\">}</td></tr>" ; done < $csv ; echo "</table>") >> $html ; sed -i '12d' $html ; fi } function csv2pdf(){ cat $CONFTEX | sed -e '/donnees/,$d' > $tex && \ cat $csv | sed -e 's/,/\ \&\ /g' -e 's/$/\ \\\\/' -e '1d' >> $tex && \ cat $CONFTEX | sed -e '1,/donnees/d' >> $tex && \ if [ ! -d $reptex ]; then echo "le repertoire LaTeX n'existe, on le crée !" mkdir $reptex fi cd $reptex pdflatex -interaction=batchmode $tex >/dev/null } DAVICALUSER="" ANNUAIRE="" REPSAUV="" CONFTEX="" PDF="" if [ $# -eq 0 ]; then usage fi while getopts "hu:a:r:t:p" option; do case $option in h) usage; exit 1 ;; u) DAVICALUSER=$OPTARG ;; a) ANNUAIRE=$OPTARG ;; r) REPSAUV=$OPTARG ;; t) CONFTEX=$OPTARG ;; p) PDF="yes" ;; esac done if [ -z $DAVICALUSER ] then echo "il manque le nom d'utilisateur·trice de Davical" echo "tapez vcf2tel -h pour plus d'options" exit 0 fi if [ -z $ANNUAIRE ] then echo "il manque un annuaire sur le quel agir" echo "tapez vcf2tel -h pour plus d'options" exit 0 fi if [ -z $REPSAUV ] then echo "il manque un répertoire de sauvegarde" echo "tapez vcf2tel -h pour plus d'options" exit 0 fi for i in $(ls $REPSAUV/*.vcf | grep $DAVICALUSER | grep $ANNUAIRE ); do vcf=$(basename $i) rep=$REPSAUV/ reptex="$REPSAUV/latex" transvcf; for nom in $vcf; do nom=${vcf%.*} echo "--> conversion de l'annuaire $nom" fichier=$rep$nom for file in $nom; do temp=$fichier.temp.csv csv=$fichier.csv html=$(echo $fichier | sed -e 's/\(.*\)\//\1\/tel-/').html tex=$fichier.tex vcf2csv && transcsv && csv2html if [[ $PDF = "yes" ]] ; then csv2pdf && echo "c'est fini"; fi done done done
Ce script utilise un script python, vcf2csv.py
qui a été modifié pour ne traiter que les champs téléphoniques :
- vcf2csv-tel.py
#!/usr/bin/python import re import sys import codecs import getopt class VCFToCSVConverter: """ todo: add comments to this mess """ def __output( self, text ): if( self.quote == True ): self.output += '"' self.output += text if( self.quote == True ): self.output += '"' self.output += self.delimiter def __resetRow( self ): array = {} for k in self.columns: array[ k ] = '' return array def __setitem__(self, k, v ): self.data[ k ] = v def __getitem__(self, k): return self.data[ k ] def __endLine( self ): for k in self.columns: try: self.__output( self.data[ k ] ) except KeyError: self.output += self.delimiter self.output += "\r\n" self.data = self.__resetRow() def __parseFile(self): try: inFile = codecs.open( self.inputFile , 'r', 'utf-8', 'ignore' ) theLine = inFile.readline() for theLine in inFile: self.__parseLine( theLine ) inFile.close() except IOError: print "error opening file.\n" sys.exit(2) outFile = codecs.open( self.outputFile, 'w', 'utf-8', 'ignore' ) outFile.write( self.output ) outFile.close() def __parseLine( self, theLine ): theLine = theLine.strip() if len( theLine ) < 1: pass elif re.match( '^BEGIN:VCARD', theLine ): pass elif re.match( '^END:VCARD', theLine ): self.__endLine() else: self.__processLine( theLine.split(":") ) def __processLine( self, pieces ): if pieces[0] == 'ADR;TYPE=HOME': self.__process_address( pieces[1] ) elif pieces[0] == 'N': self.__process_name( pieces[1] ) elif pieces[0].split(";")[0] == "TEL": self.__process_phone( pieces[0].split(";")[1], pieces[1] ) elif pieces[0].split(";")[0] == "EMAIL": self.__process_email( pieces[1] ) elif pieces[0] == 'FN': self.__process_display_name( pieces[1] ) def __process_display_name( self, nameLine ): """if nameLine != "%s %s" % ( self.data['Prenom'], self.data['Nom'] ):""" self.data['Nom Complet'] = nameLine def __process_email( self, emailLine ): self.data['Email'] = emailLine def __process_address( self, addressLine ): try: ( foo1, foo2, self.data['Address'], self.data['City'], self.data['State'], self.data['Zip'], self.data['Country'] ) = addressLine.split( ";" ) except ValueError: print "ERROR %s " % addressLine def __process_name( self, nameLine ): temp = [] try: ( temp ) = nameLine.split( ";" ) except ValueError: print "ERROR %s " % nameLine if len( temp ) > 1: self.data['Nom'] = temp[0] self.data['Prenom'] = temp[1] def __process_phone( self, phoneType, phoneLine ): phoneType = phoneType.replace("TYPE=",'') if phoneType in ('CELL','cell'): self.data['portable'] = phoneLine elif phoneType in ('home','HOME','HOME,VOICE'): self.data['fixe'] = phoneLine elif phoneType in ('work','WORK','WORK,VOICE'): self.data['Work Phone'] = phoneLine else: self.data['Other Phone'] = phoneLine def __init__( self, inputFileName, outputFileName, delimiter, quote): self.data = {} self.quote = quote self.delimiter = delimiter self.output = '' self.inputFile = inputFileName self.outputFile = outputFileName self.columns = ( 'Nom Complet', 'portable', 'fixe', ) self.data = self.__resetRow() for k in self.columns: self.__output( k ) self.__parseFile() def usage(): print "\n Ce script permet d'exporter les numeros de telephone d'un fichier de contacts (VCF) dans un fichier csv \n \noptions \n-h|--help this menu\n-i input file (VCS) *required\n-o output file (TAB) *required\n-d [comma|tab|semicolon] delimiter (tab is default)\n-q double values" def main(): try: opts, args = getopt.getopt(sys.argv[1:], "ho:i:d:q", ["help"]) except getopt.GetoptError, err: print str(err) usage() sys.exit(2) input_file = None output_file = None quote = False delimiter = "\t" delimiter_string = "tab" for option, value in opts: if option == "-i": input_file = value elif option == "-o": output_file = value elif option == "-q": quote = True elif option == "-d": if value == "comma": delimiter = "," delimiter_string = "comma" elif value == "semicolon": delimiter = ";" delimiter_string = "semicolon" else: delimiter = "\t" delimiter_string = "tab" elif option in ("-h", "--help"): usage() sys.exit(2) else: print "unhandled option %s" % option sys.exit(2) if input_file == None or output_file == None: print "missing required parameters" usage() sys.exit(2) #print "converting %s > %s (%s delimited)" % ( input_file, output_file, delimiter_string ) VCFToCSVConverter( input_file, output_file, delimiter, quote ) sys.exit(0) if __name__ == "__main__": main()