Script de backup plesk (9.x et supérieur)

== Mise à jour ==

Cet article a été mis à jour le 12 octobre 2012, avec l’ajout d’une fonction d’exclusion permettant d’exclure certains domaines. J’ai également repris les utilisateurs SQL dans backup.conf plutôt que dans le script directement.

J’utilise ce script au quotidien avec Plesk 9 et Plesk 10. Je ne l’ai pas testé avec Plesk 11. Si quelqu’un le test, merci de me donner un feedback.

Introduction

Je me suis affranchi de la configuration des sauvegardes plesk depuis le GUI. J’ai préféré faire mon propre script qui backup la configuration du serveur, la configuration de chaque revendeur, et enfin, chaque domaine individuellement. J’ai créé ce script, car en faisant des sauvegardes depuis le plesk panel vers du FTP, j’avais toujours des problèmes. Le FTP tombait, (très mauvais FTP chez OVH à cette époque), et j’avais d’autres souci comme des faux problèmes de droits sur le FTP (alors que ce n’était pas le cas). Bref, j’ai beaucoup galéré… On est jamais mieux servi que par soi-même au final.

Il y a sûrement milles façons plus simples, et plus compliquées de faire. Perso, c’est la méthode dont je me suis servi, et je la partage avec vous. Après, à vous de faire avec ou pas…

Ce script a les fonctionnalités suivantes:

  • Sauvegarde de la configuration du serveur avec notification à l’administrateur du serveur
  • Sauvegarde de la configuration des revendeurs avec notification aux revendeurs par email
  • Sauvegarde de chaque domaine individuellement avec notification au revendeur par email
  • Envoi des fichiers de sauvegarde sur un serveur FTP
  • Rétention locale avec suppression des anciens fichiers
  • Rétention FTP avec suppression des anciens fichiers
  • Suppression des fichiers temporaires afin de libérer la place pour la sauvegarde du jour suivant
  • Rapports d’erreur par email
  • Rapport résumé de l’opération par email

Ce script utilise le programme ncftp que vous pouvez installer sur votre distribution.

Ma distribution est Debian Lenny. Il se peut que vous deviez apporter des petites adaptations suivant votre distribution. Je vous laisse maitre de ça.

Le script compose de trois fichiers:

  1. /root/backup.conf qui contient les variables modifiables
  2. /root/start_backup qui lance l’exécution, et évite qu’il soit lancé une deuxième fois manuellement par exemple (ça m’est arrivé)
  3. /root/backup qui est le script en lui-même. Ces trois scripts sont disponibles en entier à la fin de cet article

Variables

Les variables utilisées dans ce scripts sont:

  • localdaystodel: Rétention locale en nombre de jours
  • remotedaystodel: Rétention distante (sur le serveur FTP) en nombre de jours
  • blogs: Chemin du dossier de sauvegarde des logs de backup et ftp
  • mailtodaylog: Nom du fichier de log du jour (ou du moment puisqu’il inclus l’heure)
  • fuser: Nom d’utilisateur FTP pour la copie distante
  • fpass: Mot de passe de l’utilisateur FTP pour la copie distante
  • fpath: Chemin de sauvegarde sur le serveur FTP
  • fserv: Nom ou adresse IP du serveur FTP
  • btmp: Chemin de stockage sauvegardes locales
  • ccmail: Option et adresse email pour l’envoi de copies des rapports de sauvegade.
  • pbpath: Chemin de l’exécutable pleskbackup
  • PMMpath: Chemin des fichiers logs de pleskbackup
  • mysqluser: Nom d’utilisateur admin MySQL pour plesk
  • mysqlpwd: Mot de passe de l’utilisateur précité
  • excl: Liste de domaines à exclure de la sauvegarde, séparés par un espace

Toutes ces variables sont à inscrire dans un fichier appeler backup.conf dont vous trouverez un exemple au bas de cet article. La variable ccmail est optionnelle. Attention: le « -c » est indispensable. Il fait partie de la commande d’envoi. Si vous indiquez une adresse email, il FAUT impérativement mettre « -c » devant.

Le script de lancement

Celui-ci n’a que pour but de s’assurer que le script de backup n’a pas déjà été exécuté, et ainsi, d’éviter que deux opérations de sauvegardes soient en cours simultanément. Il vérifie donc dans « ps ax » que le script backup n’est pas en cours d’exécution.

Le script de sauvegarde

Voici le gros morceau, expliqué point par point. Vous en trouvez une version complète téléchargeable au bas de l’article.

On commence bien sûr par la déclaration de l’environnement d’exécution

#!/bin/sh

On inclut ensuite le fichier backup.conf:

. /root/backup.conf

Le code suivant va supprimer les fichiers plus anciens que la rétention locale désirée.

rm $btmp/*`date --date="$localdaystodel days ago" +%Y%m%d`*

Pleskbackup a la désagréable tendance a garder des logs ad eternam. POur éviter des surprises d’utilisation du disque, on supprime tous les logs de plus de 30 jours

find /opt/psa/PMM/sessions -mtime +30 -type d | grep -v archives | xargs rm -Rf

On crée ensuite le fichier de log, définit par la variable maintodaylog décrite plus haut

echo -e "****************" Backup Job Started $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "***************"\\n\\n > $maintodaylog

Sauvegarde de la configuration du serveur

On récupère l’adresse email de l’administrateur de plesk dans la base de donnée plesk.

destmail=`mysql -e"use psa;select email from clients where login='admin'" -u$mysqluser -p"$mysqlpwd" | tail -n +2`

La variable current va revenir régulièrement dans le script. Elle permet de savoir à quelle tâche il en est. Ici, on définit le nom de la sauvegarde de la configuration du serveur. Je m’en sers pour faire un log pour chaque opération.

current="ServerConfig_ServerConfig_$(date +%Y%m%d_%H%M%S)"

La variable blog est ensuite utilisée pour définir le chemin du fichier de log de l’opération en cours, par opposition à « maintodaylog » qui est le log global et résumé de l’opération.

blog="$blogs/$current.log"

Toujours basé sur la variable « current », je définis le nom du fichier tar pour la sauvegarde locale

nextfile="$current.tar"

J’utilise la commande echo pour envoyer des commentaires dans le fichier de log au fur et à mesure du script. Ici, je déclare le début de l’opération

echo "===== Server configuration backup started at $(date +%T) =====" > $blog

J’exécute ma première opération. Il s’agit de la sauvegarde de la configuration du serveur:

$pbpath/pleskbackup --server --configuration --prefix=ServerConfig_ --output-file=$btmp/$nextfile

Vous remarquerez que la sauvegarde n’est pas lancée en arrière plan. C’est donc uniquement à la fin de l’opération de sauvegarde que ce script reprendra sa route.

Je cherche ensuite quel est le chemin du fichier log créé par pleskbackup afin de suivre la progression de l’opération. Et j’indique ce chemin dans mon fichier de log, de façon à pouvoir facilmeent mettre ma main sur le log original en cas de besoin. migres contient un résumé de l’opération, et miglog contient le log complet généré par pleskbackup

     migres=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.result
      miglog=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.log
      echo "----------------------------" >> $blog
      echo ">>> log files in $migres" >> $blog
      echo "----------------------------" >> $blog

Dans la partie suivante, je surveille le fichier de log en quête de l’indication de la fin de l’opération, puis, j’envoie un commentaire dans le log, et j’envoie le log à l’adresse de l’administrateur plesk, ainsi que l’adresse de copie indiquée dans backup.conf (ccmail). En cas d’erreur, j’envoie le log complet, alors qu’en cas de succès, je n’envoie que le log résumé.

resultat=`grep -c "success" $migres`
 
if [ $resultat != 0 ]
then
  status="ended successfully"
  echo "$(date +%H%M%S): The backup $status" >> $blog
	cat $migres >> $blog
  cat $blog | mail -s "Server configuration backup $status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
else
	status="failed"
  echo "$(date +%H%M%S): The backup $status" >> $blog
	cat $miglog >> $blog
	cat $migres >> $blog
	cat $blog | mail -s "Server configuration backup $status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
fi
unset resultat

Enfin, je clotûre le log de l’opération passée, et je l’insère dans le log de la journée:

echo -e "=====" ServerConfig ended at $(date +%T) "====="\\n\\n >> $blog
# append log file to main log file
cat $blog >> $maintodaylog

Sauvegarde de la configuration des revendeurs

Je récupère dans la base de donnée la liste des revendeurs:

res_array=( `mysql -e"use psa;select login from clients where type='reseller' order by login desc" -u$mysqluser -p"$mysqlpwd" | tail -n +2` )

Pour chaque revendeur, je vais faire les opérations décrites ci-dessous

for res in ${res_array[@]};
do

Je définis les variables propres à l’opération comme plus haut:

	current="$res"_Config_$(date +%Y%m%d_%H%M%S)
	blog="$blogs/$current.log"
	nextfile="$btmp/$current.tar"

Je définis un nom de fichier pour le log de l’opération, et j’y insère une entête

	todaylog=$blogs/"$res"_backup_$(date +%Y%m%d_%H%M%S).log
	echo -e "****************" "$res" Backup Job Started $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "***************"\\n > $todaylog

Je récupère l’adresse email du revendeur dans la base de donnée

	destmail=`mysql -e"use psa;select email from clients where login='$res'" -u$mysqluser -p"$mysqlpwd" | tail -n +2`

J’indique l’heure de démarrage de l’opération dans le log et j’exécute pleskbackup

	echo -e "===== $res Config backup started at $(date +%T) ====="\\n\\n > $blog
	$pbpath/pleskbackup --resellers-name $res --configuration -v --prefix=Config"$res"_ --output-file=$nextfile

Comme plus haut, je récupère les chemins des logs de pleskbackup

	migres=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.result
	miglog=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.log
	echo "----------------------------" >> $blog
	echo ">>> log files in $migres" >> $blog
	echo "----------------------------" >> $blog

Ensuite, je cherche le résultat (échec ou réussite) et j’envoie le log dans le log principal, et par email à l’adresse du revendeur, et en copie si demandé dans backup.conf

	resultat=`grep -c "success" $migres`
	if [ $resultat != 0 ]
	then
		status="$res config backup ended successfully"
		echo "$status" >> $blog
		echo "Migration result: " >> $blog
		cat $migres >> $blog
		cat $blog | mail -s "$status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
	else
		status="$res config backup failed"
		echo "$status" >> $blog
		echo "Migration log: " >> $blog
		cat $miglog >> $blog
		echo "Migration result: " >> $blog
		cat $migres >> $blog
		cat $blog | mail -s "$status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
	fi
	unset resultat

Je clos ensuite le log de cette opération, et nous passons à l’opération des domaines, qui est imbriquée dans celle des revendeurs:

	echo -e "===== $res Config ended at $(date +%T) ====="\\n\\n >> $blog
	echo -ne "$status: $res reseller configuration backup on $(date +%d.%m.%Y) at $(date +%T)"\\n >> $todaylog

Je récupère la liste des domaines que possède le revendeur en cours. Cette liste sera triée par taille de domaine. Donc les domaines les plus gros seront sauvegardés en premier.

	unset dom_array
	dom_array=(`mysql -e"use psa; select dom from (SELECT clients.login AS parent, clients_1.login as owner, clients.type AS type, domains.name as dom, domains.real_size as domsize FROM domains LEFT JOIN (clients AS clients_1 LEFT JOIN clients ON clients_1.parent_id = clients.id) ON domains.cl_id = clients_1.id) as list where if(parent='admin',owner,parent)='$res' order by domsize desc;" -u$mysqluser -p"$mysqlpwd" | tail -n +2`)

Je définis un compteur que j’utilise pour repérer facilement dans les logs le nombre d’erreur et de réussite à la fin de l’opération.

	count=0
	count1=0

Je crée une boucle qui va faire une sauvegarde de chaque domaine. La logique est toujours la même. Je ne vous refais pas la découpe.

	for dom in ${dom_array[@]};
	do

C’est ici que l’exclusion rentre en compte. Si un domaine est listé dans la variable $excl, on passe directement au suivant.

            if [[ ${excl[*]} =~ $dom ]]
                then
                        continue
        fi
		current="$dom"_$(date +%Y%m%d_%H%M%S)
		blog="$blogs/$current.log"
		count=$(($count+1))
		echo -e "=====" $dom started at $(date +%T) "====="\\n > $blog
		nextfile=$btmp/"$dom"_$(date +%Y%m%d_%H%M%S).tar
		$pbpath/pleskbackup --domains-name $dom --output-file=$nextfile
 
		migres=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.result
		miglog=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.log
		echo "----------------------------" >> $blog
		echo ">>> log files in $migres" >> $blog
		echo "----------------------------" >> $blog
 
		resultat=`grep -c "success" $migres`
		if [ $resultat != 0 ]
		then
			status="Successful"
			count1=$(($count1+1))
			cat $migres >> $blog
		else
			status="Failed"
			cat $miglog >> $blog
			cat $migres >> $blog
			cat $blog | mail -s "$status: $dom backup on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
		fi
		unset resultat
		echo -e "=====" $dom ended at $(date +%T) "====="\\n\\n >> $blog
		echo -ne "$status: $dom backup on $(date +%d.%m.%Y) at $(date +%T)"\\n >> $todaylog
	done

Une fois tous les domaines sauvegardés, je mets à jour les logs , et j’envoie le log final au revendeur.

	echo -e \\n"$count1/$count successful" >> $todaylog
	echo -e \\n"***********" "$res" Backup Job Ended $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "**********"\\n\\n >> $todaylog
	cat $todaylog | mail -s "$res reseller full backup report $(date +%d.%m.%Y)" $destmail $ccmail
	cat $todaylog >> $maintodaylog

Voilà qui clôture, je vous le rappelle, l’opération globale de sauvegarde du revendeur.

done

Envoi des données sur le serveur FTP

L’envoi des fichiers est configuré pour envoyer tous les fichiers créés à la date du jour. Vous pouvez adapter celà à votre convenance. Pour moi, ça fait mon affaire.

Nous allons ensuite nous servir de ncftp pour envoyer les fichiers sur le serveur ftp. On ajoute une entête dans le fichier log, et on remet à zéro les compteurs, puis on défini

echo -e \\n"*********** FTP Transfer started $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) ***********"\\n >> $maintodaylog
countf=0
countf1=0

On se rend ensuite dans le dossier des sauvegardes locales, et on détermine la liste des fichiers à envoyer:

cd $btmp
ftp_array=( `ls *$(date +%Y%m%d)*` )

Enfin, pour chaque fichier sélectionné, on procède aux opérations suivantes:

for ftpfile in ${ftp_array[@]};
do

On incrémente le conteur et on lance le transfert

	countf=$(($countf+1))    
	ncftpput -u $fuser -p $fpass $fserv $fpath $ftpfile

On récupère ensuite la variable de résultat de ncftpput afin de savoir si le transfert s’est bien passé. Personnellement, j’ai utilisé l’anglais. Vous êtes tous grands, vous pouvez les traduire si ça vous chante

	countf=$(($countf+1))    
	ncftpput -u $fuser -p $fpass $fserv $fpath $ftpfile
    	case $? in
	0 )
		countf1=$(($countf1+1))
		status="Success: " ;;  
	1 )
		status="Could not connect to remote host: " ;;
	2 )
		status="Could not connect to remote host - timed out: " ;;
	3 )
		status="Transfer failed: " ;;
	4 )
		status="Transfer failed - timed out: " ;;
	5 )
		status="Directory change failed: " ;;
	6 )
		status="Directory change failed - timed out: " ;;
	7 )
		status="Malformed URL: " ;;
	8 )
		status="Usage error: " ;;
	9 )
		status="Error in login configuration file: " ;;
	10 )
		status="Library initialization failed: " ;;
	11 )
		status="Session initialization failed: " ;;
	esac

Je récupère ensuite le nom du domaine depuis le nom de fichier, et j’insère un commentaire dans le log

	ftpdom=`echo $ftpfile | cut -d_ -f1`
	echo -e "$status $ftpdom" >> $maintodaylog

Voilà qui clot l’envoi des fichiers sur le serveur FTP. Reste plus à cloturer le log. Ensuite j’envoie le log en question à l’admin plesk pour information.

done
 
echo -e \\n">>>>> $countf1/$countf files succesfully transfered. <<<<<" >> $maintodaylog  
echo -e \\n"*********** FTP Transfer ended $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) ***********"\\n\\n >> $maintodaylog
 
echo -e "***********" Backup Job Ended $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "*********"\\n\\n >> $maintodaylog
destmail=`mysql -e"use psa;select email from clients where login='admin'" -u$mysqluser -p"$mysqlpwd" | tail -n +2`
cat $maintodaylog | mail -s "$res FTP Transfer report $(date +%d.%m.%Y)" $destmail $ccmail

Je supprime enfin les fichiers temporaires

rm $blog
rm -rf /var/lib/psa/dumps/resellers/*

Suppression des fichiers sur le serveur FTP

Afin de ne pas remplir inutilement le serveur FTP, nous avons défini une durée de rétention dans backup.conf. Nous allons maintenant nous en servir pour effacer les anciens fichiers. Pour ça, on utilise de nouveau ncftp

ftpdeldate=`date --date="$remotedaystodel days ago" +%Y%m%d`
ncftp -u $fuser -p $fpass $fserv <<END_OF_CMD
cd $fpath
rm -f *$ftpdeldate*
quit
END_OF_CMD

Scripts

localdaystodel=7 # Rétention locale de 7 jours
remotedaystodel=30 # rétention distante de 30 jours
blogs="/var/lib/psa/dumps/logs"
maintodaylog="$blogs/backup_$(date +%Y%m%d_%H%M%S).log" #Création d'un fichier de log dans le dossier prédéfini
fuser="monuser"
fpass="monpassword"
fserv="ftp.monserveur.com"
fpath="/mes_sauvegardes"
btmp="/var/log/mes_backups"
ccmail="-c mon@adresse.email"
pbpath="/opt/psa/bin"
PMMpath="/opt/psa/PMM"
mysqluser="sqluser"
mysqlpwd="sqlpassword"
excl="domain1.tld domain2.tld"
#!/bin/sh
if ps ax | grep -v grep | grep /root/backup > /dev/null;
then
	echo "Backup already running"
else
	/root/backup &
fi
#!/bin/sh
 
. /root/backup.conf
 
# delete local files from 5 days ago
 
rm $btmp/*`date --date="$localdaystodel days ago" +%Y%m%d`*
 
# Delete old pmm sessions log files
 
find /opt/psa/PMM/sessions -mtime +30 -type d | grep -v archives | xargs rm -Rf 
 
# create main day log
 
echo -e "****************" Backup Job Started $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "***************"\\n\\n > $maintodaylog
 
# Backup Whole server config
 
# determine plesk administrator email address
 
destmail=`mysql -e"use psa;select email from clients where login='admin'" -u$mysqluser -p"$mysqlpwd" | tail -n +2`
 
# Define current backup job, log name, and file name
 
current="ServerConfig_ServerConfig_$(date +%Y%m%d_%H%M%S)"
blog="$blogs/$current.log"
nextfile="$current.tar"
# Start log file
echo "===== Server configuration backup started at $(date +%T) =====" > $blog
 
# Proceed to backup
$pbpath/pleskbackup --server --configuration --prefix=ServerConfig_ --output-file=$btmp/$nextfile
  # Define log files
      migres=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.result
      miglog=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.log
      echo "----------------------------" >> $blog
      echo ">>> log files in $migres" >> $blog
      echo "----------------------------" >> $blog
 
# Check status of job
resultat=`grep -c "success" $migres`
# Define action for successful backup
if [ $resultat != 0 ]
then
  status="ended successfully"
  echo "$(date +%H%M%S): The backup $status" >> $blog
	cat $migres >> $blog
  cat $blog | mail -s "Server configuration backup $status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
else
	status="failed"
  echo "$(date +%H%M%S): The backup $status" >> $blog
	cat $miglog >> $blog
	cat $migres >> $blog
	cat $blog | mail -s "Server configuration backup $status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
fi
unset resultat
# End log file
echo -e "=====" ServerConfig ended at $(date +%T) "====="\\n\\n >> $blog
# append log file to main log file
cat $blog >> $maintodaylog
 
# Define list of resellers
 
res_array=( `mysql -e"use psa;select login from clients where type='reseller' order by login desc" -u$mysqluser -p"$mysqlpwd" | tail -n +2` )
 
# for each reseller, backup config, and all domains
 
for res in ${res_array[@]};
 
  do
 
  # Backup reseller config
    current="$res"_Config_$(date +%Y%m%d_%H%M%S)
    blog="$blogs/$current.log"
    nextfile="$btmp/$current.tar"
 
  # define reseller log file
    todaylog=$blogs/"$res"_backup_$(date +%Y%m%d_%H%M%S).log
  # create reseller log file
    echo -e "****************" "$res" Backup Job Started $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "***************"\\n > $todaylog
 
  # Define destination email address based on reseller
 
    destmail=`mysql -e"use psa;select email from clients where login='$res'" -u$mysqluser -p"$mysqlpwd" | tail -n +2`
 
  # create log file
		echo -e "===== $res Config backup started at $(date +%T) ====="\\n\\n > $blog
  # proceed to backup
		$pbpath/pleskbackup --resellers-name $res --configuration -v --prefix=Config"$res"_ --output-file=$nextfile
 
  # Define log files
      migres=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.result
      miglog=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.log
      echo "----------------------------" >> $blog
      echo ">>> log files in $migres" >> $blog
      echo "----------------------------" >> $blog
 
  # Determine status
		resultat=`grep -c "success" $migres`
    if [ $resultat != 0 ]
    then
			status="$res config backup ended successfully"
      echo "$status" >> $blog
      echo "Migration result: " >> $blog
     	cat $migres >> $blog
      cat $blog | mail -s "$status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
    else
			status="$res config backup failed"
      echo "$status" >> $blog
      echo "Migration log: " >> $blog
	    cat $miglog >> $blog
      echo "Migration result: " >> $blog
	    cat $migres >> $blog
	    cat $blog | mail -s "$status on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
    fi
    unset resultat
 
		echo -e "===== $res Config ended at $(date +%T) ====="\\n\\n >> $blog
 
		echo -ne "$status: $res reseller configuration backup on $(date +%d.%m.%Y) at $(date +%T)"\\n >> $todaylog
 
  # Define domain list
 
    unset dom_array
    dom_array=(`mysql -e"use psa; select dom from (SELECT clients.login AS parent, clients_1.login as owner, clients.type AS type, domains.name as dom, domains.real_size as domsize FROM domains LEFT JOIN (clients AS clients_1 LEFT JOIN clients ON clients_1.parent_id = clients.id) ON domains.cl_id = clients_1.id) as list where if(parent='admin',owner,parent)='$res' order by domsize desc;" -u$mysqluser -p"$mysqlpwd" | tail -n +2`)
 
  # create counters
    count=0
    count1=0
 
    for dom in ${dom_array[@]};
 
    do
            if [[ ${excl[*]} =~ $dom ]]
                then
                        continue
        fi
 
  # Backup reseller config
      current="$dom"_$(date +%Y%m%d_%H%M%S)
      blog="$blogs/$current.log"
#     nextfile="$btmp/$current.tar"
      count=$(($count+1))
      echo -e "=====" $dom started at $(date +%T) "====="\\n > $blog
      nextfile=$btmp/"$dom"_$(date +%Y%m%d_%H%M%S).tar
      unset pids
  # proceed to backup in background
      $pbpath/pleskbackup --domains-name $dom --output-file=$nextfile
 
      migres=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.result
      miglog=/opt/psa/PMM/sessions/`ls -lrt /opt/psa/PMM/sessions/ | awk '/^d/ { f=$NF }; END{ print f }'`/migration.log
      echo "----------------------------" >> $blog
      echo ">>> log files in $migres" >> $blog
      echo "----------------------------" >> $blog
 
      resultat=`grep -c "success" $migres`
      if [ $resultat != 0 ]
      then
        status="Successful"
        count1=$(($count1+1))
        cat $migres >> $blog
      else
        status="Failed"
        cat $miglog >> $blog
        cat $migres >> $blog
        cat $blog | mail -s "$status: $dom backup on $(date +%d.%m.%Y) at $(date +%T)" $destmail $ccmail
      fi
      unset resultat
      echo -e "=====" $dom ended at $(date +%T) "====="\\n\\n >> $blog
      echo -ne "$status: $dom backup on $(date +%d.%m.%Y) at $(date +%T)"\\n >> $todaylog
    done    
 
  echo -e \\n"$count1/$count successful" >> $todaylog
  echo -e \\n"***********" "$res" Backup Job Ended $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "**********"\\n\\n >> $todaylog
  cat $todaylog | mail -s "$res reseller full backup report $(date +%d.%m.%Y)" $destmail $ccmail
  cat $todaylog >> $maintodaylog
  done
 
  echo -e \\n"*********** FTP Transfer started $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) ***********"\\n >> $maintodaylog
 
  cd $btmp
  countf=0
  countf1=0
  ftp_array=( `ls *$(date +%Y%m%d)*` )
  for ftpfile in ${ftp_array[@]};
  do
    countf=$(($countf+1))
    ncftpput -u $fuser -p $fpass $fserv $fpath $ftpfile
    case $? in
    0 )
        countf1=$(($countf1+1))
        status="Success: " ;;
    1 )
        status="Could not connect to remote host: " ;;
    2 )
        status="Could not connect to remote host - timed out: " ;;
    3 )
        status="Transfer failed: " ;;
    4 )
        status="Transfer failed - timed out: " ;;
    5 )
        status="Directory change failed: " ;;
    6 )
        status="Directory change failed - timed out: " ;;
    7 )
        status="Malformed URL: " ;;
    8 )
        status="Usage error: " ;;
    9 )
        status="Error in login configuration file: " ;;
    10 )
        status="Library initialization failed: " ;;
    11 )
        status="Session initialization failed: " ;;
    esac
    ftpdom=`echo $ftpfile | cut -d_ -f1`
    echo -e "$status $ftpdom" >> $maintodaylog
  done
  echo -e \\n">>>>> $countf1/$countf files succesfully transfered. <<<<<" >> $maintodaylog
  echo -e \\n"*********** FTP Transfer ended $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) ***********"\\n\\n >> $maintodaylog
 
  echo -e "***********" Backup Job Ended $(date +%A) $(date +%_d) $(date +%B) $(date +%Y) at $(date +%T) "*********"\\n\\n >> $maintodaylog
  destmail=`mysql -e"use psa;select email from clients where login='admin'" -u$mysqluser -p"$mysqlpwd" | tail -n +2`
  cat $maintodaylog | mail -s "$res FTP Transfer report $(date +%d.%m.%Y)" $destmail $ccmail
  rm $blog
	rm -rf /var/lib/psa/dumps/resellers/*  
 
  # delete files on the FTP older than xx days ago
 
ftpdeldate=`date --date="$remotedaystodel days ago" +%Y%m%d`
ncftp -u $fuser -p $fpass $fserv <

11 réflexions sur “Script de backup plesk (9.x et supérieur)

  1. Bonjour et merci pour ce script.
    Par contre dans le script start_backup j’ai les erreurs suivantes :

    start_backup.sh: line 2: gt: command not found
    start_backup.sh: line 2: /dev/null: Permission non accordée
    start_backup.sh: line 7: /home/scripts/backup: Aucun fichier ou répertoire de ce type
    start_backup.sh: line 7: amp: command not found

    Qu’en penser ?

  2. Bonjour.

    Attention: Quand on se lance dans le scripting, il faut apprendre à décoder les erreur des autres 🙂

    Dans ce cas précis, il suffit de regarder ce qu’il ne trouve pas à savoir /home/scripts/backup

    Est-ceq eu le script backup es tbien dans ce dossier et a-t-il bien ce nom ? a-t-il bien les droits d’exécution ? est-ce que le fichier backup.conf se trouve bien dans le meme dossier ?

    Vérifiez les chemins, quand à moi je vais relire mon article et corriger s’il y a des erreurs. Mais entre duex, j’ai changé le chemin decertains fichier et j’ai du oublier d’en corriger d’autres.

  3. Après vérification Y a un bug dans la mise à dispo des scripts à la fin de l’article. Tous les caractères spéciaux comme & ou > ont été remplacés par le code de translation (&gt par exemple) .

    Il faut donc revoir tout le script, et corriger. C’est pas bien méchant, mais c’est clair que sans ça ça ne marchera pas.

    Je corrigerai mon article à l’occasion. Pour l’insant, je n’ai pas le temps. Mais le contenu de l’article lui-meme est correcte. C’est seulement les scripts à télécharger en bas de page qui contiennent ces erreurs de décodage. Donc vous pouvez vous fier à l’article pour corriger les scripts.

  4. Ok merci.
    C’est vrai que je suis surbooké et c’est pkoi je me suis jeté sur cette source sans vraiment essayé de comprendre.
    M’enfin y’avait bien un problème…

  5. Une fois réglé les pbs de conversion de caractère :

    les logs sont sur :
    /usr/local/psa/PMM/sessions

    et l’executable pleskbackup :
    /usr/local/psa/bin

    je suis sous plesk 10.2, cela explique peut-être la raison.

    sinon pouvez-vous me dire pkoi :

    ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: NO)

    c’est l’appel à mysql je suppose et il n’utilise pas l’user psa, mais pkoi ?

    merci.

  6. Bon en fait ‘use psa’ indique d’utiliser la base ‘psa’
    l’utilisateur root n’a pas accès a cette base donc faut passer par un autre user : admin
    son mot de passe se trouve :
    /etc/psa/.psa.shadow
    ensuite ajouter : -uadmin -p{mot de passe} lors de l’appel à mysql :
    mysql -uadmin -p{mot de passe} -e
    voilà.

  7. Bravo 🙂 en effet, j’utilise root comme utilisateur.

    Pour le mot de passe, y a aussi moyen simplement de mettre un fichier .my.cnf dans /root avec

    [client]
    user=admin
    pass=password

  8. je n’ai pas trouvé l’user ‘route’.
    Et au final le script ne fonctionne pas.
    Je reçois un mail qui comporte un tas d’erreur :

    rm: cannot remove `/var/backup_perso/*20110518*’: No such file or directory
    /home/scripts/backup.sh: line 15: /var/backup_perso/logs/backup_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 26: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied Runtime error: Error in tempfile() using /usr/local/psa/PMM/tmp/pmmcliinXXXXXX: Could not create temp file /usr/local/psa/PMM/tmp/pmmcliinKSXIzC: Permission denied at /usr/local/psa/bin/pleskbackup line 692.

    /home/scripts/backup.sh: line 33: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 34: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 35: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    grep: /usr/local/psa/PMM/sessions/2011-05-19-033110.187/migration.result: Permission denied
    /home/scripts/backup.sh: line 40: [: !=: unary operator expected
    /home/scripts/backup.sh: line 48: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 49: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 50: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 55: /var/backup_perso/logs/ServerConfig_ServerConfig_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 57: /var/backup_perso/logs/backup_20110520_033101.log: Permission denied
    /home/scripts/backup.sh: line 103: /var/backup_perso/logs/calitimo.org_20110520_033102.log: Permission denied Runtime error: Error in tempfile() using /usr/local/psa/PMM/tmp/pmmcliinXXXXXX: Could not create temp file /usr/local/psa/PMM/tmp/pmmcliinkpOSAF: Permission denied at /usr/local/psa/bin/pleskbackup line 692.

    Si vous aviez une solution, merci.

  9. ALors pourquoi j’ai écrit route, je n’en sais rien !!! Le décalage horaire peut-être ! La fatigue !!!

    Quoi qu’il en soit, il s’agit de root 😀 Pas de route.
    maintenant reprenons:

    Le script est exécuté par cron sous l’utilsiateur root. L’utilsiateur de base de donnée lui est admin (c’est le même utilisateur et mot de passe que l’admin de plesk).

    Mes excuses pour la confusion.

  10. ok mais cela ne m’explique pas pkoi le script ne fonctionne pas car je suis moi aussi en root, proprio des fichiers et je lance le cron sous l’utilisateur root :

    -rwxr-xr-x 1 root root 5921 mai 16 14:46 backup.sh
    -rwxr-xr-x 1 root root 148 mai 4 09:25 start_backup.sh

  11. Avec beaucoup de retard, désolé …

    Je ne peux décemment pas t’aider comme ça. Mon script fonctionne a merveille chez moi. Je n’ai jamais de surprise. Donc vraiment difficile de te répondre sans plus de détail. Une piste peut-être: as-tu un fichier .my.cnf avec le mot de passe de ta base de donnée dedans, permettant au script de s’y connecter ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *