diff --git a/utils/backup_app.sh b/utils/backup_app.sh new file mode 100755 index 0000000000000000000000000000000000000000..5f489fc54646d41a4c184136d73f4e6f02976236 --- /dev/null +++ b/utils/backup_app.sh @@ -0,0 +1,170 @@ +#!/bin/bash + +#=== Informations ================================================================# +#- Goal: backup App (Piwigo, prestashop, nextcloud) database and data files +#- Author: B. Mauclaire - bm@ekimia.fr - 2019/11/11 +#- Author: M. Memeteau - mm@ekimia.fr - 2020/01/01 +#- Licence: GNU Affero General Public License v3.0 +#- Note: vm archive's name will be built with the app's name. +#- Warning: sshpass package has to be installed. + +#-- File where host user's password is stored during script is runnung: +PSWDFILE=".nopasswd" + + +#=== Functions ===================================================================# + +#--- Print script's help/usage: +function print_help () +{ + echo "Usage: ./backup_app.sh APP_NAME DB_NAME DB_USER DB_PASSWORD HOST_USER_PSWD [HOST_PORT] [HOST_NAME HOST_USER] [DB_ENGINE(mysql/mariadb/pgsql)]" + exit 1 +} + + +#--- Main program tasks: +function main_proc () +{ + echo "" + echo "***** Backup $APP_NAME application *****" + + #-- Manage some variable used by the script: + declare -a APP_DIRS + echo "$HOST_USER_PSWD" > $PSWDFILE + SSHNOPASS="sshpass -p `cat $PSWDFILE` ssh -p $HOST_PORT ${HOST_USER}@$HOST_NAME" + + #-- Backup: + #testsshnopass + set_host_user_dir + set_app_directories + backup_db + backup_app_data + download_archives + + #-- Remove file whith stored password: + rm -f ./$PSWDFILE + + echo "" + echo "***** End of $APP_NAME backup *****" +} + + +#--- Command for testing not asking ssh connexion password: +function testsshnopass () +{ + + sshpass -p `cat $PSWDFILE` ssh -p $HOST_PORT ${HOST_USER}@$HOST_NAME "ls" + sudo apt install sshpass -y +} + + +#--- Set applications' directories to backup: +function set_app_directories () +{ + case $APP_NAME in + piwigo) + #-- i=photos/_data/i ; upload=photos/upload + APP_DIR="/var/www/photos" ; + APP_DIRS=( "_data/i" "upload" "local/config" ) ; + ;; + prestashop) + # See for 1.7 https://devdocs.prestashop.com/1.7/development/architecture/ + APP_DIR="/var/www/" ; + APP_DIRS=( "shop" ) ; + ;; + nextcloud) + APP_DIR="/var/www/nextcloud" ; + APP_DIRS=( "apps" "custom_apps" "config" "data" ) ; + ;; + esac +} + + +#--- Set remote user's home directory: +function set_host_user_dir () +{ + if [ "$HOST_USER" == "root" ] ; then + HOST_USER_DIR="/${HOST_USER}" + else + HOST_USER_DIR="/home/${HOST_USER}" + fi +} + + +#--- Application's files backup: +function backup_app_data () +{ + echo "" + echo "*** Build archives ${APP_NAME}*.tgz on remote host $HOST_NAME... ***" + + for APP_DIRI in ${APP_DIRS[*]} ; do + DIRI_NAME=`echo "$APP_DIRI" | sed -s 's/\//\_/g'` + echo "Build archive of directory: $APP_DIRI" + $SSHNOPASS "cd ${APP_DIR} ; tar czf ${HOST_USER_DIR}/${APP_NAME}_${DIRI_NAME}.tgz $APP_DIRI" + done + + echo "*** Archives built! ***" +} + + +#--- Download archives files built on remote app server: +function download_archives () +{ + #-- Download application's data archive: + echo "" + echo "*** Start downloading data archives (be patient)... ***" + sshpass -p `cat $PSWDFILE` scp -P $HOST_PORT ${HOST_USER}@$HOST_NAME:${HOST_USER_DIR}/${APP_NAME}*.tgz . + #TODO : test if transfer was OK + #$SSHNOPASS "rm -f ${HOST_USER_DIR}/${APP_NAME}*.tgz" + echo "*** Archives ${APP_NAME}*.tgz downloaded! ***" + + #-- Download application's database dump: + #- Database's archive downloaded in backup_db function +} + + +#--- Database backup: +function backup_db () +{ + echo "" + echo "*** Database backup from $HOST_NAME to local file ${DB_NAME}.sql ***" + + case $DB_ENGINE in + "mysql" | "mariadb") + $SSHNOPASS "mysqldump '"$DB_NAME"' -u '"$DB_USER"' -p'"${DB_PWD}"'" > ${DB_NAME}.sql + ;; + "pgsql") + #- !! TO TEST !! + # $SSHNOPASS "PGPASSWORD='"${DB_PWD}"' pg_dump --format=plain--file --create -U '"$DB_USER"' '"$DB_NAME"'" > ${DB_NAME}.sql + $SSHNOPASS "PGPASSWORD='"${DB_PWD}"' pg_dump -F p -U '"$DB_USER"' '"$DB_NAME"'" > ${DB_NAME}.sql + # pg_dump postgresql://username:password@127.0.0.1:5432/mydatabase + ;; + esac + + echo "*** Database dump downloaded! ***" +} + + + +#=== Main program ===================================================================# +#--- Manage arguments: +case $# in + 5) APP_NAME="$1" ; DB_NAME="$2" ; DB_USER="$3" ; DB_PWD="$4" ; HOST_USER_PSWD="$5" + HOST_NAME='jaguar.ekimia.fr' ; HOST_PORT=622 ; HOST_USER='root' ; DB_ENGINE="mysql" + main_proc + ;; + 6) APP_NAME="$1" ; DB_NAME="$2" ; DB_USER="$3" ; DB_PWD="$4" ; HOST_USER_PSWD="$5" ; HOST_PORT="$6" + HOST_NAME='jaguar.ekimia.fr' ; 622 ; HOST_USER='root' ; DB_ENGINE="mysql" + main_proc + ;; + 8) APP_NAME="$1" ; DB_NAME="$2" ; DB_USER="$3" ; DB_PWD="$4" ; HOST_USER_PSWD="$5" ; HOST_PORT="$6" ; HOST_NAME="$7" ; HOST_USER="$8" + DB_ENGINE="mysql" + main_proc + ;; + 9) APP_NAME="$1" ; DB_NAME="$2" ; DB_USER="$3" ; DB_PWD="$4" ; HOST_USER_PSWD="$5" ; HOST_PORT="$6" ; HOST_NAME="$7" ; HOST_USER="$8" ; DB_ENGINE="$9" + main_proc + ;; + *) print_help ; + ;; +esac +#=== End of script ==================================================================# diff --git a/utils/restore_app.sh b/utils/restore_app.sh new file mode 100755 index 0000000000000000000000000000000000000000..c76b6d9795db4741446edf2fcb297921d28ad09d --- /dev/null +++ b/utils/restore_app.sh @@ -0,0 +1,156 @@ +#!/bin/bash + + +#=== Informations ===================================================================# +#- Goal: restore application's database and data files +#- Author: B. Mauclaire - bm@ekimia.fr - 2019/11/13 +#- Licence: GNU Affero General Public License v3.0 +#- Usage: +# * Argument: application's name, database container's ID/NAME, database engine +# * The script has to be ran with sudo in order to be able to write in volume's directories. +# * Run in the directory containing vm archives + db.env + docker-compose.yml: so docker app directory's name isn't necessary. +# * Vm archive's name is built with the application's name, so files' name are generic in this script. +# * Data files will be restored in "data" directory as data file archives contain subdirectory. + + +#=== Functions ===================================================================# + +#--- Print script's help/usage: +function print_help () +{ + echo "Usage: sudo ./restore_app.sh APLICATION_NAME(piwigo/prestashop/nextcloud) DATABASE_CONTAINER_ID/NAME [DB_ENGINE(mysql/mariadb/pgsql)]" + exit 1 +} + + +#--- Main program tasks: +function main_proc () +{ + echo "" + echo "***** Restore $APP_NAME application data *****" + + #-- Manage some variable used by the script: + check_arguments + DATA_DIR='data' + + #-- Restore: + db_informations + restore_db + restore_data + update_app_config + + echo "" + echo "***** End of $APP_NAME restore *****" +} + + +#--- Check APP_NAME argument: +function check_arguments () +{ + if [ "$APP_NAME" != "piwigo" ] && [ "$APP_NAME" != "prestashop" ] && [ "$APP_NAME" != "nextcloud" ] ; then + echo "Application's name must be one of piwigo/prestashop/nextcloud." + exit 1 + fi +} + + +#--- Filling database variable from db.env: +function db_informations () +{ + echo "*** Filling database variable from db.env ***" + #-- Use db.env and pwg.env to get user + pswd already in variables without regexp: + source .env + case $DB_ENGINE in + "mysql" | "mariadb") + #- Fill the following variables: MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, PUID, PGID, TZ. + DB_NAME="$MYSQL_DATABASE" + DB_USER="$MYSQL_USER" + DB_PWD="$MYSQL_PASSWORD" + DB_ROOT_USER="root" + DB_ROOT_PWD="$MYSQL_ROOT_PASSWORD" + ;; + "pgsql") + #- // TO TEST //# + DB_NAME="$POSTGRES_DB" + DB_USER="$POSTGRES_USER" + DB_PWD="$POSTGRES_PASSWORD" + ;; + esac +} + + +#--- Restore database: +function restore_db () +{ + echo "*** Database restore from sql dump ***" + + #-- Restore database from sql archive: + #- Database container name is 'db' and it's assumed that it is define like that in app's docker-compose.yml file. + case $DB_ENGINE in + "mysql" | "mariadb") + docker-compose exec -T db bash -c "mysql -u '"$DB_ROOT_USER"' --password='"${DB_ROOT_PWD}"' '"$DB_NAME"'" < ${DB_NAME}.sql + #docker exec -i $CONT_DB_ID bash -c "mysql -u '"$DB_ROOT_USER"' -p${DB_ROOT_PWD} '"$DB_NAME"'" < ${DB_NAME}.sql + #cat ${DB_NAME}.sql | docker exec -i $CONT_DB_ID /usr/bin/mysql '"$DB_NAME"' -u '"$DB_ROOT_USER"' --password='"$DB_ROOT_PWD"' + ;; + "pgsql") + #- // TO TEST //# + docker-compose exec -T db bash -c "PGPASSWORD='"$DB_PWD"' psql -U '"$DB_USER"' '"$DB_NAME"'" < ${DB_NAME}.sql + #docker exec -i $CONT_DB_ID bash -c "PGPASSWORD='"$DB_PWD"' psql -U '"$DB_USER"' '"$DB_NAME"'" < ${DB_NAME}.sql + #cat ${DB_NAME}.sql | docker exec -i $CONT_DB_ID PGPASSWORD='"$DB_PWD"' /usr/bin/psql -U '"$DB_USER"' '"$DB_NAME"' + ;; + esac + + echo "*** Database dump restored! ***" +} + + +#--- Restore data files: +function restore_data () +{ + echo "*** Restore application data from ${APP_NAME}_*.tgz to container directory ***" + echo "** Start uncompressing archive(s) (be patient)... **" + cd $APP_DIR + for archfile in ../*.tgz ; do + echo "Uncompress $archfile..." + tar -xzf $archfile + done + echo "*** Archive(s) *.tgz restored! ***" +} + + +#--- Update application configuration files with container's setup: +#-- This function depends on application +function update_app_config () +{ + case $APP_NAME in + "piwigo") + #-- Update db_host name to be container's databse's name in docker-compose.yml, assummed 'db'. See docker-compose.yml for "config" volume name: + #sed -i -e 's/localhost/db/' "$DATA_DIR/config/database.inc.php" + sed -i -e 's/localhost/$CONT_DB_ID/' "$DATA_DIR/local/config/database.inc.php" + mv $DATA_DIR/local/config/config.inc.php $DATA_DIR/local/config/config.inc.php.old + ;; + "prestashop") + #-- Todo: + #Delete the admin dir if exists + #Change db name and mysql root password in config/settings.inc.php + ;; + "nextcloud") + #-- Todo: + ;; + esac +} + + + +#=== Main program ===================================================================# +#--- Manage arguments: +case $# in + 2) APP_NAME="$1" ; CONT_DB_ID="$2" ; DB_ENGINE="mysql" + main_proc + ;; + 3) APP_NAME="$1" ; CONT_DB_ID="$2" ; DB_ENGINE="$3" + main_proc + ;; + *) print_help ;; +esac +#=== End of script ==================================================================#