88 lines
3.5 KiB
Bash
Executable File
88 lines
3.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#=================================================
|
|
# VARIABLES ET HELPERS PROPRES À MABIBLI
|
|
#=================================================
|
|
|
|
# Nom du binaire produit par `dotnet publish MaBibli.Api`.
|
|
mabibli_binaire="MaBibli.Api"
|
|
|
|
# Base SQLite. Doit rester cohérent avec `ConnectionStrings__MaBibli` dans
|
|
# conf/systemd.service.
|
|
mabibli_base="mabibli.db"
|
|
|
|
# Copie cohérente déposée dans le répertoire de données au moment de la sauvegarde,
|
|
# puis reprise par le script de restauration.
|
|
mabibli_instantane="mabibli-instantane.db"
|
|
|
|
#=================================================
|
|
# SAUVEGARDE À CHAUD DE LA BASE SQLITE
|
|
#=================================================
|
|
#
|
|
# Pourquoi ce n'est pas un simple `cp` :
|
|
#
|
|
# La base tourne en mode **WAL** (vérifié sur le publish réel : `PRAGMA journal_mode`
|
|
# renvoie `wal`, et le répertoire contient bien `mabibli.db-wal` / `mabibli.db-shm`).
|
|
# En WAL, les écritures récentes vivent dans le fichier `-wal` et **pas** dans le
|
|
# `.db`. Sur la base fraîchement migrée mesurée en local, le `.db` faisait 4 Ko pour
|
|
# un `-wal` de 205 Ko : copier le seul `.db` aurait sauvegardé une base à peu près
|
|
# vide. Copier les trois fichiers pendant que le service écrit ne vaut guère mieux,
|
|
# puisque rien ne garantit qu'ils soient capturés au même instant.
|
|
#
|
|
# `.backup` utilise l'API de sauvegarde en ligne de SQLite : elle produit un fichier
|
|
# unique, cohérent, sans arrêter le service ni bloquer les lectures. C'est la seule
|
|
# méthode correcte pour une sauvegarde à chaud, et elle évite d'imposer une coupure
|
|
# de service à chaque sauvegarde nocturne.
|
|
#
|
|
# usage : mabibli_instantane_base "$data_dir"
|
|
mabibli_instantane_base() {
|
|
local repertoire="$1"
|
|
local source="$repertoire/$mabibli_base"
|
|
local cible="$repertoire/$mabibli_instantane"
|
|
|
|
# Un instantané laissé par une sauvegarde précédente n'a plus de valeur.
|
|
# (Il ne peut pas être effacé en fin de sauvegarde : `ynh_backup` ne fait que
|
|
# *déclarer* les chemins, la copie réelle a lieu plus tard, par le cœur de
|
|
# YunoHost.)
|
|
rm -f "$cible"
|
|
|
|
if [ ! -f "$source" ]; then
|
|
ynh_print_warn "Aucune base à $source : rien à figer. Première sauvegarde avant tout démarrage ?"
|
|
return 0
|
|
fi
|
|
|
|
# `.backup` échoue proprement si la base est corrompue : mieux vaut interrompre
|
|
# la sauvegarde que d'archiver un fichier illisible en croyant être protégé.
|
|
sqlite3 "$source" ".backup '$cible'"
|
|
|
|
chown "$app:$app" "$cible"
|
|
chmod 600 "$cible"
|
|
}
|
|
|
|
#=================================================
|
|
# REPRISE DE L'INSTANTANÉ APRÈS RESTAURATION
|
|
#=================================================
|
|
#
|
|
# usage : mabibli_reprendre_instantane "$data_dir"
|
|
mabibli_reprendre_instantane() {
|
|
local repertoire="$1"
|
|
local instantane="$repertoire/$mabibli_instantane"
|
|
|
|
if [ ! -f "$instantane" ]; then
|
|
ynh_print_warn "Pas d'instantané dans l'archive : la base est reprise telle quelle."
|
|
return 0
|
|
fi
|
|
|
|
# ⚠️ Les fichiers `-wal` et `-shm` de l'archive décrivent l'état d'une *autre*
|
|
# copie de la base. Les laisser à côté de l'instantané ferait rejouer à SQLite
|
|
# un journal qui ne lui correspond pas. Ils doivent disparaître.
|
|
rm -f "$repertoire/$mabibli_base" \
|
|
"$repertoire/$mabibli_base-wal" \
|
|
"$repertoire/$mabibli_base-shm"
|
|
|
|
mv "$instantane" "$repertoire/$mabibli_base"
|
|
|
|
chown "$app:$app" "$repertoire/$mabibli_base"
|
|
chmod 600 "$repertoire/$mabibli_base"
|
|
}
|