diff --git a/README.md b/README.md index ff2eef2..f12052c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [Flarum](http://flarum.org/), an open-source forum software, packaged for [YunoHost](https://yunohost.org/), a self-hosting server operating server. ## Development status -Package is **in progress** : installation works, removal partially works. Upgrading, backing up and restoring don't. +Package is **in progress** : installation and removal work. Upgrading, backing up and restoring are not supported yet. [SSOwat integration](https://github.com/tituspijean/flarum-ext-auth-ssowat) is **non functional** and removed. @@ -10,7 +10,7 @@ Package is **in progress** : installation works, removal partially works. Upgrad Flarum requires `composer`, which should be automatically retrieved and installed. ## Post-installation -Post-installation is **automated**. +Post-installation is **automated**. You still have to set the mail configuration in the administration panel afterwards. However, if you leave the forum title field empty in YunoHost's form, automatic post-installation will not be launched. @@ -23,3 +23,4 @@ However, if you leave the forum title field empty in YunoHost's form, automatic 3. Fill in the blanks about `MySQL` as follow, put the retrieved database password. The remaining blanks are up to you.

+ diff --git a/conf/nginx.conf b/conf/nginx.conf index 4ac3161..50212a4 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,14 +1,14 @@ -location ^~ YNH_WWW_PATH { +location ^~ __PATH__ { if ($scheme = http) { rewrite ^ https://$server_name$request_uri? permanent; } - alias YNH_WWW_FINALPATH/; + alias __FINALPATH__/; try_files $uri $uri/ /index.php?$query_string; index YNH_WWW_ROOTPATH/index.php; - # These weird try_files ... see http://stackoverflow.com/a/35102259 + # Bug in Nginx with locations and aliases (see http://stackoverflow.com/a/35102259 ) location YNH_WWW_ROOTPATH/ { try_files $uri $uri/ YNH_WWW_ROOTAPP/index.php?$query_string; } location YNH_WWW_ROOTPATH/api { try_files $uri $uri/ YNH_WWW_ROOTAPP/api.php?$query_string; } location YNH_WWW_ROOTPATH/admin { try_files $uri $uri/ YNH_WWW_ROOTAPP/admin.php?$query_string; } @@ -20,7 +20,7 @@ location ^~ YNH_WWW_PATH { location ~* \.php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; - fastcgi_pass unix:/var/run/php5-fpm-YNH_WWW_APP.sock; + fastcgi_pass unix:/var/run/php5-fpm-__NAME__.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param HTTP_PROXY ""; # Fix for https://httpoxy.org/ vulnerability diff --git a/conf/php-fpm.conf b/conf/php-fpm.conf index b2769e7..eb22ecc 100644 --- a/conf/php-fpm.conf +++ b/conf/php-fpm.conf @@ -1,7 +1,7 @@ ; Start a new pool named 'www'. ; the variable $pool can we used in any directive and will be replaced by the ; pool name ('www' here) -[YNH_WWW_APP] +[__USER__] ; Per pool prefix ; It only applies on the following directives: @@ -24,7 +24,7 @@ ; specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. -listen = /var/run/php5-fpm-YNH_WWW_APP.sock +listen = /var/run/php5-fpm-__USER__.sock ; Set listen(2) backlog. A value of '-1' means unlimited. ; Default Value: 128 (-1 on FreeBSD and OpenBSD) @@ -170,7 +170,7 @@ request_slowlog_timeout = 5s ; The log file for slow requests ; Default Value: not set ; Note: slowlog is mandatory if request_slowlog_timeout is set -slowlog = /var/log/nginx/YNH_WWW_APP.slow.log +slowlog = /var/log/nginx/__USER__.slow.log ; Set open file descriptor rlimit. ; Default Value: system defined value @@ -195,7 +195,7 @@ rlimit_core = 0 ; Chdir to this directory at the start. ; Note: relative path can be used. ; Default Value: current directory or / when chroot -chdir = YNH_WWW_ALIAS +chdir = __FINALPATH__ ; Redirect worker stdout and stderr into main error log. If not set, stdout and ; stderr will be redirected to /dev/null according to FastCGI specs. @@ -249,4 +249,4 @@ php_value[max_input_time] = 600 ;php_value[memory_limit] = 256M ;php_value[short_open_tag] = On -env[COMPOSER_HOME]= /opt/YNH_WWW_APP_composer' +env[COMPOSER_HOME]= /opt/__USER___composer' diff --git a/manifest.json b/manifest.json index c09fad7..eb04cf2 100644 --- a/manifest.json +++ b/manifest.json @@ -9,7 +9,7 @@ }, "url": "http://flarum.org/", "license": "MIT", - "version": "0.1.0-beta.6", + "version": "0.1.0-beta.7", "maintainer": { "name": "Titus PiJean", "email": "tituspijean@outlook.com" diff --git a/scripts/.functions b/scripts/.functions index 2eaaa56..7b7da78 100644 --- a/scripts/.functions +++ b/scripts/.functions @@ -60,7 +60,7 @@ CHECK_PATH () { # Vérifie la présence du / en début de path. Et son absence } CHECK_DOMAINPATH () { # Vérifie la disponibilité du path et du domaine. - sudo yunohost app checkurl $domain$path -a $app + ynh_webpath_register $app $domain $path } CHECK_FINALPATH () { # Vérifie que le dossier de destination n'est pas déjà utilisé. diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..0506dc7 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,12 @@ +# Execute a command as another user +# usage: exec_as USER COMMAND [ARG ...] +exec_as() { + local USER=$1 + shift 1 + + if [[ $USER = $(whoami) ]]; then + eval "$@" + else + sudo -u "$USER" "$@" + fi +} diff --git a/scripts/install b/scripts/install index 92cea75..459200d 100644 --- a/scripts/install +++ b/scripts/install @@ -1,10 +1,24 @@ #!/bin/bash -# Load extra functions -source .functions +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Activate TRAP to stop the script if an error is detected -TRAP_ON +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#=================================================== +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#=================================================== # This is a multi-instance app, meaning it can be installed several times independently # The id of the app as stated in the manifest is available as $YNH_APP_ID @@ -19,164 +33,205 @@ TRAP_ON app=$YNH_APP_INSTANCE_NAME # Retrieve arguments + domain=$YNH_APP_ARG_DOMAIN -path=$YNH_APP_ARG_PATH +path_url=$YNH_APP_ARG_PATH admin=$YNH_APP_ARG_ADMIN title=$YNH_APP_ARG_TITLE is_public=$YNH_APP_ARG_IS_PUBLIC -www_path=/var/www -final_path=$www_path/$app +flarum_version="v0.1.0-beta.7" -# Source YunoHost helpers$ -source /usr/share/yunohost/helpers +#=================================================== +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#=================================================== -# Check variables are not empty -CHECK_VAR "$app" "app name not set" +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die "This path already contains a folder" -# Check validity of admin user -CHECK_USER "$admin" +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path $path_url) -# Check and correct path syntax -CHECK_PATH +# Check web path availability +ynh_webpath_available $domain $path_url -# Check availibility of path and domain -CHECK_DOMAINPATH +# Register (book) web path +ynh_webpath_register $app $domain $path_url + +#=================================================== +# STORE SETTINGS FROM MANIFEST +#=================================================== # Save app settings -ynh_app_setting_set "$app" admin "$admin" -ynh_app_setting_set "$app" is_public "$is_public" -ynh_app_setting_set "$app" path "$path" +ynh_app_setting_set $app domain $domain +ynh_app_setting_set $app path $path_url +ynh_app_setting_set $app admin $admin +ynh_app_setting_set $app is_public $is_public +ynh_app_setting_set $app final_path $final_path -# Check final_path availibility. Installation stops if it already exists -CHECK_FINALPATH -sudo mkdir "$final_path" +#=================================================== +# CREATE DEDICATED USER +#=================================================== -### Nginx ### -nginxconf="../conf/nginx.conf" -if [ $path = "/" ]; then +ynh_system_user_create $app "$final_path" +sudo usermod -a -G www-data $app + +#================================================= +# COMPOSER INSTALLATION +#================================================= + +composer_path=/opt/${app}_composer +# Test if composer is installed +if ! type "${composer_path}/composer" > /dev/null; then + +# Prepare composer directories +sudo mkdir -p $composer_path +sudo mkdir -p $composer_path/cache +sudo chown -R $app:www-data $composer_path +sudo chmod -R 0775 $composer_path + +# Install composer (https://getcomposer.org) +EXPECTED_SIGNATURE=$(wget https://composer.github.io/installer.sig -O - -q) +php -r "copy('https://getcomposer.org/installer', '$composer_path/composer-setup.php');" +ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', '$composer_path/composer-setup.php');") +if [ "$EXPECTED_SIGNATURE" = "$ACTUAL_SIGNATURE" ] +then + sudo su - $app -s /bin/bash -c "php $composer_path/composer-setup.php --install-dir=$composer_path --filename=composer --quiet" + RESULT=$? +else + >&2 echo 'ERROR: Invalid Composer installer signature' + RESULT=1 +fi +if [ $RESULT != 0 ] +then + ynh_die 'Composer could not be installed' +fi + +fi + +COMPOSER_HOME=$composer_path + +#================================================= +# FLARUM INSTALLATION +#================================================= + +# Prepare Flarum temp directory +tmp=/tmp/$app +sudo mkdir -p $tmp +sudo chown -R $app:www-data $tmp +sudo chmod -R 0775 $tmp + +# Install Flarum +sudo su - $app -s /bin/bash -c "php -d memory_limit=-1 $composer_path/composer create-project flarum/flarum $tmp $flarum_version --stability=beta --ansi" + +sudo cp -Rf $tmp/* $final_path +sudo chown -R $app:www-data $final_path +sudo chmod 0775 -R $final_path +ynh_secure_remove "$tmp" + +#================================================= +# CREATE A MYSQL DATABASE +#================================================= + +db_name=$(ynh_sanitize_dbid $app) +ynh_app_setting_set $app db_name $db_name +ynh_mysql_setup_db $db_name $db_name +ynh_app_setting_set "$app" db_pwd "$db_pwd" + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# Bug in Nginx with locations and aliases (see http://stackoverflow.com/a/35102259 ) +if [ $path_url = "/" ]; then sed -i "s@YNH_WWW_ROOTPATH@@g" ../conf/nginx.conf sed -i "s@YNH_WWW_ROOTAPP@/@g" ../conf/nginx.conf else - sed -i "s@YNH_WWW_ROOTPATH@$path@g" ../conf/nginx.conf - sed -i "s@YNH_WWW_ROOTAPP@$path$path@g" ../conf/nginx.conf + sed -i "s@YNH_WWW_ROOTPATH@$path_url@g" ../conf/nginx.conf + sed -i "s@YNH_WWW_ROOTAPP@$path_url$path_url@g" ../conf/nginx.conf fi -sed -i "s@YNH_WWW_PATH@$path@g" $nginxconf -sed -i "s@YNH_WWW_FINALPATH@$final_path@g" $nginxconf -sed -i "s@YNH_WWW_APP@$app@g" $nginxconf -sudo cp $nginxconf /etc/nginx/conf.d/$domain.d/$app.conf +# Create a dedicated nginx config +ynh_add_nginx_config -### PHP ### -sed -i "s@YNH_WWW_APP@$app@g" ../conf/php-fpm.conf -sed -i "s@YNH_WWW_ALIAS@$final_path@g" ../conf/php-fpm.conf -finalphpconf=/etc/php5/fpm/pool.d/$app.conf -sudo cp ../conf/php-fpm.conf $finalphpconf -sudo chown root: $finalphpconf -sudo chmod 644 $finalphpconf -sudo service php5-fpm reload +#================================================= +# PHP-FPM CONFIGURATION +#================================================= -tmp=/tmp/flaruminstall -sudo rm -rf $tmp -sudo mkdir -p $tmp -sudo chown -R www-data:www-data $tmp -sudo chmod -R 755 $tmp +# Create a dedicated php-fpm config +ynh_add_fpm_config -# Prepare composer and cache directories -compo=/opt/${app}_composer -sudo mkdir -p $compo/cache -sudo chown -R www-data:www-data $compo -sudo chmod -R 755 $compo +#================================================= +# SETUP LOGROTATE +#================================================= -### composer ### -#if ! type "composer" > /dev/null; then - # Install composer (https://getcomposer.org) - EXPECTED_SIGNATURE=$(wget https://composer.github.io/installer.sig -O - -q) - sudo php -r "copy('https://getcomposer.org/installer', '$compo/composer-setup.php');" - ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', '$compo/composer-setup.php');") - if [ "$EXPECTED_SIGNATURE" = "$ACTUAL_SIGNATURE" ] - then -# sudo grep -q -F 'env[COMPOSER_HOME]= $compo' /etc/php5/fpm/pool.d/${app}.conf || sudo echo 'env[COMPOSER_HOME]= /opt/flarum_c$ -# sudo service php5-fpm reload -# echo "php reload" - sudo php $compo/composer-setup.php --install-dir=$compo --filename=composer -# sudo mv /opt/flarum_composer/composer /usr/local/bin -# sudo chown root:root /usr/local/bin/composer - RESULT=$? - else - >&2 echo 'ERROR: Invalid installer signature' - RESULT=1 - fi - if [ $RESULT != 0 ] - then - ynh_die - fi -#fi -### composer end ### +# Use logrotate to manage app-specific logfile(s) +ynh_use_logrotate -### Install flarum -cwd=$(pwd) -sudo su - www-data -s /bin/bash -c "mkdir -p $tmp/$app && cd $tmp/$app && php -d memory_limit=-1 /opt/flarum_composer/composer create-project flarum/flarum . --stability=beta" -sudo cp -Rf $tmp/$app $www_path/ -sudo chown -R www-data:www-data $final_path -cd $cwd -sudo rm -rf $tmp +#================================================= +# SETUP SSOWAT +#================================================= -### MySQL ### -dbuser=$app -dbname=$app -dbpass=$(ynh_string_random 15) -ynh_app_setting_set "$app" mysqlpwd "$dbpass" -ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass" - -# If app is public, add url to SSOWat conf as skipped_uris -if [[ $is_public -eq 1 ]]; then - # unprotected_uris allows SSO credentials to be passed anyway. - ynh_app_setting_set "$app" unprotected_uris "/" +if [ $is_public -eq 0 ] +then # Remove the public access + ynh_app_setting_delete $app skipped_uris +fi +# Make app public if necessary +if [ $is_public -eq 1 ] +then + # unprotected_uris allows SSO credentials to be passed anyway. + ynh_app_setting_set $app unprotected_uris "/" fi - ynh_app_setting_set "$app" skipped_uris "/api" - sudo yunohost app ssowatconf -# Reload services -sudo service nginx reload +#================================================= +# RELOAD NGINX +#================================================= -# Install the SSOwat auth extension -sudo su - www-data -s /bin/bash -c "cd $final_path && /opt/flarum_composer/composer require 'tituspijean/flarum-ext-auth-ssowat:*@dev'" +systemctl reload nginx -### POST-INSTALL ### +#================================================= +# FLARUM POST-INSTALL +#================================================= + +# Only if admin user or title were specified if [[ -n $admin && -n $title ]]; then -adminpass=$(ynh_string_random 8) -sed -i "s@YNH_APP_DOMAIN@$domain@g" ../sources/configuration.yml -sed -i "s@/YNH_WWW_PATH@$path@g" ../sources/configuration.yml -sed -i "s@YNH_WWW_APP@$app@g" ../sources/configuration.yml -sed -i "s@YNH_DB_PASS@$dbpass@g" ../sources/configuration.yml -sed -i "s@YNH_ADMIN_USER@$admin@g" ../sources/configuration.yml -sed -i "s@YNH_ADMIN_PASS@$adminpass@g" ../sources/configuration.yml -adminemail=$(ynh_user_get_info $admin mail) -sed -i "s%YNH_ADMIN_EMAIL%$adminemail%g" ../sources/configuration.yml -sed -i "s@YNH_FORUM_TITLE@$title@g" ../sources/configuration.yml -sudo cp ../sources/configuration.yml $final_path -sudo su - www-data -s /bin/bash -c "cd $final_path && php -d memory_limit=-1 flarum install -f configuration.yml" -sudo rm $final_path/configuration.yml +finalflarumconf="$final_path/configuration.yml" +cp ../sources/configuration.yml $finalflarumconf +admin_pwd=$(ynh_string_random 8) +sed -i "s@YNH_APP_DOMAIN@$domain@g" $finalflarumconf +sed -i "s@/YNH_WWW_PATH@$path_url@g" $finalflarumconf +sed -i "s@YNH_WWW_APP@$app@g" $finalflarumconf +sed -i "s@YNH_DB_PASS@$db_pwd@g" $finalflarumconf +sed -i "s@YNH_ADMIN_USER@$admin@g" $finalflarumconf +sed -i "s@YNH_ADMIN_PASS@$admin_pwd@g" $finalflarumconf +admin_mail=$(ynh_user_get_info $admin mail) +sed -i "s%YNH_ADMIN_EMAIL%$admin_mail%g" $finalflarumconf +sed -i "s@YNH_FORUM_TITLE@$title@g" $finalflarumconf +cd "$final_path" +exec_as www-data \ + php -d memory_limit=-1 flarum install -f configuration.yml # Generate and add root token for user creation and deletion roottoken=$(ynh_string_random 40) -apitablesql="CREATE TABLE IF NOT EXISTS api_keys (api_key TEXT(40) NOT NULL UNIQUE)" +apitablesql="CREATE TABLE IF NOT EXISTS api_keys (api_key TEXT(40) NOT NULL)" rootsql="INSERT INTO api_keys VALUES ('"$roottoken"')" -ynh_mysql_execute_as_root "$apitablesql" $dbname -ynh_mysql_execute_as_root "$rootsql" $dbname +ynh_mysql_execute_as_root "$apitablesql" $db_name +ynh_mysql_execute_as_root "$rootsql" $db_name ynh_app_setting_set "$app" root_token "$roottoken" -# Configure SSOwat auth extension -ssowatdomain=$(&2 echo "Installation successfull. Admin : $admin, password : $admin_pwd. Change it!" +else +>&2 echo "Installation successfull. Post-installation required, visit your Flarum instance!" fi - ->&2 echo "Admin : $admin, password : $adminpass. Change it!" diff --git a/scripts/remove b/scripts/remove index e66c04a..32b8caf 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,72 +1,68 @@ #!/bin/bash -# See comments in install script -app=$YNH_APP_INSTANCE_NAME +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Source YunoHost helpers +source _common.sh source /usr/share/yunohost/helpers -SECURE_REMOVE () { # Suppression de dossier avec vérification des variables - chaine="$1" # L'argument doit être donné entre quotes simple '', pour éviter d'interpréter les variables. - no_var=0 - while (echo "$chaine" | grep -q '\$') # Boucle tant qu'il y a des $ dans la chaine - do - no_var=1 - global_var=$(echo "$chaine" | cut -d '$' -f 2) # Isole la première variable trouvée. - only_var=\$$(expr "$global_var" : '\([A-Za-z0-9_]*\)') # Isole complètement la variable en ajoutant le $ au début et en gardant uniquement le nom de la variable. Se débarrasse surtout du / et d'un éventuel chemin derrière. - real_var=$(eval "echo ${only_var}") # `eval "echo ${var}` permet d'interpréter une variable contenue dans une variable. - if test -z "$real_var" || [ "$real_var" = "/" ]; then - echo "Variable $only_var is empty, suppression of $chaine cancelled." >&2 - return 1 - fi - chaine=$(echo "$chaine" | sed "s@$only_var@$real_var@") # remplace la variable par sa valeur dans la chaine. - done - if [ "$no_var" -eq 1 ] - then - if [ -e "$chaine" ]; then - echo "Delete directory $chaine" - sudo rm -r "$chaine" - fi - return 0 - else - echo "No detected variable." >&2 - return 1 - fi -} +#================================================= +# LOAD SETTINGS +#================================================= -REMOVE_NGINX_CONF () { # Suppression de la configuration nginx - if [ -e "/etc/nginx/conf.d/$domain.d/$app.conf" ]; then # Delete nginx config - echo "Delete nginx config" - sudo rm "/etc/nginx/conf.d/$domain.d/$app.conf" - fi -} +app=$YNH_APP_INSTANCE_NAME -REMOVE_FPM_CONF () { # Suppression de la configuration du pool php-fpm - if [ -e "/etc/php5/fpm/pool.d/$app.conf" ]; then # Delete fpm config - echo "Delete fpm config" - sudo rm "/etc/php5/fpm/pool.d/$app.conf" - fi -} +domain=$(ynh_app_setting_get $app domain) +db_name=$(ynh_app_setting_get $app db_name) +db_user=$db_name +final_path=$(ynh_app_setting_get $app final_path) -# Retrieve app settings -domain=$(ynh_app_setting_get "$app" domain) +#================================================= +# REMOVE THE MYSQL DATABASE +#================================================= -# Remove sources -SECURE_REMOVE "/tmp/composerinstall" -SECURE_REMOVE "/var/www/$app" -SECURE_REMOVE "/opt/${app}_composer" +# Remove a database if it exists, along with the associated user +ynh_mysql_remove_db $db_user $db_name -# Remove nginx and PHP-FPM files and restart services -REMOVE_NGINX_CONF -REMOVE_FPM_CONF -sudo service nginx reload -sudo service php5-fpm reload +#================================================= +# REMOVE APP MAIN DIR +#================================================= + +# Remove the app directory securely +ynh_secure_remove "$final_path" +ynh_secure_remove "/tmp/$app" +ynh_secure_remove "/opt/${app}_composer" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= + +# Remove the dedicated nginx config +ynh_remove_nginx_config + +#================================================= +# REMOVE PHP-FPM CONFIGURATION +#================================================= + +# Remove the dedicated php-fpm config +ynh_remove_fpm_config + +#================================================= +# REMOVE LOGROTATE CONFIGURATION +#================================================= + +# Remove the app-specific logrotate config +ynh_remove_logrotate + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= + +# Delete a system user +ynh_system_user_delete $app -### MySQL ### -# If a MySQL database is used: -# # Drop MySQL database and user -dbname=$app -dbuser=$app -ynh_mysql_drop_db "$dbname" || true -ynh_mysql_drop_user "$dbuser" || true -### MySQL end ###