Last active 1730124638

btrfs-backup.sh Raw
1#!/usr/bin/env bash
2
3# Config
4SOURCE="/home"
5LOCAL_DEST="/snapshots"
6DEST="/run/media/mathieu/ext_ssd/backups"
7KEEP_LOCAL=10 # Nombre de snapshots locaux à conserver
8KEEP_DISTANT=31 # Nombre de snapshots distant à conserver
9DATE=$(date +"%Y-%m-%d_%H-%M-%S")
10SNAPSHOT_NAME="$DATE"
11LAST_RUN_FILE="$DEST/.last_run"
12LAST_SNAPSHOT_FILE="$DEST/.last_snapshot"
13
14get_age_days() {
15 local file=$1
16 local file_time=$(date -r "$file" +%s)
17 local current_time=$(date +%s)
18 echo $(((current_time - file_time) / 86400))
19}
20
21if ! mountpoint -q "$DEST/.."; then
22 echo "Erreur: Le disque externe n'est pas monté sur $DEST"
23 exit 1
24fi
25
26# Vérifier la dernière exécution
27if [ -f "$LAST_RUN_FILE" ]; then
28 last_run=$(cat "$LAST_RUN_FILE")
29 days_since_last_run=$((($(date +%s) - $(date -d "$last_run" +%s)) / 86400))
30 if [ $days_since_last_run -gt 7 ]; then
31 echo "Attention: $days_since_last_run jours se sont écoulés depuis la dernière sauvegarde."
32 fi
33else
34 echo "Première exécution détectée."
35fi
36
37# Créer un nouveau snapshot en lecture seule de /home
38if sudo btrfs subvolume snapshot -r "$SOURCE" "$LOCAL_DEST/$SNAPSHOT_NAME"; then
39 echo "Snapshot local créé avec succès: $LOCAL_DEST/$SNAPSHOT_NAME"
40else
41 echo "Erreur lors de la création du snapshot local"
42 exit 1
43fi
44
45# Envoyer le snapshot vers la destination
46if [ -f "$LAST_SNAPSHOT_FILE" ]; then
47 last_snapshot=$(cat "$LAST_SNAPSHOT_FILE")
48 if [ -d "$LOCAL_DEST/$last_snapshot" ]; then
49 echo "Envoi d'un snapshot incrémentiel..."
50 if sudo btrfs send -p "$LOCAL_DEST/$last_snapshot" "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs receive "$DEST"; then
51 echo "Snapshot incrémental envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
52 else
53 echo "Erreur lors de l'envoi du snapshot incrémentiel. Tentative d'envoi complet..."
54 if sudo btrfs send "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs receive "$DEST"; then
55 echo "Snapshot complet envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
56 else
57 echo "Erreur lors de l'envoi du snapshot complet"
58 sudo btrfs subvolume delete "$LOCAL_DEST/$SNAPSHOT_NAME"
59 exit 1
60 fi
61 fi
62 else
63 echo "Le snapshot précédent n'existe pas localement. Envoi d'un snapshot complet..."
64 if sudo btrfs send "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs.receive "$DEST"; then
65 echo "Snapshot complet envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
66 else
67 echo "Erreur lors de l'envoi du snapshot complet"
68 sudo btrfs subvolume delete "$LOCAL_DEST/$SNAPSHOT_NAME"
69 exit 1
70 fi
71 fi
72else
73 echo "Aucun snapshot précédent trouvé. Envoi d'un snapshot complet..."
74 if sudo btrfs send "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs receive "$DEST"; then
75 echo "Snapshot complet envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
76 else
77 echo "Erreur lors de l'envoi du snapshot complet"
78 sudo btrfs subvolume delete "$LOCAL_DEST/$SNAPSHOT_NAME"
79 exit 1
80 fi
81fi
82
83# Mettre à jour les fichiers de suivi
84date +"%Y-%m-%d %H:%M:%S" >"$LAST_RUN_FILE"
85echo "$SNAPSHOT_NAME" >"$LAST_SNAPSHOT_FILE"
86
87# Fonction de nettoyage des snapshots locaux
88cleanup_local_snapshots() {
89 echo "Nettoyage des snapshots locaux..."
90 local snapshots=($(ls -1d "$LOCAL_DEST"/20*_*-*-* | sort -r))
91 local count=0
92 for snapshot in "${snapshots[@]}"; do
93 if [ $count -ge $KEEP_LOCAL ]; then
94 echo "Suppression du snapshot local: $snapshot"
95 sudo btrfs subvolume delete "$snapshot"
96 fi
97 count=$((count + 1))
98 done
99}
100
101# Fonction de nettoyage des snapshots sur la destination
102cleanup_remote_snapshots() {
103 echo "Nettoyage des snapshots distants..."
104 cd "$DEST" || exit
105
106 local snapshots=($(ls -1d 20*_*-*-* | sort -r))
107
108 for snapshot in "${snapshots[@]}"; do
109 local age=$(get_age_days "$snapshot")
110
111 # Supprimer tous les snapshots plus vieux que 31 jours
112 if [ $age -gt $KEEP_DISTANT ]; then
113 echo "Suppression du snapshot distant: $snapshot"
114 sudo btrfs subvolume delete "$snapshot"
115 fi
116 done
117}
118
119# Exécuter le nettoyage
120cleanup_local_snapshots
121cleanup_remote_snapshots
122
123echo "Sauvegarde et nettoyage terminés"