Il y a 389 articles et 19 utilisateurs inscrits (ce bandeau est défini dans MediaWiki:Sitenotice)

Script rsync avec copie sur période définies et rapports JSON

De AJLSM
Aller à la navigation Aller à la recherche
  • Transfert rsync avec authentification SSH par clé
  • Fenêtres horaires :
  • Rsync : vendredi 18h → lundi 08h
  • Validation hash : lundi 08h01 → vendredi 17h59
  • Reprise automatique des fichiers en erreur
  • Rapports enrichis JSON + tableau lisible
  • Notifications email à plusieurs destinataires
  • Compatible Systemd Timer pour planification automatique

Tout se passe depuis le serveur de destination (B) :

1 - Transfert Rsync ===

  • Script transfert_rsync.sh exécuté sur B.
  • Se connecte via SSH sur le serveur source (A) pour récupérer les fichiers.
  • Copie les fichiers dans $DST sur B.

2 - Validation Hash

[modifier | modifier le wikicode]
  • Script validation_hash.sh exécuté sur B.
  • Compare les fichiers copiés sur B avec ceux du serveur source A via SSH (hash SHA256).
  • Liste les erreurs/fichiers manquants pour reprise.

3 - Gestion des erreurs et rapports

[modifier | modifier le wikicode]
  • Tous les logs, fichiers d’erreurs, rapports JSON et tableaux lisibles sont générés localement sur B.
  • Emails de notification envoyés depuis B.

Donc, le serveur source (A) n’exécute aucun script, il fournit uniquement l’accès SSH pour lire les fichiers.

Arborescence suggérée

[modifier | modifier le wikicode]
/opt/rsync_sync/
├── config.sh
├── transfert_rsync.sh
├── validation_hash.sh
├── logs/
└── reports/

1️⃣ Fichier de configuration : config.sh

[modifier | modifier le wikicode]

Il contient toutes les configurations centrales :

  • Authentification SSH par clé
  • Répertoires sources et destination
  • Options rsync
  • Répertoires de logs et rapports
  • Fichier d’erreurs et fichier hash pour validation
  • Paramètres email (multi-destinataires)
  • Fenêtres horaires (pour documentation / usage)
#!/bin/bash
# =========================
# Configuration globale
# =========================

<syntaxhighlight lang="bash">| Option               | Description                                                                |                                             |
| :------------------- | :------------------------------------------------------------------------- | ------------------------------------------- |
| `-a`                 | Mode archive (permissions, dates, liens, etc.)                             |                                             |
| `-v`                 | Verbose – utile pour les logs                                              |                                             |
| `-z`                 | Active la compression pendant le transfert                                 |                                             |
| `--compress-level=3` | Niveau de compression modéré (équilibre vitesse / CPU)                     |                                             |
| `--partial`          | Reprise possible en cas d’interruption                                     |                                             |
| `--progress`         | Affiche l’avancement détaillé                                              |                                             |
| `--human-readable`   | Affiche les tailles lisibles                                               |                                             |
| `--stats`            | Statistiques détaillées à la fin du transfert                              |                                             |
| `--out-format='%i    | %n'`                                                                       | Indispensable pour les rapports et le suivi |
| `--delete-after`     | Supprime les fichiers obsolètes **à la fin** du transfert                  |                                             |
| `--timeout=600`      | Reconnexion automatique après 10 min d’inactivité                          |                                             |
| `--inplace`          | Réécrit directement les fichiers existants (gagne du temps et de l’espace) |                                             |
| `--safe-links`       | Ignore les liens symboliques potentiellement dangereux                     |                                             |
  1. --- Authentification SSH ---

RSYNC_USER="user" RSYNC_HOST="serveurA" RSYNC_SSH_OPTS="-i ~/.ssh/rsync_key -p 22"

  1. --- Répertoires ---

DIRS_TO_COPY=("/var/data" "/var/data2") # Répertoires sources sur A DST="/data/replication" # Répertoire unique sur B

  1. --- Options Rsync ---

RSYNC_OPTS="-avz --partial --progress --delete --human-readable --stats --bwlimit=50000"

  1. --- Fichiers & Dossiers internes ---

LOG_DIR="/opt/rsync_sync/logs" REPORT_DIR="/opt/rsync_sync/reports" mkdir -p "$LOG_DIR" "$REPORT_DIR" ERROR_FILE="$LOG_DIR/errors.txt" HASH_FILE="$LOG_DIR/rsync_hashes_$(date +%F).txt"

  1. --- Notifications ---

EMAIL_TO=("admin1@example.com" "admin2@example.com") EMAIL_SUBJECT_PREFIX="[SYNC SERVEUR A → B]" MAIL_CMD="mail" # ou sendmail, selon l’environnement

  1. --- Fenêtres horaires (documentation pour les scripts) ---

RSYNC_START="Fri 18:00" RSYNC_END="Mon 08:00" VALIDATION_START="Mon 08:01" VALIDATION_END="Fri 17:59"

</syntaxhighlight>

2️⃣ Script transfert rsync : transfert_rsync.sh

[modifier | modifier le wikicode]

Cette version intègre :

✅ Authentification SSH par clé
✅ Copie de plusieurs répertoires fusionnés dans un seul dossier destination
✅ Reprise automatique des erreurs
✅ Rapports détaillés (JSON + tableau lisible + logs complets)
✅ Notifications e-mail multi-destinataires
✅ Compatible avec la planification systemd.timer (vendredi 18h → lundi 8h)
| Catégorie           | Description                                                |
| ------------------- | ---------------------------------------------------------- |
| 🔐 Authentification | SSH par clé privée (sécurisée `chmod 600`)                 |
| 📦 Sources          | `/var/data` et `/var/data2` fusionnés dans `$DST`          |
| 🔁 Reprise          | Automatique via `errors.txt` et fichiers listés en erreur  |
| 🕒 Fenêtre horaire  | Planifiée via `rsync_sync.timer` (ven 18h → lun 8h)        |
| 🧾 Rapports         | JSON + tableau lisible + logs complets                     |
| 🧮 Statistiques     | Comptage précis (sources, transférés, erreurs, reprises)   |
| 📧 Email            | Multi-destinataires avec résumé clair et alerte si erreurs |
| 🪶 Organisation     | `logs/` et `reports/` bien séparés                         |
| ⚙️ Compatibilité    | 100 % Systemd Timer                                        |
#!/bin/bash
# ===============================================
# TRANSFERT RSYNC SERVEUR A → SERVEUR B
# Objectif :
# - Transférer les fichiers sources depuis A vers B
# - Gérer la reprise automatique des erreurs
# - Générer des rapports JSON + tableau clair
# - Notifier par e-mail les résultats
# ===============================================

source /opt/rsync_sync/config.sh

DATE_TAG=$(date +%F_%H-%M)
LOG_FILE="$LOG_DIR/rsync_transfer_$DATE_TAG.log"
JSON_REPORT="$REPORT_DIR/rsync_report_$DATE_TAG.json"
TABLE_REPORT="$REPORT_DIR/rsync_summary_$DATE_TAG.txt"

echo "==== DÉBUT TRANSFERT $(date) ====" >> "$LOG_FILE"

# --------------------------
# Initialisation des compteurs
# --------------------------
declare -A STATS=(["sources"]=0 ["transferred"]=0 ["errors"]=0 ["retried"]=0)
ERROR_DETAILS="$LOG_DIR/rsync_errors_$DATE_TAG.txt"
> "$ERROR_DETAILS"

# --------------------------
# Boucle sur les répertoires à transférer
# --------------------------
for src_dir in "${DIRS_TO_COPY[@]}"; do
    ((STATS["sources"]++))
    echo "[INFO] Transfert de $src_dir → $DST" >> "$LOG_FILE"

    # 1️⃣ Reprise des erreurs précédentes
    if [ -s "$ERROR_FILE" ]; then
        echo "[INFO] Reprise des erreurs précédentes listées dans $ERROR_FILE" >> "$LOG_FILE"
        rsync_output=$(rsync $RSYNC_OPTS -e "ssh $RSYNC_SSH_OPTS" --files-from="$ERROR_FILE" \
            "$RSYNC_USER@$RSYNC_HOST:$src_dir/" "$DST" 2>&1)
        echo "$rsync_output" >> "$LOG_FILE"

        retried_count=$(echo "$rsync_output" | grep -c '^>')
        STATS["retried"]=$((STATS["retried"] + retried_count))
        > "$ERROR_FILE"
    fi

    # 2️⃣ Transfert principal
    echo "[INFO] Lancement transfert principal depuis $src_dir" >> "$LOG_FILE"
    rsync_output=$(rsync $RSYNC_OPTS -e "ssh $RSYNC_SSH_OPTS" \
        "$RSYNC_USER@$RSYNC_HOST:$src_dir/" "$DST" 2>&1)
    echo "$rsync_output" >> "$LOG_FILE"

    transferred_count=$(echo "$rsync_output" | grep -c '^>')
    error_count=$(echo "$rsync_output" | grep -c 'rsync error')

    STATS["transferred"]=$((STATS["transferred"] + transferred_count))
    STATS["errors"]=$((STATS["errors"] + error_count))

    # 3️⃣ Liste des fichiers transférés pour la validation future
    ssh $RSYNC_SSH_OPTS "$RSYNC_USER@$RSYNC_HOST" "find $src_dir -type f" >> "$HASH_FILE"

    # 4️⃣ Log et rapport des erreurs
    if [ "$error_count" -gt 0 ]; then
        echo "[ERREUR] $error_count erreurs détectées sur $src_dir" >> "$ERROR_DETAILS"
    fi
done

echo "==== FIN TRANSFERT $(date) ====" >> "$LOG_FILE"

# --------------------------
# Génération du rapport JSON
# --------------------------
cat > "$JSON_REPORT" <<EOF
{
  "date": "$(date)",
  "sources": "${DIRS_TO_COPY[*]}",
  "destination": "$DST",
  "stats": {
    "sources_count": ${STATS["sources"]},
    "files_transferred": ${STATS["transferred"]},
    "files_retried": ${STATS["retried"]},
    "errors": ${STATS["errors"]}
  },
  "log_file": "$LOG_FILE",
  "error_details": "$ERROR_DETAILS"
}
EOF

# --------------------------
# Génération du tableau lisible
# --------------------------
cat > "$TABLE_REPORT" <<EOF
===========================
   RAPPORT DE TRANSFERT RSYNC
===========================
Date : $(date)
Sources : ${DIRS_TO_COPY[*]}
Destination : $DST
--------------------------------
Répertoires traités     : ${STATS["sources"]}
Fichiers transférés     : ${STATS["transferred"]}
Reprises d'erreurs       : ${STATS["retried"]}
Erreurs détectées        : ${STATS["errors"]}
--------------------------------
Logs détaillés           : $LOG_FILE
Rapport JSON             : $JSON_REPORT
--------------------------------
EOF

# --------------------------
# Rapport résumé clair dans les logs
# --------------------------
{
  echo "RÉSUMÉ DU TRANSFERT"
  echo "---------------------"
  echo "Répertoires traités : ${STATS["sources"]}"
  echo "Fichiers transférés : ${STATS["transferred"]}"
  echo "Reprises effectuées : ${STATS["retried"]}"
  echo "Erreurs détectées   : ${STATS["errors"]}"
  echo "---------------------"
} >> "$LOG_FILE"

# --------------------------
# Notifications email
# --------------------------
if [ "${#EMAIL_TO[@]}" -gt 0 ]; then
  for mail in "${EMAIL_TO[@]}"; do
    {
      echo -e "Sujet : $EMAIL_SUBJECT_PREFIX Transfert Rsync - $(date)"
      echo
      cat "$TABLE_REPORT"
      if [ "${STATS["errors"]}" -gt 0 ]; then
        echo
        echo "⚠️  Des erreurs Rsync ont été détectées. Voir :"
        echo "   $ERROR_DETAILS"
      fi
    } | $MAIL_CMD -s "$EMAIL_SUBJECT_PREFIX Transfert Rsync - $(date)" "$mail"
  done
fi

exit 0

3️⃣ Script validation hash : validation_hash.sh

[modifier | modifier le wikicode]
| Catégorie        | Description                                                                                   |
| ---------------- | --------------------------------------------------------------------------------------------- |
| 🔐 Sécurité      | SSH par clé privée (`~/.ssh/rsync_key`, chmod 600)                                            |
| 🧮 Validation    | Hash SHA256 pour chaque fichier transféré                                                     |
| 🕒 Période       | Lundi 08h01 → Vendredi 17h59 (pilotée par `systemd timer`)                                    |
| 🔁 Reprise       | Fichiers en erreur ajoutés à `errors.txt` pour reprise automatique au prochain transfert      |
| 🧾 Rapports      | `JSON_REPORT` (machine-lisible) + `TABLE_REPORT` (lisible humain) + `LOG_FILE` détaillé       |
| 📧 Notifications | Multi-destinataires (`EMAIL_TO` dans `config.sh`) avec résumé clair et alerte en cas d’erreur |
| 📂 Organisation  | Tous les fichiers regroupés dans `/opt/rsync_sync/logs/` et `/opt/rsync_sync/reports/`        |
| ⚙️ Compatibilité | Directement exécutable par le `validation_hash.service` déclenché via `systemd.timer`         |
#!/bin/bash
# ===============================================
# VALIDATION HASH SERVEUR A → SERVEUR B
# Objectif :
# - Vérifier l’intégrité des fichiers transférés
# - Identifier les erreurs de hash ou fichiers manquants
# - Générer un rapport JSON + tableau clair
# - Envoyer notifications email multi-destinataires
# ===============================================

source /opt/rsync_sync/config.sh

DATE_TAG=$(date +%F_%H-%M)
LOG_FILE="$LOG_DIR/validation_$DATE_TAG.log"
JSON_REPORT="$REPORT_DIR/validation_report_$DATE_TAG.json"
TABLE_REPORT="$REPORT_DIR/validation_summary_$DATE_TAG.txt"

echo "==== DÉBUT VALIDATION HASH $(date) ====" >> "$LOG_FILE"

# --------------------------
# Initialisation des compteurs
# --------------------------
declare -A HASH_STATS=(["checked"]=0 ["ok"]=0 ["errors"]=0 ["missing"]=0)
ERROR_DETAILS="$LOG_DIR/validation_errors_$DATE_TAG.txt"
> "$ERROR_DETAILS"

# --------------------------
# Boucle de validation
# --------------------------
while read -r file; do
    # Calcul du hash source distant
    src_hash=$(ssh $RSYNC_SSH_OPTS "$RSYNC_USER@$RSYNC_HOST" "sha256sum '$file' 2>/dev/null" | awk '{print $1}')
    dest_file="$DST/$(basename "$file")"

    if [ -f "$dest_file" ]; then
        dest_hash=$(sha256sum "$dest_file" | awk '{print $1}')
        if [ "$src_hash" == "$dest_hash" ] && [ -n "$src_hash" ]; then
            ((HASH_STATS["ok"]++))
        else
            ((HASH_STATS["errors"]++))
            echo "$file" >> "$ERROR_FILE"
            echo "[HASH ERROR] $file" >> "$LOG_FILE"
            echo "[HASH ERROR] $file" >> "$ERROR_DETAILS"
        fi
    else
        ((HASH_STATS["missing"]++))
        echo "$file" >> "$ERROR_FILE"
        echo "[MISSING] $file" >> "$LOG_FILE"
        echo "[MISSING] $file" >> "$ERROR_DETAILS"
    fi

    ((HASH_STATS["checked"]++))
done < "$HASH_FILE"

echo "==== FIN VALIDATION HASH $(date) ====" >> "$LOG_FILE"

# --------------------------
# Génération du rapport JSON
# --------------------------
cat > "$JSON_REPORT" <<EOF
{
  "date": "$(date)",
  "stats": {
    "files_checked": ${HASH_STATS["checked"]},
    "hash_ok": ${HASH_STATS["ok"]},
    "hash_errors": ${HASH_STATS["errors"]},
    "missing_files": ${HASH_STATS["missing"]}
  },
  "log_file": "$LOG_FILE",
  "errors_file": "$ERROR_DETAILS",
  "error_list_file": "$ERROR_FILE"
}
EOF

# --------------------------
# Génération du tableau lisible
# --------------------------
cat > "$TABLE_REPORT" <<EOF
==============================
  VALIDATION HASH - SYNTHÈSE
==============================
Date : $(date)
--------------------------------
Fichiers vérifiés     : ${HASH_STATS["checked"]}
Conformes (hash OK)   : ${HASH_STATS["ok"]}
Erreurs de hash        : ${HASH_STATS["errors"]}
Fichiers manquants     : ${HASH_STATS["missing"]}
--------------------------------
Logs détaillés         : $LOG_FILE
Erreurs détaillées     : $ERROR_DETAILS
Rapport JSON           : $JSON_REPORT
--------------------------------
EOF

# --------------------------
# Rapport résumé clair dans les logs
# --------------------------
{
  echo "RÉSUMÉ VALIDATION HASH"
  echo "------------------------"
  echo "Total vérifiés : ${HASH_STATS["checked"]}"
  echo "OK : ${HASH_STATS["ok"]}"
  echo "Erreurs : ${HASH_STATS["errors"]}"
  echo "Manquants : ${HASH_STATS["missing"]}"
  echo "------------------------"
} >> "$LOG_FILE"

# --------------------------
# Notifications email
# --------------------------
if [ "${#EMAIL_TO[@]}" -gt 0 ]; then
  for mail in "${EMAIL_TO[@]}"; do
    {
      echo -e "Sujet : $EMAIL_SUBJECT_PREFIX Validation Hash - $(date)"
      echo
      cat "$TABLE_REPORT"
      if [ "${HASH_STATS["errors"]}" -gt 0 ] || [ "${HASH_STATS["missing"]}" -gt 0 ]; then
        echo
        echo "⚠️  Des erreurs ont été détectées. Voir détails dans :"
        echo "   $ERROR_DETAILS"
      fi
    } | $MAIL_CMD -s "$EMAIL_SUBJECT_PREFIX Validation Hash - $(date)" "$mail"
  done
fi

exit 0

4️⃣ Workflow visuel avec fenêtres horaires

[modifier | modifier le wikicode]
Vendredi 18h                  Lundi 08h01                 Vendredi 17h59
+-----------------------------+---------------------------+
|                             |                           |
|     TRANSFERT RSYNC         |   VALIDATION HASH         |
|  (reprise erreurs + copie)  |   (fichiers copiés)      |
|                             |                           |
+-----------------------------+---------------------------+

Cycle :
- Les fichiers en erreur sont ajoutés à errors.txt
- Week-end suivant, rsync reprend les erreurs en priorité
- Transfert incrémental pour nouveaux fichiers
- Validation hash continue en semaine

Ordonnancement

[modifier | modifier le wikicode]

5️⃣ Systemd Services et Timers

[modifier | modifier le wikicode]

1️⃣ Rsync Transfer Service

[modifier | modifier le wikicode]

Service rsync : /etc/systemd/system/rsync_sync.service

[Unit]
Description=Transfert Rsync serveur A → B
After=network.target

[Service]
Type=oneshot
ExecStart=/opt/rsync_sync/transfert_rsync.sh
User=root

Timer rsync : /etc/systemd/system/rsync_sync.timer

[Unit]
Description=Planification Transfert Rsync (Ven 18h → Lun 08h)

[Timer]
# Début vendredi 18h
OnCalendar=Fri 18:00
# Persistant pour lancer le transfert même si l'heure est passée
Persistent=true

[Install]
WantedBy=timers.target

2️⃣ Validation Hash Service

[modifier | modifier le wikicode]

Service validation hash : /etc/systemd/system/validation_hash.service

[Unit]
Description=Validation Hash serveur A → B
After=network.target

[Service]
Type=oneshot
ExecStart=/opt/rsync_sync/validation_hash.sh
User=root

Timer validation hash : /etc/systemd/system/validation_hash.timer

[Unit]
Description=Planification Validation Hash (Lun 08h01 → Ven 17h59)

[Timer]
# Début lundi 08h01
OnCalendar=Mon 08:01
Persistent=true

[Install]
WantedBy=timers.target

e) Activer les timers

[modifier | modifier le wikicode]
sudo systemctl daemon-reload

# Activer et démarrer Rsync timer
sudo systemctl enable --now rsync_sync.timer

# Activer et démarrer Validation Hash timer
sudo systemctl enable --now validation_hash.timer

# Vérification des timers actifs
systemctl list-timers | grep rsync_sync
systemctl list-timers | grep validation_hash

Notes importantes

[modifier | modifier le wikicode]
  • User=root : à adapter pour exécuter les scripts avec un utilisateur non privilégié.
  • Les timers ne définissent que l’heure de départ. Les scripts eux-mêmes gèrent le traitement complet (reprise, logs, hash).
  • Persistent=true permet de lancer le job si le serveur était éteint au moment prévu.
  • Les logs et rapports se trouvent dans /opt/rsync_sync/logs et /opt/rsync_sync/reports.

1️⃣ Planification rsync via cron (vendredi 18h → lundi 08h)

[modifier | modifier le wikicode]
  1. Ouvrir le crontab pour l’utilisateur qui exécute le script :
    crontab -e
    
  2. Ajouter la ligne suivante pour lancer le transfert vendredi 18h :
    0 18 * * 5 /opt/rsync_sync/transfert_rsync.sh
    
    0 18 * * 5 → vendredi à 18h00
  3. Ajouter une ligne optionnelle pour assurer le démarrage lundi 08h (au cas où le transfert serait interrompu ou pour reprise) :
    0 8 * * 1 /opt/rsync_sync/transfert_rsync.sh
    
    0 8 * * 1 → lundi 08h00

Les scripts incluent déjà un contrôle de fin de fenêtre (RSYNC_END) pour arrêter le transfert lundi 08h00.

2️⃣ Planification validation hash via cron (lundi 08h01 → vendredi 17h59)

[modifier | modifier le wikicode]
  1. Toujours dans le crontab :
    1 8 * * 1 /opt/rsync_sync/validation_hash.sh
    
    Lancement lundi 08h01
  2. Optionnel : relancer la validation toutes les heures pendant la semaine, pour traiter les fichiers par lots si nécessaire :
    0 9-17 * * 1-5 /opt/rsync_sync/validation_hash.sh
    
    De 9h à 17h du lundi au vendredi, toutes les heures. Le script s’arrête automatiquement si la fenêtre VALIDATION_END (vendredi 17h59) est dépassée

3️⃣ Avantages de cette version cron

[modifier | modifier le wikicode]

Compatible tous serveurs Linux/Unix

  • Même logique que Systemd :
  • Reprise automatique des erreurs
  • Fenêtres horaires respectées
  • Rapports JSON + tableau lisible
  • Notifications email

Facile à tester sans redémarrer le daemon systemd