From b1f4ed9bbe83fb6178a124e264e77f8d217768db Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Fri, 15 Mar 2024 11:29:29 +0000 Subject: [PATCH 1/9] Auto-update README --- README.md | 17 ++++++++--------- README_fr.md | 19 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 29cd390..cea21f6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ @@ -21,10 +21,9 @@ 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). - **Shipped version:** 2.5.4~ynh2 -**Demo:** https://demo.yunohost.org/wallabag/ +**Demo:** ## Screenshots @@ -52,11 +51,11 @@ In addition to Wallabag core features, the following are made available with thi Warning : Doing a normal upgrade of the package with the web admin or `sudo yunohost app upgrade wallabag2` (without any URL specified) will revert you app to the master branch. *This may break you wallabag* if it goes to a previous version (if the newest is not retrocompatible). ## Documentation and resources -* Official app website: -* Official admin documentation: -* Upstream app code repository: -* YunoHost Store: -* Report a bug: +- Official app website: +- Official admin documentation: +- Upstream app code repository: +- YunoHost Store: +- Report a bug: ## Developer info @@ -64,7 +63,7 @@ Please send your pull request to the [testing branch](https://github.com/YunoHos To try the testing branch, please proceed like that. -``` bash +```bash sudo yunohost app install https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing --debug or sudo yunohost app upgrade wallabag2 -u https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing --debug diff --git a/README_fr.md b/README_fr.md index 6511e02..7910a36 100644 --- a/README_fr.md +++ b/README_fr.md @@ -1,5 +1,5 @@ @@ -20,10 +20,9 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po 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). - **Version incluse :** 2.5.4~ynh2 -**Démo :** https://demo.yunohost.org/wallabag/ +**Démo :** ## Captures d’écran @@ -56,11 +55,11 @@ Attention : Une mise à jour classique avec l'interface d'administration ou avec ## Documentations et ressources -* Site officiel de l’app : -* Documentation officielle de l’admin : -* Dépôt de code officiel de l’app : -* YunoHost Store: -* Signaler un bug : +- Site officiel de l’app : +- Documentation officielle de l’admin : +- Dépôt de code officiel de l’app : +- YunoHost Store : +- Signaler un bug : ## Informations pour les développeurs @@ -68,10 +67,10 @@ Merci de faire vos pull request sur la [branche testing](https://github.com/Yuno Pour essayer la branche testing, procédez comme suit. -``` bash +```bash sudo yunohost app install https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing --debug ou sudo yunohost app upgrade wallabag2 -u https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing --debug ``` -**Plus d’infos sur le packaging d’applications :** \ No newline at end of file +**Plus d’infos sur le packaging d’applications :** From fcaabe2eb0129570f9a1eb87e3219e7d43fa0115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 11:26:09 +0100 Subject: [PATCH 2/9] Manifest v2 --- .github/workflows/updater.sh | 90 ---- .github/workflows/updater.yml | 49 -- check_process | 30 -- conf/app.src | 7 - conf/extra_php-fpm.conf | 4 + conf/nginx.conf | 2 +- conf/php-fpm.conf | 434 ------------------ doc/ADMIN.md | 3 + doc/ADMIN_fr.md | 3 + doc/DESCRIPTION.md | 6 +- doc/DESCRIPTION_fr.md | 5 +- doc/DISCLAIMER.md | 18 - doc/DISCLAIMER_fr.md | 22 - doc/wallabag-quick-start-page.png | Bin 148049 -> 0 bytes manifest.json | 49 -- manifest.toml | 76 +++ scripts/_common.sh | 27 +- scripts/backup | 18 +- scripts/change_url | 72 +-- scripts/install | 181 ++------ scripts/remove | 69 +-- scripts/restore | 42 +- scripts/upgrade | 92 ++-- ...dap-auth.patch => main-00-ldap-auth.patch} | 0 ...h => main-01-logout-success-handler.patch} | 0 ...d.patch => main-02-oauth-workaround.patch} | 0 tests.toml | 11 + 27 files changed, 264 insertions(+), 1046 deletions(-) delete mode 100644 .github/workflows/updater.sh delete mode 100644 .github/workflows/updater.yml delete mode 100644 check_process delete mode 100644 conf/app.src create mode 100644 conf/extra_php-fpm.conf delete mode 100644 conf/php-fpm.conf create mode 100644 doc/ADMIN.md create mode 100644 doc/ADMIN_fr.md delete mode 100644 doc/DISCLAIMER.md delete mode 100644 doc/DISCLAIMER_fr.md delete mode 100644 doc/wallabag-quick-start-page.png delete mode 100644 manifest.json create mode 100644 manifest.toml rename sources/patches/{app-00-ldap-auth.patch => main-00-ldap-auth.patch} (100%) rename sources/patches/{app-01-logout-success-handler.patch => main-01-logout-success-handler.patch} (100%) rename sources/patches/{app-02-oauth-workaround.patch => main-02-oauth-workaround.patch} (100%) create mode 100644 tests.toml diff --git a/.github/workflows/updater.sh b/.github/workflows/updater.sh deleted file mode 100644 index 31aea45..0000000 --- a/.github/workflows/updater.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -#================================================= -# PACKAGE UPDATING HELPER -#================================================= - -# This script is meant to be run by GitHub Actions -# The YunoHost-Apps organisation offers a template Action to run this script periodically -# Since each app is different, maintainers can adapt its contents so as to perform -# automatic actions when a new upstream release is detected. - -#================================================= -# FETCHING LATEST RELEASE AND ITS ASSETS -#================================================= - -# Fetching information -current_version=$(cat manifest.json | jq -j '.version|split("~")[0]') -repo=$(cat manifest.json | jq -j '.upstream.code|split("https://github.com/")[1]') -# Some jq magic is needed, because the latest upstream release is not always the latest version (e.g. security patches for older versions) -version=$(curl --silent "https://api.github.com/repos/$repo/releases" | jq -r '.[] | select( .prerelease != true ) | .tag_name' | sort -V | tail -1) -asset_url="https://static.wallabag.org/releases/wallabag-release-$version.tar.gz" - -# Setting up the environment variables -echo "Current version: $current_version" -echo "Latest release from upstream: $version" -echo "VERSION=$version" >> $GITHUB_ENV -# For the time being, let's assume the script will fail -echo "PROCEED=false" >> $GITHUB_ENV - -# Proceed only if the retrieved version is greater than the current one -if ! dpkg --compare-versions "$current_version" "lt" "$version" ; then - echo "::warning ::No new version available" - exit 0 -# Proceed only if a PR for this new version does not already exist -elif git ls-remote -q --exit-code --heads https://github.com/$GITHUB_REPOSITORY.git ci-auto-update-v$version ; then - echo "::warning ::A branch already exists for this update" - exit 0 -fi - -#================================================= -# UPDATE SOURCE FILES -#================================================= - -echo "Handling asset at $asset_url" - -src="app" -extension="tar.gz" - -# Create the temporary directory -tempdir="$(mktemp -d)" - -# Download sources and calculate checksum -filename=${asset_url##*/} -curl --silent -4 -L $asset_url -o "$tempdir/$filename" -checksum=$(sha256sum "$tempdir/$filename" | head -c 64) - -# Delete temporary directory -rm -rf $tempdir - -# Rewrite source file -cat < conf/$src.src -SOURCE_URL=$asset_url -SOURCE_SUM=$checksum -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=$extension -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME= -SOURCE_EXTRACT=true -EOT -echo "... conf/$src.src updated" - -#================================================= -# SPECIFIC UPDATE STEPS -#================================================= - -# Any action on the app's source code can be done. -# The GitHub Action workflow takes care of committing all changes after this script ends. - -#================================================= -# GENERIC FINALIZATION -#================================================= - -# Replace new version in manifest -echo "$(jq -s --indent 4 ".[] | .version = \"$version~ynh1\"" manifest.json)" > manifest.json - -# No need to update the README, yunohost-bot takes care of it - -# The Action will proceed only if the PROCEED environment variable is set to true -echo "PROCEED=true" >> $GITHUB_ENV -exit 0 diff --git a/.github/workflows/updater.yml b/.github/workflows/updater.yml deleted file mode 100644 index a56d7cb..0000000 --- a/.github/workflows/updater.yml +++ /dev/null @@ -1,49 +0,0 @@ -# This workflow allows GitHub Actions to automagically update your app whenever a new upstream release is detected. -# You need to enable Actions in your repository settings, and fetch this Action from the YunoHost-Apps organization. -# This file should be enough by itself, but feel free to tune it to your needs. -# It calls updater.sh, which is where you should put the app-specific update steps. -name: Check for new upstream releases -on: - # Allow to manually trigger the workflow - workflow_dispatch: - # Run it every day at 6:00 UTC - schedule: - - cron: '0 6 * * *' -jobs: - updater: - runs-on: ubuntu-latest - steps: - - name: Fetch the source code - uses: actions/checkout@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - name: Run the updater script - id: run_updater - run: | - # Setting up Git user - git config --global user.name 'yunohost-bot' - git config --global user.email 'yunohost-bot@users.noreply.github.com' - # Run the updater script - /bin/bash .github/workflows/updater.sh - - name: Commit changes - id: commit - if: ${{ env.PROCEED == 'true' }} - run: | - git commit -am "Upgrade to v$VERSION" - - name: Create Pull Request - id: cpr - if: ${{ env.PROCEED == 'true' }} - uses: peter-evans/create-pull-request@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: Update to version ${{ env.VERSION }} - committer: 'yunohost-bot ' - author: 'yunohost-bot ' - signoff: false - base: testing - branch: ci-auto-update-v${{ env.VERSION }} - delete-branch: true - title: 'Upgrade to version ${{ env.VERSION }}' - body: | - Upgrade to v${{ env.VERSION }} - draft: false diff --git a/check_process b/check_process deleted file mode 100644 index b1fead1..0000000 --- a/check_process +++ /dev/null @@ -1,30 +0,0 @@ -;; Test complet - ; Manifest - domain="domain.tld" - path="/path" - admin="john" - ; Checks - pkg_linter=1 - setup_sub_dir=1 - setup_root=1 - setup_nourl=0 - setup_private=0 - setup_public=0 - upgrade=1 - # 2.2.3 - upgrade=1 from_commit=f75d58cb32c51a0981333ea88974dc3199324e65 - # 2.3.8~ynh3 - upgrade=1 from_commit=2e20b8f9a6b791e059b806fcfc2253f88d1aeaf2 - # 2.3.8~ynh4 - upgrade=1 from_commit=4da53256350d7e4d63812ed3244e945346a5d9b7 - backup_restore=1 - multi_instance=1 - port_already_use=0 - change_url=1 -;;; Options -Email= -Notification=none -;;; Upgrade options - ; commit=f75d58cb32c51a0981333ea88974dc3199324e65 - name= Previous package version - manifest_arg=domain=DOMAIN&path=PATH&admin=USER& diff --git a/conf/app.src b/conf/app.src deleted file mode 100644 index 1ee9801..0000000 --- a/conf/app.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/wallabag/wallabag/releases/download/2.5.4/wallabag-2.5.4.tar.gz -SOURCE_SUM=c953105e3181f18bf592541a1c46c318c6663ad00d4687052676b02a7d74c618 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME= -SOURCE_EXTRACT=true diff --git a/conf/extra_php-fpm.conf b/conf/extra_php-fpm.conf new file mode 100644 index 0000000..700c37c --- /dev/null +++ b/conf/extra_php-fpm.conf @@ -0,0 +1,4 @@ +; Additional php.ini defines, specific to this pool of workers. + +php_admin_value[upload_max_filesize] = 50M +php_admin_value[post_max_size] = 50M diff --git a/conf/nginx.conf b/conf/nginx.conf index 07d36a3..962767d 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -2,7 +2,7 @@ location __PATH__/ { # Path to source - alias __FINALPATH__/web/; + alias __INSTALL_DIR__/web/; client_body_timeout 60m; proxy_read_timeout 60m; diff --git a/conf/php-fpm.conf b/conf/php-fpm.conf deleted file mode 100644 index 9ec5826..0000000 --- a/conf/php-fpm.conf +++ /dev/null @@ -1,434 +0,0 @@ -; Start a new pool named 'www'. -; the variable $pool can be used in any directive and will be replaced by the -; pool name ('www' here) -[__NAMETOCHANGE__] - -; Per pool prefix -; It only applies on the following directives: -; - 'access.log' -; - 'slowlog' -; - 'listen' (unixsocket) -; - 'chroot' -; - 'chdir' -; - 'php_values' -; - 'php_admin_values' -; When not set, the global prefix (or /usr) applies instead. -; Note: This directive can also be relative to the global prefix. -; Default Value: none -;prefix = /path/to/pools/$pool - -; Unix user/group of processes -; Note: The user is mandatory. If the group is not set, the default user's group -; will be used. -user = __USER__ -group = __USER__ - -; The address on which to accept FastCGI requests. -; Valid syntaxes are: -; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on -; a specific port; -; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on -; a specific port; -; 'port' - to listen on a TCP socket to all addresses -; (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/php__PHPVERSION__-fpm-__NAMETOCHANGE__.sock - -; Set listen(2) backlog. -; Default Value: 511 (-1 on FreeBSD and OpenBSD) -;listen.backlog = 511 - -; Set permissions for unix socket, if one is used. In Linux, read/write -; permissions must be set in order to allow connections from a web server. Many -; BSD-derived systems allow connections regardless of permissions. -; Default Values: user and group are set as the running user -; mode is set to 0660 -listen.owner = www-data -listen.group = www-data -;listen.mode = 0660 -; When POSIX Access Control Lists are supported you can set them using -; these options, value is a comma separated list of user/group names. -; When set, listen.owner and listen.group are ignored -;listen.acl_users = -;listen.acl_groups = - -; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. -; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original -; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address -; must be separated by a comma. If this value is left blank, connections will be -; accepted from any ip address. -; Default Value: any -;listen.allowed_clients = 127.0.0.1 - -; Specify the nice(2) priority to apply to the pool processes (only if set) -; The value can vary from -19 (highest priority) to 20 (lower priority) -; Note: - It will only work if the FPM master process is launched as root -; - The pool processes will inherit the master process priority -; unless it specified otherwise -; Default Value: no set -; process.priority = -19 - -; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user -; or group is differrent than the master process user. It allows to create process -; core dump and ptrace the process for the pool user. -; Default Value: no -; process.dumpable = yes - -; Choose how the process manager will control the number of child processes. -; Possible Values: -; static - a fixed number (pm.max_children) of child processes; -; dynamic - the number of child processes are set dynamically based on the -; following directives. With this process management, there will be -; always at least 1 children. -; pm.max_children - the maximum number of children that can -; be alive at the same time. -; pm.start_servers - the number of children created on startup. -; pm.min_spare_servers - the minimum number of children in 'idle' -; state (waiting to process). If the number -; of 'idle' processes is less than this -; number then some children will be created. -; pm.max_spare_servers - the maximum number of children in 'idle' -; state (waiting to process). If the number -; of 'idle' processes is greater than this -; number then some children will be killed. -; ondemand - no children are created at startup. Children will be forked when -; new requests will connect. The following parameter are used: -; pm.max_children - the maximum number of children that -; can be alive at the same time. -; pm.process_idle_timeout - The number of seconds after which -; an idle process will be killed. -; Note: This value is mandatory. -pm = dynamic - -; The number of child processes to be created when pm is set to 'static' and the -; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. -; This value sets the limit on the number of simultaneous requests that will be -; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. -; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP -; CGI. The below defaults are based on a server without much resources. Don't -; forget to tweak pm.* to fit your needs. -; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' -; Note: This value is mandatory. -pm.max_children = 5 - -; The number of child processes created on startup. -; Note: Used only when pm is set to 'dynamic' -; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 -pm.start_servers = 2 - -; The desired minimum number of idle server processes. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -pm.min_spare_servers = 1 - -; The desired maximum number of idle server processes. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -pm.max_spare_servers = 3 - -; The number of seconds after which an idle process will be killed. -; Note: Used only when pm is set to 'ondemand' -; Default Value: 10s -;pm.process_idle_timeout = 10s; - -; The number of requests each child process should execute before respawning. -; This can be useful to work around memory leaks in 3rd party libraries. For -; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. -; Default Value: 0 -;pm.max_requests = 500 - -; The URI to view the FPM status page. If this value is not set, no URI will be -; recognized as a status page. It shows the following informations: -; pool - the name of the pool; -; process manager - static, dynamic or ondemand; -; start time - the date and time FPM has started; -; start since - number of seconds since FPM has started; -; accepted conn - the number of request accepted by the pool; -; listen queue - the number of request in the queue of pending -; connections (see backlog in listen(2)); -; max listen queue - the maximum number of requests in the queue -; of pending connections since FPM has started; -; listen queue len - the size of the socket queue of pending connections; -; idle processes - the number of idle processes; -; active processes - the number of active processes; -; total processes - the number of idle + active processes; -; max active processes - the maximum number of active processes since FPM -; has started; -; max children reached - number of times, the process limit has been reached, -; when pm tries to start more children (works only for -; pm 'dynamic' and 'ondemand'); -; Value are updated in real time. -; Example output: -; pool: www -; process manager: static -; start time: 01/Jul/2011:17:53:49 +0200 -; start since: 62636 -; accepted conn: 190460 -; listen queue: 0 -; max listen queue: 1 -; listen queue len: 42 -; idle processes: 4 -; active processes: 11 -; total processes: 15 -; max active processes: 12 -; max children reached: 0 -; -; By default the status page output is formatted as text/plain. Passing either -; 'html', 'xml' or 'json' in the query string will return the corresponding -; output syntax. Example: -; http://www.foo.bar/status -; http://www.foo.bar/status?json -; http://www.foo.bar/status?html -; http://www.foo.bar/status?xml -; -; By default the status page only outputs short status. Passing 'full' in the -; query string will also return status for each pool process. -; Example: -; http://www.foo.bar/status?full -; http://www.foo.bar/status?json&full -; http://www.foo.bar/status?html&full -; http://www.foo.bar/status?xml&full -; The Full status returns for each process: -; pid - the PID of the process; -; state - the state of the process (Idle, Running, ...); -; start time - the date and time the process has started; -; start since - the number of seconds since the process has started; -; requests - the number of requests the process has served; -; request duration - the duration in µs of the requests; -; request method - the request method (GET, POST, ...); -; request URI - the request URI with the query string; -; content length - the content length of the request (only with POST); -; user - the user (PHP_AUTH_USER) (or '-' if not set); -; script - the main script called (or '-' if not set); -; last request cpu - the %cpu the last request consumed -; it's always 0 if the process is not in Idle state -; because CPU calculation is done when the request -; processing has terminated; -; last request memory - the max amount of memory the last request consumed -; it's always 0 if the process is not in Idle state -; because memory calculation is done when the request -; processing has terminated; -; If the process is in Idle state, then informations are related to the -; last request the process has served. Otherwise informations are related to -; the current request being served. -; Example output: -; ************************ -; pid: 31330 -; state: Running -; start time: 01/Jul/2011:17:53:49 +0200 -; start since: 63087 -; requests: 12808 -; request duration: 1250261 -; request method: GET -; request URI: /test_mem.php?N=10000 -; content length: 0 -; user: - -; script: /home/fat/web/docs/php/test_mem.php -; last request cpu: 0.00 -; last request memory: 0 -; -; Note: There is a real-time FPM status monitoring sample web page available -; It's available in: /usr/share/php/7.0/fpm/status.html -; -; Note: The value must start with a leading slash (/). The value can be -; anything, but it may not be a good idea to use the .php extension or it -; may conflict with a real PHP file. -; Default Value: not set -;pm.status_path = /status - -; The ping URI to call the monitoring page of FPM. If this value is not set, no -; URI will be recognized as a ping page. This could be used to test from outside -; that FPM is alive and responding, or to -; - create a graph of FPM availability (rrd or such); -; - remove a server from a group if it is not responding (load balancing); -; - trigger alerts for the operating team (24/7). -; Note: The value must start with a leading slash (/). The value can be -; anything, but it may not be a good idea to use the .php extension or it -; may conflict with a real PHP file. -; Default Value: not set -;ping.path = /ping - -; This directive may be used to customize the response of a ping request. The -; response is formatted as text/plain with a 200 response code. -; Default Value: pong -;ping.response = pong - -; The access log file -; Default: not set -;access.log = log/$pool.access.log - -; The access log format. -; The following syntax is allowed -; %%: the '%' character -; %C: %CPU used by the request -; it can accept the following format: -; - %{user}C for user CPU only -; - %{system}C for system CPU only -; - %{total}C for user + system CPU (default) -; %d: time taken to serve the request -; it can accept the following format: -; - %{seconds}d (default) -; - %{miliseconds}d -; - %{mili}d -; - %{microseconds}d -; - %{micro}d -; %e: an environment variable (same as $_ENV or $_SERVER) -; it must be associated with embraces to specify the name of the env -; variable. Some exemples: -; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e -; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e -; %f: script filename -; %l: content-length of the request (for POST request only) -; %m: request method -; %M: peak of memory allocated by PHP -; it can accept the following format: -; - %{bytes}M (default) -; - %{kilobytes}M -; - %{kilo}M -; - %{megabytes}M -; - %{mega}M -; %n: pool name -; %o: output header -; it must be associated with embraces to specify the name of the header: -; - %{Content-Type}o -; - %{X-Powered-By}o -; - %{Transfert-Encoding}o -; - .... -; %p: PID of the child that serviced the request -; %P: PID of the parent of the child that serviced the request -; %q: the query string -; %Q: the '?' character if query string exists -; %r: the request URI (without the query string, see %q and %Q) -; %R: remote IP address -; %s: status (response code) -; %t: server time the request was received -; it can accept a strftime(3) format: -; %d/%b/%Y:%H:%M:%S %z (default) -; The strftime(3) format must be encapsuled in a %{}t tag -; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t -; %T: time the log has been written (the request has finished) -; it can accept a strftime(3) format: -; %d/%b/%Y:%H:%M:%S %z (default) -; The strftime(3) format must be encapsuled in a %{}t tag -; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t -; %u: remote user -; -; Default: "%R - %u %t \"%m %r\" %s" -;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" - -; The log file for slow requests -; Default Value: not set -; Note: slowlog is mandatory if request_slowlog_timeout is set -;slowlog = log/$pool.log.slow - -; The timeout for serving a single request after which a PHP backtrace will be -; dumped to the 'slowlog' file. A value of '0s' means 'off'. -; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) -; Default Value: 0 -;request_slowlog_timeout = 0 - -; The timeout for serving a single request after which the worker process will -; be killed. This option should be used when the 'max_execution_time' ini option -; does not stop script execution for some reason. A value of '0' means 'off'. -; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) -; Default Value: 0 -request_terminate_timeout = 1d - -; Set open file descriptor rlimit. -; Default Value: system defined value -;rlimit_files = 1024 - -; Set max core size rlimit. -; Possible Values: 'unlimited' or an integer greater or equal to 0 -; Default Value: system defined value -;rlimit_core = 0 - -; Chroot to this directory at the start. This value must be defined as an -; absolute path. When this value is not set, chroot is not used. -; Note: you can prefix with '$prefix' to chroot to the pool prefix or one -; of its subdirectories. If the pool prefix is not set, the global prefix -; will be used instead. -; Note: chrooting is a great security feature and should be used whenever -; possible. However, all PHP paths will be relative to the chroot -; (error_log, sessions.save_path, ...). -; Default Value: not set -;chroot = - -; Chdir to this directory at the start. -; Note: relative path can be used. -; Default Value: current directory or / when chroot -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. -; Note: on highloaded environement, this can cause some delay in the page -; process time (several ms). -; Default Value: no -;catch_workers_output = yes - -; Clear environment in FPM workers -; Prevents arbitrary environment variables from reaching FPM worker processes -; by clearing the environment in workers before env vars specified in this -; pool configuration are added. -; Setting to "no" will make all environment variables available to PHP code -; via getenv(), $_ENV and $_SERVER. -; Default Value: yes -;clear_env = no - -; Limits the extensions of the main script FPM will allow to parse. This can -; prevent configuration mistakes on the web server side. You should only limit -; FPM to .php extensions to prevent malicious users to use other extensions to -; execute php code. -; Note: set an empty value to allow all extensions. -; Default Value: .php -;security.limit_extensions = .php .php3 .php4 .php5 .php7 - -; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from -; the current environment. -; Default Value: clean env -;env[HOSTNAME] = $HOSTNAME -;env[PATH] = /usr/local/bin:/usr/bin:/bin -;env[TMP] = /tmp -;env[TMPDIR] = /tmp -;env[TEMP] = /tmp - -; Additional php.ini defines, specific to this pool of workers. These settings -; overwrite the values previously defined in the php.ini. The directives are the -; same as the PHP SAPI: -; php_value/php_flag - you can set classic ini defines which can -; be overwritten from PHP call 'ini_set'. -; php_admin_value/php_admin_flag - these directives won't be overwritten by -; PHP call 'ini_set' -; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. - -; Defining 'extension' will load the corresponding shared extension from -; extension_dir. Defining 'disable_functions' or 'disable_classes' will not -; overwrite previously defined php.ini values, but will append the new value -; instead. - -; Note: path INI options can be relative and will be expanded with the prefix -; (pool, global or /usr) - -; Default Value: nothing is defined by default except the values in php.ini and -; specified at startup with the -d argument -;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com -;php_flag[display_errors] = off -;php_admin_value[error_log] = /var/log/fpm-php.www.log -;php_admin_flag[log_errors] = on -;php_admin_value[memory_limit] = 32M - -; Common values to change to increase file upload limit -; php_admin_value[upload_max_filesize] = 50M -; php_admin_value[post_max_size] = 50M -; php_admin_flag[mail.add_x_header] = Off - -; Other common parameters -; php_admin_value[max_execution_time] = 600 -; php_admin_value[max_input_time] = 300 -; php_admin_value[memory_limit] = 256M -; php_admin_flag[short_open_tag] = On - -php_admin_value[max_execution_time] = 3600 -php_admin_value[upload_max_filesize] = 50M -php_admin_value[post_max_size] = 50M diff --git a/doc/ADMIN.md b/doc/ADMIN.md new file mode 100644 index 0000000..737e05a --- /dev/null +++ b/doc/ADMIN.md @@ -0,0 +1,3 @@ +### 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 diff --git a/doc/ADMIN_fr.md b/doc/ADMIN_fr.md new file mode 100644 index 0000000..6dc2907 --- /dev/null +++ b/doc/ADMIN_fr.md @@ -0,0 +1,3 @@ +### 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 diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md index f2e514a..5c08332 100644 --- a/doc/DESCRIPTION.md +++ b/doc/DESCRIPTION.md @@ -1,4 +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. +Wallabag is a self hostable Read-It-Later application allowing you to not miss any content anymore. Click, save, read it when you can. +It provides a web interface, browser (Firefox/Chrome/Opera) add-ons, mobile apps (Android/iOS/Windows Phone) and even on e-reader (PocketBook/Kobo). -It provides a web interface, browser (Firefox / Chrome / Opera) add-ons, mobile apps (Android / iOS / Windows Phone) and even on e-reader (PocketBook / Kobo). +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/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md index bf2e239..db5ccae 100644 --- a/doc/DESCRIPTION_fr.md +++ b/doc/DESCRIPTION_fr.md @@ -1,3 +1,4 @@ -[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. +Wallabag 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). -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). +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/DISCLAIMER.md b/doc/DISCLAIMER.md deleted file mode 100644 index d50d340..0000000 --- a/doc/DISCLAIMER.md +++ /dev/null @@ -1,18 +0,0 @@ -### YunoHost specific features -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 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). - -### (Beta) Testing branch -*Please be aware that the testing branch (or any PR branch)* might *contains some bugs and is not recommended if you need a stable app.* - -(Beta) Testers are welcome to try new upgrades (such as a new version), as listed in the [Pull Requests section](https://github.com/YunoHost-Apps/wallabag2_ynh/pulls). More testing will allow us to provide upgrades faster 🙂. In order to try the testing branch, use `sudo yunohost app upgrade wallabag2 -u https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing`. - -Warning : Doing a normal upgrade of the package with the web admin or `sudo yunohost app upgrade wallabag2` (without any URL specified) will revert you app to the master branch. *This may break you wallabag* if it goes to a previous version (if the newest is not retrocompatible). \ No newline at end of file diff --git a/doc/DISCLAIMER_fr.md b/doc/DISCLAIMER_fr.md deleted file mode 100644 index d5b3f53..0000000 --- a/doc/DISCLAIMER_fr.md +++ /dev/null @@ -1,22 +0,0 @@ -### Caractéristiques spécifiques YunoHost - -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 - -* 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). - - -### Branche de test (*Testing*) -*Soyez concient que la branche testing* pourrait *contenir des bugs et n'est pas recommandée si vous recherchez la stabilité de votre application.* - -Les personnes souhaitant (bêta) tester de nouvelles mises à jour (ex: une nouvelle version), listée dans la [section des Pull Requests](https://github.com/YunoHost-Apps/wallabag2_ynh/pulls), sont les bienvenues. Plus de tests nous permettrons de sortir des mises à jour plus vite. Pour tester la branche *testing*, utilisez `sudo yunohost app upgrade wallabag2 -u https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing`. - -Attention : Une mise à jour classique avec l'interface d'administration ou avec `sudo yunohost app upgrade wallabag2` (sans préciser l'URL) fera retourner votre application au niveau de la branche master. *Ceci pourrait casser votre wallabag* si vous revenez à une version précédente (et si la nouvelle n'est pas rétrocompatible). - diff --git a/doc/wallabag-quick-start-page.png b/doc/wallabag-quick-start-page.png deleted file mode 100644 index d8c25f531136b0086631eab5166e19e5b1a0958d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148049 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∨Po)Z%-q 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 diff --git a/manifest.json b/manifest.json deleted file mode 100644 index bf52728..0000000 --- a/manifest.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "Wallabag", - "id": "wallabag2", - "packaging_format": 1, - "description": { - "en": "A self hostable read-it-later app", - "fr": "Une application de lecture-plus-tard auto-hébergeable" - }, - "version": "2.5.4~ynh2", - "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" - }, - "requirements": { - "yunohost": ">= 11.0" - }, - "multi_instance": true, - "services": [ - "nginx", - "php7.3-fpm", - "mysql" - ], - "arguments": { - "install": [ - { - "name": "domain", - "type": "domain" - }, - { - "name": "path", - "type": "path", - "example": "/wallabag", - "default": "/wallabag" - }, - { - "name": "admin", - "type": "user" - } - ] - } -} diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..da54f02 --- /dev/null +++ b/manifest.toml @@ -0,0 +1,76 @@ +#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/manifest.v2.schema.json + +packaging_format = 2 + +id = "wallabag2" +name = "Wallabag" +description.en = "A self hostable read-it-later app" +description.fr = "Une application de lecture-plus-tard auto-hébergeable" + +version = "2.5.4~ynh2" + +maintainers = ["Lapineige"] + +[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" +cpe = "cpe:2.3:a:wallabag:wallabag" +fund = "???" # FIXME: optional but recommended (or remove if irrelevant / not applicable). This is meant to be an URL where people can financially support this app, especially when its development is based on volunteers and/or financed by its community. YunoHost may later advertise it in the webadmin. + +[integration] +yunohost = ">= 11.2" +architectures = "all" +multi_instance = true +ldap = true +sso = false +disk = "50M" # FIXME: replace with an **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ... +ram.build = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... +ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... + +[install] + [install.domain] + type = "domain" + + [install.path] + type = "path" + default = "/wallabag" + + [install.admin] + type = "user" + +[resources] + [resources.sources.main] + url = "https://github.com/wallabag/wallabag/releases/download/2.5.4/wallabag-2.5.4.tar.gz" + sha256 = "c953105e3181f18bf592541a1c46c318c6663ad00d4687052676b02a7d74c618" + + autoupdate.strategy = "latest_github_release" + + [resources.system_user] + + [resources.install_dir] + + [resources.permissions] + main.url = "/" + + [resources.apt] + packages = [ + "php7.4-cli", + "php7.4-mysql", + "php7.4-json", + "php7.4-gd", + "php7.4-tidy", + "php7.4-curl", + "php7.4-gettext", + "php7.4-redis", + "php7.4-xml", + "php7.4-mbstring", + "php7.4-ldap", + "php7.4-intl", + "mariadb-server", + ] + + [resources.database] + type = "mysql" diff --git a/scripts/_common.sh b/scripts/_common.sh index ad0074c..bddccb0 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,11 +4,7 @@ # COMMON VARIABLES #================================================= -YNH_PHP_VERSION="7.4" - -# dependencies used by the app -pkg_dependencies="php${YNH_PHP_VERSION}-cli php${YNH_PHP_VERSION}-mysql php${YNH_PHP_VERSION}-json php${YNH_PHP_VERSION}-gd php${YNH_PHP_VERSION}-tidy php${YNH_PHP_VERSION}-curl php${YNH_PHP_VERSION}-gettext php${YNH_PHP_VERSION}-redis php${YNH_PHP_VERSION}-xml php${YNH_PHP_VERSION}-mbstring php${YNH_PHP_VERSION}-ldap php${YNH_PHP_VERSION}-intl" - +wb_conf="$install_dir/app/config/parameters.yml" #================================================= # PERSONAL HELPERS @@ -16,29 +12,16 @@ pkg_dependencies="php${YNH_PHP_VERSION}-cli php${YNH_PHP_VERSION}-mysql php${YNH function set_permissions { # Set permissions to app files - chown -R $app:www-data $final_path - chmod -R g=u,g-w,o-rwx $final_path + chown -R $app:www-data $install_dir + chmod -R g=u,g-w,o-rwx $install_dir # Restrict rights to Wallabag user only chmod 600 $wb_conf - if [ -e $final_path/var/cache/prod/appProdProjectContainer.php ]; then - chmod 700 $final_path/var/cache/prod/appProdProjectContainer.php + if [ -e $install_dir/var/cache/prod/appProdProjectContainer.php ]; then + chmod 700 $install_dir/var/cache/prod/appProdProjectContainer.php fi } #================================================= # EXPERIMENTAL HELPERS #================================================= - -# Execute a command as another user -# usage: exec_as USER COMMAND [ARG ...] -ynh_exec_as() { - local USER=$1 - shift 1 - - if [[ $USER = $(whoami) ]]; then - eval "$@" - else - sudo -u "$USER" "$@" - fi -} diff --git a/scripts/backup b/scripts/backup index 703fbd6..0b509d5 100644 --- a/scripts/backup +++ b/scripts/backup @@ -15,19 +15,19 @@ source /usr/share/yunohost/helpers #================================================= # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_print_info --message="Loading installation settings..." +#REMOVEME? ynh_print_info --message="Loading installation settings..." -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? 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) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) +#REMOVEME? phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= # DECLARE DATA AND CONF FILES TO BACKUP @@ -39,9 +39,9 @@ ynh_print_info --message="Declaring files to be backed up..." #================================================= # Clean cache files before backup (saved some disk space) -ynh_secure_remove --file=$final_path/var/cache/prod +#REMOVEME? ynh_secure_remove --file=$install_dir/var/cache/prod -ynh_backup --src_path="$final_path" +ynh_backup --src_path="$install_dir" #================================================= # BACKUP THE NGINX CONFIGURATION diff --git a/scripts/change_url b/scripts/change_url index 7657ca3..1127468 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -8,61 +8,61 @@ source _common.sh source /usr/share/yunohost/helpers -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # RETRIEVE ARGUMENTS #================================================= -old_domain=$YNH_APP_OLD_DOMAIN -old_path=$YNH_APP_OLD_PATH +#REMOVEME? old_domain=$YNH_APP_OLD_DOMAIN +#REMOVEME? old_path=$YNH_APP_OLD_PATH -new_domain=$YNH_APP_NEW_DOMAIN -new_path=$YNH_APP_NEW_PATH +#REMOVEME? new_domain=$YNH_APP_NEW_DOMAIN +#REMOVEME? new_path=$YNH_APP_NEW_PATH -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=2 +#REMOVEME? ynh_script_progression --message="Loading installation settings..." --weight=2 -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -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) +#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) +#REMOVEME? db_user=$db_name +#REMOVEME? db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) #================================================= # BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP #================================================= -ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." +#REMOVEME? 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 () { +#REMOVEME? ynh_backup_before_upgrade +#REMOVEME? 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" +#REMOVEME? ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" # Restore it if the upgrade fails - ynh_restore_upgradebackup +#REMOVEME? ynh_restore_upgradebackup } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # CHECK WHICH PARTS SHOULD BE CHANGED #================================================= -change_domain=0 -if [ "$old_domain" != "$new_domain" ] +#REMOVEME? change_domain=0 +#REMOVEME? if [ "$old_domain" != "$new_domain" ] then - change_domain=1 + #REMOVEME? change_domain=1 fi -change_path=0 -if [ "$old_path" != "$new_path" ] +#REMOVEME? change_path=0 +#REMOVEME? if [ "$old_path" != "$new_path" ] then - change_path=1 + #REMOVEME? change_path=1 fi #================================================= @@ -72,28 +72,30 @@ fi #================================================= ynh_script_progression --message="Updating NGINX web server configuration..." --weight=2 -nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf +ynh_change_url_nginx_config + +#REMOVEME? nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf # 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 - ynh_backup_if_checksum_is_different --file="$nginx_conf_path" +#REMOVEME? ynh_backup_if_checksum_is_different --file="$nginx_conf_path" # Set global variables for NGINX helper - domain="$old_domain" - path_url="$new_path" +#REMOVEME? domain="$old_domain" +#REMOVEME? path="$new_path" # Create a dedicated NGINX config - ynh_add_nginx_config +#REMOVEME? ynh_add_nginx_config fi # Change the domain for NGINX if [ $change_domain -eq 1 ] then # Delete file checksum for the old conf file location - ynh_delete_file_checksum --file="$nginx_conf_path" - mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf +#REMOVEME? ynh_delete_file_checksum --file="$nginx_conf_path" +#REMOVEME? mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf # Store file checksum for the new config file location - ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +#REMOVEME? ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" fi #================================================= @@ -107,7 +109,7 @@ ynh_script_progression --message="Updating wallabag configuration..." ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE internal_setting SET value = 'https://$new_domain$new_path' WHERE name = 'wallabag_url'" # Change domain name in parameters.yml -ynh_replace_string --match_string="domain_name: .*" --replace_string="domain_name: https://$new_domain$new_path" --target_file=$final_path/app/config/parameters.yml +ynh_replace_string --match_string="domain_name: .*" --replace_string="domain_name: https://$new_domain$new_path" --target_file=$install_dir/app/config/parameters.yml # If "Download images locally" option has been enabled in Internal Settings download_images_enabled=$(ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "SELECT value from internal_setting WHERE name='download_images_enabled '" | tail -n 1) @@ -119,16 +121,16 @@ then fi # Clear assets cache -ynh_secure_remove --file=$final_path/var/cache +#REMOVEME? ynh_secure_remove --file=$install_dir/var/cache #================================================= # GENERIC FINALISATION #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." +#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." -ynh_systemd_action --service_name=nginx --action=reload +#REMOVEME? #REMOVEME? ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT diff --git a/scripts/install b/scripts/install index 218363f..13cb8ac 100644 --- a/scripts/install +++ b/scripts/install @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -10,138 +8,67 @@ 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 +# INITIALIZE AND STORE SETTINGS #================================================= -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 --message="This path already contains a folder" - -# Register (book) web path -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 -ynh_app_setting_set --app=$app --key=admin --value=$admin - -#================================================= -# STANDARD MODIFICATIONS -#================================================= -# INSTALL DEPENDENCIES -#================================================= -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 --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 +# Generate random DES key & password +deskey=$(ynh_string_random --length=24) +ynh_app_setting_set --app="$app" --key="deskey" --value="$deskey" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= ynh_script_progression --message="Setting up source files..." --weight=6 -ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source --dest_dir="$final_path" - -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Configuring NGINX web server..." --weight=2 +ynh_setup_source --dest_dir="$install_dir" -# Create a dedicated NGINX config -ynh_add_nginx_config +# Create log dir/file FIXME: is it useless? +mkdir -p "$install_dir/var/logs/" +touch "$install_dir/var/logs/prod.log" -#================================================= -# PHP-FPM CONFIGURATION -#================================================= -ynh_script_progression --message="Configuring PHP-FPM..." --weight=2 +chown -R "$app:www-data" "$install_dir" -# Create a dedicated PHP-FPM config -ynh_add_fpm_config --phpversion=$YNH_PHP_VERSION - -#================================================= -# SPECIFIC SETUP #================================================= # CONFIGURE WALLABAG #================================================= ynh_script_progression --message="Configuring wallabag..." --weight=35 # Copy and set Wallabag dist configuration -wb_conf=$final_path/app/config/parameters.yml -cp $final_path/app/config/parameters.yml.dist $wb_conf - -ynh_replace_string --match_string="fosuser_registration: true" --replace_string="fosuser_registration: false" --target_file=$wb_conf -ynh_replace_string --match_string="database_name: wallabag" --replace_string="database_name: $db_name" --target_file=$wb_conf -ynh_replace_string --match_string="database_user: root" --replace_string="database_user: $db_user" --target_file=$wb_conf -ynh_replace_string --match_string="database_password: ~" --replace_string="database_password: $db_pwd" --target_file=$wb_conf -ynh_replace_string --match_string="database_table_prefix: wallabag_" --replace_string="database_table_prefix: null" --target_file=$wb_conf -# Generate random DES key & password -deskey=$(ynh_string_random --length=24) -ynh_app_setting_set --app=$app --key=deskey --value=$deskey -ynh_replace_string --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" --target_file=$wb_conf -ynh_replace_string --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path_url" --target_file=$wb_conf +cp "$install_dir/app/config/parameters.yml.dist" "$wb_conf" -# Alias for php-cli execution command -php_exec="ynh_exec_as $app php$YNH_PHP_VERSION "$final_path/bin/console" --no-interaction --env=prod" +ynh_replace_string --target_file="$wb_conf" --match_string="fosuser_registration: true" --replace_string="fosuser_registration: false" +ynh_replace_string --target_file="$wb_conf" --match_string="database_name: wallabag" --replace_string="database_name: $db_name" +ynh_replace_string --target_file="$wb_conf" --match_string="database_user: root" --replace_string="database_user: $db_user" +ynh_replace_string --target_file="$wb_conf" --match_string="database_password: ~" --replace_string="database_password: $db_pwd" +ynh_replace_string --target_file="$wb_conf" --match_string="database_table_prefix: wallabag_" --replace_string="database_table_prefix: null" +ynh_replace_string --target_file="$wb_conf" --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" +ynh_replace_string --target_file="$wb_conf" --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path" + +chown -R "$app:www-data" "$install_dir" -# Set permissions to app files -chown -R $app: $final_path +# Alias for php-cli execution command +php_exec=(ynh_exec_as "$app" "php$YNH_PHP_VERSION" "$install_dir/bin/console" --no-interaction --env=prod) # Install dependencies and Wallabag -$php_exec wallabag:install +ynh_exec_as "$app" "${php_exec[@]}" wallabag:install # Add users to Wallabag -for username in $(ynh_user_list) -do - user_email=$(ynh_user_get_info --username="$username" --key=mail) - user_pass=$(ynh_string_random) - $php_exec fos:user:create "$username" "$user_email" "$user_pass" +for username in $(ynh_user_list); do + user_email=$(ynh_user_get_info --username="$username" --key=mail) + # We don't care about that thanks to LDAP + user_pass=$(ynh_string_random) + ynh_exec_as "$app" "${php_exec[@]}" fos:user:create "$username" "$user_email" "$user_pass" done # Set admin user -$php_exec fos:user:promote --super "$admin" +ynh_exec_as "$app" "${php_exec[@]}" fos:user:promote --super "$admin" # Configure Wallabag instance URL -ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE internal_setting SET value = 'https://$domain$path_url' WHERE name = 'wallabag_url'" +ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" \ + <<< "UPDATE internal_setting SET value = 'https://$domain$path' WHERE name = 'wallabag_url'" + +set_permissions #================================================= # SETUP HOOKS @@ -151,49 +78,21 @@ ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_fil ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_delete" #================================================= -# GENERIC FINALIZATION -#================================================= -# SECURE FILES AND DIRECTORIES +# SYSTEM CONFIGURATION #================================================= +ynh_script_progression --message="Adding system configurations related to $app..." --weight=1 -set_permissions +# Create a dedicated NGINX config +ynh_add_nginx_config -#================================================= -# SETUP LOGROTATE -#================================================= +# Create a dedicated PHP-FPM config +ynh_add_fpm_config -ynh_script_progression --message="Configuring log rotation..." # Use logrotate to manage application logfile(s) -touch "$final_path/var/logs/prod.log" -ynh_use_logrotate "$final_path/var/logs/prod.log" -chown $app:www-data "$final_path/var/logs/prod.log" - -#================================================= -# SETUP FAIL2BAN -#================================================= -ynh_script_progression --message="Configuring Fail2Ban..." - -# 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" +ynh_use_logrotate --logfile="$install_dir/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 permissions..." - -ynh_permission_update --permission="main" --add="visitors" - -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." - -ynh_systemd_action --service_name=nginx --action=reload +ynh_add_fail2ban_config --logpath="$install_dir/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 #================================================= # END OF SCRIPT diff --git a/scripts/remove b/scripts/remove index 608fdf6..aabd88a 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -10,85 +8,22 @@ source _common.sh source /usr/share/yunohost/helpers #================================================= -# LOAD SETTINGS +# REMOVE SYSTEM CONFIGURATIONS #================================================= -ynh_script_progression --message="Loading installation settings..." - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$db_name -final_path=$(ynh_app_setting_get --app=$app --key=final_path) - -#================================================= -# STANDARD REMOVE -#================================================= -# REMOVE LOGROTATE CONFIGURATION -#================================================= -ynh_script_progression --message="Removing logrotate configuration..." +ynh_script_progression --message="Removing system configurations related to $app..." --weight=1 # Remove the app-specific logrotate config ynh_remove_logrotate -#================================================= -# REMOVE THE MYSQL DATABASE -#================================================= -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 APP MAIN DIR -#================================================= -ynh_script_progression --message="Removing app main directory..." --weight=2 - -# Remove the app directory securely -ynh_secure_remove --file="$final_path" - -#================================================= -# REMOVE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." - # Remove the dedicated NGINX config ynh_remove_nginx_config -#================================================= -# REMOVE PHP-FPM CONFIGURATION -#================================================= -ynh_script_progression --message="Removing PHP-FPM configuration..." - # 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 -#================================================= -# GENERIC FINALIZATION -#================================================= -# REMOVE DEDICATED USER -#================================================= -ynh_script_progression --message="Removing the dedicated system user..." - -# Delete a system user -ynh_system_user_delete --username=$app - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/restore b/scripts/restore index 333f8dc..2c4fc12 100644 --- a/scripts/restore +++ b/scripts/restore @@ -15,29 +15,29 @@ source /usr/share/yunohost/helpers #================================================= # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=2 +#REMOVEME? ynh_script_progression --message="Loading installation settings..." --weight=2 -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get --app=$app --key=domain) -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) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) +#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) +#REMOVEME? db_user=$db_name +#REMOVEME? phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= -ynh_script_progression --message="Validating restoration parameters..." +#REMOVEME? ynh_script_progression --message="Validating restoration parameters..." -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " +#REMOVEME? test ! -d $install_dir \ + || ynh_die --message="There is already a directory: $install_dir " #================================================= # STANDARD RESTORATION STEPS @@ -51,23 +51,23 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # RECREATE THE DEDICATED USER #================================================= -ynh_script_progression --message="Recreating the dedicated system user..." --weight=2 +#REMOVEME? ynh_script_progression --message="Recreating the dedicated system user..." --weight=2 # Create the dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir="$final_path" +#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" #================================================= # RESTORE THE APP MAIN DIR #================================================= ynh_script_progression --message="Restoring the app main directory..." -ynh_restore_file --origin_path="$final_path" +ynh_restore_file --origin_path="$install_dir" #================================================= # RESTORE USER RIGHTS #================================================= -wb_conf=$final_path/app/config/parameters.yml +wb_conf=$install_dir/app/config/parameters.yml set_permissions @@ -99,18 +99,18 @@ ynh_systemd_action --action=restart --service_name=fail2ban #================================================= # REINSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Reinstalling dependencies..." --weight=15 +#REMOVEME? ynh_script_progression --message="Reinstalling dependencies..." --weight=15 # Define and install dependencies -ynh_install_app_dependencies $pkg_dependencies +#REMOVEME? ynh_install_app_dependencies $pkg_dependencies #================================================= # RESTORE THE MYSQL DATABASE #================================================= -ynh_script_progression --message="Restoring the MySQL database..." --weight=3 +#REMOVEME? ynh_script_progression --message="Restoring the MySQL database..." --weight=3 -db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) -ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd +#REMOVEME? db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) +#REMOVEME? ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd ynh_mysql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./db.sql #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 3ce5a5e..7cf7446 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -12,18 +12,18 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=2 +#REMOVEME? ynh_script_progression --message="Loading installation settings..." --weight=2 -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -admin=$(ynh_app_setting_get --app=$app --key=admin) -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 -db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) -deskey=$(ynh_app_setting_get --app=$app --key=deskey) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) +#REMOVEME? admin=$(ynh_app_setting_get --app=$app --key=admin) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) +#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) +#REMOVEME? db_user=$db_name +#REMOVEME? db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) +#REMOVEME? deskey=$(ynh_app_setting_get --app=$app --key=deskey) #================================================= # CHECK VERSION @@ -35,16 +35,16 @@ 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 +#REMOVEME? 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 () { +#REMOVEME? ynh_backup_before_upgrade +#REMOVEME? ynh_clean_setup () { # Restore it if the upgrade fails - ynh_restore_upgradebackup +#REMOVEME? ynh_restore_upgradebackup } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # STANDARD UPGRADE STEPS @@ -54,8 +54,8 @@ ynh_abort_if_errors ynh_script_progression --message="Ensuring downward compatibility..." # Cleaning legacy permissions -if ynh_legacy_permissions_exists; then - ynh_legacy_permissions_delete_all +#REMOVEME? if ynh_legacy_permissions_exists; then +#REMOVEME? ynh_legacy_permissions_delete_all ynh_app_setting_delete --app=$app --key=is_public fi @@ -63,28 +63,28 @@ fi # If db_name doesn't exist, create it if [ -z "$db_name" ]; then db_name=$(ynh_sanitize_dbid --db_name=$app) - ynh_app_setting_set --app=$app --key=db_name --value=$db_name +#REMOVEME? ynh_app_setting_set --app=$app --key=db_name --value=$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=$app --key=final_path --value=$final_path +# If install_dir doesn't exist, create it +if [ -z "$install_dir" ]; then +#REMOVEME? install_dir=/var/www/$app +#REMOVEME? ynh_app_setting_set --app=$app --key=install_dir --value=$install_dir fi -# If path_url doesn't exist, create it -if [ -z "$path_url" ]; then - path_url=$(ynh_app_setting_get --app=$app --key=path_url) - ynh_app_setting_set --app=$app --key=path --value=$path_url +# If path doesn't exist, create it +if [ -z "$path" ]; then +#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) +#REMOVEME? ynh_app_setting_set --app=$app --key=path --value=$path fi #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." +#REMOVEME? ynh_script_progression --message="Making sure dedicated system user exists..." # Create a dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir="$final_path" +#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -95,11 +95,11 @@ then ynh_script_progression --message="Upgrading source files..." --weight=6 # Download, check integrity, uncompress and patch the source from app.src - ynh_setup_source --dest_dir="$final_path" + ynh_setup_source --dest_dir="$install_dir" # Clear cache - ynh_secure_remove --file="$final_path/var/cache" - mkdir "$final_path/var/cache" +#REMOVEME? ynh_secure_remove --file="$install_dir/var/cache" + mkdir "$install_dir/var/cache" fi #================================================= @@ -113,9 +113,9 @@ ynh_add_nginx_config #================================================= # UPGRADE DEPENDENCIES #================================================= -ynh_script_progression --message="Upgrading dependencies..." --weight=7 +#REMOVEME? ynh_script_progression --message="Upgrading dependencies..." --weight=7 -ynh_install_app_dependencies $pkg_dependencies +#REMOVEME? ynh_install_app_dependencies $pkg_dependencies #================================================= # PHP-FPM CONFIGURATION @@ -127,14 +127,14 @@ ynh_add_fpm_config --phpversion=$YNH_PHP_VERSION # Set-up fail2ban # Create the log file is not already existing -if [ ! -f "$final_path/var/logs/prod.log" ] +if [ ! -f "$install_dir/var/logs/prod.log" ] then - mkdir -p "$final_path/var/logs/" - touch "$final_path/var/logs/prod.log" - chown $app: "$final_path/var/logs/prod.log" + mkdir -p "$install_dir/var/logs/" + touch "$install_dir/var/logs/prod.log" + chown $app: "$install_dir/var/logs/prod.log" fi # Add fail2ban config -ynh_add_fail2ban_config --logpath="$final_path/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 # same as install config +ynh_add_fail2ban_config --logpath="$install_dir/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 # same as install config #================================================= # SPECIFIC UPGRADE @@ -142,14 +142,14 @@ ynh_add_fail2ban_config --logpath="$final_path/var/logs/prod.log" --failregex='a # CONFIGURE WALLABAG #================================================= -wb_conf=$final_path/app/config/parameters.yml +wb_conf=$install_dir/app/config/parameters.yml if [ "$upgrade_type" == "UPGRADE_APP" ] then ynh_script_progression --message="Reconfiguring wallabag..." --weight=11 # Copy and set Wallabag dist configuration - cp $final_path/app/config/parameters.yml.dist $wb_conf + cp $install_dir/app/config/parameters.yml.dist $wb_conf ynh_replace_string --match_string="fosuser_registration: true" --replace_string="fosuser_registration: false" --target_file=$wb_conf ynh_replace_string --match_string="database_name: wallabag" --replace_string="database_name: $db_name" --target_file=$wb_conf @@ -157,24 +157,24 @@ then ynh_replace_string --match_string="database_password: ~" --replace_string="database_password: $db_pwd" --target_file=$wb_conf ynh_replace_string --match_string="database_table_prefix: wallabag_" --replace_string="database_table_prefix: null" --target_file=$wb_conf ynh_replace_string --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" --target_file=$wb_conf - ynh_replace_string --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path_url" --target_file=$wb_conf + ynh_replace_string --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path" --target_file=$wb_conf #================================================= # UPGRADE WALLABAG #================================================= # Alias for php-cli execution command - php_exec="ynh_exec_as $app php${YNH_PHP_VERSION} "$final_path/bin/console" --no-interaction --env=prod" + php_exec="ynh_exec_as $app php${YNH_PHP_VERSION} "$install_dir/bin/console" --no-interaction --env=prod" # Set permissions to app files - chown -R $app: $final_path + chown -R $app: $install_dir # Upgrade database and clear the cache $php_exec doctrine:migrations:migrate $php_exec cache:clear # Configure Wallabag instance URL - ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE internal_setting SET value = 'https://$domain$path_url' WHERE name = 'wallabag_url'" + ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE internal_setting SET value = 'https://$domain$path' WHERE name = 'wallabag_url'" fi #================================================= @@ -201,9 +201,9 @@ set_permissions #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." +#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." -ynh_systemd_action --service_name=nginx --action=reload +#REMOVEME? ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT diff --git a/sources/patches/app-00-ldap-auth.patch b/sources/patches/main-00-ldap-auth.patch similarity index 100% rename from sources/patches/app-00-ldap-auth.patch rename to sources/patches/main-00-ldap-auth.patch diff --git a/sources/patches/app-01-logout-success-handler.patch b/sources/patches/main-01-logout-success-handler.patch similarity index 100% rename from sources/patches/app-01-logout-success-handler.patch rename to sources/patches/main-01-logout-success-handler.patch diff --git a/sources/patches/app-02-oauth-workaround.patch b/sources/patches/main-02-oauth-workaround.patch similarity index 100% rename from sources/patches/app-02-oauth-workaround.patch rename to sources/patches/main-02-oauth-workaround.patch diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..c732129 --- /dev/null +++ b/tests.toml @@ -0,0 +1,11 @@ +#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/tests.v1.schema.json + +test_format = 1.0 + +[default] + + # ------------------------------- + # Commits to test upgrade from + # ------------------------------- + + test_upgrade_from.e9459b2bc46728427bda81e2043f3b4116771e2d.name = "2.5.4~ynh2" From 209b265c1f1a73231ae41e890b9d7478272660d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 11:34:39 +0100 Subject: [PATCH 3/9] Update manifestv2 --- scripts/backup | 37 +-------- scripts/change_url | 115 +++----------------------- scripts/install | 2 +- scripts/restore | 99 +++------------------- scripts/upgrade | 199 +++++++++------------------------------------ 5 files changed, 63 insertions(+), 389 deletions(-) diff --git a/scripts/backup b/scripts/backup index 0b509d5..5fb5b0d 100644 --- a/scripts/backup +++ b/scripts/backup @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -10,25 +8,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_print_info --message="Loading installation settings..." - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) -#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) -#REMOVEME? phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) - #================================================= # DECLARE DATA AND CONF FILES TO BACKUP #================================================= @@ -39,32 +18,20 @@ ynh_print_info --message="Declaring files to be backed up..." #================================================= # Clean cache files before backup (saved some disk space) -#REMOVEME? ynh_secure_remove --file=$install_dir/var/cache/prod +ynh_secure_remove --file=$install_dir/var/cache/prod ynh_backup --src_path="$install_dir" #================================================= -# BACKUP THE NGINX CONFIGURATION +# BACKUP THE SYSTEM CONFIGURATION #================================================= ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" -#================================================= -# BACKUP THE PHP-FPM CONFIGURATION -#================================================= - ynh_backup --src_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" -#================================================= -# BACKUP LOGROTATE -#================================================= - ynh_backup --src_path="/etc/logrotate.d/$app" -#================================================= -# BACKUP FAIL2BAN CONFIGURATION -#================================================= - ynh_backup --src_path="/etc/fail2ban/jail.d/$app.conf" ynh_backup --src_path="/etc/fail2ban/filter.d/$app.conf" diff --git a/scripts/change_url b/scripts/change_url index 1127468..e699a1e 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -1,69 +1,11 @@ #!/bin/bash -#================================================= -# GENERIC STARTING #================================================= # IMPORT GENERIC HELPERS #================================================= source _common.sh source /usr/share/yunohost/helpers -#REMOVEME? ynh_abort_if_errors - -#================================================= -# RETRIEVE ARGUMENTS -#================================================= - -#REMOVEME? old_domain=$YNH_APP_OLD_DOMAIN -#REMOVEME? old_path=$YNH_APP_OLD_PATH - -#REMOVEME? new_domain=$YNH_APP_NEW_DOMAIN -#REMOVEME? new_path=$YNH_APP_NEW_PATH - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." --weight=2 - -#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) -#REMOVEME? db_user=$db_name -#REMOVEME? db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) - -#================================================= -# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP -#================================================= -#REMOVEME? ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." - -# Backup the current version of the app -#REMOVEME? ynh_backup_before_upgrade -#REMOVEME? ynh_clean_setup () { - # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. -#REMOVEME? ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" - - # Restore it if the upgrade fails -#REMOVEME? ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# CHECK WHICH PARTS SHOULD BE CHANGED -#================================================= - -#REMOVEME? change_domain=0 -#REMOVEME? if [ "$old_domain" != "$new_domain" ] -then - #REMOVEME? change_domain=1 -fi - -#REMOVEME? change_path=0 -#REMOVEME? if [ "$old_path" != "$new_path" ] -then - #REMOVEME? change_path=1 -fi #================================================= # STANDARD MODIFICATIONS @@ -74,64 +16,29 @@ ynh_script_progression --message="Updating NGINX web server configuration..." -- ynh_change_url_nginx_config -#REMOVEME? nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf - -# 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 -#REMOVEME? ynh_backup_if_checksum_is_different --file="$nginx_conf_path" - # Set global variables for NGINX helper -#REMOVEME? domain="$old_domain" -#REMOVEME? path="$new_path" - # Create a dedicated NGINX config -#REMOVEME? ynh_add_nginx_config -fi - -# Change the domain for NGINX -if [ $change_domain -eq 1 ] -then - # Delete file checksum for the old conf file location -#REMOVEME? ynh_delete_file_checksum --file="$nginx_conf_path" -#REMOVEME? mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf - # Store file checksum for the new config file location -#REMOVEME? ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" -fi - -#================================================= -# SPECIFIC MODIFICATIONS #================================================= # UPDATE CONFIGURATION #================================================= ynh_script_progression --message="Updating wallabag configuration..." # Configure Wallabag instance URL -ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE internal_setting SET value = 'https://$new_domain$new_path' WHERE name = 'wallabag_url'" +ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" \ + <<< "UPDATE internal_setting SET value = 'https://$new_domain$new_path' WHERE name = 'wallabag_url'" # Change domain name in parameters.yml -ynh_replace_string --match_string="domain_name: .*" --replace_string="domain_name: https://$new_domain$new_path" --target_file=$install_dir/app/config/parameters.yml +ynh_replace_string --target_file="$wb_conf" --match_string="domain_name: .*" --replace_string="domain_name: https://$new_domain$new_path" # If "Download images locally" option has been enabled in Internal Settings -download_images_enabled=$(ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "SELECT value from internal_setting WHERE name='download_images_enabled '" | tail -n 1) -if [ "$download_images_enabled" = "1" ] -then - ynh_print_info --message="Updating images URL; this operation may take a while..." - # Query/replace the domain/path in every entry.content in mysql database - ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE entry SET content = REPLACE(content, '$old_domain$old_path', '$new_domain$new_path');" +download_images_enabled=$(ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" \ + <<< "SELECT value from internal_setting WHERE name='download_images_enabled '" | tail -n 1) + +if [ "$download_images_enabled" = "1" ]; then + ynh_print_info --message="Updating images URL; this operation may take a while..." + # Query/replace the domain/path in every entry.content in mysql database + ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" \ + <<< "UPDATE entry SET content = REPLACE(content, '$old_domain$old_path', '$new_domain$new_path');" fi -# Clear assets cache -#REMOVEME? ynh_secure_remove --file=$install_dir/var/cache - -#================================================= -# GENERIC FINALISATION -#================================================= -# RELOAD NGINX -#================================================= -#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." - -#REMOVEME? #REMOVEME? ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/install b/scripts/install index 13cb8ac..fd4c526 100644 --- a/scripts/install +++ b/scripts/install @@ -48,7 +48,7 @@ ynh_replace_string --target_file="$wb_conf" --match_string="domain_name: https:/ chown -R "$app:www-data" "$install_dir" # Alias for php-cli execution command -php_exec=(ynh_exec_as "$app" "php$YNH_PHP_VERSION" "$install_dir/bin/console" --no-interaction --env=prod) +php_exec=("php$YNH_PHP_VERSION" "$install_dir/bin/console" --no-interaction --env=prod) # Install dependencies and Wallabag ynh_exec_as "$app" "${php_exec[@]}" wallabag:install diff --git a/scripts/restore b/scripts/restore index 2c4fc12..e1d1346 100644 --- a/scripts/restore +++ b/scripts/restore @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -10,52 +8,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." --weight=2 - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) -#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) -#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) -#REMOVEME? db_user=$db_name -#REMOVEME? phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) - -#================================================= -# CHECK IF THE APP CAN BE RESTORED -#================================================= -#REMOVEME? ynh_script_progression --message="Validating restoration parameters..." - -#REMOVEME? test ! -d $install_dir \ - || ynh_die --message="There is already a directory: $install_dir " - -#================================================= -# STANDARD RESTORATION STEPS -#================================================= -# 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" - -#================================================= -# RECREATE THE DEDICATED USER -#================================================= -#REMOVEME? ynh_script_progression --message="Recreating the dedicated system user..." --weight=2 - -# Create the dedicated user (if not existing) -#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" - #================================================= # RESTORE THE APP MAIN DIR #================================================= @@ -63,64 +15,37 @@ ynh_script_progression --message="Restoring the app main directory..." ynh_restore_file --origin_path="$install_dir" -#================================================= -# RESTORE USER RIGHTS -#================================================= - -wb_conf=$install_dir/app/config/parameters.yml - set_permissions #================================================= -# RESTORE THE PHP-FPM CONFIGURATION +# RESTORE THE MYSQL DATABASE #================================================= -ynh_script_progression --message="Restoring the PHP-FPM configuration..." +ynh_script_progression --message="Restoring the MySQL database..." --weight=1 -ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" +ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" < ./db.sql #================================================= -# RESTORE THE LOGROTATE CONFIGURATION +# RESTORE SYSTEM CONFIGURATIONS #================================================= -ynh_script_progression --message="Restoring the logrotate configuration..." +ynh_script_progression --message="Restoring system configurations related to $app..." --weight=1 -ynh_restore_file --origin_path="/etc/logrotate.d/$app" +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" -#================================================= -# RESTORE FAIL2BAN CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the Fail2Ban configuration..." +ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" + +ynh_restore_file --origin_path="/etc/logrotate.d/$app" 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 -#================================================= -# REINSTALL DEPENDENCIES +# RELOAD NGINX AND PHP-FPM OR THE APP SERVICE #================================================= -#REMOVEME? ynh_script_progression --message="Reinstalling dependencies..." --weight=15 - -# Define and install dependencies -#REMOVEME? ynh_install_app_dependencies $pkg_dependencies +ynh_script_progression --message="Reloading NGINX web server and $app's service..." --weight=1 -#================================================= -# RESTORE THE MYSQL DATABASE -#================================================= -#REMOVEME? ynh_script_progression --message="Restoring the MySQL database..." --weight=3 - -#REMOVEME? db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) -#REMOVEME? ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd -ynh_mysql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./db.sql - -#================================================= -# GENERIC FINALIZATION -#================================================= -# RELOAD NGINX AND PHP-FPM -#================================================= -ynh_script_progression --message="Reloading NGINX web server and PHP-FPM..." +ynh_systemd_action --service_name="php$phpversion-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 7cf7446..518db49 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -9,173 +7,55 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." --weight=2 - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) -#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) -#REMOVEME? admin=$(ynh_app_setting_get --app=$app --key=admin) -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) -#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) -#REMOVEME? db_user=$db_name -#REMOVEME? db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) -#REMOVEME? 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 -#================================================= -#REMOVEME? ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=30 - -# Backup the current version of the app -#REMOVEME? ynh_backup_before_upgrade -#REMOVEME? ynh_clean_setup () { - # Restore it if the upgrade fails -#REMOVEME? ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# STANDARD UPGRADE STEPS #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= -ynh_script_progression --message="Ensuring downward compatibility..." - -# Cleaning legacy permissions -#REMOVEME? if ynh_legacy_permissions_exists; then -#REMOVEME? 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) -#REMOVEME? ynh_app_setting_set --app=$app --key=db_name --value=$db_name -fi - -# If install_dir doesn't exist, create it -if [ -z "$install_dir" ]; then -#REMOVEME? install_dir=/var/www/$app -#REMOVEME? ynh_app_setting_set --app=$app --key=install_dir --value=$install_dir -fi - -# If path doesn't exist, create it -if [ -z "$path" ]; then -#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) -#REMOVEME? ynh_app_setting_set --app=$app --key=path --value=$path -fi - -#================================================= -# CREATE DEDICATED USER -#================================================= -#REMOVEME? ynh_script_progression --message="Making sure dedicated system user exists..." - -# Create a dedicated user (if not existing) -#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" +# ynh_script_progression --message="Ensuring downward compatibility..." #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= +ynh_script_progression --message="Upgrading source files..." --weight=6 -if [ "$upgrade_type" == "UPGRADE_APP" ] -then - ynh_script_progression --message="Upgrading source files..." --weight=6 - - # Download, check integrity, uncompress and patch the source from app.src - ynh_setup_source --dest_dir="$install_dir" +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source --dest_dir="$install_dir" --full_replace=1 --keep="app/config/parameters.yml var/logs" - # Clear cache -#REMOVEME? ynh_secure_remove --file="$install_dir/var/cache" - mkdir "$install_dir/var/cache" -fi +# Create log dir/file FIXME: is it useless? +mkdir -p "$install_dir/var/logs/" +touch "$install_dir/var/logs/prod.log" -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." - -# Create a dedicated NGINX config -ynh_add_nginx_config +chown -R "$app:www-data" "$install_dir" -#================================================= -# UPGRADE DEPENDENCIES -#================================================= -#REMOVEME? ynh_script_progression --message="Upgrading dependencies..." --weight=7 - -#REMOVEME? ynh_install_app_dependencies $pkg_dependencies - -#================================================= -# PHP-FPM CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading PHP-FPM configuration..." - -# Create a dedicated PHP-FPM config -ynh_add_fpm_config --phpversion=$YNH_PHP_VERSION - -# Set-up fail2ban -# Create the log file is not already existing -if [ ! -f "$install_dir/var/logs/prod.log" ] -then - mkdir -p "$install_dir/var/logs/" - touch "$install_dir/var/logs/prod.log" - chown $app: "$install_dir/var/logs/prod.log" -fi -# Add fail2ban config -ynh_add_fail2ban_config --logpath="$install_dir/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 # same as install config - -#================================================= -# SPECIFIC UPGRADE #================================================= # CONFIGURE WALLABAG #================================================= +ynh_script_progression --message="Reconfiguring wallabag..." --weight=11 -wb_conf=$install_dir/app/config/parameters.yml +# Copy and set Wallabag dist configuration +cp "$install_dir/app/config/parameters.yml.dist" "$wb_conf" -if [ "$upgrade_type" == "UPGRADE_APP" ] -then - ynh_script_progression --message="Reconfiguring wallabag..." --weight=11 +ynh_replace_string --target_file="$wb_conf" --match_string="fosuser_registration: true" --replace_string="fosuser_registration: false" +ynh_replace_string --target_file="$wb_conf" --match_string="database_name: wallabag" --replace_string="database_name: $db_name" +ynh_replace_string --target_file="$wb_conf" --match_string="database_user: root" --replace_string="database_user: $db_user" +ynh_replace_string --target_file="$wb_conf" --match_string="database_password: ~" --replace_string="database_password: $db_pwd" +ynh_replace_string --target_file="$wb_conf" --match_string="database_table_prefix: wallabag_" --replace_string="database_table_prefix: null" +ynh_replace_string --target_file="$wb_conf" --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" +ynh_replace_string --target_file="$wb_conf" --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path" - # Copy and set Wallabag dist configuration - cp $install_dir/app/config/parameters.yml.dist $wb_conf +chown -R "$app:www-data" "$install_dir" - ynh_replace_string --match_string="fosuser_registration: true" --replace_string="fosuser_registration: false" --target_file=$wb_conf - ynh_replace_string --match_string="database_name: wallabag" --replace_string="database_name: $db_name" --target_file=$wb_conf - ynh_replace_string --match_string="database_user: root" --replace_string="database_user: $db_user" --target_file=$wb_conf - ynh_replace_string --match_string="database_password: ~" --replace_string="database_password: $db_pwd" --target_file=$wb_conf - ynh_replace_string --match_string="database_table_prefix: wallabag_" --replace_string="database_table_prefix: null" --target_file=$wb_conf - ynh_replace_string --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" --target_file=$wb_conf - ynh_replace_string --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path" --target_file=$wb_conf +# Alias for php-cli execution command +php_exec=("php$YNH_PHP_VERSION" "$install_dir/bin/console" --no-interaction --env=prod) - #================================================= - # UPGRADE WALLABAG - #================================================= +# Upgrade database and clear the cache +ynh_exec_as "$app" "${php_exec[@]}" doctrine:migrations:migrate +ynh_exec_as "$app" "${php_exec[@]}" cache:clear - # Alias for php-cli execution command - php_exec="ynh_exec_as $app php${YNH_PHP_VERSION} "$install_dir/bin/console" --no-interaction --env=prod" +# Configure Wallabag instance URL +ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name"\ + <<< "UPDATE internal_setting SET value = 'https://$domain$path' WHERE name = 'wallabag_url'" - # Set permissions to app files - chown -R $app: $install_dir - - # Upgrade database and clear the cache - $php_exec doctrine:migrations:migrate - $php_exec cache:clear - - # Configure Wallabag instance URL - ynh_mysql_connect_as --user=$db_user --password="$db_pwd" --database=$db_name <<< "UPDATE internal_setting SET value = 'https://$domain$path' WHERE name = 'wallabag_url'" -fi +set_permissions #================================================= # SETUP HOOKS @@ -185,25 +65,20 @@ ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_fil ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="../hooks/post_user_delete" #================================================= -# GENERIC FINALIZATION +# REAPPLY SYSTEM CONFIGURATIONS #================================================= -# SETUP LOGROTATE -#================================================= - -ynh_use_logrotate --non-append +ynh_script_progression --message="Upgrading system configurations related to $app..." --weight=1 -#================================================= -# SECURE FILES AND DIRECTORIES -#================================================= +# Create a dedicated NGINX config +ynh_add_nginx_config -set_permissions +# Create a dedicated PHP-FPM config +ynh_add_fpm_config -#================================================= -# RELOAD NGINX -#================================================= -#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." +ynh_use_logrotate --non-append -#REMOVEME? ynh_systemd_action --service_name=nginx --action=reload +# Add fail2ban config +ynh_add_fail2ban_config --logpath="$install_dir/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 # same as install config #================================================= # END OF SCRIPT From f5a722f3b3dfb852fcd69ec6af924c60ec2ca9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 11:47:19 +0100 Subject: [PATCH 4/9] Fix: add init_main_permission --- manifest.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manifest.toml b/manifest.toml index da54f02..2aeb312 100644 --- a/manifest.toml +++ b/manifest.toml @@ -38,6 +38,10 @@ ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requiremen type = "path" default = "/wallabag" + [install.init_main_permission] + type = "group" + default = "visitors" + [install.admin] type = "user" From 520718be8558ce14ac45a28899e0128dad3ec45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 11:48:20 +0100 Subject: [PATCH 5/9] Remove fixmes from manifest --- manifest.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/manifest.toml b/manifest.toml index 2aeb312..4540107 100644 --- a/manifest.toml +++ b/manifest.toml @@ -18,7 +18,7 @@ demo = "https://demo.yunohost.org/wallabag/" admindoc = "https://doc.wallabag.org/en/" code = "https://github.com/wallabag/wallabag" cpe = "cpe:2.3:a:wallabag:wallabag" -fund = "???" # FIXME: optional but recommended (or remove if irrelevant / not applicable). This is meant to be an URL where people can financially support this app, especially when its development is based on volunteers and/or financed by its community. YunoHost may later advertise it in the webadmin. +fund = "https://liberapay.com/wallabag" [integration] yunohost = ">= 11.2" @@ -26,9 +26,9 @@ architectures = "all" multi_instance = true ldap = true sso = false -disk = "50M" # FIXME: replace with an **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ... -ram.build = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... -ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... +disk = "50M" +ram.build = "150M" +ram.runtime = "50M" [install] [install.domain] From d655b87757acc267b01c279c463bbf48e3590619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 11:48:49 +0100 Subject: [PATCH 6/9] Bump ynh revision --- manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.toml b/manifest.toml index 4540107..907a849 100644 --- a/manifest.toml +++ b/manifest.toml @@ -7,7 +7,7 @@ name = "Wallabag" description.en = "A self hostable read-it-later app" description.fr = "Une application de lecture-plus-tard auto-hébergeable" -version = "2.5.4~ynh2" +version = "2.5.4~ynh3" maintainers = ["Lapineige"] From d6029dac519a9028c042948364d5080fd6b5bb5d Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Fri, 15 Mar 2024 11:30:05 +0000 Subject: [PATCH 7/9] Auto-update README --- README.md | 28 ++++------------------------ README_fr.md | 32 ++++---------------------------- 2 files changed, 8 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index cea21f6..5972aaa 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,12 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in ## Overview -[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. +Wallabag is a self hostable Read-It-Later application allowing you to not miss any content anymore. Click, save, read it when you can. +It provides a web interface, browser (Firefox/Chrome/Opera) add-ons, mobile apps (Android/iOS/Windows Phone) and even on e-reader (PocketBook/Kobo). -It provides a web interface, browser (Firefox / Chrome / Opera) add-ons, mobile apps (Android / iOS / Windows Phone) and even on e-reader (PocketBook / Kobo). +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). -**Shipped version:** 2.5.4~ynh2 +**Shipped version:** 2.5.4~ynh3 **Demo:** @@ -29,26 +29,6 @@ It provides a web interface, browser (Firefox / Chrome / Opera) add-ons, mobile ![Screenshot of Wallabag](./doc/screenshots/screenshot1.webp) -## Disclaimers / important information - -### YunoHost specific features -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 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). - -### (Beta) Testing branch -*Please be aware that the testing branch (or any PR branch)* might *contains some bugs and is not recommended if you need a stable app.* - -(Beta) Testers are welcome to try new upgrades (such as a new version), as listed in the [Pull Requests section](https://github.com/YunoHost-Apps/wallabag2_ynh/pulls). More testing will allow us to provide upgrades faster 🙂. In order to try the testing branch, use `sudo yunohost app upgrade wallabag2 -u https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing`. - -Warning : Doing a normal upgrade of the package with the web admin or `sudo yunohost app upgrade wallabag2` (without any URL specified) will revert you app to the master branch. *This may break you wallabag* if it goes to a previous version (if the newest is not retrocompatible). ## Documentation and resources - Official app website: diff --git a/README_fr.md b/README_fr.md index 7910a36..1ef87cb 100644 --- a/README_fr.md +++ b/README_fr.md @@ -16,11 +16,12 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po ## Vue d’ensemble -[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. +Wallabag 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). -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). +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). -**Version incluse :** 2.5.4~ynh2 +**Version incluse :** 2.5.4~ynh3 **Démo :** @@ -28,31 +29,6 @@ Sont disponibles une interface web, des add-ons pour navigateurs (Firefox / Chro ![Capture d’écran de Wallabag](./doc/screenshots/screenshot1.webp) -## Avertissements / informations importantes - -### Caractéristiques spécifiques YunoHost - -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 - -* 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). - - -### Branche de test (*Testing*) -*Soyez concient que la branche testing* pourrait *contenir des bugs et n'est pas recommandée si vous recherchez la stabilité de votre application.* - -Les personnes souhaitant (bêta) tester de nouvelles mises à jour (ex: une nouvelle version), listée dans la [section des Pull Requests](https://github.com/YunoHost-Apps/wallabag2_ynh/pulls), sont les bienvenues. Plus de tests nous permettrons de sortir des mises à jour plus vite. Pour tester la branche *testing*, utilisez `sudo yunohost app upgrade wallabag2 -u https://github.com/YunoHost-Apps/wallabag2_ynh/tree/testing`. - -Attention : Une mise à jour classique avec l'interface d'administration ou avec `sudo yunohost app upgrade wallabag2` (sans préciser l'URL) fera retourner votre application au niveau de la branche master. *Ceci pourrait casser votre wallabag* si vous revenez à une version précédente (et si la nouvelle n'est pas rétrocompatible). - - ## Documentations et ressources - Site officiel de l’app : From 93888166b4f430224ece6e8ec0c48a5e6fc0fa8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 12:43:40 +0100 Subject: [PATCH 8/9] Cleanup hooks --- hooks/post_user_create | 9 ++++++--- hooks/post_user_delete | 11 +++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/hooks/post_user_create b/hooks/post_user_create index 40b0216..44fba5b 100644 --- a/hooks/post_user_create +++ b/hooks/post_user_create @@ -2,6 +2,8 @@ app="__APP__" user="__APP__" +install_dir=$(ynh_app_setting_get --app="$app" --key=install_dir) +phpversion=$(ynh_app_setting_get --app="$app" --key=phpversion) # Retrieve arguments username=$1 @@ -14,6 +16,7 @@ source /usr/share/yunohost/helpers user_pass=$(ynh_string_random) # Create the new user in Wallabag -(cd "/var/www/$app" && \ - sudo -u "$user" php "bin/console" --no-interaction --env=prod \ - fos:user:create "$username" "$user_email" "$user_pass") +pushd "$install_dir" || ynh_die + sudo -u "$user" "php$phpversion" "bin/console" --no-interaction --env=prod \ + fos:user:create "$username" "$user_email" "$user_pass" +popd || ynh_die diff --git a/hooks/post_user_delete b/hooks/post_user_delete index 6a39516..ebf27c4 100644 --- a/hooks/post_user_delete +++ b/hooks/post_user_delete @@ -2,12 +2,15 @@ app="__APP__" user="__APP__" +install_dir=$(ynh_app_setting_get --app="$app" --key=install_dir) +phpversion=$(ynh_app_setting_get --app="$app" --key=phpversion) # Retrieve arguments username=$1 purge=$2 -# Deactivate the user from Wallabg -(cd "/var/www/$app" && \ - sudo -u "$user" php "bin/console" --no-interaction --env=prod \ - fos:user:deactivate "$username") +# Deactivate the user from Wallabag +pushd "$install_dir" || ynh_die + sudo -u "$user" "php$phpversion" "bin/console" --no-interaction --env=prod \ + fos:user:deactivate "$username" +popd || ynh_die From 4c2f0ef2313128a628276bf83bd2f0c11c396ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Fri, 15 Mar 2024 12:51:07 +0100 Subject: [PATCH 9/9] Some cleanup, to reduce diff with old_testing --- manifest.toml | 26 +++++++++++++------------- scripts/_common.sh | 12 ------------ scripts/change_url | 2 -- scripts/install | 18 +++++++++++++----- scripts/restore | 10 +++++++++- scripts/upgrade | 19 ++++++++++++------- 6 files changed, 47 insertions(+), 40 deletions(-) diff --git a/manifest.toml b/manifest.toml index 907a849..4703e6d 100644 --- a/manifest.toml +++ b/manifest.toml @@ -4,12 +4,12 @@ packaging_format = 2 id = "wallabag2" name = "Wallabag" -description.en = "A self hostable read-it-later app" -description.fr = "Une application de lecture-plus-tard auto-hébergeable" +description.en = "Save and classify articles. Read them later" +description.fr = "Enregistrez et classez les articles. Lisez-les plus tard" version = "2.5.4~ynh3" -maintainers = ["Lapineige"] +maintainers = ["lapineige"] [upstream] license = "MIT" @@ -25,8 +25,8 @@ yunohost = ">= 11.2" architectures = "all" multi_instance = true ldap = true -sso = false -disk = "50M" +sso = true +disk = "200M" ram.build = "150M" ram.runtime = "50M" @@ -61,19 +61,19 @@ ram.runtime = "50M" [resources.apt] packages = [ + "mariadb-server", "php7.4-cli", - "php7.4-mysql", - "php7.4-json", - "php7.4-gd", - "php7.4-tidy", "php7.4-curl", + "php7.4-gd", "php7.4-gettext", + "php7.4-intl", + "php7.4-json", + "php7.4-ldap", + "php7.4-mbstring", + "php7.4-mysql", "php7.4-redis", + "php7.4-tidy", "php7.4-xml", - "php7.4-mbstring", - "php7.4-ldap", - "php7.4-intl", - "mariadb-server", ] [resources.database] diff --git a/scripts/_common.sh b/scripts/_common.sh index bddccb0..7760641 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -10,18 +10,6 @@ wb_conf="$install_dir/app/config/parameters.yml" # PERSONAL HELPERS #================================================= -function set_permissions { - # Set permissions to app files - chown -R $app:www-data $install_dir - chmod -R g=u,g-w,o-rwx $install_dir - - # Restrict rights to Wallabag user only - chmod 600 $wb_conf - if [ -e $install_dir/var/cache/prod/appProdProjectContainer.php ]; then - chmod 700 $install_dir/var/cache/prod/appProdProjectContainer.php - fi -} - #================================================= # EXPERIMENTAL HELPERS #================================================= diff --git a/scripts/change_url b/scripts/change_url index e699a1e..ded4d93 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -7,8 +7,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# STANDARD MODIFICATIONS #================================================= # MODIFY URL IN NGINX CONF #================================================= diff --git a/scripts/install b/scripts/install index fd4c526..21f3764 100644 --- a/scripts/install +++ b/scripts/install @@ -27,12 +27,18 @@ ynh_setup_source --dest_dir="$install_dir" mkdir -p "$install_dir/var/logs/" touch "$install_dir/var/logs/prod.log" +# Set permissions to app files chown -R "$app:www-data" "$install_dir" +# Restrict rights to Wallabag user only +if [ -e "$install_dir/var/cache/prod/appProdProjectContainer.php" ]; then + chmod 700 "$install_dir/var/cache/prod/appProdProjectContainer.php" +fi + #================================================= -# CONFIGURE WALLABAG +# APP INITIAL CONFIGURATION #================================================= -ynh_script_progression --message="Configuring wallabag..." --weight=35 +ynh_script_progression --message="Adding $app's configuration files..." --weight=1 # Copy and set Wallabag dist configuration cp "$install_dir/app/config/parameters.yml.dist" "$wb_conf" @@ -45,13 +51,14 @@ ynh_replace_string --target_file="$wb_conf" --match_string="database_table_prefi ynh_replace_string --target_file="$wb_conf" --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" ynh_replace_string --target_file="$wb_conf" --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path" +chmod 600 "$wb_conf" chown -R "$app:www-data" "$install_dir" # Alias for php-cli execution command -php_exec=("php$YNH_PHP_VERSION" "$install_dir/bin/console" --no-interaction --env=prod) +php_exec=("php$phpversion" "$install_dir/bin/console" --no-interaction --env=prod) # Install dependencies and Wallabag -ynh_exec_as "$app" "${php_exec[@]}" wallabag:install +ynh_exec_warn_less ynh_exec_as "$app" "${php_exec[@]}" wallabag:install # Add users to Wallabag for username in $(ynh_user_list); do @@ -68,7 +75,8 @@ ynh_exec_as "$app" "${php_exec[@]}" fos:user:promote --super "$admin" ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" \ <<< "UPDATE internal_setting SET value = 'https://$domain$path' WHERE name = 'wallabag_url'" -set_permissions +# Set permissions to app files +chown -R "$app:www-data" "$install_dir" #================================================= # SETUP HOOKS diff --git a/scripts/restore b/scripts/restore index e1d1346..d9fc61c 100644 --- a/scripts/restore +++ b/scripts/restore @@ -15,7 +15,15 @@ ynh_script_progression --message="Restoring the app main directory..." ynh_restore_file --origin_path="$install_dir" -set_permissions +# Set permissions to app files +chown -R "$app:www-data" "$install_dir" + +# Restrict rights to Wallabag user only +if [ -e "$install_dir/var/cache/prod/appProdProjectContainer.php" ]; then + chmod 700 "$install_dir/var/cache/prod/appProdProjectContainer.php" +fi + +chmod 600 "$wb_conf" #================================================= # RESTORE THE MYSQL DATABASE diff --git a/scripts/upgrade b/scripts/upgrade index 518db49..c1a989b 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -24,12 +24,18 @@ ynh_setup_source --dest_dir="$install_dir" --full_replace=1 --keep="app/config/p mkdir -p "$install_dir/var/logs/" touch "$install_dir/var/logs/prod.log" +# Set permissions to app files chown -R "$app:www-data" "$install_dir" +# Restrict rights to Wallabag user only +if [ -e "$install_dir/var/cache/prod/appProdProjectContainer.php" ]; then + chmod 700 "$install_dir/var/cache/prod/appProdProjectContainer.php" +fi + #================================================= -# CONFIGURE WALLABAG +# UPDATE A CONFIG FILE #================================================= -ynh_script_progression --message="Reconfiguring wallabag..." --weight=11 +ynh_script_progression --message="Reconfiguring $app..." --weight=1 # Copy and set Wallabag dist configuration cp "$install_dir/app/config/parameters.yml.dist" "$wb_conf" @@ -42,21 +48,20 @@ ynh_replace_string --target_file="$wb_conf" --match_string="database_table_prefi ynh_replace_string --target_file="$wb_conf" --match_string="secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv" --replace_string="secret: $deskey" ynh_replace_string --target_file="$wb_conf" --match_string="domain_name: https://your-wallabag-url-instance.com" --replace_string="domain_name: https://$domain$path" +chmod 600 "$wb_conf" chown -R "$app:www-data" "$install_dir" # Alias for php-cli execution command -php_exec=("php$YNH_PHP_VERSION" "$install_dir/bin/console" --no-interaction --env=prod) +php_exec=("php$phpversion" "$install_dir/bin/console" --no-interaction --env=prod) # Upgrade database and clear the cache ynh_exec_as "$app" "${php_exec[@]}" doctrine:migrations:migrate ynh_exec_as "$app" "${php_exec[@]}" cache:clear # Configure Wallabag instance URL -ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name"\ +ynh_mysql_connect_as --user="$db_user" --password="$db_pwd" --database="$db_name" \ <<< "UPDATE internal_setting SET value = 'https://$domain$path' WHERE name = 'wallabag_url'" -set_permissions - #================================================= # SETUP HOOKS #================================================= @@ -75,7 +80,7 @@ ynh_add_nginx_config # Create a dedicated PHP-FPM config ynh_add_fpm_config -ynh_use_logrotate --non-append +ynh_use_logrotate --non-append --logfile="$install_dir/var/logs/prod.log" # Add fail2ban config ynh_add_fail2ban_config --logpath="$install_dir/var/logs/prod.log" --failregex='app.ERROR: Authentication failure for user "([\w]+)?", from IP ""' --max_retry=5 # same as install config