From f5125002b28b3c282d3c01b72fd589e8c290f9d2 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Wed, 9 Feb 2022 16:47:31 +0100 Subject: [PATCH] Apply last example_ynh (#117) * Apply last example_ynh * Cleanup backup --- .github/ISSUE_TEMPLATE.md | 55 ++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 16 ++++++ .gitignore | 2 - check_process | 16 +++--- conf/app.src | 1 + conf/nginx.conf | 7 +-- conf/php-fpm.conf | 2 +- doc/.gitkeep | 0 doc/DESCRIPTION.md | 4 ++ doc/DESCRIPTION_fr.md | 3 + doc/DISCLAIMER.md | 16 ++++++ doc/DISCLAIMER_fr.md | 14 +++++ doc/screenshots/.gitkeep | 0 doc/screenshots/screenshot1.webp | Bin 0 -> 39924 bytes manifest.json | 36 +++++------- pull_request_template.md | 24 -------- scripts/backup | 42 +++++++------- scripts/change_url | 35 +++++++++--- scripts/install | 64 +++++++++++---------- scripts/remove | 35 ++++++------ scripts/restore | 47 ++++++++------- scripts/upgrade | 95 +++++++++++++------------------ 22 files changed, 300 insertions(+), 214 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .gitignore create mode 100644 doc/.gitkeep create mode 100644 doc/DESCRIPTION.md create mode 100644 doc/DESCRIPTION_fr.md create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/DISCLAIMER_fr.md create mode 100644 doc/screenshots/.gitkeep create mode 100644 doc/screenshots/screenshot1.webp delete mode 100644 pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..2729a6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,55 @@ +--- +name: Bug report +about: When creating a bug report, please use the following template to provide all the relevant information and help debugging efficiently. + +--- + +**How to post a meaningful bug report** +1. *Read this whole template first.* +2. *Determine if you are on the right place:* + - *If you were performing an action on the app from the webadmin or the CLI (install, update, backup, restore, change_url...), you are on the right place!* + - *Otherwise, the issue may be due to the app itself. Refer to its documentation or repository for help.* + - *When in doubt, post here and we will figure it out together.* +3. *Delete the italic comments as you write over them below, and remove this guide.* +--- + +### Describe the bug + +*A clear and concise description of what the bug is.* + +### Context + +- Hardware: *VPS bought online / Old laptop or computer / Raspberry Pi at home / Internet Cube with VPN / Other ARM board / ...* +- YunoHost version: x.x.x +- I have access to my server: *Through SSH | through the webadmin | direct access via keyboard / screen | ...* +- Are you in a special context or did you perform some particular tweaking on your YunoHost instance?: *no / yes* + - If yes, please explain: +- Using, or trying to install package version/branch: +- If upgrading, current package version: *can be found in the admin, or with `yunohost app info $app_id`* + +### Steps to reproduce + +- *If you performed a command from the CLI, the command itself is enough. For example:* + ```sh + sudo yunohost app install the_app + ``` +- *If you used the webadmin, please perform the equivalent command from the CLI first.* +- *If the error occurs in your browser, explain what you did:* + 1. *Go to '...'* + 2. *Click on '...'* + 3. *Scroll down to '...'* + 4. *See error* + +### Expected behavior + +*A clear and concise description of what you expected to happen. You can remove this section if the command above is enough to understand your intent.* + +### Logs + +*When an operation fails, YunoHost provides a simple way to share the logs.* +- *In the webadmin, the error message contains a link to the relevant log page. On that page, you will be able to 'Share with Yunopaste'. If you missed it, the logs of previous operations are also available under Tools > Logs.* +- *In command line, the command to share the logs is displayed at the end of the operation and looks like `yunohost log display [log name] --share`. If you missed it, you can find the log ID of a previous operation using `yunohost log list`.* + +*After sharing the log, please copypaste directly the link provided by YunoHost (to help readability, no need to copypaste the entire content of the log here, just the link is enough...)* + +*If applicable and useful, add screenshots to help explain your problem.* diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..ef70e18 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ +## Problem + +- *Description of why you made this PR* + +## Solution + +- *And how do you fix that problem* + +## PR Status + +- [ ] Code finished and ready to be reviewed/tested +- [ ] The fix/enhancement were manually tested (if applicable) + +## Automatic tests + +Automatic tests can be triggered on https://ci-apps-dev.yunohost.org/ *after creating the PR*, by commenting "!testme", "!gogogadgetoci" or "By the power of systemd, I invoke The Great App CI to test this Pull Request!". (N.B. : for this to work you need to be a member of the Yunohost-Apps organization) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f248394..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*~ -*.sw[po] diff --git a/check_process b/check_process index 692db47..0587cd1 100644 --- a/check_process +++ b/check_process @@ -1,8 +1,8 @@ -;; Complete test +;; Test complet ; Manifest - domain="domain.tld" (DOMAIN) - path="/path" (PATH) - admin="john" (USER) + domain="domain.tld" + path="/path" + admin="john" ; Checks pkg_linter=1 setup_sub_dir=1 @@ -11,14 +11,14 @@ setup_private=0 setup_public=0 upgrade=1 - upgrade=1 from_commit=f75d58cb32c51a0981333ea88974dc3199324e65 + # 2.2.3 + upgrade=1 from_commit=f75d58cb32c51a0981333ea88974dc3199324e65 + # 2.3.8~ynh3 + upgrade=1 from_commit=2e20b8f9a6b791e059b806fcfc2253f88d1aeaf2 backup_restore=1 multi_instance=1 - incorrect_path=1 port_already_use=0 change_url=1 -;;; Levels - Level 5=auto ;;; Options Email= Notification=none diff --git a/conf/app.src b/conf/app.src index 4ab2afd..794ff5a 100644 --- a/conf/app.src +++ b/conf/app.src @@ -4,3 +4,4 @@ SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=tar.gz SOURCE_IN_SUBDIR=true SOURCE_FILENAME= +SOURCE_EXTRACT=true diff --git a/conf/nginx.conf b/conf/nginx.conf index dabfbf9..07d36a3 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -4,11 +4,6 @@ location __PATH__/ { # Path to source alias __FINALPATH__/web/; - # Force usage of https - if ($scheme = http) { - rewrite ^ https://$server_name$request_uri? permanent; - } - client_body_timeout 60m; proxy_read_timeout 60m; fastcgi_read_timeout 60m; @@ -22,7 +17,7 @@ location __PATH__/ { fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param REMOTE_USER $remote_user; - fastcgi_pass unix:/var/run/php5-fpm-__NAME__.sock; + fastcgi_pass unix:/var/run/php/php__PHPVERSION__-fpm-__NAME__.sock; fastcgi_intercept_errors on; } diff --git a/conf/php-fpm.conf b/conf/php-fpm.conf index 6505dc6..9ec5826 100644 --- a/conf/php-fpm.conf +++ b/conf/php-fpm.conf @@ -33,7 +33,7 @@ group = __USER__ ; (IPv6 and IPv4-mapped) on a specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. -listen = /var/run/php/php7.0-fpm-__NAMETOCHANGE__.sock +listen = /var/run/php/php__PHPVERSION__-fpm-__NAMETOCHANGE__.sock ; Set listen(2) backlog. ; Default Value: 511 (-1 on FreeBSD and OpenBSD) diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..f2e514a --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1,4 @@ +[Wallabag](https://www.wallabag.org/) is a self hostable Read-It-Later application allowing you to not miss any content anymore. Click, save, read it when you can. +It extracts content so that you can read it when you have time. + +It provides a web interface, browser (Firefox / Chrome / Opera) add-ons, mobile apps (Android / iOS / Windows Phone) and even on e-reader (PocketBook / Kobo). diff --git a/doc/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md new file mode 100644 index 0000000..602af14 --- /dev/null +++ b/doc/DESCRIPTION_fr.md @@ -0,0 +1,3 @@ +[Wallabag](https://www.wallabag.org/) est une application de lecture différée : elle permet simplement d’archiver une page web en ne conservant que le contenu. Les éléments superflus (menus, publicités, etc.) sont supprimés. + +Sont disponibles une interface web, des add-ons pour navigateurs (Firefox / Chrome / Opera), des applications pour mobile (Android / iOS / Windows Phone) et même sur liseuse (PocketBook / Kobo). diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..ca0778b --- /dev/null +++ b/doc/DISCLAIMER.md @@ -0,0 +1,16 @@ +In addition to Wallabag core features, the following are made available with this package: + + * Integrate with YunoHost users and SSO - i.e. logout button + * Allow one user to be the administrator (set at the installation) + * Asynchronous import using Redis (need to be enabled in the *Internal Settings*). RabbitMQ import not supported (yet ?) + +## Limitations + +* Removing a Yunohost's user won't delete the related wallabag user, but only desactivate it. You need to manualy remove it from wallabag before. See: https://github.com/YunoHost-Apps/wallabag2_ynh/issues/39 + +#### Upgrade from v1 + +The upgrade from the YunoHost [Wallabag v1](https://github.com/YunoHost-Apps/wallabag_ynh) +app requires a manual operation, that's why it's provided as a new package. +For the migration process, please refer to the +[Wallabag official documentation](https://doc.wallabag.org/en/user/import/wallabagv1.html). diff --git a/doc/DISCLAIMER_fr.md b/doc/DISCLAIMER_fr.md new file mode 100644 index 0000000..b4dd166 --- /dev/null +++ b/doc/DISCLAIMER_fr.md @@ -0,0 +1,14 @@ +En plus des fonctionnalités principales de Wallabag, ce paquet propose également : + + * Une intégration avec le système de gestion des utilisateurs et le SSO de YunoHost - e.g. un bouton de déconnexion + * De permettre à un utilisateur d'être administrateur (réglage lors de l'installation) + * Un import asynchrone utilisant Redis (à activer dans les *Paramètres Internes*). L'import via RabbitMQ n'est pas (encore ?) supporté. + +## Limitations + +* Supprimer un utilisateur YunoHost ne supprimera pas l'utilisateur Wallabag lié, il sera seulement désactivé. Vous devez le supprimer manuellement avant. Voir : https://github.com/YunoHost-Apps/wallabag2_ynh/issues/39 + +#### Mettre à niveau depuis la v1 + +La mise à niveau depuis le paquet YunoHost de [Wallabag v1](https://github.com/YunoHost-Apps/wallabag_ynh) demande une opération manuelle, c'est pourquoi un nouveau paquet est fournit. +Pour le processus de migration, merci de vous référer à [la documentation officiel de Wallabag](https://doc.wallabag.org/fr/user/import/wallabagv1.html). diff --git a/doc/screenshots/.gitkeep b/doc/screenshots/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/screenshot1.webp b/doc/screenshots/screenshot1.webp new file mode 100644 index 0000000000000000000000000000000000000000..e447c1dfa469b20e4c65079185e3028b12f7d28a GIT binary patch literal 39924 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 literal 0 HcmV?d00001 diff --git a/manifest.json b/manifest.json index af4a8cd..6065ad7 100644 --- a/manifest.json +++ b/manifest.json @@ -6,51 +6,43 @@ "en": "A self hostable read-it-later app", "fr": "Une application de lecture-plus-tard auto-hébergeable" }, - "version": "2.3.8~ynh3", + "version": "2.3.8~ynh4", "url": "https://www.wallabag.org", + "upstream": { + "license": "MIT", + "website": "https://www.wallabag.org", + "demo": "https://demo.yunohost.org/wallabag/", + "admindoc": "https://doc.wallabag.org/en/", + "code": "https://github.com/wallabag/wallabag" + }, "license": "MIT", "maintainer": { - "name": "lapineige", - "email": "" + "name": "lapineige" }, "requirements": { - "yunohost": ">= 3.7.0" + "yunohost": ">= 4.3.0" }, "multi_instance": true, "services": [ "nginx", - "php5-fpm", + "php7.3-fpm", "mysql" ], "arguments": { - "install" : [ + "install": [ { "name": "domain", - "type": "domain", - "ask": { - "en": "Choose a domain for Wallabag", - "fr": "Choisissez un domaine pour Wallabag" - }, - "example": "domain.org" + "type": "domain" }, { "name": "path", "type": "path", - "ask": { - "en": "Choose a path for Wallabag", - "fr": "Choisissez un chemin pour Wallabag" - }, "example": "/wallabag", "default": "/wallabag" }, { "name": "admin", - "type": "user", - "ask": { - "en": "Choose the Wallabag administrator", - "fr": "Choisissez l'administrateur de Wallabag" - }, - "example": "homer" + "type": "user" } ] } diff --git a/pull_request_template.md b/pull_request_template.md deleted file mode 100644 index 4c09327..0000000 --- a/pull_request_template.md +++ /dev/null @@ -1,24 +0,0 @@ -## Problem -- *Description of why you made this PR* - -## Solution -- *And how you fix that* - -## PR Status -- [ ] Code finished. -- [ ] Tested with Package_check. -- [ ] Fix or enhancement tested. -- [ ] Upgrade from last version tested. -- [ ] Can be reviewed and tested. - -## Validation ---- -*Minor decision* -- **Upgrade previous version** : -- [ ] **Code review** : -- [ ] **Approval (LGTM)** : -- [ ] **Approval (LGTM)** : -- **CI succeeded** : -[![Build Status](https://ci-apps-hq.yunohost.org/jenkins/job/wallabag2_ynh%20PR-NUM-/badge/icon)](https://ci-apps-hq.yunohost.org/jenkins/job/wallabag2_ynh%20PR-NUM-/) -*Please replace '-NUM-' in this link by the PR number.* -When the PR is marked as ready to merge, you have to wait for 3 days before really merging it. diff --git a/scripts/backup b/scripts/backup index f55f3f3..7c696c7 100644 --- a/scripts/backup +++ b/scripts/backup @@ -6,6 +6,7 @@ # IMPORT GENERIC HELPERS #================================================= +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers @@ -19,54 +20,57 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." +ynh_print_info --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME final_path=$(ynh_app_setting_get --app=$app --key=final_path) domain=$(ynh_app_setting_get --app=$app --key=domain) db_name=$(ynh_app_setting_get --app=$app --key=db_name) +phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= -# STANDARD BACKUP STEPS +# DECLARE DATA AND CONF FILES TO BACKUP #================================================= -# BACKUP APP MAIN DIR +ynh_print_info --message="Declaring files to be backed up..." + +#================================================= +# BACKUP THE APP MAIN DIR #================================================= # Clean cache files before backup (saved some disk space) ynh_secure_remove --file=$final_path/var/cache/prod -ynh_script_progression --message="Backing up the main app directory..." ynh_backup --src_path="$final_path" #================================================= -# BACKUP NGINX CONFIGURATION +# BACKUP THE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Backing up nginx web server configuration..." ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= -# BACKUP PHP-FPM CONFIGURATION +# BACKUP THE PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Backing up php-fpm configuration..." -ynh_backup --src_path="/etc/php/7.0/fpm/pool.d/$app.conf" - -#================================================= -# BACKUP MYSQL DB -#================================================= -ynh_script_progression --message="Backing up the MySQL database..." - -ynh_mysql_dump_db --database="$db_name" > db.sql +ynh_backup --src_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" #================================================= # BACKUP FAIL2BAN CONFIGURATION #================================================= -ynh_backup "/etc/fail2ban/jail.d/$app.conf" -ynh_backup "/etc/fail2ban/filter.d/$app.conf" + +ynh_backup --src_path="/etc/fail2ban/jail.d/$app.conf" +ynh_backup --src_path="/etc/fail2ban/filter.d/$app.conf" + +#================================================= +# BACKUP THE MYSQL DATABASE +#================================================= +ynh_print_info --message="Backing up the MySQL database..." + +ynh_mysql_dump_db --database="$db_name" > db.sql #================================================= # END OF SCRIPT #================================================= -ynh_script_progression --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." --last + +ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." diff --git a/scripts/change_url b/scripts/change_url index 7db3313..380370a 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -32,6 +32,23 @@ db_user=$db_name db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) final_path=$(ynh_app_setting_get --app=$app --key=final_path) +#================================================= +# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. + ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" + + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + #================================================= # CHECK WHICH PARTS SHOULD BE CHANGED #================================================= @@ -51,25 +68,25 @@ fi #================================================= # STANDARD MODIFICATIONS #================================================= -# MODIFY URL IN NGINX CONF FILE +# MODIFY URL IN NGINX CONF #================================================= -ynh_script_progression --message="Updating nginx web server configuration..." --weight=2 +ynh_script_progression --message="Updating NGINX web server configuration..." --weight=2 nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf -# Change the path in the nginx config file +# Change the path in the NGINX config file if [ $change_path -eq 1 ] then - # Make a backup of the original nginx config file if modified + # Make a backup of the original NGINX config file if modified ynh_backup_if_checksum_is_different --file="$nginx_conf_path" - # Set global variables for nginx helper + # Set global variables for NGINX helper domain="$old_domain" path_url="$new_path" - # Create a dedicated nginx config + # Create a dedicated NGINX config ynh_add_nginx_config fi -# Change the domain for nginx +# Change the domain for NGINX if [ $change_domain -eq 1 ] then # Delete file checksum for the old conf file location @@ -82,6 +99,8 @@ fi #================================================= # SPECIFIC MODIFICATIONS #================================================= +# UPDATE CONFIGURATION +#================================================= ynh_script_progression --message="Updating wallabag configuration..." # Configure Wallabag instance URL @@ -107,7 +126,7 @@ ynh_secure_remove --file=$final_path/var/cache #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading nginx web server..." +ynh_script_progression --message="Reloading NGINX web server..." ynh_systemd_action --service_name=nginx --action=reload diff --git a/scripts/install b/scripts/install index a94790d..fb21614 100644 --- a/scripts/install +++ b/scripts/install @@ -1,7 +1,7 @@ #!/bin/bash #================================================= -# GENERIC STARTING +# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -20,21 +20,19 @@ ynh_abort_if_errors # RETRIEVE ARGUMENTS FROM THE MANIFEST #================================================= -# Retrieve app id -app=$YNH_APP_INSTANCE_NAME - -# Retrieve arguments domain=$YNH_APP_ARG_DOMAIN path_url=$YNH_APP_ARG_PATH admin=$YNH_APP_ARG_ADMIN +app=$YNH_APP_INSTANCE_NAME + #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= ynh_script_progression --message="Validating installation parameters..." --weight=2 final_path=/var/www/$app -test ! -e "$final_path" || ynh_die "This path already contains a folder" +test ! -e "$final_path" || ynh_die --message="This path already contains a folder" # Register (book) web path ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url @@ -42,6 +40,7 @@ ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url #================================================= # STORE SETTINGS FROM MANIFEST #================================================= +ynh_script_progression --message="Storing installation settings..." ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=path --value=$path_url @@ -56,12 +55,20 @@ ynh_script_progression --message="Installing dependencies..." --weight=12 ynh_install_app_dependencies $pkg_dependencies +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --weight=2 + +# Create a system user +ynh_system_user_create --username=$app --home_dir="$final_path" + #================================================= # CREATE A MYSQL DATABASE #================================================= ynh_script_progression --message="Creating a MySQL database..." -db_name=$(ynh_sanitize_dbid $app) +db_name=$(ynh_sanitize_dbid --db_name=$app) db_user=$db_name ynh_app_setting_set --app=$app --key=db_name --value=$db_name ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name @@ -78,25 +85,17 @@ ynh_setup_source --dest_dir="$final_path" #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Configuring nginx web server..." --weight=2 +ynh_script_progression --message="Configuring NGINX web server..." --weight=2 -# Create a dedicated nginx config +# Create a dedicated NGINX config ynh_add_nginx_config -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Configuring system user..." --weight=2 - -# Create a system user -ynh_system_user_create --username=$app - #================================================= # PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Configuring php-fpm..." --weight=2 +ynh_script_progression --message="Configuring PHP-FPM..." --weight=2 -# Create a dedicated php-fpm config +# Create a dedicated PHP-FPM config ynh_add_fpm_config #================================================= @@ -145,14 +144,11 @@ $php_exec fos:user:promote --super "$admin" ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE craue_config_setting SET value = 'https://$domain$path_url' WHERE name = 'wallabag_url'" #================================================= -# CONFIGURE FAIL2BAN +# SETUP HOOKS #================================================= -# Create the log file is not already existing during install -mkdir -p "/var/www/$app/var/logs/" -touch "/var/www/$app/var/logs/prod.log" -chown $app: "/var/www/$app/var/logs/prod.log" -# Add fail2ban config -ynh_add_fail2ban_config --logpath="/var/www/$app/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 + +ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_create" +ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_delete" #================================================= # GENERIC FINALIZATION @@ -163,23 +159,29 @@ ynh_add_fail2ban_config --logpath="/var/www/$app/var/logs/prod.log" --failregex= set_permissions #================================================= -# SETUP HOOKS +# SETUP FAIL2BAN #================================================= +ynh_script_progression --message="Configuring Fail2Ban..." -ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_create" -ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_delete" +# Create the log file is not already existing during install +mkdir -p "/var/www/$app/var/logs/" +touch "/var/www/$app/var/logs/prod.log" +chown $app: "/var/www/$app/var/logs/prod.log" + +# Create a dedicated Fail2Ban config +ynh_add_fail2ban_config --logpath="/var/www/$app/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 #================================================= # SETUP SSOWAT #================================================= -ynh_script_progression --message="Configuring SSOwat..." +ynh_script_progression --message="Configuring permissions..." ynh_permission_update --permission="main" --add="visitors" #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading nginx web server..." +ynh_script_progression --message="Reloading NGINX web server..." ynh_systemd_action --service_name=nginx --action=reload diff --git a/scripts/remove b/scripts/remove index 70f90cf..542c8a4 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,7 +1,7 @@ #!/bin/bash #================================================= -# GENERIC STARTING +# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -26,23 +26,15 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # REMOVE THE MYSQL DATABASE #================================================= -ynh_script_progression --message="Removing the MySQL database" --weight=2 +ynh_script_progression --message="Removing the MySQL database..." --weight=2 # Remove a database if it exists, along with the associated user ynh_mysql_remove_db --db_user=$db_user --db_name=$db_name -#================================================= -# REMOVE DEPENDENCIES -#================================================= -ynh_script_progression --message="Removing dependencies" --weight=9 - -# Remove metapackage and its dependencies -ynh_remove_app_dependencies - #================================================= # REMOVE APP MAIN DIR #================================================= -ynh_script_progression --message="Removing app main directory" --weight=2 +ynh_script_progression --message="Removing app main directory..." --weight=2 # Remove the app directory securely ynh_secure_remove --file="$final_path" @@ -50,22 +42,33 @@ ynh_secure_remove --file="$final_path" #================================================= # REMOVE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Removing nginx web server configuration" +ynh_script_progression --message="Removing NGINX web server configuration..." -# Remove the dedicated nginx config +# Remove the dedicated NGINX config ynh_remove_nginx_config #================================================= # REMOVE PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Removing php-fpm configuration" +ynh_script_progression --message="Removing PHP-FPM configuration..." -# Remove the dedicated php-fpm config +# Remove the dedicated PHP-FPM config ynh_remove_fpm_config +#================================================= +# REMOVE DEPENDENCIES +#================================================= +ynh_script_progression --message="Removing dependencies..." --weight=9 + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + #================================================= # REMOVE FAIL2BAN CONFIGURATION #================================================= +ynh_script_progression --message="Removing Fail2Ban configuration..." + +# Remove the dedicated Fail2Ban config ynh_remove_fail2ban_config #================================================= @@ -73,7 +76,7 @@ ynh_remove_fail2ban_config #================================================= # REMOVE DEDICATED USER #================================================= -ynh_script_progression --message="Removing the dedicated system user" +ynh_script_progression --message="Removing the dedicated system user..." # Delete a system user ynh_system_user_delete --username=$app diff --git a/scripts/restore b/scripts/restore index 1654db7..17a42dc 100644 --- a/scripts/restore +++ b/scripts/restore @@ -6,6 +6,7 @@ # IMPORT GENERIC HELPERS #================================================= +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers @@ -19,7 +20,7 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading settings..." --weight=2 +ynh_script_progression --message="Loading installation settings..." --weight=2 app=$YNH_APP_INSTANCE_NAME @@ -28,14 +29,13 @@ path_url=$(ynh_app_setting_get --app=$app --key=path) final_path=$(ynh_app_setting_get --app=$app --key=final_path) db_name=$(ynh_app_setting_get --app=$app --key=db_name) db_user=$db_name +phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= ynh_script_progression --message="Validating restoration parameters..." -ynh_webpath_available --domain=$domain --path_url=$path_url \ - || ynh_die --message="Path not available: ${domain}${path_url}" test ! -d $final_path \ || ynh_die --message="There is already a directory: $final_path " @@ -44,23 +44,24 @@ test ! -d $final_path \ #================================================= # RESTORE THE NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Restoring the NGINX web server configuration..." ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" -#================================================= -# RESTORE THE APP MAIN DIR -#================================================= -ynh_script_progression --message="Restoring the app main directory..." - -ynh_restore_file --origin_path="$final_path" - #================================================= # RECREATE THE DEDICATED USER #================================================= ynh_script_progression --message="Recreating the dedicated system user..." --weight=2 # Create the dedicated user (if not existing) -ynh_system_user_create --username=$app +ynh_system_user_create --username=$app --home_dir="$final_path" + +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= +ynh_script_progression --message="Restoring the app main directory..." + +ynh_restore_file --origin_path="$final_path" #================================================= # RESTORE USER RIGHTS @@ -73,8 +74,18 @@ set_permissions #================================================= # RESTORE THE PHP-FPM CONFIGURATION #================================================= +ynh_script_progression --message="Restoring the PHP-FPM configuration..." -ynh_restore_file --origin_path="/etc/php/7.0/fpm/pool.d/$app.conf" +ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" + +#================================================= +# RESTORE FAIL2BAN CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the Fail2Ban configuration..." + +ynh_restore_file --origin_path="/etc/fail2ban/jail.d/$app.conf" +ynh_restore_file --origin_path="/etc/fail2ban/filter.d/$app.conf" +ynh_systemd_action --action=restart --service_name=fail2ban #================================================= # SPECIFIC RESTORATION @@ -86,14 +97,6 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=15 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies -#================================================= -# RESTORE FAIL2BAN CONFIGURATION -#================================================= -ynh_restore_file "/etc/fail2ban/jail.d/$app.conf" -ynh_restore_file "/etc/fail2ban/filter.d/$app.conf" - -ynh_systemd_action --action=reload --service_name=fail2ban # Reload instead of restart for better performance - #================================================= # RESTORE THE MYSQL DATABASE #================================================= @@ -108,9 +111,9 @@ ynh_mysql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./ #================================================= # RELOAD NGINX AND PHP-FPM #================================================= -ynh_script_progression --message="Reloading nginx web server and php-fpm..." +ynh_script_progression --message="Reloading NGINX web server and PHP-FPM..." -ynh_systemd_action --service_name=php7.0-fpm --action=reload +ynh_systemd_action --service_name=php$phpversion-fpm --action=reload ynh_systemd_action --service_name=nginx --action=reload #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 94bc0d9..cc9f1b8 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -28,14 +28,38 @@ deskey=$(ynh_app_setting_get --app=$app --key=deskey) #================================================= # CHECK VERSION #================================================= +ynh_script_progression --message="Checking version..." upgrade_type=$(ynh_check_app_version_changed) +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=30 + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD UPGRADE STEPS #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= ynh_script_progression --message="Ensuring downward compatibility..." +# Cleaning legacy permissions +if ynh_legacy_permissions_exists; then + ynh_legacy_permissions_delete_all + + ynh_app_setting_delete --app=$app --key=is_public +fi + # If db_name doesn't exist, create it if [ -z "$db_name" ]; then db_name=$(ynh_sanitize_dbid --db_name=$app) @@ -55,37 +79,13 @@ if [ -z "$path_url" ]; then fi #================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +# CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=30 +ynh_script_progression --message="Making sure dedicated system user exists..." -# Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - # restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors +# Create a dedicated user (if not existing) +ynh_system_user_create --username=$app --home_dir="$final_path" -#================================================= -# Migrate legacy permissions to new system -#================================================= -if ynh_legacy_permissions_exists -then - ynh_legacy_permissions_delete_all - - ynh_app_setting_delete --app=$app --key=is_public -fi - -#================================================= -# CHECK THE PATH -#================================================= - -path_url=$(ynh_normalize_url_path --path_url=$path_url) - -#================================================= -# STANDARD UPGRADE STEPS #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= @@ -105,9 +105,9 @@ fi #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Upgrading nginx web server configuration..." +ynh_script_progression --message="Upgrading NGINX web server configuration..." -# Create a dedicated nginx config +# Create a dedicated NGINX config ynh_add_nginx_config #================================================= @@ -117,20 +117,12 @@ ynh_script_progression --message="Upgrading dependencies..." --weight=7 ynh_install_app_dependencies $pkg_dependencies -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." - -# Create a dedicated user (if not existing) -ynh_system_user_create --username=$app - #================================================= # PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Upgrading php-fpm configuration..." +ynh_script_progression --message="Upgrading PHP-FPM configuration..." -# Create a dedicated php-fpm config +# Create a dedicated PHP-FPM config ynh_add_fpm_config # Set-up fail2ban @@ -185,6 +177,13 @@ then ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE craue_config_setting SET value = 'https://$domain$path_url' WHERE name = 'wallabag_url'" fi +#================================================= +# SETUP HOOKS +#================================================= + +ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_create" +ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_delete" + #================================================= # GENERIC FINALIZATION #================================================= @@ -193,24 +192,10 @@ fi set_permissions -#================================================= -# SETUP HOOKS -#================================================= - -ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_create" -ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_delete" - -#================================================= -# SETUP SSOWAT -#================================================= -ynh_script_progression --message="Upgrading SSOwat configuration..." - -ynh_app_setting_set "$app" unprotected_uris "/" - #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading nginx web server..." +ynh_script_progression --message="Reloading NGINX web server..." ynh_systemd_action --service_name=nginx --action=reload