Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#326 Le 02/07/2025, à 11:48

iznobe

Re : script d’automatisation sauvegardes

Salut , c' est plus que de la parano de vouloir sauvegarder en double et des fichiers toutes les heures .

Pour du perso , je n' en vois pas l' interet .
Ca serait une entreprise de dev avec une dizaine d' utilisateurs qui travaillent sur du code , là ok .
Mais ils utilisent des outils appropriés au versionning , ils n' ont donc pas besoin non plus de faire des sauvegardes toutes les heures ( encore moins en double ! ) .


il me semble qu ' il a été dis que reinventé la roue etait une enorme perte de temps :

steph810 a écrit :

Bonjour,
je pense le mieux le mieux serais d'utiliser une interfaces web mini-server apache en local ou l'ajouts de nouvelle sauvegardes. Quelques jours je suis dessus bientôt finalisé. Ca evitera de faire des erreurs et de ne plus touché au code principal qui est actuellement fonctionnel.

Mais il y en a que ca amuse à priori .

vincent a deja dis dans tes discussions , je ne sais combien de fois , d' utiliser un logiciel spécialisé , ce qui convient parfaitement une fois que tu as choisi celui qui te convient .


retour COMPLET et utilisable de commande  |  script montage partitions

MSI Z490A-pro , i7 10700 , 32 GB RAM .

Hors ligne

#327 Le 02/07/2025, à 12:36

eric63

Re : script d’automatisation sauvegardes

ça me semble pas parano de donner à 2 utilisateurs les mêmes droits de sauvegardes , c’est en plus de la curiosité de voir comment faire cela
et en attendant la proposition de steph810 la solution de rsnapshot -alpha (hourly) me conviendrait à défaut sans casser ce qui existe déjà dans sauvegarde.sh
j’explore cette possibilité


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#328 Le 05/07/2025, à 12:12

eric63

Re : script d’automatisation sauvegardes

Je vois que steph810 en est à la version 6.5 de son projet Backup Manager Web et qu’il semble fixé depuis 3 jours.
Est ce que je peux essayer à partir de maintenant ?
ou dois je attendre encore quelques temps pour des modifications à venir ?
( je n’ai pas vu de modifications concernant les sauvegardes spéciales  mais j’ai parcouru peut être un peu vite les readme et autres explications)
Sacré boulot cool


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#329 Le 08/07/2025, à 10:29

eric63

Re : script d’automatisation sauvegardes

bon je m’y suis risqué à la version 6.5

Comme attendu ça marche pô; j’ai lu attentivement pourtant. Les instructions en ligne de commande sont plus précises que le manuel
http://localhost/backup-manager-web/web/ au lieu de http://votre-serveur/backup-manager-web/web/ c’est plus parlant
j’ai fait l’installation rapide recommandée

# Cloner le projet
git clone https://github.com/ps81frt/backup-manager-web.git
cd backup-manager-web

# Installation automatique (détecte votre distribution)
sudo ./setup-web.sh
kubu@kubu-System-Product-Name:~/Documents/ScriptsVMImportants/backup-manager-web$ sudo ./setup-web.sh
[sudo] password for kubu: 
Installation de Backup Manager Web...
Détection de la distribution...
Distribution Debian/Ubuntu détectée
Vérification des dépendances...
Toutes les dépendances sont déjà installées.
Configuration du serveur web...
apache2 déjà en cours d'exécution
usermod : aucun changement
Considering dependency mpm_prefork for php8.4:
Considering conflict mpm_event for mpm_prefork:
Considering conflict mpm_worker for mpm_prefork:
Module mpm_prefork already enabled
Considering conflict php5 for php8.4:
Module php8.4 already enabled
Vérification des outils système...
Configuration des permissions...
Génération de la clé SSH...
Clé SSH déjà existante
Vérification finale...

✅ INSTALLATION RÉUSSIE !
=== ÉTAPES SUIVANTES ===
1. Modifiez config.sh avec vos vraies valeurs :
   SSH_USER_PHOTOS="votre_utilisateur"
   SSH_IP_PHOTOS="192.168.1.100"

donne

 SSH_USER_PHOTOS="Multimedias"                           # Monté sur /home/kubu/VMMultimedias/PhotosVM et Monté à partir de Multimedias@192.168.1.128:/home/Multimedias/PhotosVM "votre_utilisateur_vm_photos"
SSH_IP_PHOTOS="192.168.1.128" 
2. Copiez cette clé publique sur vos serveurs distants :
ssh-rsa AAAABxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx= backup-web@kubu-System-Product-Name

là problème pour moi c’est pas clair; sinon je vois pas comment faire exactement autrement:
je suppose qu’il faut exécuter le 3 pour copier au bon endroit ou aux bons endroits cette clé sur les serveurs distants

Multimedias@162.168.1.128

et

fanou@192.168.1.60 

????
j’ai donc poursuivis

3. Sur chaque serveur distant, exécutez :
   ssh-copy-id -i /var/www/.ssh/backup_key.pub utilisateur@serveur

donne

kubu@kubu-System-Product-Name:~$ ssh-copy-id -i /var/www/.ssh/backup_key.pub Multimedias@192.168.1.128
/usr/bin/ssh-copy-id: ERROR: failed to open ID file '/var/www/.ssh/backup_key': Permission denied
        (to install the contents of '/var/www/.ssh/backup_key.pub' anyway, look at the -f option)
kubu@kubu-System-Product-Name:~$ 

ce qui semble normal vu que ce fichier appartient à www-data
donc j’essai avec un

kubu@kubu-System-Product-Name:~$ sudo ssh-copy-id -i /var/www/.ssh/backup_key.pub Multimedias@192.168.1.128
[sudo] password for kubu: 
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/var/www/.ssh/backup_key.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -i /var/www/.ssh/backup_key 'Multimedias@192.168.1.128'"
and check to make sure that only the key(s) you wanted were added.
kubu@kubu-System-Product-Name:~/Documents/ScriptsVMImportants/backup-manager-web$ sudo -u www-data ssh -i /var/www/.ssh/backup_key Multimedias@192.168.1.128 
The authenticity of host '192.168.1.128 (192.168.1.128)' can't be established.
ED25519 key fingerprint is SHA256:f5v7hCEMhkmb3eJHG/N60kQ+9G3Kc7pRz6r5fgVXpmQ.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 

là je bloque la clé n’est pas la bonne ??? hmm
je passe en attendant

5. Le système est maintenant fonctionnel :
   - Terminal : ./sauvegarde.sh all
   - Web : http://localhost/backup-manager-web/web/

je vois enfin mon dashboard smile

j’ai aussi modifié dans /var/www/html/backup-manager-web/web/index.php
les lignes

 // Sauvegardes par défaut (depuis fichier de config)
    $defaultConfig = '../default_backups.conf';
    $defaults = ['docs_eric', 'docs_fanou', 'docs_portable_fanou','docs_communs_vm', 'photos_vm', 'images_vm', 'musiques_vm', 'projets_serveur'];

 

 // Vérifier si c'est une sauvegarde par défaut désactivée
    $defaultBackups = ['docs_eric', 'docs_fanou', 'docs_portable_fanou','docs_communs_vm',  'photos_vm', 'images_vm', 'musiques_vm', 'projets_serveur'];
    if (in_array($selection, $defaultBackups) && !isDefaultBackupEnabled($selection)) {
        return "Erreur: La sauvegarde '$selection' est désactivée dans default_backups.conf";
    }

   

 // Validation sécurisée - inclure les sauvegardes personnalisées
    $allowed = ['docs_eric', 'docs_fanou', 'docs_portable_fanou', 'docs_communs_vm',  'photos_vm', 'images_vm', 'musiques_vm', 'projets_serveur', 'all'];

reste encore à résoudre l’histoire de la clé sur le serveur distant du portable
et les sauvegardes interne des documents de la vm sur la vm avec un crontab horaire

Dernière modification par eric63 (Le 09/07/2025, à 12:40)


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#330 Le 09/07/2025, à 14:53

eric63

Re : script d’automatisation sauvegardes

essai sauvegardes1
www-data@backup-manager-web:~/backup-manager-web$ ./sauvegarde.sh --dry-run all
tee: /var/log/sauvegardes/sauvegarde_20250709.log: Permission denied
2025-07-09 14:54:39 [INFO] Configuration de l'environnement web détectée...

2025-07-09 11:25:21 [ERREUR] L'exécutable configuré pour MAIL ('/usr/bin/sendmail') n'existe pas ou n'est pas exécutable.
2025-07-09 11:25:21 [ERREUR] Code d'erreur : 127. Certaines dépendances logicielles essentielles sont manquantes ou incorrectement configurées.
2025-07-09 11:25:21 [ERREUR] Action suggérée : Une commande externe requise par le script n'a pas été trouvée dans le PATH. Vérifiez que toutes les dépendances (rsync, ssh, sshfs, mailx/mail, fusermount, etc.) sont installées et accessibles. Ou que leur chemin est correctement configuré dans config.sh.

bon c’est pas gagné sad
j’ai mis la variable

EMAIL_NOTIFICATION=""

du fichier config.sh mais cela ne fonctionne pas mieux
et les commandes mail ou mailx sont inconnues

kubu@kubu-System-Product-Name:~$ sudo apt install mail
[sudo] password for kubu: 
Erreur : Impossible de trouver le paquet mail
kubu@kubu-System-Product-Name:~$ sudo apt install mailx
Le paquet mailx est un paquet virtuel fourni par :
  mailutils 1:3.18-1
  bsd-mailx 8.1.2-0.20220412cvs-1build1
Vous devez explicitement sélectionner un paquet à installer.
Erreur : Le paquet « mailx » n'a pas de version susceptible d'être installée
kubu@kubu-System-Product-Name:~$ 

j’ai vidé l’adresse mail
déconnecté les sauvegardes sauf documents_eric
j’ai modifié les chemin de 2 variables pour les rendre accessibles

 # Répertoire où les fichiers de log du script seront stockés.
LOG_DIR="/home/kubu/log/sauvegardes/" #"/var/log/sauvegardes"

# Chemin complet du fichier de verrouillage. Doit être accessible en écriture.
PID_FILE="/home/kubu/log/$DEFAULT_NOM_SCRIPT.pid"  #"/var/run/$DEFAULT_NOM_SCRIPT.pid"

j’ai démarré la commande  sauvegarde.sh dans la konsole
ça a amélioré le départ

kubu@kubu-System-Product-Name:~$ /var/www/html/backup-manager-web/sauvegarde.sh 
2025-07-09 19:08:10 [INFO] Fichier de verrouillage créé : 9917
2025-07-09 19:08:10 [INFO] === DÉBUT DES SAUVEGARDES ===
2025-07-09 19:08:10 [INFO] Sélections à traiter : docs_eric docs_fanou docs_portable_fanou docs_communs
2025-07-09 19:08:10 [INFO] Traitement de la sauvegarde 'Docs Eric'...
2025-07-09 19:08:10 [INFO] Démarrage de la sauvegarde locale pour '/home/kubu/Documents' vers '/media/kubu/JEUX8T/SAUVEGARDES/DocumentsEric/'.
2025-07-09 19:08:10 [INFO] Création du répertoire de destination principal : /media/kubu/JEUX8T/SAUVEGARDES/DocumentsEric/
2025-07-09 19:08:10 [INFO] Création du répertoire de base incrémentale : /media/kubu/JEUX8T/SAUVEGARDES/incremental-DocumentsEric/
2025-07-09 19:08:11 [INFO] Espace disque libre sur '/media/kubu/JEUX8T/SAUVEGARDES' : 2730 Go (minimum requis : 5 Go).
2025-07-09 19:08:11 [ERREUR] La variable 'Point de montage SSHFS' ne peut pas être vide.
2025-07-09 19:08:11 [INFO] Fichier de verrouillage supprimé.
kubu@kubu-System-Product-Name:~$   

ça m’a créé 2 dossiers vides au bon endroit hmm

essai avec le dashboard
mais le bouton exécuter n’a pas l’air de lancer la sauvegarde
cette ligne m’intrigue

 La variable 'Point de montage SSHFS' ne peut pas être vide.

car je n’ai pas besoin de point de montage pour ce dossier local ????
Dans le fichier  sauvegarde.sh j’ai 4 occurences pour "montage_sshfs_point"

   # shellcheck disable=SC2154 # DEFAULT_TYPE_CONNEXION_DISTANTE est défini dans config.sh
    if [[ "$DEFAULT_TYPE_CONNEXION_DISTANTE" -eq 0 ]]; then # Mode SSHFS
        local local_source="$source_path" # Pour rsync, la source est le chemin distant MONTÉ localement.
        # Vérifie si le point de montage existe et est bien un répertoire
        valider_variable "Point de montage SSHFS" "$montage_sshfs_point" "path"
        if [[ $? -ne 0 ]]; then diagnostiquer_et_logger_erreur 13 "Point de montage SSHFS invalide: $montage_sshfs_point"; fi

        # Montage SSHFS
        monter_sshfs "$ssh_user" "$ssh_ip" "$ssh_port" "$source_path" "$montage_sshfs_point"
        local_source="$montage_sshfs_point" # La source de rsync devient le point de montage local

        # Vérifier si le point de montage est vide ou inaccessible après montage
        if ! find "$local_source" -mindepth 1 -print -quit | grep -q .; then
            log_warning "Le point de montage SSHFS '$local_source' semble vide ou inaccessible après le montage. La sauvegarde pourrait ne rien transférer."
            # Ne pas diagnostiquer comme une erreur fatale ici, car le dossier distant PEUT être vide.
            # L'erreur 13 est plus pour "source inexistante avant même de tenter un montage"
        fi

Dernière modification par eric63 (Le 09/07/2025, à 21:07)


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#331 Le 11/07/2025, à 16:12

eric63

Re : script d’automatisation sauvegardes

aucune avancée sur le problème sad
j’ai beau trituré les script je vois rien d’anormal

kubu@kubu-System-Product-Name:/var/www/html/backup-manager-web$ ./sauvegarde.sh docs_eric
2025-07-11 15:50:24 [INFO] Fichier de verrouillage créé : 20984
2025-07-11 15:50:24 [INFO] === DÉBUT DES SAUVEGARDES ===
2025-07-11 15:50:24 [INFO] Sélections à traiter : docs_eric
2025-07-11 15:50:24 [INFO] Traitement de la sauvegarde 'Docs Eric'...
2025-07-11 15:50:24 [INFO] Démarrage de la sauvegarde locale pour '/home/kubu/Documents' vers '/media/kubu/JEUX8T/SAUVEGARDES/DocumentsEric/'.
2025-07-11 15:50:24 [INFO] Espace disque libre sur '/media/kubu/JEUX8T/SAUVEGARDES' : 2730 Go (minimum requis : 5 Go).
2025-07-11 15:50:24 [ERREUR] La variable 'Point de montage SSHFS' ne peut pas être vide.
2025-07-11 15:50:24 [INFO] Fichier de verrouillage supprimé.
kubu@kubu-System-Product-Name:/var/www/html/backup-manager-web$ 

je donne les 2 scripts config.sh et sauvegarde.sh

#!/bin/bash

#===============================================================
# Fichier de configuration pour sauvegarde.sh
# Auteur : enRIKO (modifié pour production et améliorations)
# Date : 2025-06-24
# Version : 2.5
#
# Changelog :
# - 2.5 (2025-06-24) :
#   - Correction majeure : Restauration de TOUS les noms de variables en français comme dans la version originale.
#   - Ajout de nouveaux paramètres (également en français) pour une robustesse accrue,
#     sans modifier les variables existantes.
# - 2.4 (2025-06-24) :
#   - Ajout de RSYNC_DELETE pour contrôler l'option rsync --delete.
#   - Clarification des commentaires pour la personnalisation.
#===============================================================

# --- OPTIONS GLOBALES DU SCRIPT ---

# Adresse email pour les rapports de succès/échec. Laissez vide pour désactiver.
EMAIL_NOTIFICATION=""

# Espace disque minimum requis sur la destination (en Go). Le script échouera si l'espace est insuffisant.
ESPACE_DISQUE_MIN_GO=5

# Options rsync par défaut. Utilisez des exclusions pour les fichiers temporaires ou inutiles.
# --archive (-a) : mode archive (récursif, conserve les liens symboliques, permissions, temps, groupe, propriétaire)
# --human-readable (-h) : sorties lisibles par l'humain
# --info=progress2,misc0,name0 : affiche la progression et d'autres infos utiles
# --partial --progress : permet de reprendre les transferts et affiche la progression du fichier courant
DEFAULT_RSYNC_OPTIONS="-avh --partial --progress --info=progress2,misc0,name0"

# Activer (1) ou désactiver (0) l'option --delete de rsync.
# 0: Ne supprime jamais (par défaut et recommandé pour les incrémentales avec --link-dest).
# 1: Supprime les fichiers sur la destination s'ils ont été supprimés sur la source (utiliser avec prudence!).
RSYNC_DELETE=0

# Mode débogage (0=off, 1=on). Active la sortie verbeuse du script pour le diagnostic.
DEFAULT_MODE_DEBOGAGE=1

# Désactiver les journaux (0=actif, 1=désactivé). Les erreurs critiques seront toujours enregistrées dans un fichier temporaire.
DEFAULT_JOURNAUX_DESACTIVES=0

# Nom du script pour le mécanisme de verrouillage (évite les exécutions multiples).
DEFAULT_NOM_SCRIPT="sauvegarde"

# Activer le mécanisme de verrouillage (0=off, 1=on).
ACTIVERLOCK=1

# Type de connexion distante :
# 0 = SSHFS (recommandé pour une intégration transparente des chemins distants)
# 1 = SSH direct (rsync via SSH, plus simple, mais nécessite des chemins distants absolus dans rsync)
DEFAULT_TYPE_CONNEXION_DISTANTE=0

# Sélections de sauvegardes par défaut à exécuter si aucune n'est spécifiée en ligne de commande.
# Séparez les sélections par des espaces (ex: "docs_eric docs_fanou photos_vm").
# Utilisez "all" pour inclure toutes les sauvegardes définies.
DEFAULT_SELECTIONS_SAUVEGARDES="docs_eric docs_fanou docs_portable_fanou docs_communs"

# Mode incrémental par défaut (0=complet, 1=incrémental)
DEFAULT_MODE_INCREMENTAL=1


# --- CHEMINS CRITIQUES ET BINAIRES ---

# Répertoire de base où toutes les sauvegardes seront stockées.
DEST_BASE_SAUVEGARDES="/media/kubu/JEUX8T/SAUVEGARDES"

# Répertoire où les fichiers de log du script seront stockés.
LOG_DIR="/home/kubu/log/sauvegardes/" #"/var/log/sauvegardes"

# Chemin complet du fichier de verrouillage. Doit être accessible en écriture.
PID_FILE="/home/kubu/log/$DEFAULT_NOM_SCRIPT.pid"  #"/var/run/$DEFAULT_NOM_SCRIPT.pid"

# Chemin du fichier de clé privée SSH (laissez vide si authentification par agent ou mot de passe).
# Ex: SSH_KEY_PATH="/home/votre_utilisateur/.ssh/id_rsa_backup"
SSH_KEY_PATH="/home/kubu/.ssh/id_ed25519"

# Chemin du socket de l'agent SSH (laissez vide si non utilisé).
# Ex: SSH_AUTH_SOCK_PATH="/tmp/ssh-XXXXXXX/agent.XXXX"
SSH_AUTH_SOCK_PATH=""

# --- NOUVEAUX PARAMÈTRES : CHEMINS EXPLICITES VERS LES EXÉCUTABLES DES OUTILS ---
# Ces variables permettent de spécifier le chemin complet d'un exécutable si celui-ci
# n'est pas dans le PATH standard ou si une version spécifique est requise.
# Laissez vide pour utiliser la version trouvée dans le PATH du système.
CHEMIN_RSYNC="/usr/bin/rsync"        # Ex: /usr/bin/rsync
CHEMIN_SSH="/usr/bin/ssh"            # Ex: /usr/bin/ssh
CHEMIN_SSHFS="/usr/bin/sshfs"        # Ex: /usr/bin/sshfs
CHEMIN_FUSEMOUNT="/usr/bin/fusermount" # Ex: /usr/bin/fusermount
CHEMIN_MOUNTPOINT="/usr/bin/mountpoint" # Ex: /usr/bin/mountpoint
CHEMIN_LSOF="/usr/bin/lsof"          # Ex: /usr/bin/lsof
CHEMIN_KILL="/usr/bin/kill"          # Ex: /usr/bin/kill
CHEMIN_MKDIR="/usr/bin/mkdir"        # Ex: /usr/bin/mkdir
CHEMIN_MAIL="/usr/bin/mail"         # Ex: /usr/bin/mailx ou /usr/bin/mail


# --- NOUVEAUX PARAMÈTRES : GESTION AVANCÉE DES JOURNAUX ---

# Taille maximale d'un fichier de log en Mo avant rotation. (0 pour désactiver la rotation par taille)
TAILLE_MAX_LOG_MO=10

# Nombre de jours avant de compresser/purger les anciens logs (0 pour désactiver la rétention basée sur le temps).
JOURS_RETENTION_LOGS=30

# Commande de compression pour les logs archivés (ex: "gzip"). Laissez vide pour ne pas compresser.
# Assurez-vous que la commande est disponible sur le système (e.g., 'gzip', 'bzip2', 'xz').
COMMANDE_COMPRESSION_LOGS="gzip"


# --- NOUVEAUX PARAMÈTRES : OPTIONS DE CONNEXION SSH AVANCÉES ---

# Timeout de connexion SSH en secondes.
DELAI_CONNEXION_SSH_SECONDES=10

# Options SSH communes à toutes les connexions distantes.
# Par défaut, ces options sont sécurisées. Si vous avez besoin de désactiver la vérification des clés
# d'hôte, utilisez StrictHostKeyChecking_SSH (avec prudence !).
OPTIONS_COMMUNES_SSH="-o BatchMode=yes -o ConnectTimeout=${DELAI_CONNEXION_SSH_SECONDES}"

# Activer (yes), désactiver (no) ou demander (ask) StrictHostKeyChecking.
# "no" est risqué en production pour des raisons de sécurité. Laissez vide pour la configuration SSH par défaut.
StrictHostKeyChecking_SSH="" # "yes", "no", "ask" (laisser vide pour la config SSH par défaut)


# --- NOUVEAUX PARAMÈTRES : OPTIONS RSYNC AVANCÉES ---

# Timeout pour l'opération rsync en secondes. (0 = désactivé. Ex: 3600 = 1 heure)
DELAI_OPERATION_RSYNC_SECONDES=0

# Options spécifiques pour la commande rsync incrémentale.
# --link-dest est crucial pour les sauvegardes incrémentales efficaces avec hardlinks.
# Les chemins dans --link-dest sont relatifs à la DEST_INCR_BASE.
# Ne modifiez pas cette option à moins de savoir ce que vous faites.
OPTIONS_RSYNC_INCREMENTALE="--link-dest=../current"


# --- NOUVEAUX PARAMÈTRES : HOOKS PERSONNALISÉS (AVANCÉ) ---
# Vous pouvez définir des chemins vers des scripts personnalisés qui seront exécutés
# à des moments clés du processus de sauvegarde. Exemple de sauvegardes spéciales VM vers 8T.
# Exécuté au début du script sauvegarde.sh, après le chargement de la config et avant le verrouillage.
# SCRIPT_PRE_SAUVEGARDE_GLOBAL="/chemin/vers/votre_script_pre_sauvegarde_global.sh"
SCRIPT_PRE_SAUVEGARDE_GLOBAL=""

# Exécuté à la fin du script sauvegarde.sh, après toutes les sauvegardes et avant le démontage/nettoyage final.
# SCRIPT_POST_SAUVEGARDE_GLOBAL="/chemin/vers/votre_script_post_sauvegarde_global.sh"
SCRIPT_POST_SAUVEGARDE_GLOBAL=""


# --- CONFIGURATIONS DES SAUVEGARDES SPÉCIFIQUES ---
# Définissez ici les paramètres pour chaque sélection de sauvegarde.

# --- Sauvegarde : Docs Eric (Locale) ---
SOURCE_LOCALE_DOCS_ERIC="/home/kubu/Documents"
DEST_MAIN_DOCS_ERIC="$DEST_BASE_SAUVEGARDES/DocumentsEric/"
DEST_INCR_BASE_DOCS_ERIC="$DEST_BASE_SAUVEGARDES/incremental-DocumentsEric/"

# --- Sauvegarde : Docs Fanou (Locale) ---
#SOURCE_LOCALE_DOCS_FANOU="/home/fanou/Documents"
#DEST_MAIN_DOCS_FANOU="$DEST_BASE_SAUVEGARDES/DocumentsFanou/"
#DEST_INCR_BASE_DOCS_FANOU="$DEST_BASE_SAUVEGARDES/incremental-DocumentsFanou/"

# --- Sauvegarde : Docs Portable (Distante via SSHFS) ---
# NOTE: Le nom de la variable MONTAGE_SSHFS_MUSIQUES a été corrigé en MONTAGE_SSHFS_DOCS_PORTABLE pour être cohérent avec le nom de la sauvegarde.
SSH_USER_DOCS_PORTABLE="fanou" # "fanou_portable"
SSH_IP_DOCS_PORTABLE="192.168.1.60"
SSH_PORT_DOCS_PORTABLE=22
SOURCE_DIST_DOCS_PORTABLE="/home/fanou/Documents/" # Chemin ABSOLU sur le portable
MONTAGE_SSHFS_DOCS_PORTABLE="/tmp/sshfs_mounts/docs_portable_fanou"
DEST_MAIN_DOCS_PORTABLE="$DEST_BASE_SAUVEGARDES/DocumentsPortableFanou/"
DEST_INCR_BASE_DOCS_PORTABLE="$DEST_BASE_SAUVEGARDES/incremental-DocumentsPortableFanou/"

SSH_USER_DOCSCOMMUNS="Multimedias"                           # Monté sur/home/kubu/VMMultimedias/DocumentsCommunsVM et Monté à partir de Multimedias@192.168.1.128:/home/Multimedias/DocumentsCommunsVM "votre_utilisateur_vm_photos"
SSH_IP_DOCSCOMMUNS="192.168.1.128"
SSH_PORT_DOCSCOMMUNS=22
SOURCE_DIST_DOCSCOMMUNS_VM="/home/kubu/Multimedias/DocumentsCommunsVM" # /chemin/sur/vm/DocumentsCommunsVM" # Chemin ABSOLU sur la VM
MONTAGE_SSHFS_DOCSCOMMUNS="/tmp/sshfs_mounts/DocumentsCommuns_vm"
DEST_MAIN_DOCSCOMMUNS="$DEST_BASE_SAUVEGARDES/DocumentsCommunsVM/"
DEST_INCR_BASE_DOCSCOMMUNS="$DEST_BASE_SAUVEGARDES/incremental-DocumentsCommunsVM/"

# --- Sauvegarde : Photos VM (Distante via SSHFS) ---
# Note : Pour DEFAULT_TYPE_CONNEXION_DISTANTE=0 (SSHFS), SOURCE_DIST est le chemin absolu sur le serveur distant.
# MONTAGE_SSHFS_PHOTOS est le point de montage local. DEST_MAIN_PHOTOS et DEST_INCR_BASE_PHOTOS
# sont les destinations finales sur le système de sauvegarde.
SSH_USER_PHOTOS="Multimedias"                           # Monté sur/home/kubu/VMMultimedias/PhotosVM et Monté à partir de Multimedias@192.168.1.128:/home/Multimedias/PhotosVM "votre_utilisateur_vm_photos"
SSH_IP_PHOTOS="192.168.1.128"
SSH_PORT_PHOTOS=22
SOURCE_DIST_PHOTOS_VM="/home/kubu/Multimedias/PhotosVM" # /chemin/sur/vm/Photos" # Chemin ABSOLU sur la VM
MONTAGE_SSHFS_PHOTOS="/tmp/sshfs_mounts/photos_vm"
DEST_MAIN_PHOTOS="$DEST_BASE_SAUVEGARDES/PhotosVM/"
DEST_INCR_BASE_PHOTOS="$DEST_BASE_SAUVEGARDES/incremental-PhotosVM/"

SSH_USER_IMAGES="Multimedias"                           # Monté sur/home/kubu/VMMultimedias/ImagesVM et Monté à partir de Multimedias@192.168.1.128:/home/Multimedias/PhotosVM "votre_utilisateur_vm_photos"
SSH_IP_IMAGES="192.168.1.128"
SSH_PORT_IMAGES=22
SOURCE_DIST_IMAGES_VM="/home/kubu/Multimedias/ImagesVM" # /chemin/sur/vm/Images" # Chemin ABSOLU sur la VM
MONTAGE_SSHFS_IMAGES="/tmp/sshfs_mounts/images_vm"
DEST_MAIN_IMAGES="$DEST_BASE_SAUVEGARDES/ImagesVM/"
DEST_INCR_BASE_IMAGES="$DEST_BASE_SAUVEGARDES/incremental-ImagesVM/"

SSH_USER_MUSIQUES="Multimedias"                           # Monté sur/home/kubu/VMMultimedias/MusiquesVM et Monté à partir de Multimedias@192.168.1.128:/home/Multimedias/ImagesVM "votre_utilisateur_vm_photos"
SSH_IP_MUSIQUES="192.168.1.128"
SSH_PORT_MUSIQUES=22
SOURCE_DIST_MUSIQUES_VM="/home/kubu/Multimedias/MusiquesVM" # /chemin/sur/vm/Musiques" # Chemin ABSOLU sur la VM
MONTAGE_SSHFS_MUSIQUES="/tmp/sshfs_mounts/musiques_vm"
DEST_MAIN_MUSIQUES="$DEST_BASE_SAUVEGARDES/MusiquesVM/"
DEST_INCR_BASE_MUSIQUES="$DEST_BASE_SAUVEGARDES/incremental-MusiquesVM/"

# --- Sauvegarde : Projets Serveur (Distante via SSHFS) ---
# NOTE: Le nom de la variable MONTAGE_SSHFS_IMAGES a été corrigé en MONTAGE_SSHFS_PROJETS pour être cohérent avec le nom de la sauvegarde.
#SSH_USER_PROJETS="votre_utilisateur_serveur_projets"
#SSH_IP_PROJETS="192.168.1.101"
#SSH_PORT_PROJETS=22
#SOURCE_DIST_PROJETS_SERVEUR="/Projets/Serveur/" # Chemin ABSOLU sur le serveur
#MONTAGE_SSHFS_PROJETS="/tmp/sshfs_mounts/projets_serveur"
#DEST_MAIN_PROJETS="$DEST_BASE_SAUVEGARDES/ProjetsServeur/"
#DEST_INCR_BASE_PROJETS="$DEST_BASE_SAUVEGARDES/incremental-ProjetsServeur/"

# --- POLITIQUES DE RÉTENTION ---
# Définissez le nombre de versions quotidiennes, hebdomadaires et mensuelles à conserver.
# Mettez 0 pour désactiver un type de rétention.

# Rétention pour Docs Eric
JOURS_RETENTION_DOCS_ERIC_QUOTIDIEN=7
JOURS_RETENTION_DOCS_ERIC_HEBDO=4 # Nombre de semaines (4 semaines = 1 mois)
JOURS_RETENTION_DOCS_ERIC_MENSUEL=12 # Nombre de mois (12 mois = 1 an)

# Rétention pour Docs Fanou
JOURS_RETENTION_DOCS_FANOU_QUOTIDIEN=7
JOURS_RETENTION_DOCS_FANOU_HEBDO=4
JOURS_RETENTION_DOCS_FANOU_MENSUEL=12

# Rétention pour Docs Portable Fanou
JOURS_RETENTION_DOCS_PORTABLE_FANOU_QUOTIDIEN=7
JOURS_RETENTION_DOCS_PORTABLE_FANOU_HEBDO=4
JOURS_RETENTION_DOCS_PORTABLE_FANOU_MENSUEL=12

# Rétention pour Docs communes
JOURS_RETENTION_DOCS_COMMUNS_QUOTIDIEN=7
JOURS_RETENTION_DOCS_COMMUNS_HEBDO=4
JOURS_RETENTION_DOCS_COMMUNS_MENSUEL=12

# Rétention pour Photos VM
JOURS_RETENTION_PHOTOS_VM_QUOTIDIEN=7
JOURS_RETENTION_PHOTOS_VM_HEBDO=4
JOURS_RETENTION_PHOTOS_VM_MENSUEL=12

# Rétention pour Images VM
JOURS_RETENTION_IMAGES_VM_QUOTIDIEN=7
JOURS_RETENTION_IMAGES_VM_HEBDO=4
JOURS_RETENTION_IMAGES_VM_MENSUEL=12

# Rétention pour Musiques VM
JOURS_RETENTION_MUSIQUES_VM_QUOTIDIEN=7
JOURS_RETENTION_MUSIQUES_VM_HEBDO=4
JOURS_RETENTION_MUSIQUES_VM_MENSUEL=12

# Rétention pour Projets Serveur
JOURS_RETENTION_PROJETS_SERVEUR_QUOTIDIEN=7
JOURS_RETENTION_PROJETS_SERVEUR_HEBDO=4
JOURS_RETENTION_PROJETS_SERVEUR_MENSUEL=12
  
 #!/bin/bash
export LC_ALL=C

#===============================================================
# Sauvegarde des données
# Auteur : enRIKO (modifié par geole, iznobe, Watael, steph810, amélioré pour qualité irréprochable)
# Date : 2025-06-24
# Version : 6.5
# Description : Script de sauvegarde incrémentale avec validation renforcée, mode dry-run, et gestion avancée des erreurs.
#
# Changelog :
# - 6.5 (2025-06-24) :
#   - Intégration des fonctions d'erreurs avancées et des codes d'erreur spécifiques.
#   - Utilisation des chemins d'exécutables configurables depuis config.sh (CHEMIN_RSYNC, CHEMIN_SSH, etc.).
#   - Gestion améliorée de RSYNC_DELETE pour appliquer --delete conditionnellement.
#   - Correction des noms de variables de rétention (MONTAGE_SSHFS_MUSIQUES, JOURS_RETENTION_MUSIQUES_...)
#     pour correspondre à Docs Portable.
#   - Correction du nom de variable de montage pour Projets Serveur (MONTAGE_SSHFS_IMAGES).
#   - Validation initiale des chemins et des permissions critiques.
#   - Exécution des hooks PRE/POST_SAUVEGARDE_GLOBAL si configurés.
#   - Gestion du timeout Rsync.
# - 6.1 Beta (2025-06-24) :
#   - Ajout du mode --dry-run pour simuler les sauvegardes sans modification.
#   - Ajout de l'option --list pour lister les sauvegardes disponibles.
#   - Validation renforcée des variables (UUID, IP, chemins).
#   - Option rsync --delete configurable via RSYNC_DELETE.
#   - Vérification des chemins distants avant montage SSHFS.
#   - Gestion des démontages SSHFS occupés avec retries.
#   - Rapport email plus détaillé avec erreurs spécifiques.
#   - Journalisation des erreurs critiques même si les logs sont désactivés.
#===============================================================

# --- PARAMÈTRES ET OPTIONS DU SHELL ---
set -o errexit   # Quitte si une commande échoue
set -o nounset   # Traite les variables non définies comme des erreurs
set -o pipefail  # Détecte les erreurs dans les pipelines

# --- VARIABLES GLOBALES DE BASE ---
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"

# --- Source des fichiers de configuration et de fonctions ---
# C'est l'ordre crucial : config.sh d'abord pour que ses variables soient disponibles pour fonctions_erreur.sh
source "$SCRIPT_DIR/config.sh"

# Charger les sauvegardes personnalisées si le fichier existe
if [[ -f "$SCRIPT_DIR/sauvegardes_custom.conf" ]]; then
    # Filtrer les sauvegardes désactivées
    grep -v "# SAUVEGARDE_DISABLED:" "$SCRIPT_DIR/sauvegardes_custom.conf" > "/tmp/sauvegardes_active.conf"
    source "/tmp/sauvegardes_active.conf"
    rm -f "/tmp/sauvegardes_active.conf"
fi
source "$SCRIPT_DIR/fonctions_erreur.sh"

# --- FONCTION DE VÉRIFICATION DES SAUVEGARDES PAR DÉFAUT ---
# Vérifie si une sauvegarde par défaut est activée dans default_backups.conf
is_default_backup_enabled() {
    local backup_name="$1"
    local default_config="$SCRIPT_DIR/default_backups.conf"
    
    # Si le fichier n'existe pas, tout est activé par défaut
    if [[ ! -f "$default_config" ]]; then
        return 0
    fi
    
    # Vérifier si la ligne existe et est à 1
    if grep -q "^${backup_name}=1" "$default_config"; then
        return 0  # Activée
    else
        return 1  # Désactivée ou commentée
    fi
}

# --- VÉRIFICATIONS PRÉ-DÉMARRAGE ---
# Configuration pour exécution web
configure_web_environment() {
    if [[ "$(whoami)" == "www-data" ]]; then
        log_info "Configuration de l'environnement web détectée..."
        
        # Adapter les répertoires si nécessaire
        if [[ ! -w "$LOG_DIR" ]]; then
            LOG_DIR="/tmp/backup_logs"
            mkdir -p "$LOG_DIR"
            LOG_FILE="${LOG_DIR}/sauvegarde_$(date '+%Y%m%d').log"
            log_info "Logs redirigés vers: $LOG_FILE"
        fi
        
        if [[ ! -w "$DEST_BASE_SAUVEGARDES" ]]; then
            DEST_BASE_SAUVEGARDES="/tmp/backups"
            mkdir -p "$DEST_BASE_SAUVEGARDES"
            log_info "Destination adaptée vers: $DEST_BASE_SAUVEGARDES"
            
            # Recalculer tous les chemins de destination
            DEST_MAIN_DOCS_ERIC="$DEST_BASE_SAUVEGARDES/SDocumentsPcEric/"
            DEST_INCR_BASE_DOCS_ERIC="$DEST_BASE_SAUVEGARDES/incremental-SDocumentsPcEric/"
            DEST_MAIN_DOCS_FANOU="$DEST_BASE_SAUVEGARDES/SDocumentsPcFanou/"
            DEST_INCR_BASE_DOCS_FANOU="$DEST_BASE_SAUVEGARDES/incremental-SDocumentsPcFanou/"
            DEST_MAIN_DOCS_PORTABLE_FANOU="$DEST_BASE_SAUVEGARDES/SDocumentsPortableFanou/"
            DEST_INCR_BASE_DOCS_PORTABLE_FANOU="$DEST_BASE_SAUVEGARDES/incremental-SDocumentsPortableFanou/"
            DEST_MAIN_DOCS_COMMUNS="$DEST_BASE_SAUVEGARDES/SvmDocumentsCommunsVM/"
            DEST_INCR_BASE_DOCS_COMMUNS="$DEST_BASE_SAUVEGARDES/incremental-SDocumentsCommunsVM/"
            DEST_MAIN_PHOTOS="$DEST_BASE_SAUVEGARDES/SPhotosVM/"
            DEST_INCR_BASE_PHOTOS="$DEST_BASE_SAUVEGARDES/incremental-SPhotosVM/"
            DEST_MAIN_IMAGES="$DEST_BASE_SAUVEGARDES/SImagesVM/"
            DEST_INCR_BASE_IMAGES="$DEST_BASE_SAUVEGARDES/incremental-SImagesVM/"
            DEST_MAIN_MUSIQUES="$DEST_BASE_SAUVEGARDES/SMusiquesVM/"
            DEST_INCR_BASE_MUSIQUES="$DEST_BASE_SAUVEGARDES/incremental-SMusiquesVM/"
            DEST_MAIN_PROJETS="$DEST_BASE_SAUVEGARDES/SProjetsServeur/"
            DEST_INCR_BASE_PROJETS="$DEST_BASE_SAUVEGARDES/incremental-SProjetsServeur/"
        fi
        
        # Créer les points de montage SSHFS
        mkdir -p /tmp/sshfs_mounts/{docs_eric,docs_fanou,docs_portable_fanou,docs_communs_vm,photos_vm,images_vm,musiques_vm,projets_serveur}
        
        # Configurer l'environnement SSH
        export HOME="/var/www"
    fi
}

# Appeler la configuration web
configure_web_environment

# Vérifie que le répertoire de log est bien accessible en écriture
verifier_permissions_log_dir

# Initialisation de LOG_FILE avec le format journalier
# shellcheck disable=SC2154 # LOG_DIR est défini dans config.sh
LOG_FILE="${LOG_DIR}/sauvegarde_$(date '+%Y%m%d').log"

# Vérification initiale des chemins des exécutables critiques
# Ceci complète les vérifications 'command -v' des fonctions_erreur.sh
verifier_chemin_executables() {
    local exec_name
    local exec_path
    local missing_execs=0

    # shellcheck disable=SC2154 # Toutes ces variables sont définies dans config.sh
    for exec_var in CHEMIN_RSYNC CHEMIN_SSH CHEMIN_SSHFS CHEMIN_FUSEMOUNT CHEMIN_MOUNTPOINT CHEMIN_LSOF CHEMIN_KILL CHEMIN_MKDIR CHEMIN_MAIL; do
        eval "exec_path=\"\$$exec_var\"" # Récupère la valeur de la variable
        exec_name="${exec_var//CHEMIN_/}" # Extrait le nom de la commande (ex: RSYNC)

        if [[ -n "$exec_path" ]]; then # Si un chemin est explicitement défini
            if [[ ! -x "$exec_path" ]]; then
                log_error "L'exécutable configuré pour $exec_name ('$exec_path') n'existe pas ou n'est pas exécutable."
                missing_execs=$((missing_execs + 1))
            fi
        else # Si aucun chemin n'est défini, vérifie dans le PATH
            if ! command -v "$(echo "$exec_name" | tr '[:upper:]' '[:lower:]')" >/dev/null 2>&1; then
                log_error "La commande '${exec_name,,}' n'a pas été trouvée dans le PATH."
                missing_execs=$((missing_execs + 1))
            fi
        fi
    done

    if [[ "$missing_execs" -gt 0 ]]; then
        diagnostiquer_et_logger_erreur 127 "Certaines dépendances logicielles essentielles sont manquantes ou incorrectement configurées."
    fi
}
verifier_chemin_executables

# --- Initialisation des variables de suivi ---
sauvegardes_reussies=0
sauvegardes_echouees=0
nombre_sauvegardes=0
SAUVEGARDES_A_TRAITER=() # Tableau pour stocker les sélections à traiter

# --- Traitement des arguments de la ligne de commande ---
DRY_RUN=0
LIST_MODE=0

# Fonction d'affichage de l'aide
afficher_aide() {
    echo "Utilisation : $0 [--dry-run] [--list] [selection... | all]"
    echo ""
    echo "Arguments :"
    echo "  selection  : Nom d'une sauvegarde à exécuter (ex: docs_eric photos_vm)."
    echo "  all        : Exécute toutes les sauvegardes définies dans config.sh."
    echo ""
    echo "Options :"
    echo "  --dry-run  : Simule le processus de sauvegarde sans effectuer de modifications réelles."
    echo "  --list     : Affiche la liste des sélections de sauvegarde disponibles et quitte."
    echo "  --help, -h : Affiche cette aide."
    echo ""
    echo "Exemples :"
    echo "  $0 all"
    echo "  $0 docs_eric photos_vm"
    echo "  $0 --dry-run docs_eric"
    echo "  $0 --list"
    exit 0
}

# Analyse les arguments
for arg in "$@"; do
    case "$arg" in
        --dry-run)
            DRY_RUN=1
            log_info "Mode 'dry-run' activé : aucune modification ne sera effectuée."
            ;;
        --list)
            LIST_MODE=1
            ;;
        --help|-h)
            afficher_aide
            ;;
        *)
            SAUVEGARDES_A_TRAITER+=("$arg")
            ;;
    esac
done

# Si --list est activé, affiche les sélections et quitte
if [[ "$LIST_MODE" -eq 1 ]]; then
    echo "Sélections de sauvegarde disponibles :"
    echo ""
    echo "Sauvegardes par défaut :"
    for backup in docs_eric docs_fanou photos_vm projets_serveur docs_portable; do
        if is_default_backup_enabled "$backup"; then
            echo "  ✅ $backup (activée)"
        else
            echo "  ❌ $backup (désactivée)"
        fi
    done
    
    echo ""
    echo "Sauvegardes personnalisées :"
    if [[ -f "$SCRIPT_DIR/sauvegardes_custom.conf" ]]; then
        grep "# SAUVEGARDE:" "$SCRIPT_DIR/sauvegardes_custom.conf" | sed 's/# SAUVEGARDE: /  ✅ /' | sed 's/$/ (personnalisée)/'
    else
        echo "  Aucune sauvegarde personnalisée configurée"
    fi
    echo ""
    exit 0
fi

# Si aucune sélection n'est spécifiée en ligne de commande, utilise DEFAULT_SELECTIONS_SAUVEGARDES
if [[ ${#SAUVEGARDES_A_TRAITER[@]} -eq 0 ]]; then
    # shellcheck disable=SC2154 # DEFAULT_SELECTIONS_SAUVEGARDES est défini dans config.sh
    read -r -a SAUVEGARDES_A_TRAITER <<< "$DEFAULT_SELECTIONS_SAUVEGARDES"
fi

# Si "all" est spécifié, liste toutes les sauvegardes connues
if [[ " ${SAUVEGARDES_A_TRAITER[*]} " =~ " all " ]]; then
    SAUVEGARDES_A_TRAITER=(
        "docs_eric"
        "docs_fanou"
        "docs_portable_fanou" # Correction du nom de la sélection
        "docs_communs_vm"
        "photos_vm"
        "images_vm"
        "musiques_vm"
        "projets_serveur" # Correction du nom de la sélection

    )
fi


# --- FONCTIONS UTILES ---

# Fonction pour traiter les sauvegardes personnalisées
traiter_sauvegarde_personnalisee() {
    local nom_sauvegarde="$1"
    local nom_upper=$(echo "$nom_sauvegarde" | tr '[:lower:]' '[:upper:]')
    
    # Vérifier si les variables existent
    local source_locale_var="SOURCE_LOCALE_${nom_upper}"
    local source_dist_var="SOURCE_DIST_${nom_upper}"
    
    if [[ -n "${!source_locale_var:-}" ]]; then
        # Sauvegarde locale personnalisée
        log_info "Traitement de la sauvegarde locale personnalisée '$nom_sauvegarde'..."
        local dest_main_var="DEST_MAIN_${nom_upper}"
        local dest_incr_var="DEST_INCR_BASE_${nom_upper}"
        
        if effectuer_sauvegarde "locale" \
            "${!source_locale_var}" \
            "${!dest_main_var}" \
            "${!dest_incr_var}" \
            "" "" "" ""; then
            sauvegardes_reussies=$((sauvegardes_reussies + 1))
            
            # Nettoyage si configuré
            if [[ "$DRY_RUN" -eq 0 ]]; then
                local ret_q_var="JOURS_RETENTION_${nom_upper}_QUOTIDIEN"
                local ret_h_var="JOURS_RETENTION_${nom_upper}_HEBDO"
                local ret_m_var="JOURS_RETENTION_${nom_upper}_MENSUEL"
                
                if [[ "${!ret_q_var:-0}" -gt 0 || "${!ret_h_var:-0}" -gt 0 || "${!ret_m_var:-0}" -gt 0 ]]; then
                    nettoyer_anciennes_sauvegardes \
                        "${!dest_incr_var}" \
                        "${!ret_q_var:-7}" \
                        "${!ret_h_var:-4}" \
                        "${!ret_m_var:-12}"
                fi
            fi
        else
            sauvegardes_echouees=$((sauvegardes_echouees + 1))
        fi
        return 0
        
    elif [[ -n "${!source_dist_var:-}" ]]; then
        # Sauvegarde distante personnalisée
        log_info "Traitement de la sauvegarde distante personnalisée '$nom_sauvegarde'..."
        local ssh_user_var="SSH_USER_${nom_upper}"
        local ssh_ip_var="SSH_IP_${nom_upper}"
        local ssh_port_var="SSH_PORT_${nom_upper}"
        local montage_var="MONTAGE_SSHFS_${nom_upper}"
        local dest_main_var="DEST_MAIN_${nom_upper}"
        local dest_incr_var="DEST_INCR_BASE_${nom_upper}"
        
        if effectuer_sauvegarde "distante" \
            "${!source_dist_var}" \
            "${!dest_main_var}" \
            "${!dest_incr_var}" \
            "${!ssh_user_var}" \
            "${!ssh_ip_var}" \
            "${!ssh_port_var:-22}" \
            "${!montage_var}"; then
            sauvegardes_reussies=$((sauvegardes_reussies + 1))
            
            # Nettoyage si configuré
            if [[ "$DRY_RUN" -eq 0 ]]; then
                local ret_q_var="JOURS_RETENTION_${nom_upper}_QUOTIDIEN"
                local ret_h_var="JOURS_RETENTION_${nom_upper}_HEBDO"
                local ret_m_var="JOURS_RETENTION_${nom_upper}_MENSUEL"
                
                if [[ "${!ret_q_var:-0}" -gt 0 || "${!ret_h_var:-0}" -gt 0 || "${!ret_m_var:-0}" -gt 0 ]]; then
                    nettoyer_anciennes_sauvegardes \
                        "${!dest_incr_var}" \
                        "${!ret_q_var:-7}" \
                        "${!ret_h_var:-4}" \
                        "${!ret_m_var:-12}"
                fi
            fi
        else
            sauvegardes_echouees=$((sauvegardes_echouees + 1))
        fi
        return 0
    fi
    
    # Sauvegarde non trouvée
    return 1
}

# Fonction pour gérer le verrouillage du script
gerer_verrouillage() {
    # shellcheck disable=SC2154 # ACTIVERLOCK, PID_FILE sont définis dans config.sh
    if [[ "$ACTIVERLOCK" -eq 1 ]]; then
        if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
            log_error "Le script est déjà en cours d'exécution. PID : $(cat "$PID_FILE")."
            diagnostiquer_et_logger_erreur 10 "Script déjà en cours d'exécution."
        fi
        echo "$$" > "$PID_FILE"
        log_info "Fichier de verrouillage créé : $(cat "$PID_FILE")"
        trap "rm -f '$PID_FILE'; log_info 'Fichier de verrouillage supprimé.' ; exit" EXIT SIGINT SIGTERM
    fi
}

# Fonction pour envoyer le rapport par email
envoyer_rapport_email() {
    local sujet="$1"
    local corps="$2"

    # shellcheck disable=SC2154 # EMAIL_NOTIFICATION, CHEMIN_MAIL sont définis dans config.sh
    if [[ -n "$EMAIL_NOTIFICATION" ]]; then
        local mail_cmd="${CHEMIN_MAIL:-mailx}" # Utilise CHEMIN_MAIL si défini, sinon 'mailx'
        if ! command -v "$mail_cmd" >/dev/null 2>&1; then
            log_error "La commande '$mail_cmd' pour envoyer des e-mails n'a pas été trouvée. Impossible d'envoyer le rapport."
            diagnostiquer_et_logger_erreur 127 "Dépendance manquante: $mail_cmd (pour envoi d'email)."
            return 1 # Ne quitte pas complètement le script, mais signale l'échec d'envoi.
        fi
        echo "$corps" | "$mail_cmd" -s "$sujet" "$EMAIL_NOTIFICATION"
        if [[ $? -ne 0 ]]; then
            log_error "Échec de l'envoi de l'e-mail de notification. Vérifiez la configuration du MTA."
            diagnostiquer_et_logger_erreur 15 "Échec de l'envoi d'e-mail."
            return 1
        else
            log_info "Rapport envoyé par email à $EMAIL_NOTIFICATION."
            return 0
        fi
    else
        log_info "Notification par e-mail désactivée (EMAIL_NOTIFICATION non défini dans config.sh)."
        return 0
    fi
}

# Fonction pour vérifier l'espace disque
verifier_espace_disque() {
    local chemin="$1"
    local min_espace="$2" # en Go

    if [[ "$min_espace" -eq 0 ]]; then
        log_info "Vérification d'espace disque désactivée (ESPACE_DISQUE_MIN_GO=0)."
        return 0
    fi

    local espace_disque_libre
    # Utilise 'df -BG' pour obtenir l'espace en GigaBytes et extrait la valeur numérique.
    espace_disque_libre=$(df -BG "$chemin" | awk 'NR==2 {print $4}' | sed 's/G//')

    if [[ -z "$espace_disque_libre" || ! "$espace_disque_libre" =~ ^[0-9]+$ ]]; then
        log_error "Impossible de déterminer l'espace disque libre pour '$chemin'. Vérifiez le chemin ou les permissions."
        return 1 # Laisse le script continuer mais log l'erreur
    fi

    log_info "Espace disque libre sur '$chemin' : ${espace_disque_libre} Go (minimum requis : ${min_espace} Go)."

    if (( espace_disque_libre < min_espace )); then
        log_error "Espace disque insuffisant sur la destination '$chemin'. Libre: ${espace_disque_libre} Go, Requis: ${min_espace} Go."
        diagnostiquer_et_logger_erreur 4 "Espace disque insuffisant sur la destination."
    fi
    return 0
}

# Fonction pour nettoyer les anciennes sauvegardes
# Note: Cette fonction est un exemple basique et devrait être robuste.
nettoyer_anciennes_sauvegardes() {
    local base_chemin_incr="$1"
    local retention_quotidien="$2"
    local retention_hebdo="$3"
    local retention_mensuel="$4"

    log_info "Démarrage du nettoyage des anciennes sauvegardes pour $base_chemin_incr..."

    # Check if the base incremental path exists
    if [[ ! -d "$base_chemin_incr" ]]; then
        log_warning "Chemin de base incrémental '$base_chemin_incr' n'existe pas. Pas de nettoyage effectué."
        return 0
    fi

    # Supprimer les liens symboliques brisés dans 'latest' et 'current'
    find "$base_chemin_incr" -maxdepth 1 -type l ! -exec test -e {} \; -delete 2>/dev/null
    log_info "Nettoyage des liens symboliques brisés dans $base_chemin_incr effectué."

    # Suppression des sauvegardes quotidiennes (plus anciennes que $retention_quotidien jours)
    if [[ "$retention_quotidien" -gt 0 ]]; then
        # Exclure 'current', 'latest', 'weekly', 'monthly' des suppressions quotidiennes
        find "$base_chemin_incr" -maxdepth 1 -type d -name "daily-*" -mtime +"$retention_quotidien" \
            -not -path "*/current" -not -path "*/latest" \
            -exec rm -rf {} + 2>/dev/null
        log_info "Suppression des sauvegardes quotidiennes plus anciennes que $retention_quotidien jours."
    fi

    # Gestion des sauvegardes hebdomadaires
    if [[ "$retention_hebdo" -gt 0 ]]; then
        local weekly_dir="$base_chemin_incr/weekly"
        local weekly_count=$(find "$weekly_dir" -maxdepth 1 -type d -name "weekly-*" | wc -l)
        if [[ "$weekly_count" -gt "$retention_hebdo" ]]; then
            find "$weekly_dir" -maxdepth 1 -type d -name "weekly-*" | sort | head -n "$((weekly_count - retention_hebdo))" | xargs -r rm -rf 2>/dev/null
            log_info "Nettoyage des sauvegardes hebdomadaires: ${weekly_count} -> ${retention_hebdo} versions conservées."
        fi
    fi

    # Gestion des sauvegardes mensuelles
    if [[ "$retention_mensuel" -gt 0 ]]; then
        local monthly_dir="$base_chemin_incr/monthly"
        local monthly_count=$(find "$monthly_dir" -maxdepth 1 -type d -name "monthly-*" | wc -l)
        if [[ "$monthly_count" -gt "$retention_mensuel" ]]; then
            find "$monthly_dir" -maxdepth 1 -type d -name "monthly-*" | sort | head -n "$((monthly_count - retention_mensuel))" | xargs -r rm -rf 2>/dev/null
            log_info "Nettoyage des sauvegardes mensuelles: ${monthly_count} -> ${retention_mensuel} versions conservées."
        fi
    fi

    log_info "Nettoyage des anciennes sauvegardes pour $base_chemin_incr terminé."
    return 0
}

# --- FONCTION PRINCIPALE DE SAUVEGARDE ---
effectuer_sauvegarde() {
    local type_sauvegarde="$1" # "locale" ou "distante"
    local source_path="$2"
    local dest_main_path="$3"
    local dest_incr_base_path="$4" # Chemin pour les incrémentales (avec daily, weekly, monthly)
    local ssh_user="$5"
    local ssh_ip="$6"
    local ssh_port="$7"
    local montage_sshfs_point="$8" # Point de montage local pour SSHFS

    local date_courante=$(date '+%Y-%m-%d_%H%M%S')
    local dest_courante="$dest_incr_base_path/daily-${date_courante}"
    local dest_precedente="$dest_incr_base_path/current"

    log_info "Démarrage de la sauvegarde $type_sauvegarde pour '$source_path' vers '$dest_main_path'."

    # Vérification de la source
    valider_variable "Source de sauvegarde" "$source_path" "path"
    if [[ $? -ne 0 ]]; then diagnostiquer_et_logger_erreur 13 "Source invalide: $source_path"; fi

    # Vérification et création des répertoires de destination si nécessaire
    # shellcheck disable=SC2154 # CHEMIN_MKDIR est défini dans config.sh
    local mkdir_cmd="${CHEMIN_MKDIR:-mkdir}"
    if [[ ! -d "$dest_main_path" ]]; then
        log_info "Création du répertoire de destination principal : $dest_main_path"
        if ! "$mkdir_cmd" -p "$dest_main_path"; then
            log_error "Impossible de créer le répertoire de destination principal $dest_main_path."
            diagnostiquer_et_logger_erreur 12 "Échec de création du répertoire principal."
        fi
    fi

    if [[ ! -d "$dest_incr_base_path" ]]; then
        log_info "Création du répertoire de base incrémentale : $dest_incr_base_path"
        if ! "$mkdir_cmd" -p "$dest_incr_base_path"; then
            log_error "Impossible de créer le répertoire de base incrémentale $dest_incr_base_path."
            diagnostiquer_et_logger_erreur 12 "Échec de création du répertoire incrémental."
        fi
    fi

    # Vérifier l'espace disque sur la DEST_BASE_SAUVEGARDES (où sont stockées toutes les sauvegardes)
    # shellcheck disable=SC2154 # ESPACE_DISQUE_MIN_GO est défini dans config.sh
    verifier_espace_disque "$DEST_BASE_SAUVEGARDES" "$ESPACE_DISQUE_MIN_GO"

    local rsync_options="$DEFAULT_RSYNC_OPTIONS"
    # shellcheck disable=SC2154 # RSYNC_DELETE est défini dans config.sh
    if [[ "$RSYNC_DELETE" -eq 1 ]]; then
        rsync_options+=" --delete"
        log_info "Option rsync --delete activée."
    fi

    # Rsync command setup
    local rsync_cmd="${CHEMIN_RSYNC:-rsync}" # Utilise CHEMIN_RSYNC si défini, sinon 'rsync'
    if ! command -v "$rsync_cmd" >/dev/null 2>&1; then
        log_error "La commande 'rsync' (ou chemin configuré: '$CHEMIN_RSYNC') n'a pas été trouvée dans le PATH. Impossible de procéder à la sauvegarde."
        diagnostiquer_et_logger_erreur 127 "Dépendance manquante: rsync."
    fi

    local rsync_full_command=()
    local rsync_exit_code=0

    # shellcheck disable=SC2154 # DEFAULT_TYPE_CONNEXION_DISTANTE est défini dans config.sh
    if [[ "$DEFAULT_TYPE_CONNEXION_DISTANTE" -eq 0 ]]; then # Mode SSHFS
        local local_source="$source_path" #local local_source="$source_path" # Pour rsync, la source est le chemin distant MONTÉ localement.
        # Vérifie si le point de montage existe et est bien un répertoire
        valider_variable "Point de montage SSHFS" "$montage_sshfs_point" "path"
              if [[ $? -ne 0 ]]; then diagnostiquer_et_logger_erreur 13 "Point de montage SSHFS invalide: $montage_sshfs_point"; fi

        # Montage SSHFS
        monter_sshfs "$ssh_user" "$ssh_ip" "$ssh_port" "$source_path" "$montage_sshfs_point"
        local_source="$montage_sshfs_point" # La source de rsync devient le point de montage local

        # Vérifier si le point de montage est vide ou inaccessible après montage
        if ! find "$local_source" -mindepth 1 -print -quit | grep -q .; then
            log_warning "Le point de montage SSHFS '$local_source' semble vide ou inaccessible après le montage. La sauvegarde pourrait ne rien transférer."
            # Ne pas diagnostiquer comme une erreur fatale ici, car le dossier distant PEUT être vide.
            # L'erreur 13 est plus pour "source inexistante avant même de tenter un montage"
        fi

        rsync_full_command+=("$rsync_cmd")
        rsync_full_command+=("-azP") # Forcer le mode archive avec progression pour le montage local
        rsync_full_command+=("$rsync_options") # Ajoute les options par défaut, y compris les exclusions si présentes
        # shellcheck disable=SC2154 # OPTIONS_RSYNC_INCREMENTALE est défini dans config.sh
        if [[ -d "$dest_precedente" ]]; then
            rsync_full_command+=("${OPTIONS_RSYNC_INCREMENTALE:-}") # Ajoute --link-dest=../current si 'current' existe
        fi
        rsync_full_command+=("--exclude='${dest_incr_base_path##*/}/'") # Exclut le dossier incrémental lui-même si il est imbriqué

        rsync_full_command+=("$local_source/") # Source avec slash final pour synchroniser le contenu
        rsync_full_command+=("$dest_courante")

    elif [[ "$DEFAULT_TYPE_CONNEXION_DISTANTE" -eq 1 ]]; then # Mode SSH direct (rsync via SSH)
        # Vérifier la connectivité SSH et le chemin distant avant rsync
        verifier_connexion_ssh "$ssh_user" "$ssh_ip" "$ssh_port"
        verifier_chemin_distant_ssh "$ssh_user" "$ssh_ip" "$ssh_port" "$source_path"

        local ssh_cmd="${CHEMIN_SSH:-ssh}" # Utilise CHEMIN_SSH si défini, sinon 'ssh'
        # shellcheck disable=SC2154 # OPTIONS_COMMUNES_SSH, StrictHostKeyChecking_SSH sont définis dans config.sh
        local ssh_strict_host_key_opt=""
        if [[ -n "${StrictHostKeyChecking_SSH}" ]]; then
            ssh_strict_host_key_opt="-o StrictHostKeyChecking=${StrictHostKeyChecking_SSH}"
        fi
        local ssh_command_options="${OPTIONS_COMMUNES_SSH:-} ${ssh_strict_host_key_opt}"

        rsync_full_command+=("$rsync_cmd")
        rsync_full_command+=("$rsync_options") # Options par défaut
        # shellcheck disable=SC2154 # OPTIONS_RSYNC_INCREMENTALE est défini dans config.sh
        if [[ -d "$dest_precedente" ]]; then
            rsync_full_command+=("${OPTIONS_RSYNC_INCREMENTALE:-}") # Ajoute --link-dest=../current si 'current' existe
        fi
        rsync_full_command+=(-e "$ssh_cmd -p $ssh_port ${ssh_command_options}") # Spécifie SSH comme transport
        rsync_full_command+=("$ssh_user@$ssh_ip:$source_path/") # Source distante avec slash final
        rsync_full_command+=("$dest_courante")
    else # Mode local
        rsync_full_command+=("$rsync_cmd")
        rsync_full_command+=("$rsync_options") # Options par défaut
        # shellcheck disable=SC2154 # OPTIONS_RSYNC_INCREMENTALE est défini dans config.sh
        if [[ -d "$dest_precedente" ]]; then
            rsync_full_command+=("${OPTIONS_RSYNC_INCREMENTALE:-}") # Ajoute --link-dest=../current si 'current' existe
        fi
        rsync_full_command+=("$source_path/") # Source locale avec slash final
        rsync_full_command+=("$dest_courante")
    fi

    log_info "Commande Rsync à exécuter : ${rsync_full_command[*]}"

    if [[ "$DRY_RUN" -eq 1 ]]; then
        log_info "DRY-RUN: Simulation de rsync. La commande ne sera pas exécutée."
        # Simuler un succès pour le dry-run pour que le script puisse continuer et rapporter succès
        rsync_exit_code=0
    else
        # Exécution de la commande rsync avec un timeout si configuré
        # shellcheck disable=SC2154 # DELAI_OPERATION_RSYNC_SECONDES est défini dans config.sh
        if [[ "$DELAI_OPERATION_RSYNC_SECONDES" -gt 0 ]]; then
            log_info "Exécution de rsync avec un timeout de ${DELAI_OPERATION_RSYNC_SECONDES} secondes."
            timeout "${DELAI_OPERATION_RSYNC_SECONDES}s" "${rsync_full_command[@]}"
            rsync_exit_code=$?
        else
            log_info "Exécution de rsync (sans timeout)."
            "${rsync_full_command[@]}"
            rsync_exit_code=$?
        fi
    fi

    if [[ "$rsync_exit_code" -eq 0 ]]; then
        log_info "Sauvegarde réussie de '$source_path' vers '$dest_courante'."
        if [[ "$DRY_RUN" -eq 0 ]]; then
            # Mettre à jour le lien 'current' vers la nouvelle sauvegarde réussie
            rm -f "$dest_precedente" # Supprime l'ancien lien
            ln -s "${dest_courante##*/}" "$dest_precedente" # Crée le nouveau lien symbolique
            log_info "Lien 'current' mis à jour vers '$dest_courante'."
        fi
        return 0
    else
        log_error "La sauvegarde de '$source_path' a échoué avec le code de sortie rsync: $rsync_exit_code."
        diagnostiquer_et_logger_erreur 9 "Erreur rsync lors de la sauvegarde de '$source_path'. Code: $rsync_exit_code."
        return 1
    fi
}

# --- DÉBUT DU SCRIPT PRINCIPAL ---

# Gérer le verrouillage du script
gerer_verrouillage

# Exécuter le script PRE_SAUVEGARDE_GLOBAL si défini
# shellcheck disable=SC2154 # SCRIPT_PRE_SAUVEGARDE_GLOBAL est défini dans config.sh
if [[ -n "$SCRIPT_PRE_SAUVEGARDE_GLOBAL" ]]; then
    if [[ -x "$SCRIPT_PRE_SAUVEGARDE_GLOBAL" ]]; then
        log_info "Exécution du script de pré-sauvegarde global : $SCRIPT_PRE_SAUVEGARDE_GLOBAL"
        if ! "$SCRIPT_PRE_SAUVEGARDE_GLOBAL"; then
            log_warning "Le script de pré-sauvegarde global a échoué. La sauvegarde continuera."
        fi
    else
        log_warning "Le script de pré-sauvegarde global '$SCRIPT_PRE_SAUVEGARDE_GLOBAL' n'existe pas ou n'est pas exécutable."
    fi
fi

# Créer le flag de démarrage
touch /tmp/backup_running.flag
echo "$(date '+%Y-%m-%d %H:%M:%S')" > /tmp/backup_start_time.txt
echo "0" > /tmp/backup_progress.txt

log_info "=== DÉBUT DES SAUVEGARDES ==="
log_info "Sélections à traiter : ${SAUVEGARDES_A_TRAITER[*]}"

nombre_sauvegardes=${#SAUVEGARDES_A_TRAITER[@]}
current_index=0

# Boucle principale de traitement des sélections
for i in "${SAUVEGARDES_A_TRAITER[@]}"; do
    # Vérifier si c'est une sauvegarde par défaut désactivée
    case "$i" in
        docs_eric|docs_fanou|docs_portable_fanou|docs_communs_vm|photos_vm|images_vm|musiques_vm|projets_serveur)
            if ! is_default_backup_enabled "$i"; then
                log_info "Sauvegarde '$i' désactivée dans default_backups.conf, ignorée"
                continue
            fi
            ;;
    esac
    
    # Mettre à jour le statut
    echo "$i" > /tmp/current_backup.txt
    progress=$((current_index * 100 / nombre_sauvegardes))
    echo "$progress" > /tmp/backup_progress.txt
    current_index=$((current_index + 1))
    
    case "$i" in
        docs_eric)
            log_info "Traitement de la sauvegarde 'Docs Eric'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "locale" \
                "$SOURCE_LOCALE_DOCS_ERIC" \
                "$DEST_MAIN_DOCS_ERIC" \
                "$DEST_INCR_BASE_DOCS_ERIC" \
                "" "" "" ""; then # Pas de SSH pour une sauvegarde locale
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # DEFAULT_MODE_INCREMENTAL n'existe pas, utiliser la présence de DEST_INCR_BASE_DOCS_ERIC
                if [[ -n "$DEST_INCR_BASE_DOCS_ERIC" && "$DRY_RUN" -eq 0 ]]; then
                    # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                    if [[ "$JOURS_RETENTION_DOCS_ERIC_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_DOCS_ERIC_HEBDO" -gt 0 || "$JOURS_RETENTION_DOCS_ERIC_MENSUEL" -gt 0 ]]; then
                        nettoyer_anciennes_sauvegardes \
                            "$DEST_INCR_BASE_DOCS_ERIC" \
                            "$JOURS_RETENTION_DOCS_ERIC_QUOTIDIEN" \
                            "$JOURS_RETENTION_DOCS_ERIC_HEBDO" \
                            "$JOURS_RETENTION_DOCS_ERIC_MENSUEL"
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;

        docs_fanou)
            log_info "Traitement de la sauvegarde 'Docs Fanou'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "locale" \
                "$SOURCE_LOCALE_DOCS_FANOU" \
                "$DEST_MAIN_DOCS_FANOU" \
                "$DEST_INCR_BASE_DOCS_FANOU" \
                "" "" "" ""; then # Pas de SSH pour une sauvegarde locale
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # DEFAULT_MODE_INCREMENTAL n'existe pas, utiliser la présence de DEST_INCR_BASE_DOCS_FANOU
                if [[ -n "$DEST_INCR_BASE_DOCS_FANOU" && "$DRY_RUN" -eq 0 ]]; then
                    # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                    if [[ "$JOURS_RETENTION_DOCS_FANOU_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_DOCS_FANOU_HEBDO" -gt 0 || "$JOURS_RETENTION_DOCS_FANOU_MENSUEL" -gt 0 ]]; then
                        nettoyer_anciennes_sauvegardes \
                            "$DEST_INCR_BASE_DOCS_FANOU" \
                            "$JOURS_RETENTION_DOCS_FANOU_QUOTIDIEN" \
                            "$JOURS_RETENTION_DOCS_FANOU_HEBDO" \
                            "$JOURS_RETENTION_DOCS_FANOU_MENSUEL"
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;

        docs_portable_fanou) # Correction : Anciennement "musiques_portable" ou autre, maintenant "docs_portable"
            log_info "Traitement de la sauvegarde 'Docs Portable Fanou'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "distante" \
                "$SOURCE_DIST_DOCS_PORTABLE_FANOU" \
                "$DEST_MAIN_DOCS_PORTABLE_FANOU" \
                "$DEST_INCR_BASE_DOCS_PORTABLE_FANOU" \
                "$SSH_USER_DOCS_PORTABLE_FANOU" \
                "$SSH_IP_DOCS_PORTABLE_FANOU" \
                "$SSH_PORT_DOCS_PORTABLE_FANOU" \
                "$MONTAGE_SSHFS_DOCS_PORTABLE_FANOU"; then # Correction: MONTAGE_SSHFS_MUSIQUES -> MONTAGE_SSHFS_DOCS_PORTABLE
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # Utiliser la présence de DEST_INCR_BASE_DOCS_PORTABLE
                if [[ -n "$DEST_INCR_BASE_DOCS_PORTABLE_FANOU" ]]; then
                    if [[ "$DRY_RUN" -eq 0 ]]; then
                        # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                        if [[ "$JOURS_RETENTION_DOCS_PORTABLE_FANOU_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_DOCS_PORTABLE_FANOU_HEBDO" -gt 0 || "$JOURS_RETENTION_DOCS_PORTABLE_FANOU_MENSUEL" -gt 0 ]]; then
                            nettoyer_anciennes_sauvegardes \
                                "$DEST_INCR_BASE_DOCS_PORTABLE_FANOU" \
                                "$JOURS_RETENTION_DOCS_PORTABLE_FANOU_QUOTIDIEN" \
                                "$JOURS_RETENTION_DOCS_PORTABLE_FANOU_HEBDO" \
                                "$JOURS_RETENTION_DOCS_PORTABLE_FANOU_MENSUEL"
                        fi
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;
        *)
            # Tentative de traitement d'une sauvegarde personnalisée
            if traiter_sauvegarde_personnalisee "$i"; then
                log_info "Sauvegarde personnalisée '$i' traitée avec succès."
            else
                log_warning "Valeur de sélection inconnue ignorée: $i"
                diagnostiquer_et_logger_erreur 14 "Sélection de sauvegarde inconnue ou non gérée: $i."
            fi
            ;;

        docs_communs_vm) # Correction : Anciennement "musiques_portable" ou autre, maintenant "docs_portable"
            log_info "Traitement de la sauvegarde 'Docs Portable Fanou'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "distante" \
                "$SOURCE_DIST_DOCS_COMMUNS" \
                "$DEST_MAIN_DOCS_COMMUNS" \
                "$DEST_INCR_BASE_DOCS_COMMUNS" \
                "$SSH_USER_DOCS_COMMUNS" \
                "$SSH_IP_DOCS_COMMUNS" \
                "$SSH_PORT_DOCS_COMMUNS" \
                "$MONTAGE_SSHFS_DOCS_COMMUNS"; then # Correction: MONTAGE_SSHFS_MUSIQUES -> MONTAGE_SSHFS_DOCS_COMMUNS
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # Utiliser la présence de DEST_INCR_BASE_DOCS_COMMUNS
                if [[ -n "$DEST_INCR_BASE_DOCS_COMMUNS" ]]; then
                    if [[ "$DRY_RUN" -eq 0 ]]; then
                        # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                        if [[ "$JOURS_RETENTION_DOCS_COMMUNS_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_DOCS_COMMUNS_HEBDO" -gt 0 || "$JOURS_RETENTION_DOCS_COMMUNS_MENSUEL" -gt 0 ]]; then
                            nettoyer_anciennes_sauvegardes \
                                "$DEST_INCR_BASE_DOCS_COMMUNS" \
                                "$JOURS_RETENTION_DOCS_COMMUNS_QUOTIDIEN" \
                                "$JOURS_RETENTION_DOCS_COMMUNS_HEBDO" \
                                "$JOURS_RETENTION_DOCS_COMMUNS_MENSUEL"
                        fi
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;
        *)
            # Tentative de traitement d'une sauvegarde personnalisée
            if traiter_sauvegarde_personnalisee "$i"; then
                log_info "Sauvegarde personnalisée '$i' traitée avec succès."
            else
                log_warning "Valeur de sélection inconnue ignorée: $i"
                diagnostiquer_et_logger_erreur 14 "Sélection de sauvegarde inconnue ou non gérée: $i."
            fi
            ;;

        photos_vm)
            log_info "Traitement de la sauvegarde 'Photos VM'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "distante" \
                "$SOURCE_DIST_PHOTOS_VM" \
                "$DEST_MAIN_PHOTOS" \
                "$DEST_INCR_BASE_PHOTOS" \
                "$SSH_USER_PHOTOS" \
                "$SSH_IP_PHOTOS" \
                "$SSH_PORT_PHOTOS" \
                "$MONTAGE_SSHFS_PHOTOS"; then
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # DEFAULT_MODE_INCREMENTAL n'existe pas, utiliser la présence de DEST_INCR_BASE_PHOTOS
                if [[ -n "$DEST_INCR_BASE_PHOTOS" && "$DRY_RUN" -eq 0 ]]; then
                    # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                    if [[ "$JOURS_RETENTION_PHOTOS_VM_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_PHOTOS_VM_HEBDO" -gt 0 || "$JOURS_RETENTION_PHOTOS_VM_MENSUEL" -gt 0 ]]; then
                        nettoyer_anciennes_sauvegardes \
                            "$DEST_INCR_BASE_PHOTOS" \
                            "$JOURS_RETENTION_PHOTOS_VM_QUOTIDIEN" \
                            "$JOURS_RETENTION_PHOTOS_VM_HEBDO" \
                            "$JOURS_RETENTION_PHOTOS_VM_MENSUEL"
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;

        images_vm)
            log_info "Traitement de la sauvegarde 'Images VM'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "distante" \
                "$SOURCE_DIST_IMAGES_VM" \
                "$DEST_MAIN_IMAGES" \
                "$DEST_INCR_BASE_IMAGES" \
                "$SSH_USER_IMAGES" \
                "$SSH_IP_IMAGES" \
                "$SSH_PORT_IMAGES" \
                "$MONTAGE_SSHFS_IMAGES"; then
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # DEFAULT_MODE_INCREMENTAL n'existe pas, utiliser la présence de DEST_INCR_BASE_IMAGES
                if [[ -n "$DEST_INCR_BASE_IMAGES" && "$DRY_RUN" -eq 0 ]]; then
                    # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                    if [[ "$JOURS_RETENTION_IMAGES_VM_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_IMAGES_VM_HEBDO" -gt 0 || "$JOURS_RETENTION_IMAGES_VM_MENSUEL" -gt 0 ]]; then
                        nettoyer_anciennes_sauvegardes \
                            "$DEST_INCR_BASE_IMAGES" \
                            "$JOURS_RETENTION_IMAGES_VM_QUOTIDIEN" \
                            "$JOURS_RETENTION_IMAGES_VM_HEBDO" \
                            "$JOURS_RETENTION_IMAGES_VM_MENSUEL"
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;

         musiques_vm)
            log_info "Traitement de la sauvegarde 'Photos VM'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "distante" \
                "$SOURCE_DIST_MUSIQUES_VM" \
                "$DEST_MAIN_MUSIQUES" \
                "$DEST_INCR_BASE_MUSIQUES" \
                "$SSH_USER_MUSIQUES" \
                "$SSH_IP_MUSIQUES" \
                "$SSH_PORT_MUSIQUES" \
                "$MONTAGE_SSHFS_MUSIQUES"; then
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # DEFAULT_MODE_INCREMENTAL n'existe pas, utiliser la présence de DEST_INCR_BASE_MUSIQUES
                if [[ -n "$DEST_INCR_BASE_MUSIQUES" && "$DRY_RUN" -eq 0 ]]; then
                    # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                    if [[ "$JOURS_RETENTION_MUSIQUES_VM_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_MUSIQUES_VM_HEBDO" -gt 0 || "$JOURS_RETENTION_MUSIQUES_VM_MENSUEL" -gt 0 ]]; then
                        nettoyer_anciennes_sauvegardes \
                            "$DEST_INCR_BASE_MUSIQUES" \
                            "$JOURS_RETENTION_MUSIQUES_VM_QUOTIDIEN" \
                            "$JOURS_RETENTION_MUSIQUES_VM_HEBDO" \
                            "$JOURS_RETENTION_MUSIQUES_VM_MENSUEL"
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;

        projets_serveur) # Correction : Anciennement "images_serveur" ou autre, maintenant "projets_serveur"
            log_info "Traitement de la sauvegarde 'Projets Serveur'..."
            # shellcheck disable=SC2154 # Variables sont définies dans config.sh
            if effectuer_sauvegarde "distante" \
                "$SOURCE_DIST_PROJETS_SERVEUR" \
                "$DEST_MAIN_PROJETS" \
                "$DEST_INCR_BASE_PROJETS" \
                "$SSH_USER_PROJETS" \
                "$SSH_IP_PROJETS" \
                "$SSH_PORT_PROJETS" \
                "$MONTAGE_SSHFS_PROJETS"; then # Correction: MONTAGE_SSHFS_IMAGES -> MONTAGE_SSHFS_PROJETS
                sauvegardes_reussies=$((sauvegardes_reussies + 1))
                # shellcheck disable=SC2154 # DEFAULT_MODE_INCREMENTAL n'existe pas, utiliser la présence de DEST_INCR_BASE_PROJETS
                if [[ -n "$DEST_INCR_BASE_PROJETS" && "$DRY_RUN" -eq 0 ]]; then
                    # shellcheck disable=SC2154 # Jours de rétention sont définis dans config.sh
                    if [[ "$JOURS_RETENTION_PROJETS_SERVEUR_QUOTIDIEN" -gt 0 || "$JOURS_RETENTION_PROJETS_SERVEUR_HEBDO" -gt 0 || "$JOURS_RETENTION_PROJETS_SERVEUR_MENSUEL" -gt 0 ]]; then
                        nettoyer_anciennes_sauvegardes \
                            "$DEST_INCR_BASE_PROJETS" \
                            "$JOURS_RETENTION_PROJETS_SERVEUR_QUOTIDIEN" \
                            "$JOURS_RETENTION_PROJETS_SERVEUR_HEBDO" \
                            "$JOURS_RETENTION_PROJETS_SERVEUR_MENSUEL"
                    fi
                fi
            else
                sauvegardes_echouees=$((sauvegardes_echouees + 1))
            fi
            ;;

        esac
done

# --- RÉSUMÉ FINAL ---
log_info "=== FIN DES SAUVEGARDES ==="
log_info "Résumé :"
log_info "  - Sauvegardes réussies: $sauvegardes_reussies"
log_info "  - Sauvegardes échouées: $sauvegardes_echouees"
log_info "  - Total des sauvegardes traitées: $nombre_sauvegardes"

local rapport_sujet=""
local rapport_corps=""

if [[ "$sauvegardes_echouees" -eq 0 && "$nombre_sauvegardes" -gt 0 ]]; then
    rapport_sujet="[Sauvegarde RÉUSSIE] - Toutes les sauvegardes ont été effectuées."
    rapport_corps="Le script de sauvegarde a terminé avec succès.\n"
    rapport_corps+="Résumé :\n"
    rapport_corps+="- Sauvegardes réussies: $sauvegardes_reussies\n"
    rapport_corps+="- Sauvegardes échouées: $sauvegardes_echouees\n"
    rapport_corps+="- Total des sauvegardes traitées: $nombre_sauvegardes\n"
    log_info "Toutes les sauvegardes ont été effectuées avec succès."
elif [[ "$sauvegardes_echouees" -gt 0 ]]; then
    rapport_sujet="[Sauvegarde ÉCHOUÉE] - Des erreurs se sont produites lors de la sauvegarde."
    rapport_corps="Le script de sauvegarde a rencontré des erreurs.\n"
    rapport_corps+="Veuillez consulter les journaux pour plus de détails sur les erreurs spécifiques.\n"
    rapport_corps+="Résumé :\n"
    rapport_corps+="- Sauvegardes réussies: $sauvegardes_reussies\n"
    rapport_corps+="- Sauvegardes échouées: $sauvegardes_echouees\n"
    rapport_corps+="- Total des sauvegardes traitées: $nombre_sauvegardes\n"
    log_error "Des erreurs se sont produites lors de la sauvegarde. Veuillez vérifier les logs."
else
    rapport_sujet="[Sauvegarde INCOMPLÈTE] - Aucune sauvegarde n'a été traitée."
    rapport_corps="Le script de sauvegarde n'a traité aucune sélection.\n"
    rapport_corps+="Vérifiez les arguments passés au script ou DEFAULT_SELECTIONS_SAUVEGARDES dans config.sh.\n"
    log_warning "Aucune sauvegarde n'a été traitée. Vérifiez la configuration ou les arguments."
fi

# Envoyer le rapport par email
# shellcheck disable=SC2154 # EMAIL_NOTIFICATION est défini dans config.sh
if [[ -n "$EMAIL_NOTIFICATION" ]]; then
    envoyer_rapport_email "$rapport_sujet" "$rapport_corps"
fi

# Exécuter le script POST_SAUVEGARDE_GLOBAL si défini
# shellcheck disable=SC2154 # SCRIPT_POST_SAUVEGARDE_GLOBAL est défini dans config.sh
if [[ -n "$SCRIPT_POST_SAUVEGARDE_GLOBAL" ]]; then
    if [[ -x "$SCRIPT_POST_SAUVEGARDE_GLOBAL" ]]; then
        log_info "Exécution du script de post-sauvegarde global : $SCRIPT_POST_SAUVEGARDE_GLOBAL"
        if ! "$SCRIPT_POST_SAUVEGARDE_GLOBAL"; then
            log_warning "Le script de post-sauvegarde global a échoué. Le script continuera."
        fi
    else
        log_warning "Le script de post-sauvegarde global '$SCRIPT_POST_SAUVEGARDE_GLOBAL' n'existe pas ou n'est pas exécutable."
    fi
fi

# Nettoyer les fichiers de statut
rm -f /tmp/backup_running.flag /tmp/current_backup.txt /tmp/backup_progress.txt /tmp/backup_start_time.txt

# Enregistrer le résultat final
if [[ "$sauvegardes_echouees" -eq 0 ]]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Toutes les sauvegardes réussies" > /tmp/last_success.txt
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $sauvegardes_echouees sauvegarde(s) échouée(s)" > /tmp/last_error.txt
fi

log_info "Script de sauvegarde terminé."

# Si aucune erreur grave n'a été rencontrée, exit 0
if [[ "$sauvegardes_echouees" -eq 0 ]]; then
    exit 0
else
    # Si des sauvegardes ont échoué, sortir avec un code d'erreur général (par exemple 1)
    # Les erreurs spécifiques auront déjà causé un exit plus tôt. Ceci est un fallback.
    exit 1
fi
 

le shellcheck ne me renseigne pas beaucoup plus

$ shellcheck myscript
 
Line 43:
source "$SCRIPT_DIR/config.sh"
       ^-- SC1091 (info): Not following: ./config.sh was not specified as input (see shellcheck -x).
 
Line 49:
    source "/tmp/sauvegardes_active.conf"
           ^-- SC1091 (info): Not following: /tmp/sauvegardes_active.conf was not specified as input (see shellcheck -x).
 
Line 52:
source "$SCRIPT_DIR/fonctions_erreur.sh"
       ^-- SC1091 (info): Not following: ./fonctions_erreur.sh was not specified as input (see shellcheck -x).
 
Line 261:
    local nom_upper=$(echo "$nom_sauvegarde" | tr '[:lower:]' '[:upper:]')
          ^-- SC2155 (warning): Declare and assign separately to avoid masking return values.
 
Line 353:
        trap "rm -f '$PID_FILE'; log_info 'Fichier de verrouillage supprimé.' ; exit" EXIT SIGINT SIGTERM
                     ^-- SC2064 (warning): Use single quotes, otherwise this expands now rather than when signalled.
 
Line 371:
        if [[ $? -ne 0 ]]; then
              ^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
 
Line 445:
        local weekly_count=$(find "$weekly_dir" -maxdepth 1 -type d -name "weekly-*" | wc -l)
              ^-- SC2155 (warning): Declare and assign separately to avoid masking return values.
 
Line 455:
        local monthly_count=$(find "$monthly_dir" -maxdepth 1 -type d -name "monthly-*" | wc -l)
              ^-- SC2155 (warning): Declare and assign separately to avoid masking return values.
 
Line 477:
    local date_courante=$(date '+%Y-%m-%d_%H%M%S')
          ^-- SC2155 (warning): Declare and assign separately to avoid masking return values.
 
Line 485:
    if [[ $? -ne 0 ]]; then diagnostiquer_et_logger_erreur 13 "Source invalide: $source_path"; fi
          ^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
 
Line 532:
              if [[ $? -ne 0 ]]; then diagnostiquer_et_logger_erreur 13 "Point de montage SSHFS invalide: $montage_sshfs_point"; fi
                    ^-- SC2181 (style): Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
 
Line 646:
echo "$(date '+%Y-%m-%d %H:%M:%S')" > /tmp/backup_start_time.txt
     ^-- SC2005 (style): Useless echo? Instead of 'echo $(cmd)', just use 'cmd'.
 
Line 753:
        *)
        ^-- SC2221 (warning): This pattern always overrides a later one on line 763.
 
Line 763:
        docs_communs_vm) # Correction : Anciennement "musiques_portable" ou autre, maintenant "docs_portable"
        ^-- SC2222 (warning): This pattern never matches because of a previous pattern on line 753.
 
Line 792:
        *)
        ^-- SC2221 (warning): This pattern always overrides a later one on line 802.
 
Line 802:
        photos_vm)
        ^-- SC2222 (warning): This pattern never matches because of a previous pattern on line 792.
 corrigé
Line 924:
local rapport_sujet=""
^-- SC2168 (error): 'local' is only valid in functions.
 
Line 925:
local rapport_corps=""
^-- SC2168 (error): 'local' is only valid in functions.

Dernière modification par eric63 (Le 11/07/2025, à 16:14)


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#332 Le 02/08/2025, à 10:25

O_20_100_O

Re : script d’automatisation sauvegardes

aucune avancée sur le problème

Salut, en as-tu fini avec ces sauvegardes ?

Hors ligne

#333 Le 02/08/2025, à 10:58

eric63

Re : script d’automatisation sauvegardes

Non malheureusement je suis complètement bloqué . Rien ne fonctionne comme prévu et j’ai du en faire quelques une de plus car mon disque 8T à subit quelques modifications involontaires de ma part roll

kubu@kubu-System-Product-Name:/media/kubu$ ls -la
total 16
drwxr-x---+  4 kubu kubu        4096 août   2 10:06 .
drwxr-xr-x   8 root root        4096 avril 23 12:31 ..
drwxrwxr-x   3 kubu kubu        4096 juil. 18 16:25 JEUX8T
drwxrwxrwx  40 4242 nas-freebox 4096 juil. 25 17:59 JEUX8T1
kubu@kubu-System-Product-Name:/media/kubu$ 

les droits et utilisateur et groupe de JEUX8T1 ne me semble pas correct
donc JEUX8T/SAUVEGARDES/ se retrouve avec les dossiers vides qui sont conformes aux sauvegardes demandées par le script 6.5 de steph810
et
JEUX8T1 est le nouveau point de montage de mon disque 8T qui contient bien le dossier /SAUVEGARDES/ et tous les dossiers vides pour l’instant des dossiers de sauvegardes que je veux avoir (sauf incrementalSMusiquesOld qui est pourri)

kubu@kubu-System-Product-Name:/media/kubu/JEUX8T1/SAUVEGARDES$ ls -la
total 52
drwxrwxr-x 12 kubu kubu        4096 juil.  9 19:08 .
drwxrwxrwx 40 4242 nas-freebox 4096 juil. 25 17:59 ..
-rw-------  1 kubu kubu          34 juin  18 10:35 .directory
drwxrwxr-x  2 kubu kubu        4096 juil.  9 19:08 DocumentsEric
drwxrwxr-x  2 kubu kubu        4096 juil.  9 19:08 incremental-DocumentsEric
drwxrwxr-x  3 kubu kubu        4096 juin  21 23:00 incremental-SMusiquesOld
drwxrwxr-x  2 kubu kubu        4096 juin  21 23:55 SDocumentsCommunsVM
drwxrwxr-x  2 kubu kubu        4096 juin  21 23:55 SDocumentsPcEric
drwxrwxr-x  2 kubu kubu        4096 juin  26 09:11 SDocumentsPcFanou
drwxrwxr-x  2 kubu kubu        4096 juin  26 09:10 SDocumentsPortableFanou
drwxrwxr-x  2 kubu kubu        4096 juin  22 10:43 SImagesVM
drwxrwxr-x  2 kubu kubu        4096 juin  22 10:42 SMusiquesVM
drwxrwxr-x  2 kubu kubu        4096 juin  22 10:42 SPhotosVM
kubu@kubu-System-Product-Name:/media/kubu/JEUX8T1/SAUVEGARDES$ 

les droits et utilisateur et groupe de JEUX8T1 ne me semble pas correct non plus à ce niveau

je n’y est pas touché depuis de peur de faire une connerie de plus
et j’aimerais continuer sur le script de steph810 qui possède me semble t il tout ce que je souhaite

Mais il faut que je fasse fonctionner cette interface Backup Manager - Dasboard qui ne lance pas mes sauvegardes donc il y a un bug quelque part dans les scripts de config.sg ou sauvegarde.sh,
les log dans tmp ne fonctionnent pas et n’existe pas ??  et j’ai des blocages qui me disent que je n’ai pas les droits pour valider la sauvegarde
Je sais plus trop ou chercher pour améliorer ça sad

Dernière modification par eric63 (Le 02/08/2025, à 10:59)


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#334 Le 02/08/2025, à 11:33

O_20_100_O

Re : script d’automatisation sauvegardes

Ah, d'accord, alors bon courage pour la suite. Il me semble que c'est l'été dernier que vous avez perdu quelques données de Mme. Mais tu as certainement au moins une bonne sauvegarde faite simplement "à la main".

Je sais plus trop ou chercher pour améliorer ça

Le temps finira par améliorer les choses. Il a fallu 2000 ans après l'invention de la roue pour que quelqu'un pense à l'évider smile

La roue fut d'abord inventée en basse Mésopotamie (l'Irak actuel) par les Sumériens, au cours du 4e millénaire avant notre ère, en perçant un disque de bois pour y placer un axe de rotation. Il faut attendre 2000 av. JC pour que le disque soit évidé pour alléger la roue.

https://www.citeco.fr/10000-ans-histoir … de-la-roue

Hors ligne

#335 Le 02/08/2025, à 11:50

eric63

Re : script d’automatisation sauvegardes

Merci de vous moquer gentiment de moi mais la roue fut complètement inutile au Pérou car la géologie n’était pas la plus adapté pour découvrir cela, en Amazonie et autres lieux aquatiques, le bateau fut bien plus profitable.


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#336 Le 02/08/2025, à 15:24

O_20_100_O

Re : script d’automatisation sauvegardes

moquer gentiment

Oui, c'est tout à fait cela.
Pas très positif, mais vu ton objectif, pas possible de faire mieux.

Mais ta réponse montre que l'on l'on peut atteindre le même but, le transport, par des moyens différents : chariot, barque, traîneau ...

Pour ton projet de transport de données vers un disque externe, tu pourrais envisager un autre moyen de transport cool

Hors ligne

#337 Hier à 01:40

krodelabestiole

Re : script d’automatisation sauvegardes

si tu veux un coup de main pour mettre le #313 (!) en place, ou autre plan détaillé, claire, logique et sensée, je suis ok pour t'aider dans la mesure du possible.
le reste à base de rédaction de script sans poser clairement les choses en amont me semble juste être une perte de temps et d'énergie malheureusement (comme déjà dit, mais j'ai peur que ce soit de plus en plus évident).

Hors ligne

#338 Hier à 11:34

eric63

Re : script d’automatisation sauvegardes

Vous me demander de changer mon modèle de sauvegarde ?? désolé mais je capte pas grand chose du #313 qui me semble autrement plus obscur que la proposition que je suis.
Qu’est ce qui vous chagrine tant dans le modèle que je suis actuellement qui soit si problématique ?,
mis à part que je me plante sûrement dans mes droits de dossiers et que vous ne voulez pas en discuter
voir #329 #330 #331 au début de cette page et le lien vers le site
Je suis cette voie parce qu’elle poursuit ma façon de voir les choses depuis que steph810 est intervenu, me semble claire, assez «simple»: 2 scripts principaux config.sh et sauvegarde.sh, une interface web, que je peux y mettre mes dossiers sources et destinations aux endroits que j’ai choisis et comme j’ai choisi , qui me guide dans ce que je veux faire.
Il y a des trucs que je n’appréhende pas dans l’installation des fichiers ou le fonctionnement de l’interface web puisqu’ au final les sauvegardes ne fonctionnent pas.
même les plus basiques: sauvegarder mon dossier Documents de mon PC vers la VM ou vers le disque8T/SAUVEGARDES
Mais je me dis que je fais juste mal les choses et que ce n’est pas le programme proposé par steph810 qui est en cause sauf si vous y voyez de gros problèmes
Mais visiblement personne ne veut s’engager à résoudre ce problème ( et c’est votre droit ) sauf à me proposer d’autres alternatives.

Mais c’est pas ma demande pour l’instant .
Je veux juste savoir pourquoi cette interface web peut me créer des dossiers aux bons endroits corrects mais vides et que les dossiers de log dans /tmp soient inaccessibles ??


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#339 Hier à 15:30

O_20_100_O

Re : script d’automatisation sauvegardes

eric63 a écrit :

vous ne voulez pas en discuter ... Il y a des trucs que je n’appréhende pas dans l’installation des fichiers ou le fonctionnement de l’interface web puisqu’ au final les sauvegardes ne fonctionnent pas ... Je veux juste savoir pourquoi cette interface web peut me créer des dossiers aux bons endroits corrects mais vides

Tu conviendras que pour t'aider à utiliser cet outil, le mieux placé est celui qui l'a créé et qui te le conseille.
Le fait qu'il ne réponde pas est peut-être lié à une absence temporaire. Mais si c'est parce qu'il est passé à autre chose, c'est tant mieux pour toi.
Autant constater tout de suite à quel point tu dépends d'une seule personne pour faire tes sauvegardes. Alors qu'il existe plusieurs outils bien maintenus et documentés, très utilisés dans le monde entier.

Hors ligne

#340 Hier à 22:06

eric63

Re : script d’automatisation sauvegardes

OUI je suis conscient de tout cela
et je comprend aussi que les vacances ne sont pas le plus approprié pour avoir des retours.
On verra en septembre si rien n’a bougé je regarderais autre chose mais je suis patient


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#341 Aujourd'hui à 03:14

krodelabestiole

Re : script d’automatisation sauvegardes

eric63 a écrit :

Vous me demander de changer mon modèle de sauvegarde ?? désolé mais je capte pas grand chose du #313 qui me semble autrement plus obscur que la proposition que je suis.

ça m'étonne un peu : de ton point de vue, des chemins tels que
192.168.1.128:/home/VMMultimédias/VMMultimediasCommuns/VMDocumentsPerso//VMSauvegardesDocumentsFanou
ou
/media/kubu/JEUX8T/SAUVEGARDES/SPhotos/SauvegardesDocumentsPartages
seraient beaucoup plus simples ou lisibles (et moins sujets aux erreurs, par ex.) que ce que je te propose en 313 :
/mnt/8T/backup/home/$USER pour le plus long...
c'est bien vrai ?

j'avais été interloqué précédemment par le choix qui avait été fait de te faire développer en bash, me demandant jusqu'où ça irait je ne m'attendais pas à ce qu'on te propose de déployer un serveur lamp, avec apache et php depuis les dépôts (pas pour nextcloud, donc, mais pour de la sauvegarde standard, détail à ne pas oublier...)

je suis surpris que tu te lances dans l'administration web alors que tu prétends ne pas comprendre ce qui est écrit en #313...
si tu ne comprends pas ce qui est écrit, à cause par exemple d'un vocabulaire trop technique, tu peux demander, plein de monde ici sera en mesure de te l'expliquer.
mais si en en comprennant les termes tu ne comprends cette idée et sa logique : "réserver le disque dur pour des sauvegardes et la freebox pour des partages", ou que tu la trouves obscure ou trop technique, je ne crois malheureusement pas à ta capacité à mettre en place ton projet. dans ce cas il vaudrait mieux demander à quelqu'un de déployer un système de sauvegardes à ta place.


eric63 a écrit :

et je comprend aussi que les vacances ne sont pas le plus approprié pour avoir des retours.
On verra en septembre si rien n’a bougé je regarderais autre chose mais je suis patient

oui, si malgré ces quelques milliers de messages, et quelques dizaines d'intervenants (... qui ont souvent exprimé ne plus souhaiter participer), la bonne route pour sauvegarder te semble être de bricoler du bash, apache et php avec ces chemins à rallonge dispersés sur plusieurs supports, je suppose que ce n'est pas bien urgent (mais je trouve quand-même ça un peu inquiétant, s'agissant de sauvegarde).

Hors ligne

#342 Aujourd'hui à 09:32

eric63

Re : script d’automatisation sauvegardes

ça m'étonne un peu : de ton point de vue, des chemins tels que
192.168.1.128:/home/VMMultimédias/VMMultimediasCommuns/VMDocumentsPerso//VMSauvegardesDocumentsFanou
ou
/media/kubu/JEUX8T/SAUVEGARDES/SPhotos/SauvegardesDocumentsPartages
seraient beaucoup plus simples ou lisibles (et moins sujets aux erreurs, par ex.) que ce que je te propose en 313 :
/mnt/8T/backup/home/$USER pour le plus long...
c'est bien vrai ?

mes lignes ne sont pas aussi longues que tu les écrits
chez moi c’est au pire pour la plus longue dans le 8T: 
/media/kubu/JEUX8T/SAUVEGARDES/SDocumentsCommunsVM
ou /media/kubu/JEUX8T/SAUVEGARDES/SDocumentsPcEric
au pire pour la plus longue dans la VM
/home/kubu/VMMultimedias/SDocumentsCommunsVM
chaque sauvegarde est détaillée je sais d’où ça vient et où ça va et ce que c‘est: sauvegarde ou dossier
«/media/kubu/JEUX8T/SAUVEGARDES/» le chemin destination de la sauvegarde; S:pour sauvegarde; DocumentsCommuns:le nom du dossier; VM:origine de la source
Moi ça me parle ça vraiment; même si on peut simplifier et regrouper les chemins comme tu le fait,

d’ailleurs dans le script config.sh c’est ce qui est fait on regroupe /media/kubu/JEUX8T/SAUVEGARDES sous une variable et /home/kubu/VMMultimedias/ sous une autre variable que je n’ai pas encore intégré vu que la sauvegarde vers le 8T ne fonctionne pas pour l’instant.
si je bloque c’est déjà au niveau de la sauvegarde la plus simple mon dossier Document vers mon 8T
je n’arrive pas à voir ce qui ne va pas à ce niveau donc pour les autres sauvegarde ça peut pas être mieux. une pierre à la fois


Kubuntu 25.04 wayland Plasma 6.4.3 KDE Qt 6.8.3 noyau 6.14.0-24 Asus B760+D4 i5-12400F 4.4Ghz DDR4 32Go nvidia RTX 3060 12GB
Utilisez les drivers libres avant d’ installer une brother avec le script demonipuch
J’utilise le clavier LDLC AFNOR

En ligne

#343 Aujourd'hui à 13:45

krodelabestiole

Re : script d’automatisation sauvegardes

c'est pourtant ce que j'ai compris de ton message #291 !

eric63 a écrit :

sur la VM Multimédias@192.168.1.128:/home
/VMMultimédias
                          /VMMultimediasCommuns
                                                                     /VMDocumentsPerso/VMSauvegardesDocumentsEric
                                                                     /VMDocumentsPerso//VMSauvegardesDocumentsFanou
                                                                     /VMPhotos (stock)
                                                                     /VMImages (stock) 
                                                                     /VMMusiques (stock)
                                                                     /VMDocumentsPartages (stock)
                                                                     /VMSauvegardesDocumentsPartages

sur le 8T /media/kubu/JEUX8T/
/SAUVEGARDES/SPhotos
                            /SImages
                            /SMusiques
                            /SauvegardesDocumentsPartages

Est ce clair pour vous ??

à moins que l'indentation soit "accidentelle" ? (mais dans ce cas je comprends encore moins...)

Hors ligne

#344 Aujourd'hui à 14:00

krodelabestiole

Re : script d’automatisation sauvegardes

eric63 a écrit :

une pierre à la fois

ok mais sans plan d'architecte on fait des pâtés de sable.
et vu le plan en 291 ça me semble dans tous les cas être un édifice sacrément biscornu. je serais très étonné qu'il tienne debout un jour (en dehors du fait qu'il semble ne pas prendre forme du tout, et encore moins en autonomie).

Hors ligne

#345 Aujourd'hui à 15:26

iznobe

Re : script d’automatisation sauvegardes

Bonjour , allez , vu que ca n' a pas bougé d' un pouce depuis que je n ' ai plus mis le nez dans cette discussion je remet ma couche perso .
l ' organisation de l' arborescence des noms de dossiers que tu as choisis porte plus que clairement à confusion .
c' est la source de tous les problemes ( discussion qui n' avance pas , plan pas etabli clairement , script qui ne fonctionne pas .... ) :

eric63 a écrit :

sur la VM Multimédias@192.168.1.128:/home
/VMMultimédias
                          /VMMultimediasCommuns
                                                                     /VMDocumentsPerso/VMSauvegardesDocumentsEric
                                                                     /VMDocumentsPerso//VMSauvegardesDocumentsFanou
                                                                     /VMPhotos (stock)
                                                                     /VMImages (stock)
                                                                     /VMMusiques (stock)
                                                                     /VMDocumentsPartages (stock)
                                                                     /VMSauvegardesDocumentsPartages

une arborescence " correcte " selon moi devrait etre de la sorte si un seul utilisateur nommé " VM "

/home/VM
/home/VM/communs
/home/VM/communs/photos
/home/VM/communs/documents
/home/VM/communs/etc...

/home/VM/fanou/photos
/home/VM/fanou/documents
/home/VM/fanou/etc...

/home/VM/eric/photos
/home/VM/eric/documents
/home/VM/eric/etc...

et pour sauvegarder, :

rsync ... VM      dans dossier  sauvegarde

au passage mettre une etiquette " JEUX8T " pour y mettre des sauvegardes , ça rejoint exactement ce que tu fais depuis le début ... des noms de dossiers qui ne correspondent pas a leur contenu respectif ...ce qui rend impossible la comprehension du contenu des dossiers et quasi impossible la comprehension du script , et carrément impossible le débogage de celui-ci !
une etiquette " 8T " serait mieux appropriée comme point de montage .
Ensuite , tu crées un dossier :
JEUX et SAUVEGARDES .
tant que tu ne changeras pas les noms de dossiers pour un truc clair et approprié , et bien ca pataugera .


le truc etant le plus simple , tu met tout en vrac dans le dossier correspondant : :/home/VMMultimédias .
plus de soucis , puisque le nom est adapté pour ça .


D ' autre part , tu dois etre capable de maintenir et de modifier toi-meme un script que tu utilises .
ce qui n' a pas l ' air d' etre le cas du tout ...
je me demande comment tu feras , le jour où , pour une raison " X " , tu devras te repencher dessus pour ajouter un dossier a sauvegarder ou quoi que ce soit d' autre ...

Dernière modification par iznobe (Aujourd'hui à 15:39)


retour COMPLET et utilisable de commande  |  script montage partitions

MSI Z490A-pro , i7 10700 , 32 GB RAM .

Hors ligne

#346 Aujourd'hui à 17:54

krodelabestiole

Re : script d’automatisation sauvegardes

@iznobe :
tu as lu le #313 ?
c'est la structure que je mettrais en place. ça me semble assez simple et lisible, et j'ai essayé d'expliquer chaque choix.

dommage que eric63 trouve ça obscur, ça m'étonne.
malheureusement si c'est le cas je pense qu'on ne s'en sortira vraiment jamais ! dans ce cas je regrette cette perte de temps perso.

Hors ligne

#347 Aujourd'hui à 18:08

krodelabestiole

Re : script d’automatisation sauvegardes

mais quand-même !
voir conseiller de partir sur une install de lamp, après et par dessus les bricolages bash, pour que quelqu'un qui a du mal à se dépatouiller avec la simple organisation et la gestion de ses fichiers et répertoires puisse mettre en place une simple solution de sauvegarde, ça me donne l'impression d'assister à un sketch.
visiblement plus la solution est tordue, de bas niveau et inadaptée, plus on va sauter dessus. un peu comme conseiller à un débutant d'utiliser kali linux pour de la bureautique : j'imagine que ça fait bien. c'est vrai que ça fait savant, mais ça n'apprend à personne à pêcher.
tout le monde a besoin de sauvegardes, pour peu qu'on ait un vie numérique. heureusement qu'il y a des solutions plus simples et adaptées.

Hors ligne

#348 Aujourd'hui à 18:11

iznobe

Re : script d’automatisation sauvegardes

krodelabestiole a écrit :

@iznobe :
tu as lu le #313 ?
c'est la structure que je mettrais en place. ça me semble assez simple et lisible.

je n' avais pas lu ton message .

c' est ce que je ferais ( a peu de chose prés ) si c' était pour moi . je l' avais déjà dis , il y a bien longtemps ...
chacun son home + un répertoire commun .

On est donc sur la même logique .



Mon dernier message est une arborescence proposée dans le cadre d ' un seul et unique utilisateur ( ce que semble vouloir mettre en place eric63 ) , ce qui simplifie au niveau des permissions et que je peux comprendre ( mais que je ne conseille pas ). Dans ce cas là , la technique , c' est de simplement créé un dossier par utilisateur ( + commun ) dans le seul home existant de la VM , afin de " reproduire des homes utilisateurs séparés " qui contiennent leur dossier usuels ( documents , videos , musique et tout ce qu ' on veut d' autre ) .
il pourrait aussi y ajouter un dossier sauvegarde .

on aurait alors comme base d' arborescence :

/home/VM/fanou
/home/VM/eric
/home/VM/commun
/home/VM/sauvegarde

dans lesquels il suffira de mettre des dossiers appropriés avec des noms qui decrivent correctement leur contenu respectif ... comme photos , etc ...


retour COMPLET et utilisable de commande  |  script montage partitions

MSI Z490A-pro , i7 10700 , 32 GB RAM .

Hors ligne