diff --git a/backup/containers/.keep b/backup/containers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/backup/hosts/.keep b/backup/hosts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/backup/run.bash b/backup/run.bash new file mode 100644 index 0000000..7d53af2 --- /dev/null +++ b/backup/run.bash @@ -0,0 +1,148 @@ +#!/bin/bash +#################################################################################### +## VARIABLES +# Activer ou non le mode debug (message) +DEBUG=0 + +# Extraire le chemin où est stocké le script +basePath=$(dirname $0) + +# Récupérer le nom du script +scriptName=$(basename $0) + +# Définir le nombre de sauvegarde à conserver (valeur dépendante du cron) +retentionPolicy="9" + +#################################################################################### +## PRE-CHAUFFAGE +# Enregistrer la date au format YYYY-MM-DD +date=$(date --iso-8601) + +# Construire le chemin de stockage des sauvegardes de l'hôte +hostPath="${basePath}/hosts" + +# Construire le chemin de stockage des sauvegardes des conteneurs +containersPath="${basePath}/containers" + +# Construire le chemin du verrou +lockPath="${basePath}/.lock" + +# Construire le chemin des instances insclues +excludesPath="${basePath}/doNotBackup.list" + +# Liste des fichiers à sauvegarder +host=( + "/etc/network/interfaces" + "/etc/systemd/network" + "/etc/nftables.conf" + "/etc/ndppd.conf" + "/etc/wireguard/wg0.conf" +) + +# Liste des conteneurs à savegarder +[[ -x "/snap/bin/lxd" ]] && containers=$(/snap/bin/lxc list --columns "nsL" --format csv | grep "$(hostname)" | awk -F ',' '{print $1}') + +# Récupérer la liste des conteneurs à ne pas sauvegarder +exclude=""; [[ -f $excludesPath ]] && [[ -z "$(cat $excludesPath)" ]] && readarray exclude < "${excludesPath}" + +#################################################################################### +## TRAITEMENT (gérer le verrou) +# Attendre la levé du verrou +while [[ -f $lockPath ]]; do + sleep 60s +done + +# Créer le verrou +touch $lockPath + +#################################################################################### +## TRAITEMENT (système) +# Vérifier la présence du dossier de sauvegarde de l'hôte +if [[ ! -d $hostPath ]]; then + [[ $DEBUG -eq 1 ]] && echo "[DEBUG] ${hostPath}: directory does not exist" +else + for item in "${host[@]}"; do + # SI l'élément est un fichier + if [[ -f $item ]]; then + # Construire le chemin complet de sauvegarde + backupFile="${hostPath}/${date}_$(basename $item)" + + # SI le fichier n'existe pas déjà, alors sauvegarder + [[ ! -f $backupFile ]] && cp $item $backupFile + fi + + # SI l'élément est un dossier + if [[ -d $item ]]; then + # Construire le chemin complet de sauvegarde + backupFile="${hostPath}/${date}_$(basename $item).tar" + + # SI le fichier n'existe pas déjà, alors sauvegarder + [[ ! -f $backupFile ]] && tar cf $backupFile $item > /dev/null 2>&1 + fi + done +fi + +#################################################################################### +## TRAITEMENT (lxd) +# Vérifier la présence du dossier de sauvegarde de l'hôte +if [[ ! -d $hostPath ]]; then + [[ $DEBUG -eq 1 ]] && echo "[DEBUG] ${hostPath}: directory does not exist" +# Vérifier la présence de l'exécutable lxd +elif [[ ! -x "/snap/bin/lxd" ]]; then + [[ $DEBUG -eq 1 ]] && echo "[DEBUG] /snap/bin/lxd: command not found" +else + # Sauvegarder la configuration de l'hôte + backupFile="${hostPath}/${date}_lxd-dump.yml" + [[ ! -f $backupFile ]] && /snap/bin/lxd init --dump | tee $backupFile + + # Sauvegarder le profile par défaut + backupFile="${hostPath}/${date}_lxc-default-profile.yml" + [[ ! -f $backupFile ]] && /snap/bin/lxc profile show default | tee $backupFile +fi + +#################################################################################### +## TRAITEMENT (lxc) +# Vérifier la présence du dossier de sauvegarde des conteneurs +if [[ ! -d $containersPath ]]; then + [[ $DEBUG -eq 1 ]] && echo "[DEBUG] ${containersPath}: directory does not exist" +# Vérifier la présence de l'exécutable lxd +elif [[ ! -x "/snap/bin/lxd" ]]; then + [[ $DEBUG -eq 1 ]] && echo "[DEBUG] /snap/bin/lxd: command not found" +else + # Parcourir la liste des conteneurs et les sauvegarder + for container in $containers; do + # Passer si le conteneur est exclu + [[ " ${exclude[@]} " =~ "${container}" ]] && continue + + # Sauvegarder le conteneur + backupFile="${containersPath}/${date}_${container}.tar.gz" + [[ ! -f $backupFile ]] && nice -n 10 ionice -c2 -n 7 /snap/bin/lxc export "${container}" "${backupFile}" --instance-only + done +fi + +#################################################################################### +## TRAITEMENT (retention) +# Appliquer la rétention sur le dossier de l'hôte +[[ "$(/bin/ls ${hostPath})" ]] && find ${hostPath}/* -mtime "+${retentionPolicy}" -exec rm {} \; + +# Si des sauvegardes de conteneurs existent +if [[ "$(/bin/ls ${containersPath})" ]]; then + # Attendre que le lock soit supprimé + until [[ ! -f "${containersPath}/${scriptName}.lock" ]]; do + sleep 15s + done + + # Créer le fichier de lock + hostname | tee "${containersPath}/${scriptName}.lock" + + # Appliquer la rétention + [[ "$(/bin/ls ${containersPath})" ]] && find ${containersPath}/* -mtime "+${retentionPolicy}" -exec rm {} \; + + # Supprimer le lock + rm "${containersPath}/${scriptName}.lock" +fi + +#################################################################################### +## TRAITEMENT (gérer le verrou) +# Supprimer le verrou +rm $lockPath diff --git a/balance-containers.bash b/balance-containers/run.bash old mode 100755 new mode 100644 similarity index 100% rename from balance-containers.bash rename to balance-containers/run.bash diff --git a/doNotBackup.list b/doNotBackup.list new file mode 100644 index 0000000..e69de29