-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.bash
More file actions
294 lines (260 loc) · 10.3 KB
/
script.bash
File metadata and controls
294 lines (260 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/bash
# ==============================================================================
# CONFIGURATION DES LOGS
# ==============================================================================
LOG_FILE="backup_$(date +%Y%m%d).log"
# 1. Vérifier si on utilise bien Bash (nécessaire pour la redirection complexe)
if [ -z "$BASH_VERSION" ]; then
echo "ERREUR : Ce script doit être exécuté avec bash (ex: bash script.sh)"
exit 1
fi
# 2. Créer/Initialiser le fichier log immédiatement pour vérifier les droits
touch "$LOG_FILE" || { echo "Erreur : Impossible de créer le fichier log"; exit 1; }
# 3. Redirection globale vers le log et le terminal
# On utilise une fonction de nettoyage pour fermer proprement le log à la fin
# Fonction pour ajouter au corps du mail
add_log() {
MAIL_BODY+="$1\n"
}
# Fonction de finalisation : logs + envoi mail
cleanup() {
echo "$(date '+%Y-%m-%d %H:%M:%S') === Fin du script (Arrêt propre) ==="
# Envoi du mail de notification
local subject
subject="[Backup][$BACKUP_STATUS] ${ARCHIVE_NAME:-no-archive} $(date +'%Y-%m-%d %H:%M')"
local body
body="Status: $BACKUP_STATUS\n$(printf "%b" "$MAIL_BODY")"
if [ -z "$MAIL_TO" ]; then
echo "⚠ MAIL_TO not set - cannot send mail"
else
# Envoi avec msmtp et pièce jointe encodée en MIME
local boundary="----=_Part_$(date +%s)_$$"
{
echo "To: $MAIL_TO"
echo "Subject: $subject"
echo "MIME-Version: 1.0"
echo "Content-Type: multipart/mixed; boundary=\"$boundary\""
echo ""
echo "--$boundary"
echo "Content-Type: text/plain; charset=utf-8"
echo ""
printf "%b" "$body"
echo ""
if [ -f "$LOG_FILE" ]; then
echo "--$boundary"
echo "Content-Type: text/plain; name=\"$(basename "$LOG_FILE")\""
echo "Content-Transfer-Encoding: base64"
echo "Content-Disposition: attachment; filename=\"$(basename "$LOG_FILE")\""
echo ""
base64 "$LOG_FILE"
fi
echo "--$boundary--"
} | msmtp "$MAIL_TO" 2>/dev/null || echo "⚠ Échec envoi mail"
fi
}
trap cleanup EXIT
# Lancement de la redirection
exec > >(while read -r line; do echo "$(date '+%Y-%m-%d %H:%M:%S') $line" | tee -a "$LOG_FILE"; done) 2>&1
echo "=== Initialisation du script ==="
echo "Fichier log créé avec succès : $LOG_FILE"
# ==============================================================================
# CHARGEMENT DE LA CONFIGURATION
# ==============================================================================
# Charger la configuration depuis script.conf
CONFIG_FILE="./script.conf"
if [ -f "$CONFIG_FILE" ]; then
. "$CONFIG_FILE"
echo "Chargé: $CONFIG_FILE"
else
echo "⚠ ERREUR: Fichier de configuration $CONFIG_FILE introuvable"
exit 1
fi
# Variables internes (ne pas modifier)
URL="$URL1"
BACKUP_STATUS="unknown"
MAIL_BODY=""
echo "=== Début du script de téléchargement et transfert ==="
echo "Journalisation active dans : $LOG_FILE"
# 1. Vérifier que l'URL existe
echo "1. Vérification de l'URL..."
echo " Tentative avec URL1: $URL1"
if timeout 15 wget --spider --no-check-certificate "$URL1" 2>&1 | grep -q "200 OK"; then
echo "✓ URL1 accessible"
URL="$URL1"
else
echo "⚠ URL1 non accessible, tentative avec URL2: $URL2"
if wget --spider --no-check-certificate "$URL2" 2>&1 | grep -q "200 OK"; then
echo "✓ URL2 accessible"
URL="$URL2"
else
echo "✗ ERREUR CRITIQUE: Aucune URL n'est accessible"
BACKUP_STATUS="error"
add_log "ERROR: Aucune URL accessible"
exit 1
fi
fi
add_log "URL sélectionnée: $URL"
# Adapter les noms de fichiers selon l'URL utilisée
if [ "$URL" = "$URL1" ]; then
SQL_FILE="test100.sql"
BACKUP_FILE="test100_backup.sql"
ARCHIVE_PREFIX="test100"
else
SQL_FILE="world-db/world.sql"
BACKUP_FILE="world_backup.sql"
ARCHIVE_PREFIX="world"
fi
# 2. Télécharger le fichier .zip
echo "2. Téléchargement du fichier .zip..."
wget --no-check-certificate "$URL" -O "$ZIP_FILE" 2>&1
if [ $? -eq 0 ] && [ -f "$ZIP_FILE" ] && [ -s "$ZIP_FILE" ]; then
echo "✓ Fichier .zip téléchargé avec succès ($(du -h "$ZIP_FILE" | cut -f1))"
add_log "Téléchargement réussi: $(du -h "$ZIP_FILE" | cut -f1)"
else
echo "✗ ERREUR: Échec du téléchargement du zip"
BACKUP_STATUS="error"
add_log "ERROR: Échec du téléchargement du zip"
exit 1
fi
# 3. Vérifier le contenu du .zip
echo "3. Vérification du contenu du .zip..."
SQL_BASENAME="$(basename "$SQL_FILE")"
if unzip -l "$ZIP_FILE" | grep -q "$SQL_BASENAME"; then
echo "✓ Le fichier $SQL_BASENAME est présent dans l'archive"
else
echo "✗ ERREUR: Le fichier $SQL_BASENAME n'est pas présent dans l'archive"
BACKUP_STATUS="error"
add_log "ERROR: Le fichier $SQL_BASENAME n'est pas présent dans l'archive"
rm -f "$ZIP_FILE"
exit 1
fi
# 4. Extraire le fichier SQL
echo "4. Extraction du fichier SQL..."
unzip -o -q "$ZIP_FILE"
if [ -f "$SQL_FILE" ] && [ -s "$SQL_FILE" ]; then
echo "✓ Extraction réussie: $(du -h "$SQL_FILE" | cut -f1)"
add_log "Extraction réussie: $(du -h "$SQL_FILE" | cut -f1)"
else
echo "✗ ERREUR: Extraction échouée ou fichier vide"
BACKUP_STATUS="error"
add_log "ERROR: Extraction échouée ou fichier vide"
rm -f "$ZIP_FILE"
exit 1
fi
# 5. Comparaison avec la dernière version présente sur le serveur
echo "5. Comparaison avec la version du serveur..."
CURRENT_SQL="$SQL_FILE"
[ "$URL" = "$URL2" ] && CURRENT_SQL="world-db/world.sql"
# On cherche le nom de l'archive la plus récente sur le serveur via SSH
# (On utilise 'ls -t' pour trier par date et 'head -1' pour prendre le premier)
LATEST_REMOTE=$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$SFTP_USER@$SFTP_HOST" \
"ls -t $SFTP_REMOTE_DIR/${ARCHIVE_PREFIX}-*.tar.gz 2>/dev/null | head -n 1")
if [ -n "$LATEST_REMOTE" ]; then
echo "✓ Archive trouvée sur le serveur : $(basename "$LATEST_REMOTE")"
echo " Téléchargement pour comparaison..."
# On télécharge l'archive distante dans un fichier temporaire
TEMP_REMOTE="remote_check.tar.gz"
scp "$SFTP_USER@$SFTP_HOST:$LATEST_REMOTE" "$TEMP_REMOTE" >/dev/null 2>&1
# On extrait le contenu de cette archive distante dans un dossier temporaire
mkdir -p ./temp_compare
tar -xzf "$TEMP_REMOTE" -C ./temp_compare
# Identification du fichier SQL extrait (il peut s'appeler différemment selon l'URL)
REMOTE_SQL_EXTRACTED="./temp_compare/$(basename "$SQL_FILE")"
# Comparaison réelle
if cmp -s "$CURRENT_SQL" "$REMOTE_SQL_EXTRACTED"; then
echo "✓ Le fichier est identique à la version déjà présente sur le serveur - arrêt."
rm -rf "$TEMP_REMOTE" ./temp_compare "$ZIP_FILE"
exit 0
else
echo "✓ Le fichier local est différent de la version du serveur."
fi
# Nettoyage des fichiers de comparaison
rm -rf "$TEMP_REMOTE" ./temp_compare
else
echo "✓ Aucune archive correspondante sur le serveur - première publication."
fi
# 6. Création de l'archive .tgz
echo "6. Création de l'archive .tgz..."
ARCHIVE_NAME="${ARCHIVE_PREFIX}-$(date +%Y%m%d-%H%M%S).tar.gz"
if [ "$URL" = "$URL2" ]; then
tar -czf "$ARCHIVE_NAME" -C "world-db" "world.sql"
else
tar -czf "$ARCHIVE_NAME" "$SQL_FILE"
fi
if [ $? -eq 0 ] && [ -f "$ARCHIVE_NAME" ]; then
echo "✓ Archive créée: $ARCHIVE_NAME"
add_log "Archive créée: $ARCHIVE_NAME"
else
echo "✗ ERREUR: Échec création archive"
BACKUP_STATUS="error"
add_log "ERROR: Échec création archive"
exit 1
fi
# 7. Test SFTP
echo "7. Test de connexion SFTP..."
if sftp -o ConnectTimeout=10 -o BatchMode=no "$SFTP_USER@$SFTP_HOST" <<EOF 2>&1 | grep -q "sftp>"; then
pwd
bye
EOF
echo "✓ Connexion SFTP établie"
add_log "Connexion SFTP établie"
else
echo "✗ ERREUR: Connexion SFTP impossible"
BACKUP_STATUS="error"
add_log "ERROR: Connexion SFTP impossible"
exit 1
fi
# 8. Transfert
echo "8. Transfert via SFTP..."
sftp "$SFTP_USER@$SFTP_HOST" <<EOF
cd $SFTP_REMOTE_DIR
put $ARCHIVE_NAME
bye
EOF
if [ $? -eq 0 ]; then
echo "✓ Transfert SFTP réussi"
add_log "Transfert SFTP réussi: $ARCHIVE_NAME -> $SFTP_HOST:$SFTP_REMOTE_DIR"
# 9. Vérification distante [cite: 19]
echo "9. Vérification sur le serveur distant..."
if sftp "$SFTP_USER@$SFTP_HOST" <<EOF 2>&1 | grep -q "$ARCHIVE_NAME"; then
cd $SFTP_REMOTE_DIR
ls -l $ARCHIVE_NAME
bye
EOF
echo "✓ Fichier confirmé sur le serveur"
add_log "Fichier confirmé sur le serveur: $ARCHIVE_NAME"
# 10. Historisation (Épuration)
if [ "$HISTORISATION_ENABLED" = "true" ]; then
echo "10. Nettoyage des archives (Rétention: $RETENTION_DAYS jours)"
if ! echo "$RETENTION_DAYS" | grep -Eq '^[0-9]+$'; then
echo "⚠ Erreur: RETENTION_DAYS n'est pas un nombre"
elif ssh -o BatchMode=yes -o ConnectTimeout=10 "$SFTP_USER@$SFTP_HOST" "echo 2>&1" >/dev/null 2>&1; then
DELETED_LIST=$(ssh "$SFTP_USER@$SFTP_HOST" "find '$SFTP_REMOTE_DIR' -maxdepth 1 -type f -name '${ARCHIVE_PREFIX}-*.tar.gz' -mtime +$RETENTION_DAYS -print -delete" 2>/dev/null)
if [ -n "$DELETED_LIST" ]; then
echo "✓ Fichiers supprimés :"
echo "$DELETED_LIST"
else
echo "✓ Aucun fichier à supprimer"
fi
else
echo "⚠ SSH non disponible pour le nettoyage"
fi
fi
# Mise à jour backup local et nettoyage
[ "$URL" = "$URL2" ] && cp "world-db/world.sql" "$BACKUP_FILE" || cp "$SQL_FILE" "$BACKUP_FILE"
rm -f "$ZIP_FILE"
BACKUP_STATUS="success"
add_log "Backup succeeded: $ARCHIVE_NAME transferred to $SFTP_HOST:$SFTP_REMOTE_DIR"
echo "=== Script terminé avec succès ==="
else
echo "✗ ERREUR: Transfert invisible sur le serveur"
BACKUP_STATUS="error"
add_log "ERROR: Transfert invisible sur le serveur"
exit 1
fi
else
echo "✗ ERREUR: Échec du transfert SFTP"
BACKUP_STATUS="error"
add_log "ERROR: Échec du transfert SFTP"
exit 1
fi