#!/bin/bash # Author: Edgar Roncero # Email: eroncero@digitalstack.es # Date: 04-july-2023 # Purpose: This script is to either backup or restore Moodle database, www-site and moodledata. # License: GPLv3 ############################################################################################### ### Backup target directory ################################################################### global_backup_absolutepath="/home/edgar/backups" global_backup_dirname="backups" # This var isn't really used yet. ### Database credentials ###################################################################### mariadb_host="localhost" mariadb_user="moodle" mariadb_db="moodle" mariadb_pw="secret" ### www/site source path ###################################################################### www_absolutepath="/var/www/moodle" www_dirname="moodle" ### moodledata source path #################################################################### moodledata_absolutepath="/var/moodledata" moodledata_dirname="moodledata" ############################################################################################### ### .sql file to restore. It can either be .sql or .sql.gz, script is wise enough. ############ sqlfile_to_restore_absolutepath="/home/edgar/backups/legacy_db_20230706_152414.sql.gz" # ex: 2023129318.sql or 2023129318.sql.gz sqlfile_to_restore_filename="" # This var isn't really used yet. ############################################################################################### ##################################### # Functions to check if dir exists. # ##################################### # fn_check_backup_dirname() { if [ -d "$global_backup_absolutepath" ]; then echo "${0} info: OK! The directory ${global_backup_absolutepath} exists." else echo "${0} info: ERROR! The directory ${global_backup_absolutepath} does not exist, please check global_backup_absolutepath=\"\". Exiting..." >&2 ;sleep 1 ;exit 1 fi } fn_check_www_dirname() { if [ -d "${www_absolutepath}" ]; then echo "${0} info: OK! The directory ${www_absolutepath} exists." else echo "${0} info: ERROR! The directory ${www_absolutepath} does not exist, please check www_absolutepath=\"\". Exiting..." >&2 ;sleep 1 ;exit 1 fi } fn_check_moodledata_dirname() { if [ -d "${moodledata_absolutepath}" ]; then echo "${0} info: OK! The directory ${moodledata_absolutepath} exists." else echo "${0} info: ERROR! The directory ${moodledata_absolutepath} does not exists, please check moodledata_absolutepath=\"\". Exiting..." >&2 ;sleep 1 ;exit 1 fi } fn_check_mariadb_restore() { echo "Function to be implemented. For now it is somehow implemented in the perform function instead." } ###################################################################### # Function to check the current user's identity and group membership # ###################################################################### # fn_check_user_and_group() { # Get the current user name current_user=$(whoami) # Check if the user is "apache," "www-data," or "root" if [ "$current_user" = "apache" ] || [ "$current_user" = "www-data" ] || [ "$current_user" = "root" ]; then echo "${0} info: OK! The current user is $current_user. It appears valid to perform backups." else echo "${0} info: ERROR! The current user is neither apache, www-data, nor root. It is $current_user. It wont't be able to backup www or moodledata properly due to insufficient permissions." >&2 ;sleep 1 ;exit 1 fi # Check if the user belongs to the "www-data" or "apache" group if groups "$current_user" | grep -q -w "www-data\|apache\|root"; then echo "${0} info: OK! The current user $current_user belongs to the 'www-data' or 'apache' group."; sleep 1 else echo "${0} info: ERROR! The current user $current_user does not belong to the 'www-data' or 'apache', or 'root' group. It wont't be able to backup www or moodledata properly due to insufficient permissions." >&2 ;sleep 1 ;exit 1 fi } ############################################## # Performs the following functions in a row. # ############################################## # fn_initial_check() { fn_check_backup_dirname fn_check_user_and_group fn_check_www_dirname fn_check_moodledata_dirname } ##################### # Restore functions # ##################### # fn_restore_mariadb() { if [[ ${sqlfile_to_restore_absolutepath} == *.gz ]]; then gunzip < ${sqlfile_to_restore_absolutepath} | mysql --user=${mariadb_user} --password=${mariadb_pw} ${mariadb_db} else mysql --user=${mariadb_user} --password=${mariadb_pw} ${mariadb_db} < ${sqlfile_to_restore_absolutepath} fi local mysql_exitcode=${?} echo "${0} info: gunzip or mysql action of fn_restore_mariadb() returned exit code ${mysql_exitcode}" if [ ${mysql_exitcode} -ne 0 ]; then echo "${0} info: ERROR!" ; exit ${mysql_exitcode} fi } fn_restore_wwwsite() { echo "Sorry, this function is not here yet. Why? Because it can ve very evil if you misunderstood the variable value, say you typed www_absolutepath=\"/var\". You breake the Operating System." && sleep 1 echo "Please restore it manually instead." } fn_restore_moodledata() { echo "Sorry, this function is not here yet. Why? Because it can ve very evil if you misunderstood the variable value, say you typed moodledata_absolutepath=\"/var\". You breake the Operating System." && sleep 1 echo "Please restore it manually instead." } datetime_now=$(date +"%Y%m%d_%H%M%S") # es te que instanciar just al moment del backup aixi la data es correcta. ################## # MariaDB backup # ################## # fn_backup_mariadb() { local file_backup_name=${mariadb_db}_${datetime_now}.sql local generated_backup=${global_backup_absolutepath}/${file_backup_name} # generated_backup is the abosutepath + fullname of the file ending with .sql extension echo "running mysqldump" && mysqldump --default-character-set=utf8mb4 -h ${mariadb_host} -u ${mariadb_user} --password=${mariadb_pw} -C -Q -e --create-options ${mariadb_db} > ${generated_backup} && gzip ${generated_backup} generated_backup="${generated_backup}.gz" # after generating the .sql file, it compresses it to .gz, so var needs to be renamed properly. local mysqldump_exitcode=${?} #2do, it doensn't hande error for gzip and mysql separately. echo "${0} info: mysqldump action of fn_backup_mariadb() returned exit code ${mysqldump_exitcode}" if [ ${mysqldump_exitcode} -ne 0 ]; then echo "Removing incomplete backup file" ;rm ${generated_backup} ; echo "${0} info: ERROR!" ;exit ${mysqldump_exitcode} fi } ################### # www/site backup # ################### # fn_backup_wwwsite() { local file_backup_name="www_${datetime_now}.tar.gz" cd ${www_absolutepath}/.. # it goes to the parent directory where moodledata directory is located echo "running tar" && tar -czf ${global_backup_absolutepath}/${file_backup_name} ${www_dirname} # it compresses moodledata with a custom filename, ex: moodledata_2023000000.tar.gz local tar_exitcode=${?} echo "${0} info: tar action of fn_backup_wwwsite() returned exit code ${tar_exitcode}" if [ ${tar_exitcode} -ne 0 ]; then echo "Removing incomplete backup file" ;rm ${global_backup_absolutepath}/${file_backup_name} ; echo "${0} info: ERROR!" ;exit ${tar_exitcode} fi } ##################### # moodledata backup # ##################### # fn_backup_moodledata() { local file_backup_name="moodledata_${datetime_now}.tar.gz" cd ${moodledata_absolutepath}/.. # it goes to the parent directory where moodledata directory is located echo "running tar" && tar -czf ${global_backup_absolutepath}/${file_backup_name} ${moodledata_dirname} # it compresses moodledata with a custom filename, ex: moodledata_2023000000.tar.gz local tar_exitcode=${?} echo "${0} info: tar action of fn_backup_moodledata() returned exit code ${tar_exitcode}" if [ ${tar_exitcode} -ne 0 ]; then echo "Removing incomplete backup file" ;rm ${global_backup_absolutepath}/${file_backup_name} ; echo "${0} info: ERROR!" ;exit ${tar_exitcode} fi } ##################### # backup everything # ##################### # fn_backup_everything() { fn_backup_mariadb fn_backup_wwwsite fn_backup_moodledata echo "" && echo "Listing ALL backup files:" && find ${global_backup_absolutepath} -type f du -hs ${global_backup_absolutepath} } ########################################## # Function to display usage instructions # ########################################## # display_help() { echo "Usage: $0 [OPTION]" echo "Options:" echo " --initial-check It will check if everything is properly set in order to do backups" echo " --backup-everything Perform FULL backup" echo " --backup-mariadb Perform mariadb backup" echo " --backup-wwwsite Perform www site backup" echo " --backup-moodledata Perform moodledata backup" echo " --restore-mariadb Perform mariadb restore" echo " --restore-wwwsite Perform www-site restore" echo " --restore-moodledata Perform moodledata restore" echo " --help Display this help message" } ################################################################# # Check if no arguments are provided and display help if needed # ################################################################# # if [ $# -eq 0 ]; then display_help exit 0 fi ################################################################### # Check the argument provided and call the corresponding function # ################################################################### # case "$1" in --initial-check) fn_initial_check ;; --backup-everything) fn_backup_everything ;; --backup-mariadb) fn_backup_mariadb ;; --backup-wwwsite) fn_backup_wwwsite ;; --backup-moodledata) fn_backup_moodledata ;; --restore-mariadb) fn_restore_mariadb ;; --restore-wwwsite) fn_restore_wwwsite ;; --restore-moodledata) fn_restore_moodledata ;; --help) display_help ;; *) echo "Invalid option. Use '$0 --help' to see available options." exit 1 ;; esac