#!/bin/bash
##==============================================================================================
##                                                                                            ##
##                                   Script gitea-backup.sh                                   ##
##                                                                                            ##
##==============================================================================================
##                                                                                            ##
## gitea-backup.sh [<méthode de backup>]                                                      ##
##        <méthode de backup> est facultatif. S'il n'est pas spécifié, on fait les deux !     ##
##        <méthode de backup>   = gitea_dump                                                  ##
##                              = archive_dossier                                             ##
##                                                                                            ##
##==============================================================================================

##==============================================================================================
##                                                                                            ##
## MAJ du 19.04.2021 : La partie de sauvegarde gite_dump a été commentée, et n'est donc       ##
## plus utilisée, car la restauration de cette archive est trop galère à mettre en place.     ##
## Donc soit on ne donne aucun paramètre en argument au script, soit on met archive_dossier.  ##
## L'autre paramètre n'aura donc plus aucun effet.                                            ##
##                                                                                            ##
##==============================================================================================

##==============================================================================================
##                                                                                            ##
## Objectif du script : faire une sauvegarde de l'installation Gitea @ Docker                 ##
## Il y a aura un shutdown du conteneur le temps de la sauvegarde afin que la base de         ##
## données ne soit pas modifiée pendant le backup, puis le conteneur sera redémarré.          ##
##                                                                                            ##
## Il faudra créer une tâche planifiée pour lancer la sauvegarde toutes les nuits, par        ##
## exemple à 3h du matin.                                                                     ##
##                                                                                            ##
##==============================================================================================
##                                                                                            ##
##          Une méthode officielle de backup de la base de données est présente ici :         ##
##             https://docs.gitea.io/en-us/backup-and-restore/#backup-command-dump            ##
##                                                                                            ##
##==============================================================================================



# Récupération des arguments qu'on place dans des variables constantes
declare -r nb_arg=$#            # Nombre d'argument(s) fourni(s) au script.
declare -r methode="$1"         # 1er argument fourni

if [ "$methode" = "--help" ] || [ "$methode" = "-help" ] || [ "$methode" = "-h" ] || [ "$methode" = "--h" ]; then
  echo "Le script gitea-backup.sh permet de faire une sauvegarde des données du conteneur Gitea."
  echo "Utilisation : gitea-backup.sh [<méthode de backup>]"
  echo "L'argument <méthode de backup> est facultatif. S'il n'est pas spécifié, on fait les deux !"
  echo "           <méthode de backup>   = gitea_dump"
  echo "                                 = archive_dossier"
  echo
  exit 0
fi

mode_backup=0   # 0 = aucune méthode indiquée ; 1 = gitea_dump ; 2 = archive_dossier

##────  ────────────────────────────────────────────────────────────────────────────────────────
##────  ────────────────────────────────────────────────────────────────────────────────────────
##                                                                                            ##
##                                   VALEURS À PERSONNALISER                                  ##
##                                                                                            ##
##       Chemin d'accès vers votre dossier docker et vers le dossier de backup de gitea       ##

# Chemin du dossier qui contient le dossier des données (data) et des backups (backup-data)
GITEA_DOCKER_DIR=/volume1/docker/gitea

# Les noms des dossiers montés dans le conteneur doivent êtres identiques à ceux présents sur la machine hôte. Sinon faudra modifier le script...
# Nom du dossier contenant les backups qui doit exister car il doit être monté dans le conteneur à l'aide du docker-compose.yml.
GITEA_BACKUP_DIR=backup-data

# Nom du dossier contenant les donneés de Gitea (data) 
GITEA_DATA_DIR=data

# Nom du conteneur
NOM_CONTENEUR=gitea

# ID de l'utilisateur du NAS qui a les droits sur le conteneur
ID_USER_NAS=1060

# Nombre de jours d'archives-backup à garder (ça inclus le jour actuel)
NB_JOURS_A_GARDER=10

##────  ────────────────────────────────────────────────────────────────────────────────────────
##────  ────────────────────────────────────────────────────────────────────────────────────────

function pause() {
  read -p "$*"
}

echo "$(date "+%R:%S - ")    Script de sauvegarde des données du conteneur Gitea"


##==============================================================================================
##                    Vérification de la présence des dossiers du conteneur                   ##

cd $GITEA_DOCKER_DIR
num_erreur=$?           # On stocke le code de retour de la commande précédente.
if [ $num_erreur -ne 0 ]; then    # Si ce code n'est pas 0, il y a eu une erreur, on arrète le script.
  echo "    Le chemin '$GITEA_DOCKER_DIR' est invalide ! Veuillez vérifier le chemin d'accès..."
  echo "    Abandon, avec code d'erreur $num_erreur"
  exit $num_erreur
fi

dossier_manquant=""
if [ ! -d "$GITEA_BACKUP_DIR" ]; then
  dossier_manquant = "$GITEA_BACKUP_DIR"
fi
if [ ! -d "$GITEA_DATA_DIR" ]; then
  dossier_manquant = dossier_manquant + " ; $GITEA_DATA_DIR"
fi
if [ "$dossier_manquant" != "" ]; then
  echo "    Le(s) dossier(s) suivant(s) n'existe(nt) pas : $dossier_manquant  ."
  echo "    Abandon, avec code d'erreur 999."
  exit 999
else
  echo "-- Les dossiers $GITEA_BACKUP_DIR et $GITEA_DATA_DIR existent bien. Le script peut continuer."
fi

# Autre méthode, effectuant davantage de tests... donc moins efficace...
# if [ ! -d "$GITEA_BACKUP_DIR" ] || [ ! -d "$GITEA_DATA_DIR" ]; then    # Au moins un des dossiers n'existe pas
#   if [ ! -d "$GITEA_BACKUP_DIR" ]; then   # Le dossier $GITEA_BACKUP_DIR n'existe pas !
#     echo "    Le dossier '$GITEA_BACKUP_DIR' n'existe pas !"
#   fi
#   if [ ! -d "$GITEA_DATA_DIR" ]; then       # Le dossier $GITEA_DATA_DIR n'existe pas !
#     echo "    Le dossier '$GITEA_DATA_DIR' n'existe pas !"
#   fi
#   echo "    Abandon, avec code d'erreur 999"
#   exit 999
# else
#   echo "-- Les dossiers $GITEA_BACKUP_DIR et $GITEA_DATA_DIR existent bien. On peut continuer." 
# fi
##==============================================================================================


##==============================================================================================
##                                                                                            ##
##      Définition du mode de backup à faire en fonction de la méthode donnée en argument     ##
case $methode in
  gitea_dump)         # Méthode gitea_dump sélectionnée                                       ##
    mode_backup=1
    #echo "mode_backup=$mode_backup"
    ;;
  
  archive_dossier)    # Méthode archive_dossier sélectionnée                                  ##
    mode_backup=2
    #echo "mode_backup=$mode_backup"
    ;;
  
  *)                  # Aucune méthode sélectionnée                                           ##
    mode_backup=0
    #echo "mode_backup=$mode_backup"
    ;;
esac
##==============================================================================================


##==============================================================================================
##                                                                                            ##
##                              Partie concernant les sauvegardes                             ##
# if [ $mode_backup -eq 0 ] || [ $mode_backup -eq 1 ]; then
#   # Aucune méthode n'est choisie ou bien méthode gitea_dump sélectionnée
  
#   # Rappel des variables :
#   #     GITEA_DOCKER_DIR=/volume1/docker/gitea
#   #     GITEA_BACKUP_DIR=backup-data
#   #     GITEA_DATA_DIR=data
#   #     NOM_CONTENEUR=gitea
#   #     ID_USER_NAS=1060

#   echo "-- Sauvegarde via Gitea dump. (un peu chiant à restaurer...)"
#   echo "###############################################################################"
#   # Dans la commande suivante, les chemins d'accès donnés en paramètres sont des chemins d'accès à l'intérieur du conteneur, montés avec le docker-compose.yml.
#   # Exemple de commande sans variables :
#   #       docker exec -u 1060 -i -w /backup-data $(docker ps -qf "name=^gitea$") bash -c '/app/gitea/gitea dump -c /data/gitea/conf/app.ini'
#   # Note : La commande lancée dans une tâche CRON (planifiée) ne permet pas l'utilisation du paramètre -t.
#   # Commande à lancer dans un terminal :
#   # docker exec -u 1060 -i -w /backup-data $(docker ps -qf "name=^gitea$") bash -c '/app/gitea/gitea dump -c /data/gitea/conf/app.ini'
#   # Explication pour $(docker ps -qf "name=^gitea$")   ici : https://stackoverflow.com/a/34497614

#   docker exec -u $ID_USER_NAS -i -w /$GITEA_BACKUP_DIR $(docker ps -qf "name=^$NOM_CONTENEUR$") bash -c "/app/gitea/gitea dump -c /$GITEA_DATA_DIR/gitea/conf/app.ini"
#   num_erreur=$?           # On stocke le code de retour de la commande précédente.
#   if [ $num_erreur -ne 0 ]; then    # Si ce code n'est pas 0, il y a eu une erreur, on arrète le script.
#     echo "!!!!!!  Erreur lors de la commande de backup gitea dump."
#     #echo "!!!!!!  Commande lancée :"
#     #echo "        docker exec -u $ID_USER_NAS -it -w /$GITEA_BACKUP_DIR $(docker ps -qf "name=$NOM_CONTENEUR") bash -c "/app/gitea/gitea dump -c /$GITEA_DATA_DIR/gitea/conf/app.ini""
#     echo "!!!!!!  Abandon, avec code d'erreur $num_erreur"
#     exit $num_erreur
#   fi
#   echo "###############################################################################"
#   echo "-- Sauvegarde via Gitea dump terminée."
# fi


if [ $mode_backup -eq 0 ] || [ $mode_backup -eq 2 ]; then
  # Aucune méthode n'est choisie ou bien méthode archive_dossier sélectionnée
  echo "-- Sauvegarde par création d'une archive de tout le dossier $GITEA_DATA_DIR"
  echo "###############################################################################"
  cd $GITEA_DOCKER_DIR    # Même si on est censé déjà être là...
  
  #retour_cmd=1111 # Valeur reset
  echo "-- Extinction du conteneur $(docker stop $NOM_CONTENEUR) : OK."
  # retour_cmd=$?     # Le code d'exit de la fonction est stocké dans cette variable.
  # if [ $retour_cmd -ne 0 ]; then
  #   if [ $retour_cmd -eq 1111 ]; then
  #     echo "### DEBUG : soucis avec la récupération du retour de commande #1470000 "
  #     exit 1470000
  #   fi
  #   echo "!! Le conteneur $NOM_CONTENEUR ne peut pas être arrêté..."
  #   echo "!! Fin du script. Erreur 777"
  #   echo
  #   exit 777
  # fi
  echo "-- Création de l'archive du dossier $GITEA_DATA_DIR"
  
  # Compression tar.gz :
  #tar -czf $GITEA_BACKUP_DIR/Gitea-Data-Backup-`date +%Y-%m-%d--%Hh%Mm%Ss`.tar.gz ./$GITEA_DATA_DIR

  # Compression 7z après obtention d'un .tar
  # On Linux/Unix, in order to backup directories you must use tar :
  #   - to backup a directory : tar cf - directory | 7z a -si directory.tar.7z
  #   - to restore your backup : 7z x -so directory.tar.7z | tar xf -
  tar cf - ./$GITEA_DATA_DIR | 7z a -si $GITEA_BACKUP_DIR/Gitea-Data-Backup-`date +%Y-%m-%d--%Hh%Mm%Ss`.7z
  
  echo "-- Archive de tout le dossier $GITEA_DATA_DIR créée."

  # retour_cmd=1111 # Valeur reset
  echo "-- Redémarrage du conteneur $(docker start $NOM_CONTENEUR) : OK."
  # retour_cmd=$?     # Le code d'exit de la fonction est stocké dans cette variable.
  # if [ $retour_cmd -ne 0 ]; then
  #   if [ $retour_cmd -eq 1111 ]; then
  #     echo "### DEBUG : soucis avec la récupération du retour de commande #1470000 "
  #     exit 1470000
  #   fi
  #   echo "!! Le conteneur $NOM_CONTENEUR ne peut pas être redémarré..."
  #   echo "!! Fin du script. Erreur 777"
  #   echo
  #   exit 777
  # fi

  # Section concernant la rotation des sauvegardes.
  echo
  echo "-- Rotation des sauvegardes anciennes selon le nombre de jours d'archives à garder (=$NB_JOURS_A_GARDER) incluant ce jour :"
  echo
  echo
  echo "-- -- Utilisation de la fonction find pour trouver les fichiers de plus de $nb_jours_a_garder jours (incluant ce jour)."
  echo "-- -- Les fichiers suivants seront supprimés :"
  find $GITEA_BACKUP_DIR/* -name 'Gitea-Data-Backup*' -mtime +"$((NB_JOURS_A_GARDER - 1))" -exec ls -lat --color {} \;

  # Utile pour débugguer avant de supprimer réellement les fichiers.
  #pause '--DEBUG-- Appuyer sur la touche [Entrer] pour continuer...'

  echo "-- -- Suppression de ces fichiers..."
  find $GITEA_BACKUP_DIR/* -name 'Gitea-Data-Backup*' -mtime +"$((NB_JOURS_A_GARDER - 1))" -exec rm -v {} \;
  
  ############################################################
  # Cette partie peut être commentée
  echo
  echo "-- -- Il reste donc les fichiers suivants :"
  ls -lat --color $GITEA_BACKUP_DIR/Gitea-Data-Backup*
  ############################################################


  echo "###############################################################################"
  echo "-- Processus de sauvegarde par création d'archive terminé."

fi

echo "$(date "+%R:%S - ")    Fin du script de sauvegarde des donneés du conteneur Gitea"
exit 0
##                                                                                            ##
##==============================================================================================