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

Arborescence suggérée

/opt/rsync_sync/
├─ config.sh
├─ transfert_rsync.sh
├─ validation_hash.sh
└─ logs/  # dossier pour logs et rapports

1️⃣ Fichier de configuration : config.sh

#!/bin/bash
# /opt/rsync_sync/config.sh

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

# Répertoire unique de destination sur le serveur B
DST="/chemin/destination_sur_B/"

# Options rsync
RSYNC_OPTS="-avz --partial --progress --bwlimit=50000"

# Répertoires sources sur le serveur A
DIRS_TO_COPY=("/var/data" "/var/data2")

# Logs et erreurs
LOG_DIR="/opt/rsync_sync/logs"
mkdir -p "$LOG_DIR"
ERROR_FILE="/opt/rsync_sync/errors.txt"
HASH_FILE="$LOG_DIR/rsync_hashes_$(date +%F).txt"

# Fenêtre de transfert (vendredi 18h → lundi 08h)
RSYNC_START=$(date -d "Fri 18:00" +%s)
RSYNC_END=$(date -d "Mon 08:00" +%s)

# Fenêtre de validation hash (lundi 08h01 → vendredi 17h59)
VALIDATION_START=$(date -d "Mon 08:01" +%s)
VALIDATION_END=$(date -d "Fri 17:59" +%s)

# Destinataires email (optionnel)
EMAIL_TO="admin@example.com"

2️⃣ Script transfert rsync : transfert_rsync.sh

#!/bin/bash
# /opt/rsync_sync/transfert_rsync.sh
source /opt/rsync_sync/config.sh

LOG_FILE="$LOG_DIR/rsync_transfer_$(date +%F).log"
echo "==== DÉBUT TRANSFERT $(date) ====" >> "$LOG_FILE"

for src_dir in "${DIRS_TO_COPY[@]}"; do
    # 1. Reprise des fichiers en erreur
    if [ -f "$ERROR_FILE" ] && [ -s "$ERROR_FILE" ]; then
        rsync $RSYNC_OPTS -e "ssh $RSYNC_SSH_OPTS" --files-from="$ERROR_FILE" "$RSYNC_USER@$RSYNC_HOST:$src_dir/" "$DST" >> "$LOG_FILE" 2>&1
        > "$ERROR_FILE"
    fi

    # 2. Transfert principal
    rsync $RSYNC_OPTS -e "ssh $RSYNC_SSH_OPTS" "$RSYNC_USER@$RSYNC_HOST:$src_dir/" "$DST" >> "$LOG_FILE" 2>&1

    # 3. Ajouter les fichiers copiés à la liste pour validation
    ssh $RSYNC_SSH_OPTS "$RSYNC_USER@$RSYNC_HOST" "find $src_dir -type f" >> "$HASH_FILE"
done

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

# Optionnel : envoyer notification email
if [ -n "$EMAIL_TO" ]; then
    mail -s "Rsync terminé $(date)" "$EMAIL_TO" < "$LOG_FILE"
fi

3️⃣ Script validation hash : validation_hash.sh

#!/bin/bash
source /opt/rsync_sync/config.sh

REPORT_JSON="$LOG_DIR/rsync_report_$(date +%F).json"
REPORT_TABLE="$LOG_DIR/rsync_report_$(date +%F).txt"
HASH_FILES="$LOG_DIR/rsync_hashes_*.txt"

# Initialisation compteurs
TOTAL_COPIED=$(grep "^>" "$LOG_DIR/rsync_transfer_*.log" | wc -l)
> "$ERROR_FILE"

echo "==== DÉBUT VALIDATION $(date) ====" > "$REPORT_TABLE"
echo "RAPPORT DE VALIDATION RSYNC" >> "$REPORT_TABLE"
echo "==============================" >> "$REPORT_TABLE"

echo "{" > "$REPORT_JSON"
echo '  "date": "'$(date +%F)'",' >> "$REPORT_JSON"
echo '  "total_copied": '"$TOTAL_COPIED"',' >> "$REPORT_JSON"
echo '  "errors": [' >> "$REPORT_JSON"

validate_file() {
    local file="$1"
    SRC_HASH=$(ssh -i "$RSYNC_SSH_KEY" user@serveurA "sha256sum '$file'" | awk '{print $1}')
    DST_HASH=$(sha256sum "$DST/$file" 2>/dev/null | awk '{print $1}')
    if [ "$SRC_HASH" != "$DST_HASH" ]; then
        echo "$file" >> "$ERROR_FILE"
        echo "ERREUR: $file" >> "$REPORT_TABLE"
        echo '    {"file":"'"$file"'"}' >> "$REPORT_JSON"
    fi
}

for hf in $HASH_FILES; do
    while read -r file; do
        if [ $(date +%s) -ge $VALIDATION_END ]; then
            echo "Fin de la fenêtre de validation."
            break 2
        fi
        validate_file "$file"
    done < "$hf"
done

# Clôture JSON
echo "  ]" >> "$REPORT_JSON"
echo "}" >> "$REPORT_JSON"

# Informations supplémentaires
TOTAL_ERRORS=$(wc -l < "$ERROR_FILE")
TOTAL_SIZE=$(du -sh "$DST" | awk '{print $1}')
START_TIME=$(date -d "$(head -1 "$LOG_DIR/rsync_transfer_*.log")" +%s)
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

# Tableau lisible
{
echo "Date: $(date)"
echo "Total fichiers copiés: $TOTAL_COPIED"
echo "Total fichiers en erreur: $TOTAL_ERRORS"
echo "Taille totale copiée: $TOTAL_SIZE"
echo "Durée du transfert: $DURATION secondes"
} >> "$REPORT_TABLE"

# Email avec les deux rapports
mailx -s "$MAIL_SUBJECT" -a "$REPORT_JSON" -a "$REPORT_TABLE" "$EMAIL_TO" < <(echo "Rapport Rsync attaché")

4️⃣ Workflow visuel avec fenêtres horaires

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

5️⃣ Systemd Services et Timers

a) Service rsync : /etc/systemd/system/rsync_transfer.service

[Unit]
Description=Transfert rsync du serveur A vers B

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

b) Timer rsync : /etc/systemd/system/rsync_transfer.timer

[Unit]
Description=Timer pour lancer rsync chaque weekend

[Timer]
OnCalendar=Fri 18:00
Persistent=true

[Install]
WantedBy=timers.target

c) Service validation hash : /etc/systemd/system/rsync_validation.service

[Unit]
Description=Validation hash Rsync

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

d) Timer validation hash : /etc/systemd/system/rsync_validation.timer

[Unit]
Description=Timer validation hash Rsync

[Timer]
OnCalendar=Mon 08:01
Persistent=true

[Install]
WantedBy=timers.target

e) Activer les timers

sudo systemctl daemon-reload
sudo systemctl enable --now rsync_transfer.timer
sudo systemctl enable --now rsync_validation.timer

Crontab

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

  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)

  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

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