From a68eff5e0b25b94cbfea8edb21686af44dbc4906 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Sat, 2 Apr 2022 15:11:39 +0200 Subject: [PATCH] First commit --- LICENSE | 4 + README.md | 84 ++++++ README_fr.md | 66 +++++ check_process | 27 ++ conf/app.src | 7 + conf/database.php | 17 ++ conf/nginx.conf | 26 ++ conf/php-fpm.conf | 430 +++++++++++++++++++++++++++++ config_panel.toml.example | 295 ++++++++++++++++++++ doc/.gitkeep | 0 doc/DESCRIPTION.md | 1 + doc/DISCLAIMER.md | 12 + doc/screenshots/.gitkeep | 0 doc/screenshots/slider-item-1.png | Bin 0 -> 115139 bytes manifest.json | 50 ++++ scripts/_common.sh | 78 ++++++ scripts/backup | 70 +++++ scripts/change_url | 129 +++++++++ scripts/config | 102 +++++++ scripts/install | 160 +++++++++++ scripts/remove | 79 ++++++ scripts/restore | 114 ++++++++ scripts/upgrade | 102 +++++++ sources/extra_files/app/.gitignore | 2 + sources/patches/.gitignore | 2 + 25 files changed, 1857 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 README_fr.md create mode 100644 check_process create mode 100644 conf/app.src create mode 100644 conf/database.php create mode 100644 conf/nginx.conf create mode 100644 conf/php-fpm.conf create mode 100644 config_panel.toml.example create mode 100644 doc/.gitkeep create mode 100644 doc/DESCRIPTION.md create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/screenshots/.gitkeep create mode 100644 doc/screenshots/slider-item-1.png create mode 100644 manifest.json create mode 100644 scripts/_common.sh create mode 100755 scripts/backup create mode 100644 scripts/change_url create mode 100644 scripts/config create mode 100755 scripts/install create mode 100755 scripts/remove create mode 100755 scripts/restore create mode 100644 scripts/upgrade create mode 100644 sources/extra_files/app/.gitignore create mode 100644 sources/patches/.gitignore diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7d1e40b --- /dev/null +++ b/LICENSE @@ -0,0 +1,4 @@ +File containing the license of your package. + +More information here: +https://yunohost.org/packaging_apps_guidelines#yep-1-3 diff --git a/README.md b/README.md new file mode 100644 index 0000000..820e437 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ + +# Packaging an app, starting from this example + +- Copy this app before working on it, using the ['Use this template'](https://github.com/YunoHost/example_ynh/generate) button on the Github repo. +- Edit the `manifest.json` with app specific info. +- Edit the `install`, `upgrade`, `remove`, `backup`, and `restore` scripts, and any relevant conf files in `conf/`. + - Using the [script helpers documentation.](https://yunohost.org/packaging_apps_helpers) +- Add a `LICENSE` file for the package. +- Edit `doc/DISCLAIMER*.md` +- The `README.md` files are to be automatically generated by https://github.com/YunoHost/apps/tree/master/tools/README-generator + + +--- + + + +# Example app for YunoHost + +[![Integration level](https://dash.yunohost.org/integration/example.svg)](https://dash.yunohost.org/appci/app/example) ![](https://ci-apps.yunohost.org/ci/badges/example.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/example.maintain.svg) +[![Install example with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=example) + +*[Lire ce readme en français.](./README_fr.md)* + +> *This package allows you to install example quickly and simply on a YunoHost server. +If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* + +## Overview + +Explain in *a few (10~15) words* the purpose of the app or what it actually does (it is meant to give a rough idea to users browsing a catalog of 100+ apps) + +**Shipped version:** 1.0~ynh1 + +**Demo:** https://demo.example.com + + +## Screenshots + + + ![](./doc/screenshots/example.jpg) + + + + +## Disclaimers / important information + +* Any known limitations, constrains or stuff not working, such as (but not limited to): + * requiring a full dedicated domain ? + * architectures not supported ? + * not-working single-sign on or LDAP integration ? + * the app requires an important amount of RAM / disk / .. to install or to work properly + * etc... + +* Other infos that people should be aware of, such as: + * any specific step to perform after installing (such as manually finishing the install, specific admin credentials, ...) + * how to configure / administrate the application if it ain't obvious + * upgrade process / specificities / things to be aware of ? + * security considerations ? + + + +## Documentation and resources + +* Official app website: https://example.com +* Official user documentation: https://yunohost.org/apps +* Official admin documentation: https://yunohost.org/packaging_apps +* Upstream app code repository: https://some.forge.com/example/example +* YunoHost documentation for this app: https://yunohost.org/app_example +* Report a bug: https://github.com/YunoHost-Apps/example_ynh/issues + +## Developer info + +Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/example_ynh/tree/testing). + +To try the testing branch, please proceed like that. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/example_ynh/tree/testing --debug +or +sudo yunohost app upgrade example -u https://github.com/YunoHost-Apps/example_ynh/tree/testing --debug +``` + +**More info regarding app packaging:** https://yunohost.org/packaging_apps diff --git a/README_fr.md b/README_fr.md new file mode 100644 index 0000000..d856bf9 --- /dev/null +++ b/README_fr.md @@ -0,0 +1,66 @@ +# Example app pour YunoHost + +[![Niveau d'intégration](https://dash.yunohost.org/integration/example.svg)](https://dash.yunohost.org/appci/app/example) ![](https://ci-apps.yunohost.org/ci/badges/example.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/example.maintain.svg) +[![Installer example avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=example) + +*[Read this readme in english.](./README.md)* +*[Lire ce readme en français.](./README_fr.md)* + +> *This package allows you to install example quickly and simply on a YunoHost server. +If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* + +## Vue d'ensemble + +Expliquez en *quelques* (10~15) mots l'utilité de l'app ou ce qu'elle fait (l'objectif est de donner une idée grossière pour des utilisateurs qui naviguent dans un catalogue de 100+ apps) + +**Version incluse:** 1.0~ynh1 + +**Démo:** https://demo.example.com + + +## Captures d'écran + + + ![](./doc/screenshots/example.jpg) + + + + +## Avertissements / informations importantes + +* Any known limitations, constrains or stuff not working, such as (but not limited to): + * requiring a full dedicated domain ? + * architectures not supported ? + * not-working single-sign on or LDAP integration ? + * the app requires an important amount of RAM / disk / .. to install or to work properly + * etc... + +* Other infos that people should be aware of, such as: + * any specific step to perform after installing (such as manually finishing the install, specific admin credentials, ...) + * how to configure / administrate the application if it ain't obvious + * upgrade process / specificities / things to be aware of ? + * security considerations ? + + + +## Documentations et ressources + +* Site official de l'app : https://example.com +* Documentation officielle utilisateur: https://yunohost.org/apps +* Documentation officielle de l'admin: https://yunohost.org/packaging_apps +* Dépôt de code officiel de l'app: https://some.forge.com/example/example +* Documentation YunoHost pour cette app: https://yunohost.org/app_example +* Signaler un bug: https://github.com/YunoHost-Apps/example_ynh/issues + +## Informations pour les développeurs + +Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/example_ynh/tree/testing). + +Pour essayer la branche testing, procédez comme suit. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/example_ynh/tree/testing --debug +or +sudo yunohost app upgrade example -u https://github.com/YunoHost-Apps/example_ynh/tree/testing --debug +``` + +**Plus d'infos sur le packaging d'applications:** https://yunohost.org/packaging_apps \ No newline at end of file diff --git a/check_process b/check_process new file mode 100644 index 0000000..9f8650a --- /dev/null +++ b/check_process @@ -0,0 +1,27 @@ +;; Test complet + ; Manifest + domain="domain.tld" + path="/path" + is_public=1 + language="fr" + admin="john" + password="1Strong-Password" + ; Checks + pkg_linter=1 + setup_sub_dir=1 + setup_root=1 + setup_nourl=0 + setup_private=1 + setup_public=1 + upgrade=1 + #upgrade=1 from_commit=CommitHash + backup_restore=1 + multi_instance=1 + change_url=1 +;;; Options +Email= +Notification=none +;;; Upgrade options + ; commit=CommitHash + name=Name and date of the commit. + manifest_arg=domain=DOMAIN&path=PATH&is_public=1&language=fr&admin=USER&password=pass&port=666& diff --git a/conf/app.src b/conf/app.src new file mode 100644 index 0000000..fb8b19c --- /dev/null +++ b/conf/app.src @@ -0,0 +1,7 @@ +SOURCE_URL=https://github.com/phpback/phpback/archive/refs/tags/v1.3.2.tar.gz +SOURCE_SUM=51dff0437ab754c7dd58d689ed0caf930ff8ab554d7c335df28efa2ec933e74f +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= +SOURCE_EXTRACT=true diff --git a/conf/database.php b/conf/database.php new file mode 100644 index 0000000..511797d --- /dev/null +++ b/conf/database.php @@ -0,0 +1,17 @@ +}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 diff --git a/config_panel.toml.example b/config_panel.toml.example new file mode 100644 index 0000000..c6bccd8 --- /dev/null +++ b/config_panel.toml.example @@ -0,0 +1,295 @@ + +## Config panel are available from webadmin > Apps > YOUR_APP > Config Panel Button +## Those panels let user configure some params on their apps using a friendly interface, +## and remove the need to manually edit files from the command line. + +## From a packager perspective, this .toml is coupled to the scripts/config script, +## which may be used to define custom getters/setters. However, most use cases +## should be covered automagically by the core, thus it may not be necessary +## to define a scripts/config at all! + +## ----------------------------------------------------------------------------- +## IMPORTANT: In accordance with YunoHost's spirit, please keep things simple and +## do not overwhelm the admin with tons of misunderstandable or advanced settings. +## ----------------------------------------------------------------------------- + +## The top level describe the entire config panels screen. + +## The version is a required property. +## Here a small reminder to associate config panel version with YunoHost version +## | Config | YNH | Config panel small change log | +## | ------ | --- | ------------------------------------------------------- | +## | 0.1 | 3.x | 0.1 config script not compatible with YNH >= 4.3 | +## | 1.0 | 4.3.x | The new config panel system with 'bind' property | +version = "1.0" + +## (optional) i18n property let you internationalize questions, however this feature +## is only available in core configuration panel (like yunohost domain config). +## So in app config panel this key is ignored for now, but you can internationalize +## by using a lang dictionary (see property name bellow) +# i18n = "prefix_translation_key" + +################################################################################ +#### ABOUT PANELS +################################################################################ + +## The next level describes web admin panels +## You have to choose an ID for each panel, in this example the ID is "main" +## Keep in mind this ID will be used in CLI to refer to your question, so choose +## something short and meaningfull. +## In the webadmin, each panel corresponds to a distinct tab / form +[main] + +## Define the label for your panel +## Internationalization works similarly to the 'description' and 'ask' questions in the manifest +# name.en = "Main configuration" +# name.fr = "Configuration principale" + +## (optional) If you need to trigger a service reload-or-restart after the user +## change a question in this panel, you can add your service in the list. +services = ["__APP__"] +# or services = ["nginx", "__APP__"] to also reload-or-restart nginx + +## (optional) This help properties is a short help displayed on the same line +## than the panel title but not displayed in the tab. +# help = "" + + ############################################################################ + #### ABOUT SECTIONS + ############################################################################ + + ## A panel is composed of one or several sections. + ## + ## Sections are meant to group questions together when they correspond to + ## a same subtopic. This impacts the rendering in terms of CLI prompts + ## and HTML forms + ## + ## You should choose an ID for your section, and prefix it with the panel ID + ## (Be sure to not make a typo in the panel ID, which would implicitly create + ## an other entire panel) + ## + ## We use the context of pepettes_ynh as an example, + ## which is a simple donation form app written in python, + ## and for which the admin will want to edit the configuration + [main.customization] + + ## (optional) Defining a proper title for sections is not mandatory + ## and depends on the exact rendering you're aiming for the CLI / webadmin + name = "" + + ## (optional) This help properties is a short help displayed on the same line + ## than the section title, meant to provide additional details + # help = "" + + ## (optional) As for panel, you can specify to trigger a service + ## reload-or-restart after the user change a question in this section. + ## This property is added to the panel property, it doesn't deactivate it. + ## So no need to replicate, the service list from panel services property. + # services = [] + + ## (optional) By default all questions are optionals, but you can specify a + ## default behaviour for question in the section + optional = false + + ## (optional) It's also possible with the 'visible' property to only + ## display the section depending on the user's answers to previous questions. + ## + ## Be careful that the 'visible' property should only refer to **previous** questions + ## Hence, it should not make sense to have a "visible" property on the very first section. + ## + ## Also, keep in mind that this feature only works in the webadmin and not in CLI + ## (therefore a user could be prompted in CLI for a question that may not be relevant) + # visible = true + + ######################################################################## + #### ABOUT QUESTIONS + ######################################################################## + + ## A section is compound of one or several questions. + + ## --------------------------------------------------------------------- + ## IMPORTANT: as for panel and section you have to choose an ID, but this + ## one should be unique in all this document, even if the question is in + ## an other panel. + ## --------------------------------------------------------------------- + + ## You can use same questions types and properties than in manifest.yml + ## install part. However, in YNH 4.3, a lot of change has been made to + ## extend availables questions types list. + ## See: TODO DOC LINK + + [main.customization.project_name] + + ## (required) The ask property is equivalent to the ask property in + ## the manifest. However, in config panels, questions are displayed on the + ## left side and therefore have less space to be rendered. Therefore, + ## it is better to use a short question, and use the "help" property to + ## provide additional details if necessary. + ask.en = "Name of the project" + + ## (required) The type property indicates how the question should be + ## displayed, validated and managed. Some types have specific properties. + ## + ## Types available: string, boolean, number, range, text, password, path + ## email, url, date, time, color, select, domain, user, tags, file. + ## + ## For a complete list with specific properties, see: TODO DOC LINK + type = "string" + + ######################################################################## + #### ABOUT THE BIND PROPERTY + ######################################################################## + + ## (recommended) 'bind' property is a powerful feature that let you + ## configure how and where the data will be read, validated and written. + + ## By default, 'bind property is in "settings" mode, it means it will + ## **only** read and write the value in application settings file. + ## bind = "settings" + + ## However, settings usually correspond to key/values in actual app configurations + ## Hence, a more useful mode is to have bind = ":FILENAME". In that case, YunoHost + ## will automagically find a line with "KEY=VALUE" in FILENAME + ## (with the adequate separator between KEY and VALUE) + ## + ## YunoHost will then use this value for the read/get operation. + ## During write/set operations, YunoHost will overwrite the value + ## in **both** FILENAME and in the app's settings.yml + + ## Configuration file format supported: yaml, toml, json, ini, env, php, + ## python. The feature probably works with others formats, but should be tested carefully. + + ## Note that this feature only works with relatively simple cases + ## such as `KEY: VALUE`, but won't properly work with + ## complex data structures like multilin array/lists or dictionnaries. + ## It also doesn't work with XML format, custom config function call, php define(), ... + + ## More info on TODO + # bind = ":/var/www/__APP__/settings.py" + + + ## By default, bind = ":FILENAME" will use the question ID as KEY + ## ... but the question ID may sometime not be the exact KEY name in the configuration file. + ## + ## In particular, in pepettes, the python variable is 'name' and not 'project_name' + ## (c.f. https://github.com/YunoHost-Apps/pepettes_ynh/blob/5cc2d3ffd6529cc7356ff93af92dbb6785c3ab9a/conf/settings.py##L11 ) + ## + ## In that case, the key name can be specified before the column ':' + + bind = "name:/var/www/__APP__/settings.py" + + ## --------------------------------------------------------------------- + ## IMPORTANT: other 'bind' mode exists: + ## + ## bind = "FILENAME" (with no column character before FILENAME) + ## may be used to bind to the **entire file content** (instead of a single KEY/VALUE) + ## This could be used to expose an entire configuration file, or binary files such as images + ## For example: + ## bind = "/var/www/__APP__/img/logo.png" + ## + ## bind = "null" can be used to disable reading / writing in settings. + ## This creates sort of a "virtual" or "ephemeral" question which is not related to any actual setting + ## In this mode, you are expected to define custom getter/setters/validators in scripts/config: + ## + ## getter: get__QUESTIONID() + ## setter: set__QUESTIONID() + ## validator: validate__QUESTIONID() + ## + ## You can also specify a common getter / setter / validator, with the + ## function 'bind' mode, for example here it will try to run + ## get__array_settings() first. + # bind = "array_settings()" + ## --------------------------------------------------------------------- + + ## --------------------------------------------------------------------- + ## IMPORTANT: with the exception of bind=null questions, + ## question IDs should almost **always** correspond to an app setting + ## initialized / reused during install/upgrade. + ## Not doing so may result in inconsistencies between the config panel mechanism + ## and the use of ynh_add_config + ## --------------------------------------------------------------------- + + ######################################################################## + #### OTHER GENERIC PROPERTY FOR QUESTIONS + ######################################################################## + + ## (optional) An help text for the question + help = "Fill the name of the project which will received donation" + + ## (optional) An example display as placeholder in web form + # example = "YunoHost" + + ## (optional) set to true in order to redact the value in operation logs + # redact = false + + ## (optional) A validation pattern + ## --------------------------------------------------------------------- + ## IMPORTANT: your pattern should be between simple quote, not double. + ## --------------------------------------------------------------------- + pattern.regexp = '^\w{3,30}$' + pattern.error = "The name should be at least 3 chars and less than 30 chars. Alphanumeric chars are accepted" + + ## Note: visible and optional properties are also available for questions + + + [main.customization.contact_url] + ask = "Contact url" + type = "url" + example = "mailto: contact@example.org" + help = "mailto: accepted" + pattern.regexp = '^mailto:[^@]+@[^@]+|https://$' + pattern.error = "Should be https or mailto:" + bind = ":/var/www/__APP__/settings.py" + + [main.customization.logo] + ask = "Logo" + type = "file" + accept = ".png" + help = "Fill with an already resized logo" + bind = "__FINALPATH__/img/logo.png" + + [main.customization.favicon] + ask = "Favicon" + type = "file" + accept = ".png" + help = "Fill with an already sized favicon" + bind = "__FINALPATH__/img/favicon.png" + + + [main.stripe] + name = "Stripe general info" + optional = false + + # The next alert is overwrited with a getter from the config script + [main.stripe.amount] + ask = "Donation in the month : XX € + type = "alert" + style = "success" + + [main.stripe.publishable_key] + ask = "Publishable key" + type = "string" + redact = true + help = "Indicate here the stripe publishable key" + bind = ":/var/www/__APP__/settings.py" + + [main.stripe.secret_key] + ask = "Secret key" + type = "string" + redact = true + help = "Indicate here the stripe secret key" + bind = ":/var/www/__APP__/settings.py" + + [main.stripe.prices] + ask = "Prices ID" + type = "tags" + help = """\ + Indicates here the prices ID of donation products you created in stripe interfaces. \ + Go on [Stripe products](https://dashboard.stripe.com/products) to create those donation products. \ + Fill it tag with 'FREQUENCY/CURRENCY/PRICE_ID' \ + FREQUENCY: 'one_time' or 'recuring' \ + CURRENCY: 'EUR' or 'USD' \ + PRICE_ID: ID from stripe interfaces starting with 'price_' \ + """ + pattern.regexp = '^(one_time|recuring)/(EUR|USD)/price_.*$' + pattern.error = "Please respect the format describe in help text for each price ID" diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..66ee82b --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1 @@ +PHPBack is an open source feedback system you can use for your website. It gives your customers a way to communicate their ideas to improve your products. User feedback has proved to be really effective even if you have a community project or a commercial project. \ No newline at end of file diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..aded581 --- /dev/null +++ b/doc/DISCLAIMER.md @@ -0,0 +1,12 @@ +* Any known limitations, constrains or stuff not working, such as (but not limited to): + * requiring a full dedicated domain ? + * architectures not supported ? + * not-working single-sign on or LDAP integration ? + * the app requires an important amount of RAM / disk / .. to install or to work properly + * etc... + +* Other infos that people should be aware of, such as: + * any specific step to perform after installing (such as manually finishing the install, specific admin credentials, ...) + * how to configure / administrate the application if it ain't obvious + * upgrade process / specificities / things to be aware of ? + * security considerations ? diff --git a/doc/screenshots/.gitkeep b/doc/screenshots/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/slider-item-1.png b/doc/screenshots/slider-item-1.png new file mode 100644 index 0000000000000000000000000000000000000000..cfd85ad6ccd3d79545e2a10a353d7128f9f0666e GIT binary patch literal 115139 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%0APN7D^T|%Q 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 z%0D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 4.3.0" + }, + "multi_instance": true, + "services": [ + "nginx", + "php7.4-fpm", + "mysql" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain" + }, + { + "name": "path", + "type": "path", + "example": "/phpback", + "default": "/phpback" + }, + { + "name": "is_public", + "type": "boolean", + "default": true + } + ] + } +} diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..4a52444 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +#================================================= +# COMMON VARIABLES +#================================================= + +YNH_PHP_VERSION="7.4" + +pkg_dependencies="php${YNH_PHP_VERSION}-mysql" + +#================================================= +# PERSONAL HELPERS +#================================================= + +#================================================= +# EXPERIMENTAL HELPERS +#================================================= + +#================================================= +# FUTURE OFFICIAL HELPERS +#================================================= + +# Send an email to inform the administrator +# +# usage: ynh_send_readme_to_admin app_message [recipients] +# | arg: app_message - The message to send to the administrator. +# | arg: recipients - The recipients of this email. Use spaces to separate multiples recipients. - default: root +# example: "root admin@domain" +# If you give the name of a YunoHost user, ynh_send_readme_to_admin will find its email adress for you +# example: "root admin@domain user1 user2" +ynh_send_readme_to_admin() { + local app_message="${1:-...No specific information...}" + local recipients="${2:-root}" + + # Retrieve the email of users + find_mails () { + local list_mails="$1" + local mail + local recipients=" " + # Read each mail in argument + for mail in $list_mails + do + # Keep root or a real email address as it is + if [ "$mail" = "root" ] || echo "$mail" | grep --quiet "@" + then + recipients="$recipients $mail" + else + # But replace an user name without a domain after by its email + if mail=$(ynh_user_get_info "$mail" "mail" 2> /dev/null) + then + recipients="$recipients $mail" + fi + fi + done + echo "$recipients" + } + recipients=$(find_mails "$recipients") + + local mail_subject="☁️🆈🅽🅷☁️: \`$app\` has important message for you" + + local mail_message="This is an automated message from your beloved YunoHost server. +Specific information for the application $app. +$app_message +--- +Automatic diagnosis data from YunoHost +$(yunohost tools diagnosis | grep -B 100 "services:" | sed '/services:/d')" + + # Define binary to use for mail command + if [ -e /usr/bin/bsd-mailx ] + then + local mail_bin=/usr/bin/bsd-mailx + else + local mail_bin=/usr/bin/mail.mailutils + fi + + # Send the email to the recipients + echo "$mail_message" | $mail_bin -a "Content-Type: text/plain; charset=UTF-8" -s "$mail_subject" "$recipients" +} diff --git a/scripts/backup b/scripts/backup new file mode 100755 index 0000000..4547eef --- /dev/null +++ b/scripts/backup @@ -0,0 +1,70 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source ../settings/scripts/_common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +ynh_clean_setup () { + ### Remove this function if there's nothing to clean before calling the remove script. + true +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_print_info --message="Loading installation settings..." + +app=$YNH_APP_INSTANCE_NAME + +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +domain=$(ynh_app_setting_get --app=$app --key=domain) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) +phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) + +#================================================= +# DECLARE DATA AND CONF FILES TO BACKUP +#================================================= +ynh_print_info --message="Declaring files to be backed up..." + +#================================================= +# BACKUP THE APP MAIN DIR +#================================================= + +ynh_backup --src_path="$final_path" + +#================================================= +# BACKUP THE NGINX 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 THE MYSQL DATABASE +#================================================= +ynh_print_info --message="Backing up the MySQL database..." + +ynh_mysql_dump_db --database="$db_name" > db.sql + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." diff --git a/scripts/change_url b/scripts/change_url new file mode 100644 index 0000000..11f740d --- /dev/null +++ b/scripts/change_url @@ -0,0 +1,129 @@ +#!/bin/bash + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +old_domain=$YNH_APP_OLD_DOMAIN +old_path=$YNH_APP_OLD_PATH + +new_domain=$YNH_APP_NEW_DOMAIN +new_path=$YNH_APP_NEW_PATH + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --time --weight=1 + +# Needed for helper "ynh_add_nginx_config" +final_path=$(ynh_app_setting_get --app=$app --key=final_path) + +#================================================= +# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --time --weight=1 + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. + ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" + + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# CHECK WHICH PARTS SHOULD BE CHANGED +#================================================= + +change_domain=0 +if [ "$old_domain" != "$new_domain" ] +then + change_domain=1 +fi + +change_path=0 +if [ "$old_path" != "$new_path" ] +then + change_path=1 +fi + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." --time --weight=1 + +ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log" + +#================================================= +# MODIFY URL IN NGINX CONF +#================================================= +ynh_script_progression --message="Updating NGINX web server configuration..." --time --weight=1 + +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" + # Set global variables for NGINX helper + domain="$old_domain" + path_url="$new_path" + # Create a dedicated NGINX config + 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 + # Store file checksum for the new config file location + ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +fi + +#================================================= +# SPECIFIC MODIFICATIONS +#================================================= +# ... +#================================================= + +#================================================= +# GENERIC FINALISATION +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." --time --weight=1 + +ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Change of URL completed for $app" --time --last diff --git a/scripts/config b/scripts/config new file mode 100644 index 0000000..b9e79f8 --- /dev/null +++ b/scripts/config @@ -0,0 +1,102 @@ +#!/bin/bash +# In simple cases, you don't need a config script. + +# With a simple config_panel.toml, you can write in the app settings, in the +# upstream config file or replace complete files (logo ...) and restart services. + +# The config scripts allows you to go further, to handle specific cases +# (validation of several interdependent fields, specific getter/setter for a value, +# display dynamic informations or choices, pre-loading of config type .cube... ). + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source /usr/share/yunohost/helpers + +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +final_path=$(ynh_app_setting_get $app final_path) + +#================================================= +# SPECIFIC GETTERS FOR TOML SHORT KEY +#================================================= + +get__amount() { + # Here we can imagine to have an API call to stripe to know the amount of donation during a month + local amount = 200 + + # It's possible to change some properties of the question by overriding it: + if [ $amount -gt 100 ] + then + cat << EOF +style: success +value: $amount +ask: + en: A lot of donation this month: **$amount €** +EOF + else + cat << EOF +style: danger +value: $amount +ask: + en: Not so much donation this month: $amount € +EOF + fi +} + +get__prices() { + local prices = "$(grep "DONATION\['" "$final_path/settings.py" | sed -r "s@^DONATION\['([^']*)'\]\['([^']*)'\] = '([^']*)'@\1/\2/\3@g" | sed -z 's/\n/,/g;s/,$/\n/')" + if [ "$prices" == "," ]; + then + # Return YNH_NULL if you prefer to not return a value at all. + echo YNH_NULL + else + echo $prices + fi +} + + +#================================================= +# SPECIFIC VALIDATORS FOR TOML SHORT KEYS +#================================================= +validate__publishable_key() { + + # We can imagine here we test if the key is really a publisheable key + (is_secret_key $publishable_key) && + echo 'This key seems to be a secret key' +} + +#================================================= +# SPECIFIC SETTERS FOR TOML SHORT KEYS +#================================================= +set__prices() { + + #--------------------------------------------- + # IMPORTANT: setter are trigger only if a change is detected + #--------------------------------------------- + for price in $(echo $prices | sed "s/,/ /"); do + frequency=$(echo $price | cut -d/ -f1) + currency=$(echo $price | cut -d/ -f2) + price_id=$(echo $price | cut -d/ -f3) + sed "d/DONATION\['$frequency'\]\['$currency'\]" "$final_path/settings.py" + + echo "DONATION['$frequency']['$currency'] = '$price_id'" >> "$final_path/settings.py" + done + + #--------------------------------------------- + # IMPORTANT: to be able to upgrade properly, you have to saved the value in settings too + #--------------------------------------------- + ynh_app_setting_set $app prices $prices +} + +#================================================= +# GENERIC FINALIZATION +#================================================= +ynh_app_config_run $1 diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000..b355486 --- /dev/null +++ b/scripts/install @@ -0,0 +1,160 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +ynh_clean_setup () { + ### Remove this function if there's nothing to clean before calling the remove script. + true +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH +is_public=$YNH_APP_ARG_IS_PUBLIC + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= +ynh_script_progression --message="Validating installation parameters..." --weight=1 + +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..." --weight=3 + +ynh_app_setting_set --app=$app --key=domain --value=$domain +ynh_app_setting_set --app=$app --key=path --value=$path_url + +#================================================= +# INSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Installing dependencies..." --weight=10 + +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --weight=1 + +# 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..." --weight=2 + +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 + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= +ynh_script_progression --message="Setting up source files..." --weight=3 + +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" + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:www-data "$final_path" +chmod -R 755 "$final_path/application/config" + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring NGINX web server..." --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring PHP-FPM..." --weight=1 + +# Create a dedicated PHP-FPM config +ynh_add_fpm_config + +#================================================= +# ADD A CONFIGURATION +#================================================= +ynh_script_progression --message="Adding a configuration file..." --weight=1 + +ynh_add_config --template="../conf/database.php" --destination="$final_path/application/config/database.php" + +chmod 755 "$final_path/application/config/database.php" +chown $app:$app "$final_path/application/config/database.php" + +#================================================= +# SETUP SSOWAT +#================================================= +ynh_script_progression --message="Configuring permissions..." --weight=1 + +# Make app public if necessary +if [ $is_public -eq 1 ] +then + # Everyone can access the app. + # The "main" permission is automatically created before the install script. + ynh_permission_update --permission="main" --add="visitors" +fi + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# SEND A README FOR THE ADMIN +#================================================= +ynh_script_progression --message="Sending a readme for the admin..." --weight=1 + +message="PHPBack was successfully installed :) + +Please open your $app domain: https://$domain$path_url + +Complete the registration process from the setup page displayed. +Details for MySQL database to be enterted while registration process: +MySQL hostname: localhost +MySQL username: $db_name +MySQL password: $db_pwd + +If you are facing any problem or want to improve this app, please open a new issue here: https://github.com/YunoHost-Apps/phpback_ynh/issues" + +ynh_send_readme_to_admin "$message" + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Installation of $app completed" --last diff --git a/scripts/remove b/scripts/remove new file mode 100755 index 0000000..1dd3f88 --- /dev/null +++ b/scripts/remove @@ -0,0 +1,79 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --weight=1 + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get --app=$app --key=domain) +port=$(ynh_app_setting_get --app=$app --key=port) +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) + +#================================================= +# REMOVE THE MYSQL DATABASE +#================================================= +ynh_script_progression --message="Removing the MySQL database..." --weight=1 + +# 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=3 + +# Remove the app directory securely +ynh_secure_remove --file="$final_path" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Removing NGINX web server configuration..." --weight=1 + +# Remove the dedicated NGINX config +ynh_remove_nginx_config + +#================================================= +# REMOVE PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Removing PHP-FPM configuration..." --weight=1 + +# Remove the dedicated PHP-FPM config +ynh_remove_fpm_config + +#================================================= +# REMOVE DEPENDENCIES +#================================================= +ynh_script_progression --message="Removing dependencies..." --weight=3 + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= +ynh_script_progression --message="Removing the dedicated system user..." --weight=1 + +# Delete a system user +ynh_system_user_delete --username=$app + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Removal of $app completed" --last diff --git a/scripts/restore b/scripts/restore new file mode 100755 index 0000000..5f743b9 --- /dev/null +++ b/scripts/restore @@ -0,0 +1,114 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source ../settings/scripts/_common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +ynh_clean_setup () { + #### Remove this function if there's nothing to clean before calling the remove script. + true +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --time --weight=1 + +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) + +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= +ynh_script_progression --message="Validating restoration parameters..." --time --weight=1 + +test ! -d $final_path \ + || ynh_die --message="There is already a directory: $final_path " + +#================================================= +# STANDARD RESTORATION STEPS +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the NGINX web server configuration..." --time --weight=1 + +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..." --time --weight=1 + +# Create the dedicated user (if not existing) +ynh_system_user_create --username=$app --home_dir="$final_path" + +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= +ynh_script_progression --message="Restoring the app main directory..." --time --weight=1 + +ynh_restore_file --origin_path="$final_path" + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:www-data "$final_path" + +#================================================= +# RESTORE THE PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the PHP-FPM configuration..." --time --weight=1 + +ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" + +#================================================= +# SPECIFIC RESTORATION +#================================================= +# REINSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Reinstalling dependencies..." --time --weight=1 + +# Define and install dependencies +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# RESTORE THE MYSQL DATABASE +#================================================= +ynh_script_progression --message="Restoring the MySQL database..." --time --weight=1 + +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 +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..." --time --weight=1 + +ynh_systemd_action --service_name=php$phpversion-fpm --action=reload +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Restoration completed for $app" --time --last diff --git a/scripts/upgrade b/scripts/upgrade new file mode 100644 index 0000000..367bc62 --- /dev/null +++ b/scripts/upgrade @@ -0,0 +1,102 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --time --weight=1 + +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) + +#================================================= +# CHECK VERSION +#================================================= + +upgrade_type=$(ynh_check_app_version_changed) + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --time --weight=1 + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Making sure dedicated system user exists..." --time --weight=1 + +# Create a dedicated user (if not existing) +ynh_system_user_create --username=$app --home_dir="$final_path" + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + ynh_script_progression --message="Upgrading source files..." --time --weight=1 + + # Download, check integrity, uncompress and patch the source from app.src + ynh_setup_source --dest_dir="$final_path" +fi + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:www-data "$final_path" + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading NGINX web server configuration..." --time --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# UPGRADE DEPENDENCIES +#================================================= +ynh_script_progression --message="Upgrading dependencies..." --time --weight=1 + +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading PHP-FPM configuration..." --time --weight=1 + +# Create a dedicated PHP-FPM config +ynh_add_fpm_config + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Upgrade of $app completed" --time --last diff --git a/sources/extra_files/app/.gitignore b/sources/extra_files/app/.gitignore new file mode 100644 index 0000000..783a4ae --- /dev/null +++ b/sources/extra_files/app/.gitignore @@ -0,0 +1,2 @@ +*~ +*.sw[op] diff --git a/sources/patches/.gitignore b/sources/patches/.gitignore new file mode 100644 index 0000000..783a4ae --- /dev/null +++ b/sources/patches/.gitignore @@ -0,0 +1,2 @@ +*~ +*.sw[op]