From c988ee4568a9f2c0c999b4c6ed8711b30ee66e48 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sat, 21 Aug 2021 17:30:03 +0200 Subject: [PATCH] Apply example_ynh --- .github/ISSUE_TEMPLATE.md | 55 +++++ .github/PULL_REQUEST_TEMPLATE.md | 16 ++ check_process.default => check_process | 4 - conf/mailman-hyperkitty.cfg | 20 ++ conf/mailman-web.py | 116 +++++++++- conf/mailman.cfg | 206 ++++++++++++++++- doc/.gitkeep | 0 doc/DISCLAIMER.md | 95 ++++++++ doc/screenshots/.gitkeep | 0 doc/screenshots/screenshot1.webp | Bin 0 -> 23668 bytes manifest.json | 33 +-- pull_request_template.md | 23 -- scripts/_common.sh | 9 +- scripts/backup | 91 ++------ scripts/install | 196 ++++++----------- scripts/remove | 83 ++++--- scripts/restore | 97 ++++---- scripts/upgrade | 110 ++++++++- scripts/ynh_add_extra_apt_repos__3 | 294 ------------------------- 19 files changed, 798 insertions(+), 650 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md rename check_process.default => check_process (79%) create mode 100644 doc/.gitkeep create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/screenshots/.gitkeep create mode 100644 doc/screenshots/screenshot1.webp delete mode 100644 pull_request_template.md delete mode 100644 scripts/ynh_add_extra_apt_repos__3 diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..2729a6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,55 @@ +--- +name: Bug report +about: When creating a bug report, please use the following template to provide all the relevant information and help debugging efficiently. + +--- + +**How to post a meaningful bug report** +1. *Read this whole template first.* +2. *Determine if you are on the right place:* + - *If you were performing an action on the app from the webadmin or the CLI (install, update, backup, restore, change_url...), you are on the right place!* + - *Otherwise, the issue may be due to the app itself. Refer to its documentation or repository for help.* + - *When in doubt, post here and we will figure it out together.* +3. *Delete the italic comments as you write over them below, and remove this guide.* +--- + +### Describe the bug + +*A clear and concise description of what the bug is.* + +### Context + +- Hardware: *VPS bought online / Old laptop or computer / Raspberry Pi at home / Internet Cube with VPN / Other ARM board / ...* +- YunoHost version: x.x.x +- I have access to my server: *Through SSH | through the webadmin | direct access via keyboard / screen | ...* +- Are you in a special context or did you perform some particular tweaking on your YunoHost instance?: *no / yes* + - If yes, please explain: +- Using, or trying to install package version/branch: +- If upgrading, current package version: *can be found in the admin, or with `yunohost app info $app_id`* + +### Steps to reproduce + +- *If you performed a command from the CLI, the command itself is enough. For example:* + ```sh + sudo yunohost app install the_app + ``` +- *If you used the webadmin, please perform the equivalent command from the CLI first.* +- *If the error occurs in your browser, explain what you did:* + 1. *Go to '...'* + 2. *Click on '...'* + 3. *Scroll down to '...'* + 4. *See error* + +### Expected behavior + +*A clear and concise description of what you expected to happen. You can remove this section if the command above is enough to understand your intent.* + +### Logs + +*When an operation fails, YunoHost provides a simple way to share the logs.* +- *In the webadmin, the error message contains a link to the relevant log page. On that page, you will be able to 'Share with Yunopaste'. If you missed it, the logs of previous operations are also available under Tools > Logs.* +- *In command line, the command to share the logs is displayed at the end of the operation and looks like `yunohost log display [log name] --share`. If you missed it, you can find the log ID of a previous operation using `yunohost log list`.* + +*After sharing the log, please copypaste directly the link provided by YunoHost (to help readability, no need to copypaste the entire content of the log here, just the link is enough...)* + +*If applicable and useful, add screenshots to help explain your problem.* diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..ef70e18 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ +## Problem + +- *Description of why you made this PR* + +## Solution + +- *And how do you fix that problem* + +## PR Status + +- [ ] Code finished and ready to be reviewed/tested +- [ ] The fix/enhancement were manually tested (if applicable) + +## Automatic tests + +Automatic tests can be triggered on https://ci-apps-dev.yunohost.org/ *after creating the PR*, by commenting "!testme", "!gogogadgetoci" or "By the power of systemd, I invoke The Great App CI to test this Pull Request!". (N.B. : for this to work you need to be a member of the Yunohost-Apps organization) diff --git a/check_process.default b/check_process similarity index 79% rename from check_process.default rename to check_process index ffaa2b3..965445a 100644 --- a/check_process.default +++ b/check_process @@ -1,7 +1,6 @@ ;; Test complet ; Manifest domain="domain.tld" (DOMAIN) - domain_ip="192.168.1.1" is_public=1 (PUBLIC|public=1|private=0) ; Checks pkg_linter=1 @@ -16,12 +15,9 @@ multi_instance=0 port_already_use=1 change_url=1 -;;; Levels - Level 5=auto ;;; Options Email= Notification=none ;;; Upgrade options ; commit=CommitHash name=Name and date of the commit. - manifest_arg=domain=DOMAIN&domain_ip='192.168.1.1'&is_public=1 diff --git a/conf/mailman-hyperkitty.cfg b/conf/mailman-hyperkitty.cfg index eb7eb7a..aa582ed 100644 --- a/conf/mailman-hyperkitty.cfg +++ b/conf/mailman-hyperkitty.cfg @@ -1,3 +1,23 @@ +# mailman-hyperkitty.cfg +# This is the mailman extension configuration file to enable HyperKitty as an +# archiver. Remember to add the following lines in the mailman.cfg file: +# +# [archiver.hyperkitty] +# class: mailman_hyperkitty.Archiver +# enable: yes +# configuration: /path/to/here/mailman-hyperkitty.cfg +# + [general] + +# This is your HyperKitty installation, preferably on the localhost. This +# address will be used by Mailman to forward incoming emails to HyperKitty +# for archiving. It does not need to be publicly available, in fact it's +# better if it is not. +# However, if your Mailman installation is accessed via HTTPS, the URL needs +# to match your SSL certificate (e.g. https://lists.example.com/hyperkitty). base_url: https://__DOMAIN__/hyperkitty + +# Shared API key, must be the identical to the value in HyperKitty's +# settings. api_key: __ARCHIVER_KEY__ diff --git a/conf/mailman-web.py b/conf/mailman-web.py index fc189a4..3f2f558 100644 --- a/conf/mailman-web.py +++ b/conf/mailman-web.py @@ -1,16 +1,32 @@ +# This file is imported by the Mailman Suite. It is used to override +# the default settings from /usr/share/mailman3-web/settings.py. + +# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '__SECRET_KEY__' ADMINS = ( ('Mailman Suite Admin', 'root@__DOMAIN__'), ) -ALLOWED_HOSTS = ['*'] +# Hosts/domain names that are valid for this site; required if DEBUG is False +# See https://docs.djangoproject.com/en/1.8/ref/settings/#allowed-hosts +# Set to '*' per default in the Deian package to allow all hostnames. Mailman3 +# is meant to run behind a webserver reverse proxy anyway. +ALLOWED_HOSTS = [ + #"localhost", # Archiving API from Mailman, keep it. + # "lists.your-domain.org", + # Add here all production URLs you may have. + '*' +] -MAILMAN_REST_API_URL = 'http://localhost:__PORT_WEB__' +# Mailman API credentials +MAILMAN_REST_API_URL = 'http://localhost:__PORT__' MAILMAN_REST_API_USER = '__REST_API_ADMIN_USER__' MAILMAN_REST_API_PASS = '__REST_API_ADMIN_PWD__' MAILMAN_ARCHIVER_KEY = '__ARCHIVER_KEY__' -MAILMAN_ARCHIVER_FROM = ('127.0.0.1', '::1', '__DOMAIN_IP__') +MAILMAN_ARCHIVER_FROM = ('127.0.0.1', '::1') + +# Application definition INSTALLED_APPS = ( 'hyperkitty', @@ -33,27 +49,60 @@ INSTALLED_APPS = ( 'allauth', 'allauth.account', 'allauth.socialaccount', + 'django_mailman3.lib.auth.fedora', + #'allauth.socialaccount.providers.openid', + #'allauth.socialaccount.providers.github', + #'allauth.socialaccount.providers.gitlab', + #'allauth.socialaccount.providers.google', + #'allauth.socialaccount.providers.facebook', + #'allauth.socialaccount.providers.twitter', + #'allauth.socialaccount.providers.stackexchange', ) +# Database +# https://docs.djangoproject.com/en/1.8/ref/settings/#databases + DATABASES = { 'default': { + # Use 'sqlite3', 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. + #'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': '__DB_NAME__', - 'USER': '__DB_USER__', - 'PASSWORD': '__DB_PWD__', + #'ENGINE': 'django.db.backends.mysql', + # DB name or path to database file if using sqlite3. + 'NAME': '__DB_NAME_WEB__', + # The following settings are not used with sqlite3: + 'USER': '__DB_USER_WEB__', + 'PASSWORD': '__DB_PWD_WEB__', + # HOST: empty for localhost through domain sockets or '127.0.0.1' for + # localhost through TCP. 'HOST': '', + # PORT: set to empty string for default. 'PORT': '', + # OPTIONS: Extra parameters to use when connecting to the database. 'OPTIONS': { + # Set sql_mode to 'STRICT_TRANS_TABLES' for MySQL. See + # https://docs.djangoproject.com/en/1.11/ref/ + # databases/#setting-sql-mode + #'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", }, } } +# If you're behind a proxy, use the X-Forwarded-Host header +# See https://docs.djangoproject.com/en/1.8/ref/settings/#use-x-forwarded-host USE_X_FORWARDED_HOST = True + +# And if your proxy does your SSL encoding for you, set SECURE_PROXY_SSL_HEADER +# https://docs.djangoproject.com/en/1.8/ref/settings/#secure-proxy-ssl-header SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_SCHEME', 'https') + +# Other security settings SECURE_SSL_REDIRECT = True +# If you set SECURE_SSL_REDIRECT to True, make sure the SECURE_REDIRECT_EXEMPT +# contains at least this line: SECURE_REDIRECT_EXEMPT = [ "archives/api/mailman/.*", ] @@ -64,21 +113,76 @@ CSRF_COOKIE_SECURE = True CSRF_COOKIE_HTTPONLY = True X_FRAME_OPTIONS = 'DENY' + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + LANGUAGE_CODE = 'en-us' + TIME_ZONE = 'UTC' + USE_I18N = True USE_L10N = True USE_TZ = True + +# Set default domain for email addresses. EMAILNAME = '__DOMAIN__' + +# If you enable internal authentication, this is the address that the emails +# will appear to be coming from. Make sure you set a valid domain name, +# otherwise the emails may get rejected. +# https://docs.djangoproject.com/en/1.8/ref/settings/#default-from-email +# DEFAULT_FROM_EMAIL = "mailing-lists@you-domain.org" DEFAULT_FROM_EMAIL = 'postorius@{}'.format(EMAILNAME) + +# If you enable email reporting for error messages, this is where those emails +# will appear to be coming from. Make sure you set a valid domain name, +# otherwise the emails may get rejected. +# https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-SERVER_EMAIL +# SERVER_EMAIL = 'root@your-domain.org' SERVER_EMAIL = 'root@{}'.format(EMAILNAME) + +# Django Allauth ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https" + +# +# Social auth +# SOCIALACCOUNT_PROVIDERS = { + #'openid': { + # 'SERVERS': [ + # dict(id='yahoo', + # name='Yahoo', + # openid_url='http://me.yahoo.com'), + # ], + #}, + #'google': { + # 'SCOPE': ['profile', 'email'], + # 'AUTH_PARAMS': {'access_type': 'online'}, + #}, + #'facebook': { + # 'METHOD': 'oauth2', + # 'SCOPE': ['email'], + # 'FIELDS': [ + # 'email', + # 'name', + # 'first_name', + # 'last_name', + # 'locale', + # 'timezone', + # ], + # 'VERSION': 'v2.4', + #}, } +# On a production setup, setting COMPRESS_OFFLINE to True will bring a +# significant performance improvement, as CSS files will not need to be +# recompiled on each requests. It means running an additional "compress" +# management command after each code upgrade. +# http://django-compressor.readthedocs.io/en/latest/usage/#offline-compression COMPRESS_OFFLINE = True POSTORIUS_TEMPLATE_BASE_URL = 'https://__DOMAIN__' diff --git a/conf/mailman.cfg b/conf/mailman.cfg index 477a3f6..4b9c8c7 100644 --- a/conf/mailman.cfg +++ b/conf/mailman.cfg @@ -1,47 +1,214 @@ +# Copyright (C) 2008-2017 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see . + +# This file contains the Debian configuration for mailman. It uses ini-style +# formats under the lazr.config regime to define all system configuration +# options. See for details. + + [mailman] +# This address is the "site owner" address. Certain messages which must be +# delivered to a human, but which can't be delivered to a list owner (e.g. a +# bounce from a list owner), will be sent to this address. It should point to +# a human. site_owner: root@__DOMAIN__ + +# This is the local-part of an email address used in the From field whenever a +# message comes from some entity to which there is no natural reply recipient. +# Mailman will append '@' and the host name of the list involved. This +# address must not bounce and it must not point to a Mailman process. noreply_address: noreply + +# The default language for this server. default_language: en + +# Membership tests for posting purposes are usually performed by looking at a +# set of headers, passing the test if any of their values match a member of +# the list. Headers are checked in the order given in this variable. The +# value From_ means to use the envelope sender. Field names are case +# insensitive. This is a space separate list of headers. sender_headers: from from_ reply-to sender + +# Mail command processor will ignore mail command lines after designated max. email_commands_max_lines: 10 + +# Default length of time a pending request is live before it is evicted from +# the pending database. pending_request_life: 3d + +# How long should files be saved before they are evicted from the cache? cache_life: 7d + +# A callable to run with no arguments early in the initialization process. +# This runs before database initialization. pre_hook: + +# A callable to run with no arguments late in the initialization process. +# This runs after adapters are initialized. post_hook: + +# Which paths.* file system layout to use. +# You should not change this variable. layout: debian + +# Can MIME filtered messages be preserved by list owners? filtered_messages_are_preservable: no + +# How should text/html parts be converted to text/plain when the mailing list +# is set to convert HTML to plaintext? This names a command to be called, +# where the substitution variable $filename is filled in by Mailman, and +# contains the path to the temporary file that the command should read from. +# The command should print the converted text to stdout. html_to_plain_text_command: /usr/bin/lynx -dump $filename + +# Specify what characters are allowed in list names. Characters outside of +# the class [-_.+=!$*{}~0-9a-z] matched case insensitively are never allowed, +# but this specifies a subset as the only allowable characters. This must be +# a valid character class regexp or the effect on list creation is +# unpredictable. listname_chars: [-_.0-9a-z] + [shell] +# `mailman shell` (also `withlist`) gives you an interactive prompt that you +# can use to interact with an initialized and configured Mailman system. Use +# --help for more information. This section allows you to configure certain +# aspects of this interactive shell. + +# Customize the interpreter prompt. prompt: >>> + +# Banner to show on startup. banner: Welcome to the GNU Mailman shell + +# Use IPython as the shell, which must be found on the system. Valid values +# are `no`, `yes`, and `debug` where the latter is equivalent to `yes` except +# that any import errors will be displayed to stderr. use_ipython: no + +# Set this to allow for command line history if readline is available. This +# can be as simple as $var_dir/history.py to put the file in the var directory. history_file: + [paths.debian] +# Important directories for Mailman operation. These are defined here so that +# different layouts can be supported. For example, a developer layout would +# be different from a FHS layout. Most paths are based off the var_dir, and +# often just setting that will do the right thing for all the other paths. +# You might also have to set spool_dir though. +# +# Substitutions are allowed, but must be of the form $var where 'var' names a +# configuration variable in the paths.* section. Substitutions are expanded +# recursively until no more $-variables are present. Beware of infinite +# expansion loops! +# +# This is the root of the directory structure that Mailman will use to store +# its run-time data. var_dir: /var/lib/mailman3 +# This is where the Mailman queue files directories will be created. queue_dir: $var_dir/queue +# This is the directory containing the Mailman 'runner' and 'master' commands +# if set to the string '$argv', it will be taken as the directory containing +# the 'mailman' command. bin_dir: /usr/lib/mailman3/bin +# All list-specific data. list_data_dir: $var_dir/lists +# Directory where log files go. log_dir: /var/log/mailman3 +# Directory for system-wide locks. lock_dir: $var_dir/locks +# Directory for system-wide data. data_dir: $var_dir/data +# Cache files. cache_dir: $var_dir/cache +# Directory for configuration files and such. etc_dir: /etc/mailman3 +# Directory containing Mailman plugins. ext_dir: $var_dir/ext +# Directory where the default IMessageStore puts its messages. messages_dir: $var_dir/messages +# Directory for archive backends to store their messages in. Archivers should +# create a subdirectory in here to store their files. archive_dir: $var_dir/archives +# Root directory for site-specific template override files. template_dir: $var_dir/templates +# There are also a number of paths to specific file locations that can be +# defined. For these, the directory containing the file must already exist, +# or be one of the directories created by Mailman as per above. +# +# This is where PID file for the master runner is stored. pid_file: /run/mailman3/master.pid +# Lock file. lock_file: $lock_dir/master.lck + [database] +# The class implementing the IDatabase. +#class: mailman.database.sqlite.SQLiteDatabase +#class: mailman.database.mysql.MySQLDatabase class: mailman.database.postgresql.PostgreSQLDatabase -url: postgres://__DB_USER__:__DB_PWD__@localhost/__DB_NAME__ + +# Use this to set the Storm database engine URL. You generally have one +# primary database connection for all of Mailman. List data and most rosters +# will store their data in this database, although external rosters may access +# other databases in their own way. This string supports standard +# 'configuration' substitutions. +#url: sqlite:///$DATA_DIR/mailman.db +#url: mysql+pymysql://mailman3:mmpass@localhost/mailman3?charset=utf8&use_unicode=1 +url: postgres://__DB_USER_APP__:__DB_PWD_APP__@localhost/__DB_NAME_APP__ + debug: no + [logging.debian] +# This defines various log settings. The options available are: +# +# - level -- Overrides the default level; this may be any of the +# standard Python logging levels, case insensitive. +# - format -- Overrides the default format string +# - datefmt -- Overrides the default date format string +# - path -- Overrides the default logger path. This may be a relative +# path name, in which case it is relative to Mailman's LOG_DIR, +# or it may be an absolute path name. You cannot change the +# handler class that will be used. +# - propagate -- Boolean specifying whether to propagate log message from this +# logger to the root "mailman" logger. You cannot override +# settings for the root logger. +# +# In this section, you can define defaults for all loggers, which will be +# prefixed by 'mailman.'. Use subsections to override settings for specific +# loggers. The names of the available loggers are: +# +# - archiver -- All archiver output +# - bounce -- All bounce processing logs go here +# - config -- Configuration issues +# - database -- Database logging (SQLAlchemy and Alembic) +# - debug -- Only used for development +# - error -- All exceptions go to this log +# - fromusenet -- Information related to the Usenet to Mailman gateway +# - http -- Internal wsgi-based web interface +# - locks -- Lock state changes +# - mischief -- Various types of hostile activity +# - runner -- Runner process start/stops +# - smtp -- Successful SMTP activity +# - smtp-failure -- Unsuccessful SMTP activity +# - subscribe -- Information about leaves/joins +# - vette -- Message vetting information format: %(asctime)s (%(process)d) %(message)s datefmt: %b %d %H:%M:%S %Y propagate: no @@ -49,23 +216,58 @@ level: info path: mailman.log [webservice] +# The hostname at which admin web service resources are exposed. hostname: localhost -port: __PORT_WEB__ + +# The port at which the admin web service resources are exposed. +port: __PORT__ + +# Whether or not requests to the web service are secured through SSL. use_https: no + +# Whether or not to show tracebacks in an HTTP response for a request that +# raised an exception. show_tracebacks: yes + +# The API version number for the current (highest) API. api_version: 3.1 + +# The administrative username. admin_user: __REST_API_ADMIN_USER__ + +# The administrative password. admin_pass: __REST_API_ADMIN_PWD__ [mta] +# The class defining the interface to the incoming mail transport agent. +#incoming: mailman.mta.exim4.LMTP incoming: mailman.mta.postfix.LMTP + +# The callable implementing delivery to the outgoing mail transport agent. +# This must accept three arguments, the mailing list, the message, and the +# message metadata dictionary. outgoing: mailman.mta.deliver.deliver + +# How to connect to the outgoing MTA. If smtp_user and smtp_pass is given, +# then Mailman will attempt to log into the MTA when making a new connection. smtp_host: localhost smtp_port: 25 smtp_user: smtp_pass: + +# Where the LMTP server listens for connections. Use 127.0.0.1 instead of +# localhost for Postfix integration, because Postfix only consults DNS +# (e.g. not /etc/hosts). lmtp_host: 127.0.0.1 lmtp_port: 8024 + +# Where can we find the mail server specific configuration file? The path can +# be either a file system path or a Python import path. If the value starts +# with python: then it is a Python import path, otherwise it is a file system +# path. File system paths must be absolute since no guarantees are made about +# the current working directory. Python paths should not include the trailing +# .cfg, which the file must end with. +#configuration: python:mailman.config.exim4 configuration: python:mailman.config.postfix [archiver.hyperkitty] diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..5f11883 --- /dev/null +++ b/doc/DISCLAIMER.md @@ -0,0 +1,95 @@ +* 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: + * No LDAP support yet (apparently under development) + * Users can also just sign up themselves to manage details + * Users can use mailing lists without signing up? + +## Post-installation steps + +### Setup Admin User + +You must [configure the admin user](http://docs.mailman3.org/en/latest/config-web.html#setting-up-admin-account): + +```bash +$ cd /usr/share/mailman3-web +$ python3 manage.py createsuperuser +``` + +You should then attempt to log in with this user account in the web UI. Once you've logged in, a confirmation mail will be sent to your email address that you specified. Therefore, you should have something like [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) installed to view mail on your YunoHost installation. + +### Setup your main domain + +You'll need to log in as administrator and visit the `/admin/site/site`. + +If you're Mailman3 is setup on `https://myyunohost.org` then that would be the following: + +> https://myyunohost.org/admin/site/site + +### Configure incoming mail + +Mailman3 implements an LMTP server for receiving mail from Postfix. This means that Mailman3 doesn't need anything from Dovecot. This is important to understand because Dovecot is the default YunoHost local delivery agent. Therefore, the default YunoHost Postfix configuration uses Dovecot. So, in order to deliver incoming mail, we need to override which delivery agent handles which mails based on the addresses. In other words, if you create a mailing list "mylist@myyunohost.org" you want Mailman3's LMTP server to receive this, *not* Dovecot, becaues Dovecot only delivers to LDAP created user accounts. + +You'll need to add this to your Postfix configuration: + +```bash +owner_request_special = no + +transport_maps = + hash:/var/lib/mailman3/data/postfix_lmtp + +local_recipient_maps = + hash:/var/lib/mailman3/data/postfix_lmtp + +virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf, hash:/var/lib/mailman3/data/postfix_lmtp +``` + +And then run: + +```bash +$ sudo -su list mailman aliases +``` + +This is unfortunately a manual step at this point because the package remains experimental. Once it matures, this will be integrated into a hook or the default Postfix configuration. For now, remember that when you run `yunohost tools regen-conf postfix` or if any installation invokes `regen-conf`, your Postfix configuration will not be changed because it has diverged from the default configuration. This may cause you problems if YunoHost core expects that there is some new value in your Postfix configuration. + +### Configure outgoing mail + +Postfix relies on using SMTP which should be configured in your `/etc/postfix/main.cf`. + +You should make sure that you have outgoing mail working before getting started with Mailman 3. + +## General Configuration + +Mailman 3 or "The Mailman Suite" is made up of 5 moving parts. See the following documentation for more: + +> http://docs.mailman3.org/en/latest/index.html#the-mailman-suite + +On your YunoHost, all the configuration files you need to worry about are in: + +* `/etc/mailman3/` +* `/usr/share/mailman3-web/` + +The services you need to manage can be checked with: + +* `systemctl status mailman3` +* `systemctl status mailman3-web` + +It is important to note that this package makes use of the [mailman3-full](http://docs.mailman3.org/en/latest/prodsetup.html#distribution-packages) Debian package contained in the Debian Stretch backports repository. The default installation assumes the use of a SQLite3 database but the installation script overrides this and uses a PostgreSQL database instead. + +Finally, you also configure things through the Django web admin available at `/admin/`. + +## Limitations + +* Migrating from Mailman 2.X is not officially supported, sorry. However, there is a manual and + which details an experimental process. Please see [the documentation](https://docs.mailman3.org/en/latest/migration.html). + +* Mailman3 must be configured to use a root domain (https://myyunohost.org and not https://myyunohost.org/mailman3). + +* You must have a HTTPS certificate installed on the root domain. + +* There may be only one installation per YunoHost. diff --git a/doc/screenshots/.gitkeep b/doc/screenshots/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/screenshot1.webp b/doc/screenshots/screenshot1.webp new file mode 100644 index 0000000000000000000000000000000000000000..2dab2f73b02318605c49fc112ec3a740d0302169 GIT binary patch literal 23668 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

=}nvm3! zBx@IA@jvMfK@xG?9g|Y|M4=AU8n?<(M&Bq5$HXgPhp?bGE3A{0L}YLpF;i`7hS$eU z7uiK5&}@NTlM+YUXn)_auPYVfbG<3 zApk8|UoG2FC$@snvmEB8l+DpVP8JK1AZ(dvye?Z3YWTNgq|j!E7gDg&QX5~eS%K!- z$5e#Lp_edbeb=;ev%=ol9%yDR1~3IM*(>wE4LlGE52YBp{9E?aoNq!0vn7QiN@KpO z9>dRvA#r9Aui-Sy?Y55W`ueiZXpzc~oWI5k`Ma}nvrv(&@M8Y&r_r=rbX z&`kLZL)Qyj|7@tWBsnAXcuzn)CH7nGlR$24Vg<9%XYD-`5B$WE`mGbDTZqBf8_g;a zXBbHkrt7r3vA5{>dUT=Gvy}5NKApUEqLus&T}22f2Ozm26(`^ngT+WbGFmkH5#51( z15>AsAU@_Oo)l&eEeQMTkSn&8Ai?`Ns~fW_XP6lONekh(go%EZET<4BE6 z%6qI(lzFMTc9P_%yALMH)}EiGzMh_pTJxORoUE}9Kf$=wZa`%ejP$hzy?4JY&aG`s z7?F7RFZ=K2oR=#-D}e2C^D(V%2bl>G4OXvFhiu+g>hXPkSvr|jzB6Xdob*Ec#@PWu z3oBxsN#))Wu)In~n^f>y2d54Q@$*)F`IZyNnR)pqP1AL=-{eRSHEgrc2cnIdN+00^dRu2PnU7VSloMW_4X|+Uy_MNu!mMhC0s~zzQF^Py8qqF3(dq$bHaEO(6`r)d_hWnJ)5TSJn!( X|8|^0a0IG@@m=<0W~i+FH9GJBsGn?B literal 0 HcmV?d00001 diff --git a/manifest.json b/manifest.json index 264e500..21e42f4 100644 --- a/manifest.json +++ b/manifest.json @@ -7,7 +7,15 @@ "fr": "Un gestionnaire de liste de discussion par email" }, "version": "1.0~ynh1", - "url": "http://docs.mailman3.org/", + "url": "http://www.list.org/", + "upstream": { + "license": "AGPL-3.0-or-later", + "website": "http://www.list.org/", + "demo": "https://lists.mailman3.org/mailman3/lists/", + "admindoc": "https://docs.mailman3.org/en/latest/", + "userdoc": "http://docs.mailman3.org/en/latest/userguide.html", + "code": "https://gitlab.com/mailman/mailman-suite" + }, "license": "AGPL-3.0-or-later", "maintainer": { "name": "decentral1se", @@ -15,39 +23,22 @@ "url": "https://decentral1.se/" }, "requirements": { - "yunohost": ">= 3.6" + "yunohost": ">= 4.1.3" }, "multi_instance": false, "services": [ - "nginx", - "postgresql" + "nginx" ], "arguments": { "install" : [ { "name": "domain", "type": "domain", - "ask": { - "en": "Choose a domain name for Mailman3", - "fr": "Choisissez un nom de domaine pour Mailman3" - }, - "example": "myyunohost.org" - }, - { - "name": "domain_ip", - "type": "string", - "ask": { - "en": "Specify the IP address of your domain" - }, - "example": "192.168.24.6" + "example": "example.com" }, { "name": "is_public", "type": "boolean", - "ask": { - "en": "Is it a public application?", - "fr": "Est-ce une application publique ?" - }, "default": true } ] diff --git a/pull_request_template.md b/pull_request_template.md deleted file mode 100644 index 9d61f01..0000000 --- a/pull_request_template.md +++ /dev/null @@ -1,23 +0,0 @@ -## Problem - -- *Description of why you made this PR* - -## Solution - -- *And how do you fix that problem* - -## PR Status - -- [ ] Code finished. -- [ ] Tested with Package_check. -- [ ] Fix or enhancement tested. -- [ ] Upgrade from last version tested. -- [ ] Can be reviewed and tested. - -## Package_check results - ---- - -*If you have access to [App Continuous Integration for packagers](https://yunohost.org/#/packaging_apps_ci) you can provide a link to the package_check results like below, replacing '-NUM-' in this link by the PR number and USERNAME by your username on the ci-apps-dev. Or you provide a screenshot or a pastebin of the results* - -[![Build Status](https://ci-apps-dev.yunohost.org/jenkins/job/APP_ynh%20PR-NUM-%20(USERNAME)/badge/icon)](https://ci-apps-dev.yunohost.org/jenkins/job/APP_ynh%20PR-NUM-%20(USERNAME)/) diff --git a/scripts/_common.sh b/scripts/_common.sh index 6ab9422..f8851af 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,9 +4,8 @@ # COMMON VARIABLES #================================================= -pkg_dependencies="postgresql lynx" - -mailman3_suite_pkg="mailman3-full" +# dependencies used by the app +pkg_dependencies="postgresql lynx mailman3-full" #================================================= # PERSONAL HELPERS @@ -15,3 +14,7 @@ mailman3_suite_pkg="mailman3-full" #================================================= # EXPERIMENTAL HELPERS #================================================= + +#================================================= +# FUTURE OFFICIAL HELPERS +#================================================= diff --git a/scripts/backup b/scripts/backup index c3e545c..e8f2cd4 100755 --- a/scripts/backup +++ b/scripts/backup @@ -1,15 +1,12 @@ #!/bin/bash -# TODO(decentral1se) - #================================================= # 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 @@ -18,98 +15,52 @@ source /usr/share/yunohost/helpers #================================================= ynh_clean_setup () { - ynh_clean_check_starting + 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..." --weight=2 +ynh_print_info --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME + domain=$(ynh_app_setting_get --app=$app --key=domain) db_name_app=$(ynh_app_setting_get --app=$app --key=db_name_app) -db_name_app_web=$(ynh_app_setting_get --app=$app --key=db_name_app_web) +db_name_web=$(ynh_app_setting_get --app=$app --key=db_name_web) #================================================= -# STANDARD BACKUP STEPS +# DECLARE DATA AND CONF FILES TO BACKUP #================================================= - -#================================================= -# STOP SYSTEMD SERVICE -#================================================= - -ynh_script_progression --message="Stopping systemd services..." --weight=10 - -ynh_systemd_action --service_name=$app --action=stop - -ynh_systemd_action --service_name="${app}-web" --action="stop" - -#================================================= -# BACKUP THE APP MAIN DIR -#================================================= - -ynh_script_progression --message="Backing up the main application directory..." --weight=2 - -ynh_backup --src_path=/etc/mailman3/ - -ynh_backup --src_path=/usr/share/mailman3-web +ynh_print_info --message="Declaring files to be backed up..." #================================================= # BACKUP THE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Backing up NGINX web server configuration..." --weight=2 - ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" +#================================================= +# SPECIFIC BACKUP + +#================================================= +# BACKUP VARIOUS FILES +#================================================= + +ynh_backup --src_path="/etc/$app" + #================================================= # BACKUP THE POSTGRESQL DATABASE #================================================= +ynh_print_info --message="Backing up the PostgreSQL database..." -ynh_script_progression --message="Backing up the PostgreSQL databases..." --weight=4 - -ynh_psql_dump_db --database="$db_name_app" > "${app}_db.sql" - -ynh_psql_dump_db --database="$db_name_app_web" > "${app}_web_db.sql" - -#================================================= -# SPECIFIC BACKUP -#================================================= - -#================================================= -# BACKUP SYSTEMD -#================================================= - -ynh_script_progression --message="Backing up systemd configurations..." --weight=2 - -ynh_backup --src_path="/etc/systemd/system/multi-user.target.wants/$app.service" - -ynh_backup --src_path="/etc/systemd/system/multi-user.target.wants/${app}-web.service" - -#================================================= -# BACKUP A CRON FILE -#================================================= - -ynh_script_progression --message="Backing up crontab configuration..." --weight=2 - -ynh_backup --src_path="/etc/cron.d/$app" - -#================================================= -# START SYSTEMD SERVICE -#================================================= - -ynh_script_progression --message="Starting systemd services..." --weight=1 - -ynh_systemd_action --action=start --service_name=$app - -ynh_systemd_action --action=start --service_name="${app}-web" +ynh_psql_dump_db --database="$db_name_app" > db_app.sql +ynh_psql_dump_db --database="$db_name_web" > db_web.sql #================================================= # END OF SCRIPT #================================================= -ynh_script_progression --message="Backup script completed for $app" --last +ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." diff --git a/scripts/install b/scripts/install index e023a0a..0aa0f69 100755 --- a/scripts/install +++ b/scripts/install @@ -8,7 +8,6 @@ source _common.sh source /usr/share/yunohost/helpers -source ynh_add_extra_apt_repos__3 #================================================= # MANAGE SCRIPT FAILURE @@ -17,220 +16,163 @@ source ynh_add_extra_apt_repos__3 ynh_clean_setup () { ynh_clean_check_starting } - +# Exit if an error occurs during the execution of the script ynh_abort_if_errors #================================================= # RETRIEVE ARGUMENTS FROM THE MANIFEST #================================================= -app=$YNH_APP_INSTANCE_NAME -app_web="mailman3_web" - domain=$YNH_APP_ARG_DOMAIN -domain_ip=$YNH_APP_ARG_DOMAIN_IP +path_url="/" 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..." -ynh_script_progression --message="Validating installation parameters..." --weight=2 +test ! -e /usr/share/$app-web || ynh_die --message="Mailman3 is already installed !" -test ! -e /usr/share/mailman3-web || ynh_die --message="Mailman3 is already installed?" +test ! -e /etc/$app || ynh_die --message="Mailman3 is already installed !" -test ! -e /etc/mailman3 || ynh_die --message="Mailman3 is already installed?" +# 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=1 +ynh_script_progression --message="Storing installation settings..." ynh_app_setting_set --app=$app --key=domain --value=$domain -ynh_app_setting_set --app=$app --key=domain_ip --value=$domain_ip -ynh_app_setting_set --app=$app --key=is_public --value=$is_public -ynh_app_setting_set --app=$app --key=path --value="/" +ynh_app_setting_set --app=$app --key=path --value=$path_url #================================================= # STANDARD MODIFICATIONS -#================================================= - -#================================================= -# NGINX CONFIGURATION -#================================================= - -ynh_script_progression --message="Configuring NGINX web server..." --weight=3 - -ynh_add_nginx_config - #================================================= # FIND AND OPEN A PORT #================================================= +ynh_script_progression --message="Finding an available port..." -ynh_script_progression --message="Configuring firewall..." --weight=1 - -port_web=$(ynh_find_port --port=3000) - -ynh_app_setting_set --app=$app --key=port_web --value=$port_web - -#================================================= -# ENABLE BACKPORTS REPOSITORY -#================================================= - -ynh_script_progression --message="Enabling stretch backports ..." --weight=2 - -ynh_install_extra_repo \ - --repo="deb http://deb.debian.org/debian stretch-backports main" \ - --name=stretch-backports +# Find an available port +port=$(ynh_find_port --port=8095) +ynh_app_setting_set --app=$app --key=port --value=$port #================================================= # INSTALL DEPENDENCIES #================================================= - -ynh_script_progression --message="Installing dependencies..." --weight=10 +ynh_script_progression --message="Installing dependencies..." ynh_install_app_dependencies $pkg_dependencies -# Note(decentral1se): enable backports during install -DEBIAN_FRONTEND=noninteractive apt-get \ - --no-remove \ - --assume-yes \ - -o Dpkg::Options::=--force-confdef \ - -o Dpkg::Options::=--force-confold \ - -t stretch-backports \ - install \ - $mailman3_suite_pkg - -# Note(decentral1se): See https://github.com/YunoHost-Apps/mailman3_ynh/issues/2 -apt-mark hold $mailman3_suite_pkg - #================================================= # CREATE A POSTGRESQL DATABASE #================================================= - -ynh_script_progression --message="Creating PostgreSQL databases..." --weight=5 +ynh_script_progression --message="Creating a PostgreSQL database..." ynh_psql_test_if_first_run -# mailman3 database -db_pwd_app=$(ynh_string_random 30) -ynh_app_setting_set --app=$app --key=db_name_app --value=$app -ynh_app_setting_set --app=$app --key=db_user_app --value=$app +# mailman3-app database +db_name_app=$(ynh_sanitize_dbid --db_name="${app}_app") +db_user_app=$db_name_app +db_pwd_app=$(ynh_string_random --length=30) +ynh_app_setting_set --app=$app --key=db_name_app --value=$db_name_app ynh_app_setting_set --app=$app --key=db_pwd_app --value=$db_pwd_app -ynh_psql_create_user "$app" "$db_pwd_app" -ynh_psql_create_db "$app" "$app" +ynh_psql_setup_db --db_user=$db_user_app --db_name=$db_name_app --db_pwd=$db_pwd_app # mailman3-web database -db_pwd_app_web=$(ynh_string_random 30) -ynh_app_setting_set --app=$app --key=db_name_app_web --value="$app_web" -ynh_app_setting_set --app=$app --key=db_user_app_web --value="$app_web" -ynh_app_setting_set --app=$app --key=db_pwd_app_web --value=$db_pwd_app_web -ynh_psql_create_user "$app_web" "$db_pwd_app_web" -ynh_psql_create_db "$app_web" "$app_web" +db_name_web=$(ynh_sanitize_dbid --db_name="${app}_web") +db_user_web=$db_name_web +db_pwd_web=$(ynh_string_random --length=30) +ynh_app_setting_set --app=$app --key=db_name_web --value=$db_name_web +ynh_app_setting_set --app=$app --key=db_pwd_web --value=$db_pwd_web +ynh_psql_setup_db --db_user=$db_user_web --db_name=$db_name_web --db_pwd=$db_pwd_web #================================================= -# MODIFY A CONFIG FILE +# NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Configuring NGINX web server..." -ynh_script_progression --message="Modifying necessary config files..." --weight=2 +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# SPECIFIC SETUP +#================================================= +# ADD A CONFIGURATION +#================================================= +ynh_script_progression --message="Adding a configuration file..." # mailman3 core configuration -rest_api_admin="rest_admin" +rest_api_admin_user="rest_admin" rest_api_admin_pwd=$(head -n15 /dev/urandom | tail -n +1 | tr -dc -d 'a-z0-9' | head -c15) -ynh_app_setting_set --app=$app --key=rest_admin --value="$rest_api_admin" +ynh_app_setting_set --app=$app --key=rest_admin_user --value="$rest_api_admin_user" ynh_app_setting_set --app=$app --key=rest_admin_pwd --value="$rest_api_admin_pwd" -cp -f ../conf/mailman.cfg /etc/mailman3/mailman.cfg -ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="/etc/mailman3/mailman.cfg" -ynh_replace_string --match_string="__DB_USER__" --replace_string="$app" --target_file="/etc/mailman3/mailman.cfg" -ynh_replace_string --match_string="__DB_NAME__" --replace_string="$app" --target_file="/etc/mailman3/mailman.cfg" -ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd_app" --target_file="/etc/mailman3/mailman.cfg" -ynh_replace_string --match_string="__PORT_WEB__" --replace_string="$port_web" --target_file="/etc/mailman3/mailman.cfg" -ynh_replace_string --match_string="__REST_API_ADMIN_USER__" --replace_string="$rest_api_admin" --target_file="/etc/mailman3/mailman.cfg" -ynh_replace_string --match_string="__REST_API_ADMIN_PWD__" --replace_string="$rest_api_admin_pwd" --target_file="/etc/mailman3/mailman.cfg" +ynh_add_config --template="../conf/mailman.cfg" --destination="/etc/mailman3/mailman.cfg" + +chmod 400 "/etc/mailman3/mailman.cfg" +chown list:list "/etc/mailman3/mailman.cfg" # hyperkitty configuration archiver_key=$(head -n32 /dev/urandom | tail -n +1 | tr -dc -d 'a-z0-9' | head -c32) ynh_app_setting_set --app=$app --key=archiver_key --value="$archiver_key" -cp -f ../conf/mailman-hyperkitty.cfg /etc/mailman3/mailman-hyperkitty.cfg -ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="/etc/mailman3/mailman-hyperkitty.cfg" -ynh_replace_string --match_string="__ARCHIVER_KEY__" --replace_string="$archiver_key" --target_file="/etc/mailman3/mailman-hyperkitty.cfg" +ynh_add_config --template="../conf/mailman-hyperkitty.cfg" --destination="/etc/mailman3/mailman-hyperkitty.cfg" + +chmod 400 "/etc/mailman3/mailman-hyperkitty.cfg" +chown list:list "/etc/mailman3/mailman-hyperkitty.cfg" # mailman3-web configuration secret_key=$(head -n64 /dev/urandom | tail -n +1 | tr -dc -d 'a-z0-9' | head -c64) ynh_app_setting_set --app=$app --key=secret_key --value="$secret_key" -cp -f ../conf/mailman-web.py /etc/mailman3/mailman-web.py -ynh_replace_string --match_string="__SECRET_KEY__" --replace_string="$secret_key" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__DOMAIN_IP__" --replace_string="$domain_ip" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__PORT_WEB__" --replace_string="$port_web" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__REST_API_ADMIN_USER__" --replace_string="$rest_api_admin" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__REST_API_ADMIN_PWD__" --replace_string="$rest_api_admin_pwd" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__ARCHIVER_KEY__" --replace_string="$archiver_key" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__DB_NAME__" --replace_string="$app_web" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__DB_USER__" --replace_string="$app_web" --target_file="/etc/mailman3/mailman-web.py" -ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd_app_web" --target_file="/etc/mailman3/mailman-web.py" +ynh_add_config --template="../conf/mailman-web.py" --destination="/etc/mailman3/mailman-web.py" #================================================= # RUN DATABASE MIGRATIONS #================================================= - ynh_script_progression --message="Running database migrations..." --weight=6 -cd /usr/share/mailman3-web && python3 manage.py migrate || ynh_die --message="Mailman3 migrations failed!" - -#================================================= -# STORE THE CONFIG FILE CHECKSUM -#================================================= - -ynh_script_progression --message="Storing configuration checksum..." --weight=1 - -ynh_store_file_checksum --file=/etc/mailman3/mailman.cfg -ynh_store_file_checksum --file=/etc/mailman3/mailman-hyperkitty.cfg -ynh_store_file_checksum --file=/etc/mailman3/mailman-web.cfg +pushd /usr/share/mailman3-web + python3 manage.py migrate || ynh_die --message="Mailman3 migrations failed!" +popd #================================================= # GENERIC FINALIZATION #================================================= - -#================================================= -# ADVERTISE SERVICE IN ADMIN PANEL +# INTEGRATE SERVICE IN YUNOHOST #================================================= +ynh_script_progression --message="Integrating service in YunoHost..." -ynh_script_progression --message="Advertising services in admin panel..." --weight=3 - -yunohost service add "$app" - -yunohost service add "$app-web" +yunohost service add $app --description="Mailman3 daemon" +yunohost service add "$app-web" --description="Mailman3 web daemon" #================================================= # START SYSTEMD SERVICE #================================================= +ynh_script_progression --message="Starting a systemd service..." -ynh_script_progression --message="Starting the $app and $app-web services..." --weight=10 - -ynh_systemd_action --service_name=$app --action=enable -ynh_systemd_action --service_name="$app-web" --action=enable - -ynh_systemd_action --service_name=$app --action=restart -ynh_systemd_action --service_name="$app-web" --action=restart +# Start a systemd service +ynh_systemd_action --service_name=$app --action="start" +ynh_systemd_action --service_name="$app-web" --action="start" #================================================= # SETUP SSOWAT #================================================= +ynh_script_progression --message="Configuring permissions..." -ynh_script_progression --message="Configuring SSOwat..." --weight=1 - +# Make app public if necessary if [ $is_public -eq 1 ] then - ynh_app_setting_set --app=$app --key=unprotected_uris --value="/" + # 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=2 +ynh_script_progression --message="Reloading NGINX web server..." ynh_systemd_action --service_name=nginx --action=reload @@ -238,4 +180,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Installation of $app completed" --last +ynh_script_progression --message="Installation of $app completed" diff --git a/scripts/remove b/scripts/remove index 038cf61..5f50a44 100755 --- a/scripts/remove +++ b/scripts/remove @@ -8,89 +8,82 @@ source _common.sh source /usr/share/yunohost/helpers -source ynh_add_extra_apt_repos__3 #================================================= # LOAD SETTINGS #================================================= - -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME -app_web="${app}_web" + +domain=$(ynh_app_setting_get --app=$app --key=domain) +port=$(ynh_app_setting_get --app=$app --key=port) +db_name_app=$(ynh_app_setting_get --app=$app --key=db_name_app) +db_user_app=$db_name_app +db_name_web=$(ynh_app_setting_get --app=$app --key=db_name_web) +db_user_web=$db_name_web #================================================= # STANDARD REMOVE #================================================= - -#================================================= -# REMOVE BACKPORTS REPOSITORY +# REMOVE SERVICE INTEGRATION IN YUNOHOST #================================================= -ynh_script_progression --message="Removing stretch backports ..." --weight=2 +# Remove the service from the list of services known by YunoHost (added from `yunohost service add`) +if ynh_exec_warn_less yunohost service status $app >/dev/null +then + ynh_script_progression --message="Removing $app service integration..." + yunohost service remove $app +fi -ynh_remove_extra_repo --name=stretch-backports +# Remove the service from the list of services known by YunoHost (added from `yunohost service add`) +if ynh_exec_warn_less yunohost service status $app >/dev/null +then + ynh_script_progression --message="Removing $app-web service integration..." + yunohost service remove "$app-web" +fi #================================================= # REMOVE THE POSTGRESQL DATABASE #================================================= +ynh_script_progression --message="Removing the PostgreSQL database..." -ynh_script_progression --message="Removing the PostgreSQL databases..." --weight=4 - -ynh_psql_remove_db --db_user=$app --db_name=$app - -ynh_psql_remove_db --db_user="$app_web" --db_name="$app_web" +# Remove a database if it exists, along with the associated user +ynh_psql_remove_db --db_user=$db_user_app --db_name=$db_name_app +ynh_psql_remove_db --db_user=$db_user_web --db_name=$db_name_web #================================================= # REMOVE DEPENDENCIES #================================================= +ynh_script_progression --message="Removing dependencies..." -ynh_script_progression --message="Removing dependencies..." --weight=6 - +# Remove metapackage and its dependencies ynh_remove_app_dependencies -ynh_package_autopurge $mailman3_suite_pkg - -ynh_secure_remove /usr/share/mailman3-web - -ynh_secure_remove /etc/mailman3 - #================================================= # REMOVE NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Removing NGINX web server configuration..." -ynh_script_progression --message="Removing NGINX web server configuration..." --weight=2 - +# Remove the dedicated NGINX config ynh_remove_nginx_config -#================================================= -# REMOVE SERVICE FROM ADMIN PANEL -#================================================= - -ynh_script_progression --message="Removing registered services..." --weight=3 - -if yunohost service status $app >/dev/null 2>&1 -then - ynh_script_progression --message="Removing $app service..." --weight=2 - yunohost service remove "$app" -fi - -if yunohost service status "$app-web" >/dev/null 2>&1 -then - ynh_script_progression --message="Removing $app-web service..." --weight=2 - yunohost service remove "$app-web" -fi - #================================================= # SPECIFIC REMOVE #================================================= +# REMOVE VARIOUS FILES +#================================================= +ynh_script_progression --message="Removing various files..." + +ynh_secure_remove --file="/usr/share/mailman3-web" + +# Remove a directory securely +ynh_secure_remove --file="/etc/$app" #================================================= # GENERIC FINALIZATION -#================================================= - #================================================= # END OF SCRIPT #================================================= -ynh_script_progression --message="Removal of $app completed" --last +ynh_script_progression --message="Removal of $app completed" diff --git a/scripts/restore b/scripts/restore index 31416cd..0dcc81c 100755 --- a/scripts/restore +++ b/scripts/restore @@ -1,130 +1,121 @@ #!/bin/bash -# TODO(decentral1se) - #================================================= # 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 -source ../settings/scripts/ynh_add_extra_apt_repos__3 #================================================= # MANAGE SCRIPT FAILURE #================================================= ynh_clean_setup () { - ynh_clean_check_starting + ynh_clean_check_starting } - +# Exit if an error occurs during the execution of the script ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= - -ynh_script_progression --message="Loading settings..." --weight=2 +ynh_script_progression --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +db_name_app=$(ynh_app_setting_get --app=$app --key=db_name_app) +db_user_app=$db_name_app +db_name_web=$(ynh_app_setting_get --app=$app --key=db_name_web) +db_user_web=$db_name_web #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= +ynh_script_progression --message="Validating restoration parameters..." -ynh_script_progression --message="Validating restoration parameters..." --weight=2 - -ynh_webpath_available --domain=$domain \ - || ynh_die --message="Path not available: ${domain}" - +ynh_webpath_available --domain=$domain --path_url=$path_url \ + || ynh_die --message="Path not available: ${domain}${path_url}" test ! -d /usr/share/mailman3-web \ || ynh_die --message="There is already an installation present at /usr/share/mailman3-web?" #================================================= # STANDARD RESTORATION STEPS -#================================================= - #================================================= # RESTORE THE NGINX CONFIGURATION #================================================= - -ynh_script_progression --message="Restoring nginx configuration..." --weight=1 +ynh_script_progression --message="Restoring the NGINX web server configuration..." ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" -#================================================= -# RESTORE THE APP MAIN DIRS -#================================================= - -# TODO(decentral1se) -# ynh_script_progression --message="Restoring the app main directory..." --weight=30 - #================================================= # SPECIFIC RESTORATION -#================================================= - #================================================= # REINSTALL DEPENDENCIES #================================================= +ynh_script_progression --message="Reinstalling dependencies..." -# TODO(decentral1se) -# ynh_script_progression --message="Reinstalling dependencies..." --weight=30 +# Define and install dependencies +ynh_install_app_dependencies $pkg_dependencies #================================================= -# RESTORE THE POSTGRESQL DATABASES +# RESTORE THE POSTGRESQL DATABASE #================================================= +ynh_script_progression --message="Restoring the PostgreSQL database..." -# TODO(decentral1se) -# ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=14 -# ynh_psql_test_if_first_run -# ynh_psql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd -# ynh_psql_execute_file_as_root --file="./db.sql" --database="$db_name" +ynh_psql_test_if_first_run + +db_pwd_app=$(ynh_app_setting_get --app=$app --key=db_pwd_app) +ynh_psql_setup_db --db_user=$db_user_app --db_name=$db_name_app --db_pwd=$db_pwd_app +ynh_psql_execute_file_as_root --file="./db_app.sql" --database=$db_name_app + +db_pwd_web=$(ynh_app_setting_get --app=$app --key=db_pwd_web) +ynh_psql_setup_db --db_user=$db_user_web --db_name=$db_name_web --db_pwd=$db_pwd_web +ynh_psql_execute_file_as_root --file="./db_web.sql" --database=$db_name_web #================================================= -# RESTORE SYSTEMD CONFIGURATION +# RESTORE VARIOUS FILES #================================================= +ynh_script_progression --message="Restoring various files..." -# TODO(decentral1se) -# ynh_script_progression --message="Restoring the systemd configuration..." --weight=3 +ynh_restore_file --origin_path="/etc/$app/" #================================================= -# ADVERTISE SERVICE IN ADMIN PANEL +# INTEGRATE SERVICE IN YUNOHOST #================================================= +ynh_script_progression --message="Integrating service in YunoHost..." -# TODO(decentral1se) -# ynh_script_progression --message="Advertising service in admin panel..." --weight=3 +yunohost service add $app --description="Mailman3 daemon" +yunohost service add "$app-web" --description="Mailman3 web daemon" #================================================= # START SYSTEMD SERVICE #================================================= +ynh_script_progression --message="Starting a systemd service..." -# TODO(decentral1se) -# ynh_script_progression --message="Starting a systemd service..." --weight=41 +# Start a systemd service +ynh_systemd_action --service_name=$app --action=enable +ynh_systemd_action --service_name="$app-web" --action=enable -#================================================= -# RESTORE THE CRON FILE -#================================================= - -# TODO(decentral1se) -# ynh_script_progression --message="Restoring a cron job for removing cache..." --weight=2 -# ynh_restore_file --origin_path="/etc/cron.d/$app" +ynh_systemd_action --service_name=$app --action=restart +ynh_systemd_action --service_name="$app-web" --action=restart #================================================= # GENERIC FINALIZATION #================================================= -# RELOAD NGINX +# RELOAD NGINX AND PHP-FPM #================================================= +ynh_script_progression --message="Reloading NGINX web server..." -# TODO(decentral1se) -# ynh_script_progression --message="Reloading NGINX web server..." --weight=2 -# ynh_systemd_action --service_name=nginx --action=reload +ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT #================================================= -ynh_script_progression --message="Restoration completed for $app" --last +ynh_script_progression --message="Restoration completed for $app" diff --git a/scripts/upgrade b/scripts/upgrade index be7a862..1b1ce1d 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,4 +1,110 @@ #!/bin/bash -# TODO(decentral1se) -# Also, see https://github.com/YunoHost-Apps/mailman3_ynh/issues/2 +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +db_name_app=$(ynh_app_setting_get --app=$app --key=db_name_app) +db_name_web=$(ynh_app_setting_get --app=$app --key=db_name_web) + +#================================================= +# CHECK VERSION +#================================================= +ynh_script_progression --message="Checking version..." + +upgrade_type=$(ynh_check_app_version_changed) + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." + +ynh_systemd_action --service_name=$app --action="stop" +ynh_systemd_action --service_name="$app-web" --action=stop + +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= +ynh_script_progression --message="Ensuring downward compatibility..." + +# Cleaning legacy permissions +if ynh_legacy_permissions_exists; then + ynh_legacy_permissions_delete_all + + ynh_app_setting_delete --app=$app --key=is_public +fi + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading NGINX web server configuration..." + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# UPGRADE DEPENDENCIES +#================================================= +ynh_script_progression --message="Upgrading dependencies..." + +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# GENERIC FINALIZATION +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." + +yunohost service add $app --description="A short description of the app" --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." + +ynh_systemd_action --service_name=$app --action=start +ynh_systemd_action --service_name="$app-web" --action=start + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Upgrade of $app completed" diff --git a/scripts/ynh_add_extra_apt_repos__3 b/scripts/ynh_add_extra_apt_repos__3 deleted file mode 100644 index b784159..0000000 --- a/scripts/ynh_add_extra_apt_repos__3 +++ /dev/null @@ -1,294 +0,0 @@ -#!/bin/bash - -# Pin a repository. -# -# usage: ynh_pin_repo --package=packages --pin=pin_filter [--priority=priority_value] [--name=name] [--append] -# | arg: -p, --package - Packages concerned by the pin. Or all, *. -# | arg: -i, --pin - Filter for the pin. -# | arg: -p, --priority - Priority for the pin -# | arg: -n, --name - Name for the files for this repo, $app as default value. -# | arg: -a, --append - Do not overwrite existing files. -# -# See https://manpages.debian.org/stretch/apt/apt_preferences.5.en.html for information about pinning. -# -ynh_pin_repo () { - # Declare an array to define the options of this helper. - local legacy_args=pirna - declare -Ar args_array=( [p]=package= [i]=pin= [r]=priority= [n]=name= [a]=append ) - local package - local pin - local priority - local name - local append - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - package="${package:-*}" - priority=${priority:-50} - name="${name:-$app}" - append=${append:-0} - - if [ $append -eq 1 ] - then - append="tee -a" - else - append="tee" - fi - - mkdir -p "/etc/apt/preferences.d" - echo "Package: $package -Pin: $pin -Pin-Priority: $priority" \ - | $append "/etc/apt/preferences.d/$name" -} - -# Add a repository. -# -# usage: ynh_add_repo --uri=uri --suite=suite --component=component [--name=name] [--append] -# | arg: -u, --uri - Uri of the repository. -# | arg: -s, --suite - Suite of the repository. -# | arg: -c, --component - Component of the repository. -# | arg: -n, --name - Name for the files for this repo, $app as default value. -# | arg: -a, --append - Do not overwrite existing files. -# -# Example for a repo like deb http://forge.yunohost.org/debian/ stretch stable -# uri suite component -# ynh_add_repo --uri=http://forge.yunohost.org/debian/ --suite=stretch --component=stable -# -ynh_add_repo () { - # Declare an array to define the options of this helper. - local legacy_args=uscna - declare -Ar args_array=( [u]=uri= [s]=suite= [c]=component= [n]=name= [a]=append ) - local uri - local suite - local component - local name - local append - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - name="${name:-$app}" - append=${append:-0} - - if [ $append -eq 1 ] - then - append="tee -a" - else - append="tee" - fi - - mkdir -p "/etc/apt/sources.list.d" - # Add the new repo in sources.list.d - echo "deb $uri $suite $component" \ - | $append "/etc/apt/sources.list.d/$name.list" -} - -# Add an extra repository correctly, pin it and get the key. -# -# usage: ynh_install_extra_repo --repo="repo" [--key=key_url] [--priority=priority_value] [--name=name] [--append] -# | arg: -r, --repo - Complete url of the extra repository. -# | arg: -k, --key - url to get the public key. -# | arg: -p, --priority - Priority for the pin -# | arg: -n, --name - Name for the files for this repo, $app as default value. -# | arg: -a, --append - Do not overwrite existing files. -ynh_install_extra_repo () { - # Declare an array to define the options of this helper. - local legacy_args=rkpna - declare -Ar args_array=( [r]=repo= [k]=key= [p]=priority= [n]=name= [a]=append ) - local repo - local key - local priority - local name - local append - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - name="${name:-$app}" - append=${append:-0} - key=${key:-0} - priority=${priority:-} - - if [ $append -eq 1 ] - then - append="--append" - wget_append="tee -a" - else - append="" - wget_append="tee" - fi - - # Split the repository into uri, suite and components. - # Remove "deb " at the beginning of the repo. - repo="${repo#deb }" - - # Get the uri - local uri="$(echo "$repo" | awk '{ print $1 }')" - - # Get the suite - local suite="$(echo "$repo" | awk '{ print $2 }')" - - # Get the components - local component="${repo##$uri $suite }" - - # Add the repository into sources.list.d - ynh_add_repo --uri="$uri" --suite="$suite" --component="$component" --name="$name" $append - - # Pin the new repo with the default priority, so it won't be used for upgrades. - # Build $pin from the uri without http and any sub path - local pin="${uri#*://}" - pin="${pin%%/*}" - # Set a priority only if asked - if [ -n "$priority" ] - then - priority="--priority=$priority" - fi - ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append - - # Get the public key for the repo - if [ -n "$key" ] - then - mkdir -p "/etc/apt/trusted.gpg.d" - wget -q "$key" -O - | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg > /dev/null - fi - - # Update the list of package with the new repo - ynh_package_update -} - -# Remove an extra repository and the assiociated configuration. -# -# usage: ynh_remove_extra_repo [--name=name] -# | arg: -n, --name - Name for the files for this repo, $app as default value. -ynh_remove_extra_repo () { - # Declare an array to define the options of this helper. - local legacy_args=n - declare -Ar args_array=( [n]=name= ) - local name - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - name="${name:-$app}" - - ynh_secure_remove "/etc/apt/sources.list.d/$name.list" - ynh_secure_remove "/etc/apt/preferences.d/$name" - ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.gpg" - ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.asc" - - # Update the list of package to exclude the old repo - ynh_package_update -} - -# Install packages from an extra repository properly. -# -# usage: ynh_install_extra_app_dependencies --repo="repo" --package="dep1 dep2" [--key=key_url] [--name=name] -# | arg: -r, --repo - Complete url of the extra repository. -# | arg: -p, --package - The packages to install from this extra repository -# | arg: -k, --key - url to get the public key. -# | arg: -n, --name - Name for the files for this repo, $app as default value. -ynh_install_extra_app_dependencies () { - # Declare an array to define the options of this helper. - local legacy_args=rpkn - declare -Ar args_array=( [r]=repo= [p]=package= [k]=key= [n]=name= ) - local repo - local package - local key - local name - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - name="${name:-$app}" - key=${key:-0} - - # Set a key only if asked - if [ -n "$key" ] - then - key="--key=$key" - fi - # Add an extra repository for those packages - ynh_install_extra_repo --repo="$repo" $key --priority=995 --name=$name - - # Install requested dependencies from this extra repository. - ynh_add_app_dependencies --package="$package" - - # Remove this extra repository after packages are installed - ynh_remove_extra_repo --name=$app -} - -#================================================= - -# patched version of ynh_install_app_dependencies to be used with ynh_add_app_dependencies - -# Define and install dependencies with a equivs control file -# This helper can/should only be called once per app -# -# usage: ynh_install_app_dependencies dep [dep [...]] -# | arg: dep - the package name to install in dependence -# You can give a choice between some package with this syntax : "dep1|dep2" -# Example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5" -# This mean in the dependence tree : dep1 & dep2 & (dep3 | dep4 | dep5) -# -# Requires YunoHost version 2.6.4 or higher. -ynh_install_app_dependencies () { - local dependencies=$@ - dependencies="$(echo "$dependencies" | sed 's/\([^\<=\>]\)\ \([^(]\)/\1, \2/g')" - dependencies=${dependencies//|/ | } - local manifest_path="../manifest.json" - if [ ! -e "$manifest_path" ]; then - manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place - fi - - local version=$(grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file. - if [ ${#version} -eq 0 ]; then - version="1.0" - fi - local dep_app=${app//_/-} # Replace all '_' by '-' - - # Handle specific versions - if [[ "$dependencies" =~ [\<=\>] ]] - then - # Replace version specifications by relationships syntax - # https://www.debian.org/doc/debian-policy/ch-relationships.html - # Sed clarification - # [^(\<=\>] ignore if it begins by ( or < = >. To not apply twice. - # [\<=\>] matches < = or > - # \+ matches one or more occurence of the previous characters, for >= or >>. - # [^,]\+ matches all characters except ',' - # Ex: package>=1.0 will be replaced by package (>= 1.0) - dependencies="$(echo "$dependencies" | sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g')" - fi - - cat > /tmp/${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build -Section: misc -Priority: optional -Package: ${dep_app}-ynh-deps -Version: ${version} -Depends: ${dependencies} -Architecture: all -Description: Fake package for $app (YunoHost app) dependencies - This meta-package is only responsible of installing its dependencies. -EOF - ynh_package_install_from_equivs /tmp/${dep_app}-ynh-deps.control \ - || ynh_die --message="Unable to install dependencies" # Install the fake package and its dependencies - rm /tmp/${dep_app}-ynh-deps.control - ynh_app_setting_set --app=$app --key=apt_dependencies --value="$dependencies" -} - -ynh_add_app_dependencies () { - # Declare an array to define the options of this helper. - local legacy_args=pr - declare -Ar args_array=( [p]=package= [r]=replace) - local package - local replace - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - replace=${replace:-0} - - local current_dependencies="" - if [ $replace -eq 0 ] - then - local dep_app=${app//_/-} # Replace all '_' by '-' - if ynh_package_is_installed --package="${dep_app}-ynh-deps" - then - current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) " - fi - - current_dependencies=${current_dependencies// | /|} - fi - - ynh_install_app_dependencies "${current_dependencies}${package}" -}