#!/usr/bin/env bash # This file is part of RootDB. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # AUTHORS # PORQUET Sébastien ############################################################################################### declare SCRIPT_PATH pushd . >/dev/null SCRIPT_PATH="${BASH_SOURCE[0]}" if ([ -h "${SCRIPT_PATH}" ]); then while ([ -h "${SCRIPT_PATH}" ]); do cd "$(dirname "$SCRIPT_PATH")" || exit SCRIPT_PATH=$(readlink "${SCRIPT_PATH}") done fi cd "$(dirname ${SCRIPT_PATH})" || exit >/dev/null SCRIPT_PATH=$(pwd) popd || exit >/dev/null ############################################################################################### # Script options. declare error=false declare ignore_software_dependencies=false declare rdb_asked_version # User defined, or fetched online. declare data_dir="/var/www/rootdb" declare log_file="${SCRIPT_PATH}/log" declare rdb_online_archive_url="https://builds.rootdb.fr/rootdb" declare rdb_online_latest_version_url="${rdb_online_archive_url}/latest" declare rdb_archive_file declare rdb_archives_dir="${data_dir}/archives" declare rdb_current_version # From API directory (.version file) declare rdb_latest_version_available # Fetched online. declare rdb_version_dir # / # Directories and configuration files. declare api_dir declare front_dir declare api_frontend_themes_dir # /api/frontend-themes declare api_env_file # /api/.env declare front_app_config_js_file # /frontend/public/app-config.js # Main configuration file user can tune. declare root_api_env_file="${SCRIPT_PATH}/api_env" declare root_front_app_config_js_file="${SCRIPT_PATH}/app-config.js" # To know if RootDB is installed and configured. declare rdb_init_file # Only used when we bootstrap RootDB declare api_db_root_password # Environments variables declare api_memcached_host declare api_memcached_port declare api_db_host declare api_db_port declare api_db_username declare api_db_user_password declare api_db_limit_to_ip declare nginx_user declare nginx_group # # Log functions # # Use to add some colors. declare txtblue="\\033[1;34m" declare txtgreen="\\033[1;32m" declare txtnormal="\\033[0;39m" declare txtred="\\033[1;31m" declare txtyellow="\\033[1;33m" ####################################### # Display a log message, with or without carrige return char at the end. # Arguments: # Message to display. # Carriage return : # * true : Do not add the carriage return char at the end of the string. # * false: Add the carriage return at the end of the string. # Outputs: # Writes the message, preceded by "log" # Globals: # txtyellow # txtnormal ####################################### function logInfo() { if [[ ! $2 ]]; then echo -e "${txtyellow}log${txtnormal} | $1" else echo -en "${txtyellow}log${txtnormal} | $1" fi } ####################################### # Append [ OK ] to the end of current line # Outputs: # Writes "[ OK ]" # Globals: # txtgreen # txtnormal ####################################### function logInfoAddOK() { echo -e "[${txtgreen}OK${txtnormal}]" || logInfo "[OK]" } ####################################### # Append [ Fail ] to the end of current line # Arguments: # None # Outputs: # Writes "[ Fail ]" # Globals: # txtred # txtnormal ####################################### function logInfoAddFail() { echo -e "[${txtred}Fail${txtnormal}]" || logInfo "[Fail]" } ####################################### # Display an error message. # Arguments: # Message to display. # Outputs: # Writes the error message, preceded by "error" # Globals: # txtred # txtnormal ####################################### function logError() { echo -e "${txtred}error${txtnormal} | $1" } ####################################### # Display a log message, without return char at the end.. # Arguments: # Message to display. # Outputs: # Writes the message, preceded by "log" # Globals: # txtblue # txtnormal ####################################### function logQuestion() { echo -en "${txtblue}log${txtnormal} | $1" } # # Utility functions # ####################################### # Get username of file. # Arguments: # Path to the file. # Returns: # The group. ####################################### function getUser() { stat -c '%U' "$1" } ####################################### # Get user group of a file. # Arguments: # Path to the file. # Returns: # The group. ####################################### function getGroup() { stat -c '%G' "$1" } # # Pre-installation functions # ####################################### # Display the welcome message # Outputs: # Writes the welcome message # Globals: # txtyellow # txtred # textgreen # txtnormal # Arguments: # None ####################################### function welcome() { echo -e "############################################################" echo -e "# #" echo -e "# Welcome to ${txtyellow}RootDB${txtnormal} install script #" echo -e "# #" echo -e "############################################################" echo echo -e "This script will install or update RootDB code with, by default, the latest version available." echo echo -e "${txtred}This script does not handle the configuration of these services below :${txtnormal}" echo -e "* nginx : https://documentation.rootdb.fr/install/install_without_docker.html#nginx" echo -e "* memcached" echo -e "* php-fpm : https://documentation.rootdb.fr/install/install_without_docker.html#php-fpm" echo -e "* mariadb : https://documentation.rootdb.fr/install/install_without_docker.html#mariadb" echo -e " You should have a specific rootdb api user already setup: https://documentation.rootdb.fr/install/install_without_docker.html#mariadb" echo -e "* supervisor : https://documentation.rootdb.fr/install/install_without_docker.html#supervisor" echo echo echo -e "${txtgreen}Steps executed by this script${txtnormal}" echo -e "\t1 - check if software dependencies & PHP modules are available." echo -e "\t2 - check directories, supervisor configuration, memcached, mariadb connexion are OK." echo -e "\t3 - download RootDB code from git repositories." echo -e "\t4 - link the API and frontend environments files." echo -e "\t5 - bootstrap RootDB." echo echo -e "${txtgreen}Notes${txtnormal}" echo -e "\tUse argument ${txtyellow}-v${txtnormal} to display all available options." echo -e "\tBefore running this script you should update your ${txtyellow}environments${txtnormal} files :" echo -e "\t- ${txtyellow}api_env${txtnormal} - API configuration" echo -e "\t- ${txtyellow}app-config.js${txtnormal} - Frontend configuration" echo } ####################################### # Check if user of this script is the root system user. # If not, stop the execution of the script, return code 1 # Arguments: # None ####################################### function isRootUser() { if [[ "$(whoami)" != "root" ]]; then echo logError "you have to be \`root\` user in order to run this script." echo exit 1 fi } ####################################### # Ask the user if he setup his environment files correctly. # If not, stop the execution of the script. # Globals: # txtyellow # txtnormal # Arguments: # None ####################################### function warningEnvFiles() { logQuestion "Did you think to configure your ${txtyellow}environment${txtnormal} files ? [Y/n]" read -r env_ok echo [[ -z "${env_ok}" ]] && env_ok="y" if [[ "${env_ok}" != "y" ]]; then logInfo "Stopping here." exit 0 fi } ####################################### # Check if the env file is available. If not, stop the script execution. # Globals: # root_api_env_file # root_api_env_file # Arguments: # None ####################################### function checkEnvFiles() { if [[ ! -f "${root_api_env_file}" ]]; then logError "env file \"${root_api_env_file}\" does not exists." exit 1 fi if [[ ! -f "${root_api_env_file}" ]]; then logError "env file \"${root_front_app_config_js_file}\" does not exists." exit 1 fi } ####################################### # Everything start here # Globals: # env_file # version # data_dir # api_memcached_host # api_memcached_port # api_db_host # api_db_port # api_db_root_password # api_db_user_password # api_db_username # api_db_limit_to_ip # nginx_user # nginx_group # rdb_archives_dir # api_dir # front_dir # api_frontend_themes_dir # api_env_file # front_app_config_js_file # root_api_env_file # root_front_app_config_js_file # api_init_file # front_init_file # rdb_init_file # rdb_asked_version # Arguments: # None ####################################### function setEnvVariables() { logInfo "Get some info from environment & system files..." api_memcached_host=$(grep "^MEMCACHED_HOST" "${root_api_env_file}" | sed "s/MEMCACHED_HOST=//") api_memcached_port=$(grep "^MEMCACHED_PORT" "${root_api_env_file}" | sed "s/MEMCACHED_PORT=//") api_db_host=$(grep "^DB_HOST" "${root_api_env_file}" | sed "s/DB_HOST=//") api_db_port=$(grep "^DB_PORT" "${root_api_env_file}" | sed "s/DB_PORT=//") api_db_username=$(grep "^DB_USERNAME" "${root_api_env_file}" | sed "s/DB_USERNAME=//") api_db_user_password=$(grep "^DB_PASSWORD" "${root_api_env_file}" | sed "s/DB_PASSWORD=//") api_db_limit_to_ip=$(grep "^DB_LIMIT_TO_IP" "${root_api_env_file}" | sed "s/DB_LIMIT_TO_IP=//") nginx_user=$(grep '^user' /etc/nginx/nginx.conf | sed "s/user \(.*\);/\1/") nginx_group=$(grep '^user' /etc/nginx/nginx.conf | sed "s/user \(.*\);/\1/") logInfo "Summary :" logInfo logInfo "data dir : ${data_dir}" logInfo "api memcached host : ${api_memcached_host}" logInfo "api memcached port : ${api_memcached_port}" logInfo "api db host : ${api_db_host}" logInfo "api db port : ${api_db_port}" logInfo "api db user password : ****" logInfo "api db limit to ip : ${api_db_limit_to_ip}" logInfo "nginx user : ${nginx_user}" logInfo "nginx group : ${nginx_group}" rdb_archives_dir="${data_dir}/archives" api_dir="${data_dir}/api" front_dir="${data_dir}/frontend" api_frontend_themes_dir="${api_dir}/frontend-themes" api_env_file="${api_dir}/.env" front_app_config_js_file="${front_dir}/app-config.js" rdb_init_file="${data_dir}/.rdb_initialized" echo logQuestion "Is it OK ? [Y/n] " read -r env_ok echo [[ -z "${env_ok}" ]] && env_ok="y" if [[ "${env_ok}" != "y" ]]; then logInfo "Stopping here." exit 0 fi } ####################################### # Check mandatory executable and PHP modules. # Stop the execution of the script if there are missing stuff. # Globals: # error # ignore_software_dependencies # Arguments: # None ####################################### function checkDependencies() { # software dependencies & php modules if [[ ${ignore_software_dependencies} == false ]]; then declare software_checks_failed=false logInfo "Check software dependencies..." true declare commands="awk bunzip2 col curl memcached mysql mysqldump pgrep php sed semver supervisorctl tar" for command_looped in ${commands}; do type -P "${command_looped}" &>/dev/null && continue || { error=true [[ ${software_checks_failed} == false ]] && logInfoAddFail software_checks_failed=true logError "missing software : ${command_looped}" } done [[ ${software_checks_failed} == false ]] && logInfoAddOK declare php_modules_checks_failed=false logInfo "Check PHP modules..." true declare php_modules="bcmath curl ctype dom gd gettext iconv mbstring memcached pcntl pdo zip" for php_module_looped in ${php_modules}; do if [[ -z $(php -r "echo extension_loaded('${php_module_looped}') ? 'ok' : 'ko';" | grep 'ok') ]]; then error=true [[ ${php_modules_checks_failed} == false ]] && logInfoAddFail php_modules_checks_failed=true logError "missing PHP module : ${php_module_looped}" fi done [[ ${php_modules_checks_failed} == false ]] && logInfoAddOK if [[ ${error} == true || ${software_checks_failed} == true || ${php_modules_checks_failed} == true ]]; then logError "There are errors, stopping here." exit 1 fi fi } ####################################### # Check if the installation directory exists and display a warning if not exists. # Globals: # error # data_dir # Arguments: # None ####################################### function checkInstallDirectory() { logInfo "Check install directory..." true if [[ ! -d "${data_dir}" ]]; then error=true logInfoAddFail logError "install directory \"${data_dir}\" does not exists." else logInfoAddOK fi } ####################################### # Check if we have write access to installation directory and display a warning if not. # Globals: # data_dir # error # Arguments: # None ####################################### function checkDirectoriesPermissions() { logInfo "Check permissions..." true if [[ ! -w "${data_dir}" ]]; then error=true logInfoAddFail logError "no write access to : ${data_dir}" else logInfoAddOK fi } ####################################### # Check MariaDB connexion with the root db user. If we cannot connect, display a warning. # Globals: # api_db_root_password # api_db_host # error # Arguments: # None ####################################### function checkMariadbConnexion() { logQuestion "What is the MariaDB root password (used for initial database seeding only) ? " true read -r api_db_root_password echo logInfo "Check mariadb connexion..." true mysql -h "${api_db_host}" -u root -p${api_db_root_password} -e ";" &>/dev/null if [[ $? == 1 ]]; then error=true logInfoAddFail logError "Unable to connect to MariaDB server." else logInfoAddOK fi } ####################################### # Check if API database use has all the needed privileges to run SQL migrations. # If we cannot connect, display a warning. # Globals: # error # api_db_user_password # api_db_username # api_db_limit_to_ip # api_db_host # Arguments: # None ####################################### function checkApiUserGrants() { logInfo "Check API user grants..." true mysql -h "${api_db_host}" -u ${api_db_username} -p${api_db_user_password} -e "SHOW GRANTS FOR '${api_db_username}'@'${api_db_limit_to_ip}';" &>/tmp/grants if [[ $? == 1 ]]; then logInfoAddFail logError "Unable to connect to MariaDB server." error=true else if ! grep -q "ALL PRIVILEGES" /tmp/grants; then declare grants grants=("CREATE" "INSERT" "UPDATE" "DELETE" "DROP" "ALTER") for grant in "${grants[@]}"; do if ! grep -q "${grant}" /tmp/grants; then error=true logInfoAddFail logError "Missing grant: ${grant}" fi done fi fi rm -f /tmp/grants if [[ ${error} == true ]]; then logError "There was an issue fetching ${api_db_username}@${api_db_limit_to_ip} grants." else logInfoAddOK fi } ####################################### # Check if Memcached is working correctly. If not, display a warning. # Globals: # error # api_memcached_port # api_memcached_host # Arguments: # None ####################################### function checkMemcached() { logInfo "Check memcached connexion..." true declare -i test_res test_res=$(php -r "\$c = new Memcached(); \$c->addServer(\"${api_memcached_host}\", ${api_memcached_port}); var_dump(\$c->getStats());" | grep 'array' | wc -l) if [[ ${test_res} -eq 0 ]]; then error=true logInfoAddFail logError "Unable to connect to memcached server." else logInfoAddOK fi } # # # RooDB installation and boostrap # # ####################################### # Check if SSL certificate and private key are available. # Stop the script if there's an issue while fetching the version online. # Globals: # rdb_latest_version_available # rdb_online_latest_version_url # Arguments: # None ####################################### function fetchLatestRootDBVersion() { logInfo "Check latest version of RootDB available..." true rdb_latest_version_available=$(curl --silent "${rdb_online_latest_version_url}" /dev/null 2>&1 | head -1) if [[ -z "${rdb_latest_version_available}" ]]; then logInfoAddFail logError "unable to fetch the latest version of RootDB online :/" exit 1 else logInfoAddOK logInfo "Latest RootDB version available : ${rdb_latest_version_available}" fi } ####################################### # Check RootDB version from API directory, if already installed installed. # Globals: # rdb_current_version # rdb_init_file # Arguments: # None ####################################### function getCurrentRootDBVersion() { logInfo "Check installed version of RootDB..." true if [[ -f "${rdb_init_file}" && -d "${api_dir}" ]]; then rdb_current_version=$(cat "${api_dir}/.version") logInfoAddOK logInfo "Detected version of RootDB currently in use: ${rdb_current_version}" else logInfoAddOK logInfo "RootDB in not yet installed." fi } ####################################### # Check if we can upgrade if the version of RootDB asked is superior to the one currently installed. # Stop the script if there's an issue while fetching the archive online... # Globals: # rdb_asked_version # rdb_current_version # rdb_asked_version # rdb_init_file # Arguments: # None ####################################### function checkIfWeCanUpgradeOrInstall() { declare semver_compare_res=0 if [[ -f "${rdb_init_file}" ]]; then logQuestion "Do you want to rollback to a previous version of RootDB ? [y/N]" read -r rollback echo [[ -z "${rollback}" ]] && rollback="n" if [[ "${rollback}" == "y" ]]; then rollbackRootDB exit 0 fi logInfo "Check if we can update..." semver_compare_res=$(semver compare "${rdb_asked_version}" "${rdb_current_version}") if [[ ${semver_compare_res} == 0 ]]; then logInfo "Nothing to do." echo exit 0 fi fi } ####################################### # Download RootDB archive. # Stop the script if there's an issue while fetching the archive online.. # Globals: # rdb_archive_file # rdb_archives_dir # rdb_version_dir # log_file # Arguments: # rootdb_version ####################################### function extractRootDBArchive() { logInfo "Extracting code from downloaded archive... ( in ${rdb_archives_dir} ) " true [[ -d "${rdb_version_dir}" ]] && rm -Rf "${rdb_version_dir}" tar -xjf "${rdb_archive_file}" -C "${rdb_archives_dir}" &>"${log_file}" if [[ $? != 0 ]]; then logInfoAddFail logError "There was an issue while extracting the code from archive." exit 1 else logInfoAddOK fi } ####################################### # Download RootDB archive. # Stop the script if there's an issue while fetching the archive online.. # Globals: # archive_file # rdb_archives_dir # log_file # Arguments: # rootdb_version ####################################### function downloadAndExtractRootDB() { rdb_archive_file="rootdb-$1.tar.bz2" logInfo "Downloading ${rdb_archive_file}..." true [[ -f ${rdb_archive_file} ]] && rm -f ${rdb_archive_file} curl --silent -O "https://builds.rootdb.fr/rootdb/${rdb_archive_file}" "${log_file}" 2>&1 if [[ ! -f "${rdb_archive_file}" ]]; then logInfoAddFail logError "Unable to download the archive." exit 1 fi logInfoAddOK [[ ! -d "${rdb_archives_dir}" ]] && mkdir "${rdb_archives_dir}" extractRootDBArchive logInfo "Deleting downloaded archive..." rm -f "${rdb_archive_file}" } ####################################### # Bootstrap RootDB database, when we install for the first time RootDB. # Stop the script if there's an issue. # Globals: # api_db_host # api_db_root_password # rdb_version_dir # log_file # Arguments: # None ####################################### function bootstrapDatabase() { echo logQuestion "\`root-db\` schema will be wiped, is it OK ? [Y/n] (n: ignore this step) " read -r env_ok echo [[ -z "${env_ok}" ]] && env_ok="y" if [[ "${env_ok}" == "y" ]]; then logInfo "Database initialization..." true mysql -h "${api_db_host}" -u root -p"${api_db_root_password}" -e "DROP TABLE IF EXISTS telescope_entries_tags; DROP TABLE IF EXISTS telescope_entries;" "rootdb-api" &>"${log_file}" mysql -h "${api_db_host}" -u root -p"${api_db_root_password}" "rootdb-api" <"${rdb_version_dir}/api/storage/app/seeders/production/seeder_init.sql" &>"${log_file}" if [[ $? != 0 ]]; then logInfoAddFail logError "There was an issue while initializing RootDB." exit 1 else logInfoAddOK fi else logInfo "Skipping database initialization." fi } ####################################### # Create all symlinks for api,frontend directories and env files. # Stop the script if there's an issue. # Globals: # rdb_version_dir # data_dir # root_api_env_file # api_frontend_themes_dir # front_app_config_js_file # Arguments: # None ####################################### function symlinkDirAndEnvFiles() { logInfo "Sym-linking api and frontend directories..." logInfo "${rdb_version_dir}/api -> ${data_dir}/api " true [[ -L "${data_dir}/api" ]] && rm -f "${data_dir}/api" ln -s "${rdb_version_dir}/api" "${data_dir}/" if [[ ! -L "${data_dir}/api" ]]; then logInfoAddFail logInfo "Unable to create the symlink." exit 1 else logInfoAddOK fi logInfo "${rdb_version_dir}/frontend -> ${data_dir}/frontend " true [[ -L "${data_dir}/frontend" ]] && rm -f "${data_dir}/frontend" ln -s "${rdb_version_dir}/frontend" "${data_dir}/" if [[ ! -L "${data_dir}/frontend" ]]; then logInfoAddFail logInfo "Unable to create the symlink." exit 1 else logInfoAddOK fi logInfo "Sym-linking env files..." logInfo "${root_api_env_file} -> ${api_env_file} " true [[ -f "${api_env_file}" ]] && rm -f "${api_env_file}" ln -s "${root_api_env_file}" "${api_env_file}" if [[ ! -f "${api_env_file}" ]]; then logInfoAddFail logInfo "Unable to create the symlink." exit 1 else logInfoAddOK fi logInfo "${rdb_version_dir}/frontend/themes -> ${api_frontend_themes_dir} " true [[ -L "${api_frontend_themes_dir}" ]] && rm -f "${api_frontend_themes_dir}" ln -s "${rdb_version_dir}/frontend/themes" "${api_frontend_themes_dir}" if [[ ! -L "${api_frontend_themes_dir}" ]]; then logInfoAddFail logInfo "Unable to create the symlink." exit 1 else logInfoAddOK fi logInfo "${root_front_app_config_js_file} -> ${front_app_config_js_file} " true [[ -f "${front_app_config_js_file}" ]] && rm -f "${front_app_config_js_file}" ln -s "${root_front_app_config_js_file}" "${front_app_config_js_file}" if [[ ! -f "${front_app_config_js_file}" ]]; then logInfoAddFail logInfo "Unable to create the symlink." exit 1 else logInfoAddOK fi } ####################################### # Make sure directories and TLS associated files have the rights permissions. # Globals: # nginx_user # nginx_group # data_dir # Arguments: # None ####################################### function setupFilesPermissions() { logInfo "Setup permissions..." true chown -R ${nginx_user}:${nginx_group} "${data_dir}" logInfoAddOK } ####################################### # Run the SQL migration if needed. # Stop the script if there's any issue. # Globals: # log_file # api_dir # Arguments: # None ####################################### function runSQLMigration() { echo "[API] SQL migrations..." true php "${api_dir}/artisan" migrate -n --force >>"${log_file}" 2>&1 if [[ $? != 0 ]]; then logInfoAddFail logError "There was an issue while running the SQL migration :/" logInfo "Logs: less ${api_dir}/storage/logs/laravel.log" exit 1 else logInfoAddOK fi } ####################################### # Simply display some useful commands. # Globals: # data_dir # rdb_archives_dir # Arguments: # None ####################################### function listInstallDir() { echo logInfo "Install directory:" ls -lha "${data_dir}" echo logInfo "Archive directory:" ls -lha "${rdb_archives_dir}" } ####################################### # Simply display some useful commands. # Globals: # Arguments: # None ####################################### function displayServicesToRestart() { echo logInfo "You should now start (or restart) supervisor, php-fpm, nginx" logInfo "For instance :" logInfo "systemctl restart php8.2-fpm" logInfo "systemctl restart supervisor" logInfo "systemctl restart nginx" } ####################################### # Install RootDB, code, configure API & frontend env file and bootstrap DB is not yet done. # Globals: # rdb_asked_version # rdb_init_file # Arguments: # None ####################################### function installRootDB() { downloadAndExtractRootDB "${rdb_asked_version}" bootstrapDatabase symlinkDirAndEnvFiles setupFilesPermissions # Since we exit the script when there's something wrong, # if we are here, normally, all should be fine. # So let's finalize the installation. touch "${rdb_init_file}" } ####################################### # List all RootDB version currently installed, display a choice list, and ask user to which version # he wants to rollback. # Globals: # rdb_archives_dir # rdb_asked_version # rdb_version_dir # api_env_file # api_frontend_themes_dir # front_app_config_js_file # Arguments: # None ####################################### function getRootDBVersionToRollbackTo() { declare -i choice_num declare -A rollback_versions=() logInfo "Installed version of RootDB :" echo while IFS= read -r rollback_version; do if [[ "${rdb_current_version}" == "${rollback_version}" ]]; then echo -e "${txtyellow}*${txtnormal} - ${rollback_version}" else choice_num=$((choice_num + 1)) rollback_versions[${choice_num}]="${rollback_version}" echo -e "${txtgreen}${choice_num}${txtnormal} - ${rollback_version} " fi done <<<"$(ls -1 "${rdb_archives_dir}")" echo logQuestion "Rollback to which version [1..x] ? " read -r selected_choice if [[ -z "${selected_choice}" ]]; then getRootDBVersionToRollbackTo fi if [[ -z "${rollback_versions[$selected_choice]}" ]]; then getRootDBVersionToRollbackTo fi rdb_asked_version="${rollback_versions[$selected_choice]}" rdb_version_dir="${rdb_archives_dir}/${rdb_asked_version}" api_env_file="${rdb_version_dir}/api/.env" api_frontend_themes_dir="${rdb_version_dir}/api/frontend-themes" front_app_config_js_file="${rdb_version_dir}/frontend/app-config.js" } ####################################### # Rollback to a previous version of RootDB. # Exit if something wrong. # Globals: # rdb_archives_dir # rdb_version_dir # Arguments: # None ####################################### function rollbackRootDB() { logInfo "---------------" logInfo "Rollback RootDB" logInfo "---------------" getRootDBVersionToRollbackTo if [[ ! -d "${rdb_version_dir}" ]]; then logError "${rdb_version_dir} does not exist !" exit 1 fi logInfo "Rollback to RootDB version: ${rdb_asked_version}" symlinkDirAndEnvFiles setupFilesPermissions logInfo "RootDB rollback-ed to ${rdb_asked_version}." } ####################################### # Update RootDB, code, and run SQL migrations. # Globals: # rdb_asked_version # rdb_init_file # Arguments: # None ####################################### function updateRootDB() { downloadAndExtractRootDB "${rdb_asked_version}" symlinkDirAndEnvFiles setupFilesPermissions runSQLMigration logInfo "RootDB upgraded to ${rdb_asked_version}." } ####################################### # Display all available options for this script. # Globals: # OPTARG # ignore_software_dependencies # ignore_mariadb_db_and_user_setup # Arguments: # None ####################################### function help() { echo "$0 [OPTIONS]" echo echo "Options:" echo -e "\t-i - ignore software dependencies checks." echo -e "\t-v - set version of RootDB to download. ( x.y.z )" echo echo -e "\t-d - RootDB main directory file ( ${data_dir} )" echo echo -e "\t-h - display this help and quit." echo exit 0 } while getopts d:e:iv:h option; do case "${option}" in d) data_dir=${OPTARG} ;; i) ignore_software_dependencies=true ;; v) rdb_asked_version=${OPTARG} ;; h) help ;; *) logInfo "Unrecognized option." ;; esac done ####################################### # Everything start here. # Globals: # api_env_file # error # rdb_asked_version # rdb_latest_version_available # api_env_file # front_app_config_js_file # api_frontend_themes_dir # rdb_init_file # Arguments: # None ####################################### function main() { welcome isRootUser warningEnvFiles checkEnvFiles setEnvVariables checkDependencies checkInstallDirectory checkDirectoriesPermissions # Check root db user - only in install mode if [[ ! -f "${rdb_init_file}" ]]; then checkMariadbConnexion fi checkApiUserGrants checkMemcached if [[ ${error} == true ]]; then logInfo "There are errors, stopping here." exit 1 fi # If user does not want a specific version. if [[ -z ${rdb_asked_version} ]]; then fetchLatestRootDBVersion rdb_asked_version=${rdb_latest_version_available} fi getCurrentRootDBVersion checkIfWeCanUpgradeOrInstall logInfo "RootDB version to install or update to : ${txtblue}${rdb_asked_version}${txtnormal}" rdb_version_dir="${rdb_archives_dir}/${rdb_asked_version}" api_env_file="${rdb_version_dir}/api/.env" api_frontend_themes_dir="${rdb_version_dir}/api/frontend-themes" front_app_config_js_file="${rdb_version_dir}/frontend/app-config.js" # If we are here it's because current version of RootDB installed is inferior to the one asked # or it's a fresh installation. if [[ ! -f "${rdb_init_file}" ]]; then logInfo "--------------------------" logInfo "New installation of RootDB" logInfo "--------------------------" installRootDB else logInfo "-------------" logInfo "Update RootDB" logInfo "------------" updateRootDB fi listInstallDir displayServicesToRestart echo logInfo "Done." } main "$@"