From 1a3ae94a75de87585ba70a0e41740a717a8bb5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Thu, 16 Nov 2017 21:10:21 +0100 Subject: [PATCH] Create Final App --- README.md | 9 +++ conf/app.src | 6 -- conf/armv7.src | 11 +++ conf/config_local.py | 1 + conf/nginx.conf | 32 ++------ conf/pgadmin.ini | 27 +++++++ conf/setup.exp | 20 +++++ conf/virtualenv_activate | 78 +++++++++++++++++++ manifest.json | 5 +- scripts/_common.sh | 66 +++++++++++++---- scripts/backup | 28 ++----- scripts/config_database.py | 41 ++++++++++ scripts/install | 53 ++++++++----- scripts/pgsql.sh | 92 ----------------------- scripts/psql.sh | 148 +++++++++++++++++++++++++++++++++++++ scripts/remove | 16 +++- scripts/restore | 58 +++++---------- scripts/upgrade | 74 ++++--------------- 18 files changed, 480 insertions(+), 285 deletions(-) delete mode 100644 conf/app.src create mode 100644 conf/armv7.src create mode 100644 conf/config_local.py create mode 100644 conf/pgadmin.ini create mode 100644 conf/setup.exp create mode 100644 conf/virtualenv_activate create mode 100644 scripts/config_database.py delete mode 100644 scripts/pgsql.sh create mode 100644 scripts/psql.sh diff --git a/README.md b/README.md index a78282e..0988501 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ Pgadmin for yunohost *https://www.pgadmin.org +[![Integration level](https://dash.yunohost.org/integration/pgadmin.svg)](https://ci-apps.yunohost.org/jenkins/job/pgadmin%20%28Community%29/lastBuild/consoleFull) + +[![Install PgAdmin with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=pgadmin) + Install ------- @@ -22,3 +26,8 @@ License ------- Pgadmin is published under the the PostgreSQL licence : https://www.pgadmin.org/licence/ + +TODO +---- + +- Test temps build arm \ No newline at end of file diff --git a/conf/app.src b/conf/app.src deleted file mode 100644 index d1b5871..0000000 --- a/conf/app.src +++ /dev/null @@ -1,6 +0,0 @@ -SOURCE_URL=https://github.com/phppgadmin/phppgadmin/archive/c7c6beb7d9f98ff50c0efa3911f1a2d86a5eed95.zip -SOURCE_SUM=2cad00762b1901706392a05ecc1d86ecf1bb43bb51605572629414699cfe1aef -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=zip -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME= diff --git a/conf/armv7.src b/conf/armv7.src new file mode 100644 index 0000000..867d2cb --- /dev/null +++ b/conf/armv7.src @@ -0,0 +1,11 @@ +SOURCE_URL=https://github.com/Josue-T/pgadmin_python_build/releases/download/v4-2.0/pgadmin_4-2.0-bin1_armv7l.tar.gz +SOURCE_SUM=442c5ec2192b2f8cb3441937d3628c301f6eaae30754cedfd8bed8cbf30855a2 +# (Optional) Program to check the integrity (sha256sum, md5sum...) +# default: sha256 +SOURCE_SUM_PRG=sha256sum +# (Optional) Archive format +# default: tar.gz +SOURCE_FORMAT=tar.gz +# (Optional) Put false if sources are directly in the archive root +# default: true +SOURCE_IN_SUBDIR=true diff --git a/conf/config_local.py b/conf/config_local.py new file mode 100644 index 0000000..bad0b92 --- /dev/null +++ b/conf/config_local.py @@ -0,0 +1 @@ +DESKTOP_USER = '__USER__@__DOMAIN__' \ No newline at end of file diff --git a/conf/nginx.conf b/conf/nginx.conf index fac6349..3746141 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,29 +1,7 @@ location __PATH__ { + include uwsgi_params; + uwsgi_pass unix:///run/uwsgi/app/pgadmin/socket; - alias __FINALPATH__/ ; - - if ($scheme = http) { - rewrite ^ https://$server_name$request_uri? permanent; - } - - index index.php; - - client_max_body_size 50M; - - try_files $uri $uri/ index.php; - location ~ [^/]\.php(/|$) { - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - fastcgi_pass unix:/var/run/php5-fpm-__NAME__.sock; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param REMOTE_USER $remote_user; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_read_timeout 600; - fastcgi_buffers 16 16k; - fastcgi_buffer_size 32k; - } - - # Include SSOWAT user panel. - include conf.d/yunohost_panel.conf.inc; -} + # Include SSOWAT user panel. + include conf.d/yunohost_panel.conf.inc; +} \ No newline at end of file diff --git a/conf/pgadmin.ini b/conf/pgadmin.ini new file mode 100644 index 0000000..32cb96c --- /dev/null +++ b/conf/pgadmin.ini @@ -0,0 +1,27 @@ +[uwsgi] +# Who will run the code +uid = __USER__ +gid = __USER__ + +# Number of workers +workers = 1 + +# The right granted on the created socket +chmod-socket = 666 + +# Plugin to use and interpretor config +single-interpreter = true +master = true +plugin = python + +# Manage the subpath +manage-script-name = true +mount = __PATH__=pgAdmin4.py + +# Virtualenv and python path +virtualenv = __FINALPATH__ +pythonpath = __FINALPATH__ +chdir = __FINALPATH__/lib/python2.7/site-packages/pgadmin4 + +# The variable holding flask application +callable = app \ No newline at end of file diff --git a/conf/setup.exp b/conf/setup.exp new file mode 100644 index 0000000..be9b28c --- /dev/null +++ b/conf/setup.exp @@ -0,0 +1,20 @@ +#!/usr/bin/expect +set timeout 10 + +set cmd [lindex $argv 0] +set path [lindex $argv 1] +set user [lindex $argv 2] +set password [lindex $argv 3] + +spawn $cmd $path + +expect "Email address:" +send "$user\r"; + +expect "Password:" +send "$password\r"; + +expect "Retype password:" +send "$password\r"; + +interact diff --git a/conf/virtualenv_activate b/conf/virtualenv_activate new file mode 100644 index 0000000..6aea9b1 --- /dev/null +++ b/conf/virtualenv_activate @@ -0,0 +1,78 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + unset -f pydoc >/dev/null 2>&1 + + # reset old environment variables + # ! [ -z ${VAR+_} ] returns true if VAR is declared at all + if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then + PATH="$_OLD_VIRTUAL_PATH" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then + PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null + fi + + if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then + PS1="$_OLD_VIRTUAL_PS1" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/opt/yunohost/pgadmin" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +if ! [ -z "${PYTHONHOME+_}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then + _OLD_VIRTUAL_PS1="$PS1" + if [ "x" != x ] ; then + PS1="$PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1" + fi + export PS1 +fi + +# Make sure to unalias pydoc if it's already there +alias pydoc 2>/dev/null >/dev/null && unalias pydoc + +pydoc () { + python -m pydoc "$@" +} + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null +fi diff --git a/manifest.json b/manifest.json index 14d7be7..61f2728 100644 --- a/manifest.json +++ b/manifest.json @@ -8,7 +8,7 @@ }, "version": "4-2.0", "url": "https://www.pgadmin.org", - "license": " PostgreSQL", + "license": "PostgreSQL", "maintainer": { "name": "Josué", "email": "josue@tille.ch" @@ -19,6 +19,7 @@ "multi_instance": false, "services": [ "nginx", + "uwsgi" ], "arguments": { "install" : [ @@ -49,7 +50,7 @@ "fr": "Choisissez l'unique utilisateur autorisé" }, "example": "johndoe" - } + }, { "name": "admin_password", "type": "password", diff --git a/scripts/_common.sh b/scripts/_common.sh index 3056f9a..d1f7be4 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -1,8 +1,18 @@ app=$YNH_APP_INSTANCE_NAME -db_user="$app" +final_path=/opt/yunohost/$app +pgadmin_user="pgadmin" + +get_app_version_from_json() { + manifest_path="../manifest.json" + if [ ! -e "$manifest_path" ]; then + manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place + fi + echo $(grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file. +} +APP_VERSION=$(get_app_version_from_json) install_dependance() { - ynh_install_app_dependencies postgresql php5-pgsql + ynh_install_app_dependencies python-pip build-essential python-dev python-virtualenv postgresql uwsgi uwsgi-plugin-python expect } psql_create_admin() { @@ -10,22 +20,48 @@ psql_create_admin() { "CREATE USER ${1} WITH PASSWORD '${2}';" } +setup_dir() { + # Create empty dir for pgadmin + mkdir -p /var/lib/pgadmin + mkdir -p /var/log/pgadmin + mkdir -p $final_path +} +install_source() { + if [ -n "$(uname -m | grep arm)" ] + then + ynh_setup_source $final_path/ "armv7" + else +# Install virtualenv if it don't exist + test -e $final_path/bin || virtualenv -p python2.7 $final_path +# Install pgadmin in virtualenv + PS1="" + cp ../conf/virtualenv_activate $final_path/bin/activate + source $final_path/bin/activate + pip install --upgrade pip + pip install --upgrade https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v2.0/pip/pgadmin${APP_VERSION}-py2.py3-none-any.whl + deactivate + fi +} +set_permission() { + # Set permission + chown $pgadmin_user:root -R $final_path + chown $pgadmin_user:root -R /var/lib/pgadmin + chown $pgadmin_user:root -R /var/log/pgadmin +} +config_pgadmin() { + ynh_replace_string __USER__ $pgadmin_user ../conf/config_local.py + ynh_replace_string __DOMAIN__ $domain ../conf/config_local.py + cp ../conf/config_local.py $final_path/lib/python2.7/site-packages/pgadmin4/config_local.py +} - - - - - - - - - - - - - +config_uwsgi() { + ynh_replace_string __USER__ $pgadmin_user ../conf/pgadmin.ini + ynh_replace_string __FINALPATH__ $final_path ../conf/pgadmin.ini + ynh_replace_string __PATH__ $path_url ../conf/pgadmin.ini + cp ../conf/pgadmin.ini /etc/uwsgi/apps-enabled/ +} diff --git a/scripts/backup b/scripts/backup index d1f991a..bcabd7c 100644 --- a/scripts/backup +++ b/scripts/backup @@ -7,35 +7,21 @@ source /usr/share/yunohost/helpers ynh_abort_if_errors # Import common cmd -source ./_common.sh +source ../settings/scripts/_common.sh +source ../settings/scripts/psql.sh # LOAD SETTINGS final_path=$(ynh_app_setting_get $app final_path) domain=$(ynh_app_setting_get $app domain) db_name=$(ynh_app_setting_get $app db_name) -#================================================= -# STANDARD BACKUP STEPS -#================================================= # BACKUP THE APP MAIN DIR -#================================================= - ynh_backup "$final_path" -#================================================= -# BACKUP THE NGINX CONFIGURATION -#================================================= - +# Backup config ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" +ynh_backup "/etc/uwsgi/apps-enabled/pgadmin.ini" -#================================================= -# BACKUP THE PHP-FPM CONFIGURATION -#================================================= - -ynh_backup "/etc/php5/fpm/pool.d/$app.conf" - -#================================================= -# BACKUP THE MYSQL DATABASE -#================================================= - -ynh_mysql_dump_db "$db_name" > db.sql +# Backup Data and LOG +ynh_backup "/var/lib/pgadmin" +ynh_backup "/var/log/pgadmin" diff --git a/scripts/config_database.py b/scripts/config_database.py new file mode 100644 index 0000000..85e6837 --- /dev/null +++ b/scripts/config_database.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + +import imp +import sqlite3 +import sys + +# Import crypto from pgadmin project +crypto = imp.load_source('crypt', '/opt/yunohost/pgadmin/lib/python2.7/site-packages/pgadmin4/pgadmin/utils/crypto.py') + +# Get arguments +username = sys.argv[1] +password = sys.argv[2] + +# Connect to sqlite3 +conn = sqlite3.connect('/var/lib/pgadmin/pgadmin4.db') + +# Get encrypte user password from the database +cursor = conn.execute('SELECT `password`,1 FROM `user`') +user_encrypted_password = cursor.fetchone()[0] + +# Encrypt database password +crypted_password = crypto.encrypt(password, user_encrypted_password) + +# Declare database data to put in database +data = {'id': 1,'user_id': 1, 'servergroup_id' : 1, 'name': 'Yunohost Server', 'host': 'localhost', 'port': 5432,'maintenance_db':'postgres','username':username, + 'ssl_mode':'prefer', 'comment' : '', 'password' :crypted_password,'role':'', 'discovery_id':'', 'hostaddr':'','db_res':'','passfile':'', + 'sslcert' :'','sslkey':'','sslrootcert':'','sslcrl':''} + +# Insert new data in database +cursor = conn.cursor() +cursor.execute('''INSERT INTO `server`( + `id`,`user_id`,`servergroup_id`,`name`,`host`,`port`,`maintenance_db`,`username`, + `ssl_mode`,`comment`,`password`,`role`,`discovery_id`,`hostaddr`,`db_res`,`passfile`,`sslcert`,`sslkey`,`sslrootcert`,`sslcrl` + ) VALUES( + :id,:user_id,:servergroup_id,:name,:host,:port,:maintenance_db,:username, + :ssl_mode,:comment,:password,:role,:discovery_id,:hostaddr,:db_res,:passfile,:sslcert,:sslkey,:sslrootcert,:sslcrl + )''', data) +conn.commit() + +# Close connection +conn.close() \ No newline at end of file diff --git a/scripts/install b/scripts/install index 32b278a..66bd331 100644 --- a/scripts/install +++ b/scripts/install @@ -8,15 +8,16 @@ ynh_abort_if_errors # Import common cmd source ./_common.sh +source ./psql.sh # RETRIEVE ARGUMENTS FROM THE MANIFEST domain=$YNH_APP_ARG_DOMAIN path_url=$(ynh_normalize_url_path $YNH_APP_ARG_PATH) admin=$YNH_APP_ARG_ADMIN admin_pwd=$YNH_APP_ARG_ADMIN_PASSWORD +db_user="pgadmin" # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS -final_path=/var/www/$app test ! -e "$final_path" || ynh_die "This path already contains a folder" # Check web path availability @@ -27,50 +28,62 @@ ynh_webpath_register $app $domain $path_url # Build user password db_pwd=$(ynh_string_random 30) +# Reserch an opened porf for pgadmin +port=$(ynh_find_port 5050) + # STORE SETTINGS FROM MANIFEST ynh_app_setting_set $app domain $domain ynh_app_setting_set $app path $path_url +ynh_app_setting_set $app pgadmin_port $port ynh_app_setting_set $app admin $admin ynh_app_setting_set $app admin_pwd "$admin_pwd" +ynh_app_setting_set $app db_user "$db_user" +ynh_app_setting_set $app db_pwd "$db_pwd" # Install dependance install_dependance +# Create user +ynh_system_user_create $pgadmin_user /var/lib/pgadmin + # DOWNLOAD, CHECK AND UNPACK SOURCE ynh_app_setting_set $app final_path $final_path # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source "$final_path" +setup_dir +install_source + +# CONFIGURE PGADMIN +config_pgadmin + +# Config uwsgi +config_uwsgi # Create a dedicated nginx config ynh_add_nginx_config -# Create a dedicated php-fpm config -ynh_add_fpm_config +# initialisation sqlite database for pgadmin +chmod +x ../conf/setup.exp +source $final_path/bin/activate +../conf/setup.exp "$final_path/bin/python2.7" "$final_path/lib/python2.7/site-packages/pgadmin4/setup.py" "$admin@$domain" "$admin_pwd" # POPULATE THE DATABASE ynh_psql_test_if_first_run -psql_create_admin $db_user "$admin_pwd" +su --command="psql -c\"CREATE USER ${db_user} WITH PASSWORD '${db_pwd}' SUPERUSER CREATEDB CREATEROLE REPLICATION\"" postgres -# CONFIGURE PHPMYADMIN +# Add Server In PGadmin database +$final_path/bin/python2.7 config_database.py "$db_user" "$db_pwd" +deactivate -# ynh_replace_string "YNH_DOMAIN" "$domain" ../conf/config.inc.php -# ynh_replace_string "YNH_PMA_USER" "$db_name" ../conf/config.inc.php -# ynh_replace_string "YNH_PMA_PASSWORD" "$db_pwd" ../conf/config.inc.php -# ynh_replace_string "YNH_MYSQL_ROOT_PASSWORD" "$(cat $MYSQL_ROOT_PWD_FILE)" ../conf/config.inc.php -cp ../conf/config.inc.php ${final_path}/conf/ - -# Recalculate and store the config file checksum into the app settings -ynh_store_file_checksum "$final_path/conf/config.inc.php" - -# Set permissions to app files -chown -R root: $final_path -# config.inc.php contains sensitive data, restrict its access -chown root:$app $final_path/conf/config.inc.php -chmod 640 $final_path/conf/config.inc.php +# Set permission after initialisation +set_permission # Restrict access to admin only yunohost app addaccess --users=$admin $app +# Configuration de logrotate +ynh_use_logrotate /var/log/pgadmin + # RELOAD NGINX systemctl reload nginx +systemctl restart uwsgi diff --git a/scripts/pgsql.sh b/scripts/pgsql.sh deleted file mode 100644 index 2aa0580..0000000 --- a/scripts/pgsql.sh +++ /dev/null @@ -1,92 +0,0 @@ -# Open a connection as a user -# -# example: ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;" -# example: ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql -# -# usage: ynh_psql_connect_as user pwd [db] -# | arg: user - the user name to connect as -# | arg: pwd - the user password -# | arg: db - the database to connect to -ynh_psql_connect_as() { - ynh_die "ynh_psql_connect_as is not yet implemented" -} - -# # Execute a command as root user -# -# usage: ynh_psql_execute_as_root sql [db] -# | arg: sql - the SQL command to execute -# | arg: db - the database to connect to -ynh_psql_execute_as_root () { - sudo su -c "psql" - postgres <<< ${1} -#TODO support db argument ? -} - -# Execute a command from a file as root user -# -# usage: ynh_psql_execute_file_as_root file [db] -# | arg: file - the file containing SQL commands -# | arg: db - the database to connect to -ynh_psql_execute_file_as_root() { - ynh_die "ynh_psql_execute_file_as_root is not yet implemented" -} - -# Create a database and grant optionnaly privilegies to a user -# -# usage: ynh_psql_create_db db [user [pwd]] -# | arg: db - the database name to create -# | arg: user - the user to grant privilegies -# | arg: pwd - the password to identify user by -ynh_psql_create_db() { - db=$1 - # grant all privilegies to user - if [[ $# -gt 1 ]]; then - ynh_psql_create_user ${2} "${3}" - sudo su -c "createdb -O ${2} $db" - postgres - else - sudo su -c "createdb $db" - postgres - fi - -} - -# Drop a database -# -# usage: ynh_psql_drop_db db -# | arg: db - the database name to drop -ynh_psql_drop_db() { - sudo su -c "dropdb ${1}" - postgres -} - -# Create a user -# -# usage: ynh_psql_create_user user pwd [host] -# | arg: user - the user name to create -# | arg: pwd - the password to identify user by -ynh_psql_create_user() { - ynh_psql_execute_as_root \ - "CREATE USER ${1} WITH PASSWORD '${2}';" -} - -# Drop a user -# -# usage: ynh_psql_drop_user user -# | arg: user - the user name to drop -ynh_psql_drop_user() { - sudo su -c "dropuser ${1}" - postgres -} - -ynh_psql_test_if_first_run() { - if [ -f /etc/yunohost/psql ]; - then - echo "PostgreSQL is already installed, no need to create master password" - else - local pgsql=$(ynh_string_random) - echo "$pgsql" >> /etc/yunohost/psql - systemctl start postgresql - sudo -u postgres psql -c "ALTER user postgres WITH PASSWORD '${pgsql}'" - # we can t use peer since YunoHost create users with nologin - sed -i '/local\s*all\s*all\s*peer/i \ - local all all password' /etc/postgresql/9.4/main/pg_hba.conf - systemctl enable postgresql - systemctl reload postgresql - fi -} \ No newline at end of file diff --git a/scripts/psql.sh b/scripts/psql.sh new file mode 100644 index 0000000..9789a29 --- /dev/null +++ b/scripts/psql.sh @@ -0,0 +1,148 @@ +#================================================= +# POSTGRES HELPERS +#================================================= + +# Open a connection as a user +# +# example: ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;" +# example: ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql +# +# usage: ynh_psql_connect_as user pwd [db] +# | arg: user - the user name to connect as +# | arg: pwd - the user password +# | arg: db - the database to connect to +ynh_psql_connect_as() { + user="$1" + pwd="$2" + db="$3" + su --command="PGUSER=\"${user}\" PGPASSWORD=\"${pwd}\" psql \"${db}\"" postgres +} + +# # Execute a command as root user +# +# usage: ynh_psql_execute_as_root sql [db] +# | arg: sql - the SQL command to execute +# | arg: db - the database to connect to +ynh_psql_execute_as_root () { + sql="$1" + su --command="psql" postgres <<< "$sql" +} + +# Execute a command from a file as root user +# +# usage: ynh_psql_execute_file_as_root file [db] +# | arg: file - the file containing SQL commands +# | arg: db - the database to connect to +ynh_psql_execute_file_as_root() { + file="$1" + db="$2" + su -c "psql $db" postgres < "$file" +} + +# Create a database, an user and its password. Then store the password in the app's config +# +# After executing this helper, the password of the created database will be available in $db_pwd +# It will also be stored as "psqlpwd" into the app settings. +# +# usage: ynh_psql_setup_db user name [pwd] +# | arg: user - Owner of the database +# | arg: name - Name of the database +# | arg: pwd - Password of the database. If not given, a password will be generated +ynh_psql_setup_db () { + db_user="$1" + app="$1" + db_name="$2" + new_db_pwd=$(ynh_string_random) # Generate a random password + # If $3 is not given, use new_db_pwd instead for db_pwd. + db_pwd="${3:-$new_db_pwd}" + ynh_psql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database + ynh_app_setting_set "$app" psqlpwd "$db_pwd" # Store the password in the app's config +} + +# Create a database and grant optionnaly privilegies to a user +# +# usage: ynh_psql_create_db db [user [pwd]] +# | arg: db - the database name to create +# | arg: user - the user to grant privilegies +# | arg: pwd - the user password +ynh_psql_create_db() { + db="$1" + user="$2" + pwd="$3" + ynh_psql_create_user "$user" "$pwd" + su --command="createdb --owner=\"${user}\" \"${db}\"" postgres +} + +# Drop a database +# +# usage: ynh_psql_drop_db db user +# | arg: db - the database name to drop +# | arg: user - the user to drop +ynh_psql_remove_db() { + db="$1" + user="$2" + su --command="dropdb \"${db}\"" postgres + ynh_psql_drop_user "${user}" +} + +# Dump a database +# +# example: ynh_psql_dump_db 'roundcube' > ./dump.sql +# +# usage: ynh_psql_dump_db db +# | arg: db - the database name to dump +# | ret: the psqldump output +ynh_psql_dump_db() { + db="$1" + su --command="pg_dump \"${db}\"" postgres +} + + +# Create a user +# +# usage: ynh_psql_create_user user pwd [host] +# | arg: user - the user name to create +ynh_psql_create_user() { + user="$1" + pwd="$2" + su --command="psql -c\"CREATE USER ${user} WITH PASSWORD '${pwd}'\"" postgres +} + +# Drop a user +# +# usage: ynh_psql_drop_user user +# | arg: user - the user name to drop +ynh_psql_drop_user() { + user="$1" + su --command="dropuser \"${user}\"" postgres +} + + +ynh_psql_test_if_first_run() { + if [ -f /etc/yunohost/psql ]; + then + echo "PostgreSQL is already installed, no need to create master password" + else + pgsql=$(ynh_string_random) + pg_hba="" + echo "$pgsql" >> /etc/yunohost/psql + + if [ -e /etc/postgresql/9.4/ ] + then + pg_hba=/etc/postgresql/9.4/main/pg_hba.conf + elif [ -e /etc/postgresql/9.6/ ] + then + pg_hba=/etc/postgresql/9.6/main/pg_hba.conf + else + ynh_die "postgresql shoud be 9.4 or 9.6" + fi + + systemctl start postgresql + su --command="psql -c\"ALTER user postgres WITH PASSWORD '${pgsql}'\"" postgres + # we can't use peer since YunoHost create users with nologin + sed -i '/local\s*all\s*all\s*peer/i \ + local all all password' "$pg_hba" + systemctl enable postgresql + systemctl reload postgresql + fi +} \ No newline at end of file diff --git a/scripts/remove b/scripts/remove index df948a8..5f5cb07 100644 --- a/scripts/remove +++ b/scripts/remove @@ -8,11 +8,12 @@ set -u # Import common cmd source ./_common.sh +source ./psql.sh # LOAD SETTINGS domain=$(ynh_app_setting_get $app domain) db_name=$(ynh_app_setting_get $app db_name) -final_path=$(ynh_app_setting_get $app final_path) +db_user="pgadmin" # Remove db user ynh_psql_drop_user $db_user @@ -23,11 +24,20 @@ ynh_remove_app_dependencies || true # Remove the app directory securely ynh_secure_remove "$final_path" +# Remove app data +ynh_secure_remove /var/lib/pgadmin + +# Remove logrotate +ynh_remove_logrotate + +# Remove logs +ynh_secure_remove /var/log/pgadmin + # Remove the dedicated nginx config ynh_remove_nginx_config -# Remove the dedicated php-fpm config -ynh_remove_fpm_config +# Remove uwsgi config +ynh_secure_remove /etc/uwsgi/apps-enabled/pgadmin.ini # Delete a system user ynh_system_user_delete $app diff --git a/scripts/restore b/scripts/restore index 735a656..752bf55 100644 --- a/scripts/restore +++ b/scripts/restore @@ -7,7 +7,8 @@ source /usr/share/yunohost/helpers ynh_abort_if_errors # Import common cmd -source ./_common.sh +source ../settings/scripts/_common.sh +source ../settings/scripts/psql.sh # LOAD SETTINGS domain=$(ynh_app_setting_get $app domain) @@ -15,50 +16,31 @@ path_url=$(ynh_app_setting_get $app path) admin=$(ynh_app_setting_get $app admin) final_path=$(ynh_app_setting_get $app final_path) db_name=$(ynh_app_setting_get $app db_name) +db_user=$(ynh_app_setting_get $app db_user) +db_pwd=$(ynh_app_setting_get $app db_pwd) -#================================================= -# CHECK IF THE APP CAN BE RESTORED -#================================================= +# Install dependance +install_dependance -ynh_webpath_available $domain $path_url \ - || ynh_die "Path not available: ${domain}${path_url}" -test ! -d $final_path \ - || ynh_die "There is already a directory: $final_path " +# Create user +ynh_system_user_create $pgadmin_user /var/lib/pgadmin -#================================================= -# STANDARD RESTORATION STEPS -#================================================= -# RESTORE THE NGINX CONFIGURATION -#================================================= +# Restore all config and data +ynh_restore -ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" +# POPULATE THE DATABASE +ynh_psql_test_if_first_run +su --command="psql -c\"CREATE USER ${db_user} WITH PASSWORD '${db_pwd}' SUPERUSER CREATEDB CREATEROLE REPLICATION\"" postgres -#================================================= -# RESTORE THE APP MAIN DIR -#================================================= +# Set the permission +set_permission -ynh_restore_file "$final_path" +# Restrict access to admin only +yunohost app addaccess --users=$admin $app -#================================================= -# RESTORE THE MYSQL DATABASE -#================================================= - -db_pwd=$(ynh_app_setting_get $app mysqlpwd) -ynh_mysql_setup_db $db_name $db_name $db_pwd -ynh_mysql_connect_as $db_name $db_pwd $db_name < ./db.sql - -# Create the dedicated user (if not existing) -ynh_system_user_create $app - -# config.inc.php contains sensitive data, restrict its access -chown root:$app $final_path/config.inc.php - -#================================================= -# RESTORE THE PHP-FPM CONFIGURATION -#================================================= - -ynh_restore_file "/etc/php5/fpm/pool.d/$app.conf" +# Configuration de logrotate +ynh_use_logrotate /var/log/pgadmin # RELOAD NGINX AND PHP-FPM -systemctl reload php5-fpm +systemctl restart uwsgi systemctl reload nginx diff --git a/scripts/upgrade b/scripts/upgrade index 8240e77..f94bcd6 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -8,82 +8,34 @@ ynh_abort_if_errors # Import common cmd source ./_common.sh +source ./psql.sh # LOAD SETTINGS domain=$(ynh_app_setting_get $app domain) -path_url=$(ynh_app_setting_get $app path) +path_url=$(ynh_normalize_url_path $(ynh_app_setting_get $app path)) admin=$(ynh_app_setting_get $app admin) -final_path=$(ynh_app_setting_get $app final_path) -db_name=$(ynh_app_setting_get $app db_name) - -#================================================= -# ENSURE DOWNWARD COMPATIBILITY -#================================================= - -# If db_name doesn't exist, create it -if [ -z $db_name ]; then - # In older version, db_name was always phpmyadmin - db_name=phpmyadmin - ynh_app_setting_set $app db_name $db_name -fi - -# If final_path doesn't exist, create it -if [ -z $final_path ]; then - final_path="/var/www/$app" - ynh_app_setting_set $app final_path $final_path -fi - -# In older version, the admin setting was admin_user -if [ -z $admin ]; then - admin=$(ynh_app_setting_get $app admin_user) - ynh_app_setting_set "$app" admin "$admin" - ynh_app_setting_delete $app admin_user -fi # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP ynh_backup_before_upgrade # Backup the current version of the app ynh_clean_setup () { ynh_restore_upgradebackup # restore it if the upgrade fails } -ynh_abort_if_errors # Exit if an error occurs during the execution of the script - -# Normalize the URL path syntax -path_url=$(ynh_normalize_url_path $path_url) # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source "$final_path" +install_source + +# CONFIGURE PGADMIN +config_pgadmin + +# Config uwsgi +config_uwsgi + +# Set permission after initialisation +set_permission # Create a dedicated nginx config ynh_add_nginx_config -# Create a system user -ynh_system_user_create $app - -# Create a dedicated php-fpm config -ynh_add_fpm_config - -# CONFIGURE PHPMYADMIN - -# Verify the checksum and backup the file if it's different -ynh_backup_if_checksum_is_different "$final_path/config.inc.php" - -ynh_replace_string "YNH_DOMAIN" "$domain" ../conf/config.inc.php -ynh_replace_string "YNH_PMA_USER" "$db_name" ../conf/config.inc.php -ynh_replace_string "YNH_PMA_PASSWORD" "$db_pwd" ../conf/config.inc.php -ynh_replace_string "YNH_MYSQL_ROOT_PASSWORD" "$(cat $MYSQL_ROOT_PWD_FILE)" ../conf/config.inc.php -cp ../conf/config.inc.php $final_path - -# Recalculate and store the config file checksum into the app settings -ynh_store_file_checksum "$final_path/config.inc.php" - -# Set permissions to app files -chown -R root: $final_path -# config.inc.php contains sensitive data, restrict its access -chown root:$app $final_path/config.inc.php -chmod 640 $final_path/config.inc.php - -# Restrict access to admin only -yunohost app addaccess --users=$admin $app - # RELOAD NGINX systemctl reload nginx +systemctl reload uwsgi