#!/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}/host" # 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" ) # SI la commande est lxd est disponible if [[ -x "/snap/bin/lxd" ]]; then # Liste des conteneurs à savegarder containers=$(/snap/bin/lxc list --columns "nsL" --format csv | grep "$(hostname)" | awk -F ',' '{print $1}') # SI la liste est vide, tenter avec le nodename if [[ -z "${containers}" ]]; then # Récupérer le nom du noeud lxc nodename=$(/snap/bin/lxc info | grep "server_name" | awk -F':' '{print $NF}' | sed 's# ##g') # Récupérer la liste des conteneurs containers=$(/snap/bin/lxc list --columns "nsL" --format csv | grep "${nodename}" | awk -F ',' '{print $1}') fi fi # 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}/* ! -path "*kept*" -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" > /dev/null # Appliquer la rétention [[ "$(/bin/ls ${containersPath})" ]] && find ${containersPath}/* ! -path "*kept*" -mtime "+${retentionPolicy}" -exec rm {} \; # Supprimer le lock rm "${containersPath}/${scriptName}.lock" fi #################################################################################### ## TRAITEMENT (gérer le verrou) # Supprimer le verrou rm $lockPath