btrfs-backup.sh
· 4.3 KiB · Bash
Raw
#!/usr/bin/env bash
# Config
SOURCE="/home"
LOCAL_DEST="/snapshots"
DEST="/run/media/mathieu/ext_ssd/backups"
KEEP_LOCAL=10 # Nombre de snapshots locaux à conserver
KEEP_DISTANT=31 # Nombre de snapshots distant à conserver
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
SNAPSHOT_NAME="$DATE"
LAST_RUN_FILE="$DEST/.last_run"
LAST_SNAPSHOT_FILE="$DEST/.last_snapshot"
get_age_days() {
local file=$1
local file_time=$(date -r "$file" +%s)
local current_time=$(date +%s)
echo $(((current_time - file_time) / 86400))
}
if ! mountpoint -q "$DEST/.."; then
echo "Erreur: Le disque externe n'est pas monté sur $DEST"
exit 1
fi
# Vérifier la dernière exécution
if [ -f "$LAST_RUN_FILE" ]; then
last_run=$(cat "$LAST_RUN_FILE")
days_since_last_run=$((($(date +%s) - $(date -d "$last_run" +%s)) / 86400))
if [ $days_since_last_run -gt 7 ]; then
echo "Attention: $days_since_last_run jours se sont écoulés depuis la dernière sauvegarde."
fi
else
echo "Première exécution détectée."
fi
# Créer un nouveau snapshot en lecture seule de /home
if sudo btrfs subvolume snapshot -r "$SOURCE" "$LOCAL_DEST/$SNAPSHOT_NAME"; then
echo "Snapshot local créé avec succès: $LOCAL_DEST/$SNAPSHOT_NAME"
else
echo "Erreur lors de la création du snapshot local"
exit 1
fi
# Envoyer le snapshot vers la destination
if [ -f "$LAST_SNAPSHOT_FILE" ]; then
last_snapshot=$(cat "$LAST_SNAPSHOT_FILE")
if [ -d "$LOCAL_DEST/$last_snapshot" ]; then
echo "Envoi d'un snapshot incrémentiel..."
if sudo btrfs send -p "$LOCAL_DEST/$last_snapshot" "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs receive "$DEST"; then
echo "Snapshot incrémental envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
else
echo "Erreur lors de l'envoi du snapshot incrémentiel. Tentative d'envoi complet..."
if sudo btrfs send "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs receive "$DEST"; then
echo "Snapshot complet envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
else
echo "Erreur lors de l'envoi du snapshot complet"
sudo btrfs subvolume delete "$LOCAL_DEST/$SNAPSHOT_NAME"
exit 1
fi
fi
else
echo "Le snapshot précédent n'existe pas localement. Envoi d'un snapshot complet..."
if sudo btrfs send "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs.receive "$DEST"; then
echo "Snapshot complet envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
else
echo "Erreur lors de l'envoi du snapshot complet"
sudo btrfs subvolume delete "$LOCAL_DEST/$SNAPSHOT_NAME"
exit 1
fi
fi
else
echo "Aucun snapshot précédent trouvé. Envoi d'un snapshot complet..."
if sudo btrfs send "$LOCAL_DEST/$SNAPSHOT_NAME" | sudo btrfs receive "$DEST"; then
echo "Snapshot complet envoyé avec succès vers $DEST/$SNAPSHOT_NAME"
else
echo "Erreur lors de l'envoi du snapshot complet"
sudo btrfs subvolume delete "$LOCAL_DEST/$SNAPSHOT_NAME"
exit 1
fi
fi
# Mettre à jour les fichiers de suivi
date +"%Y-%m-%d %H:%M:%S" >"$LAST_RUN_FILE"
echo "$SNAPSHOT_NAME" >"$LAST_SNAPSHOT_FILE"
# Fonction de nettoyage des snapshots locaux
cleanup_local_snapshots() {
echo "Nettoyage des snapshots locaux..."
local snapshots=($(ls -1d "$LOCAL_DEST"/20*_*-*-* | sort -r))
local count=0
for snapshot in "${snapshots[@]}"; do
if [ $count -ge $KEEP_LOCAL ]; then
echo "Suppression du snapshot local: $snapshot"
sudo btrfs subvolume delete "$snapshot"
fi
count=$((count + 1))
done
}
# Fonction de nettoyage des snapshots sur la destination
cleanup_remote_snapshots() {
echo "Nettoyage des snapshots distants..."
cd "$DEST" || exit
local snapshots=($(ls -1d 20*_*-*-* | sort -r))
for snapshot in "${snapshots[@]}"; do
local age=$(get_age_days "$snapshot")
# Supprimer tous les snapshots plus vieux que 31 jours
if [ $age -gt $KEEP_DISTANT ]; then
echo "Suppression du snapshot distant: $snapshot"
sudo btrfs subvolume delete "$snapshot"
fi
done
}
# Exécuter le nettoyage
cleanup_local_snapshots
cleanup_remote_snapshots
echo "Sauvegarde et nettoyage terminés"
1 | #!/usr/bin/env bash |
2 | |
3 | # Config |
4 | SOURCE="/home" |
5 | LOCAL_DEST="/snapshots" |
6 | DEST="/run/media/mathieu/ext_ssd/backups" |
7 | KEEP_LOCAL=10 # Nombre de snapshots locaux à conserver |
8 | KEEP_DISTANT=31 # Nombre de snapshots distant à conserver |
9 | DATE=$(date +"%Y-%m-%d_%H-%M-%S") |
10 | SNAPSHOT_NAME="$DATE" |
11 | LAST_RUN_FILE="$DEST/.last_run" |
12 | LAST_SNAPSHOT_FILE="$DEST/.last_snapshot" |
13 | |
14 | get_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 | |
21 | if ! mountpoint -q "$DEST/.."; then |
22 | echo "Erreur: Le disque externe n'est pas monté sur $DEST" |
23 | exit 1 |
24 | fi |
25 | |
26 | # Vérifier la dernière exécution |
27 | if [ -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 |
33 | else |
34 | echo "Première exécution détectée." |
35 | fi |
36 | |
37 | # Créer un nouveau snapshot en lecture seule de /home |
38 | if sudo btrfs subvolume snapshot -r "$SOURCE" "$LOCAL_DEST/$SNAPSHOT_NAME"; then |
39 | echo "Snapshot local créé avec succès: $LOCAL_DEST/$SNAPSHOT_NAME" |
40 | else |
41 | echo "Erreur lors de la création du snapshot local" |
42 | exit 1 |
43 | fi |
44 | |
45 | # Envoyer le snapshot vers la destination |
46 | if [ -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 |
72 | else |
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 |
81 | fi |
82 | |
83 | # Mettre à jour les fichiers de suivi |
84 | date +"%Y-%m-%d %H:%M:%S" >"$LAST_RUN_FILE" |
85 | echo "$SNAPSHOT_NAME" >"$LAST_SNAPSHOT_FILE" |
86 | |
87 | # Fonction de nettoyage des snapshots locaux |
88 | cleanup_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 |
102 | cleanup_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 |
120 | cleanup_local_snapshots |
121 | cleanup_remote_snapshots |
122 | |
123 | echo "Sauvegarde et nettoyage terminés" |