From cf560b8f91b4221d0d4363093f6a1dc8d0e96704 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Thu, 31 Dec 2020 14:05:39 +0100 Subject: [PATCH 001/131] [mod] activate moulinette.core logging in cli --- src/yunohost/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/yunohost/__init__.py b/src/yunohost/__init__.py index 76449a7e4..0c3cb8355 100644 --- a/src/yunohost/__init__.py +++ b/src/yunohost/__init__.py @@ -143,6 +143,11 @@ def init_logging(interface="cli", 'handlers': ['file', 'tty'] if not quiet else ['file'], 'propagate': False, }, + 'moulinette.core': { + 'level': 'DEBUG' if debug else 'ERROR', + 'handlers': ['file', 'tty'] if not quiet else ['file'], + 'propagate': False, + }, }, 'root': { 'level': 'DEBUG', From c931f8a5323a9c2e734a0764330d03f73dd87dfc Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Thu, 31 Dec 2020 14:05:58 +0100 Subject: [PATCH 002/131] [mod] activate moulinette.core and moulinette.interface.api logging in api --- src/yunohost/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/yunohost/__init__.py b/src/yunohost/__init__.py index 0c3cb8355..bda2cb994 100644 --- a/src/yunohost/__init__.py +++ b/src/yunohost/__init__.py @@ -203,6 +203,16 @@ def init_logging(interface="cli", 'handlers': [], 'propagate': True, }, + 'moulinette.core': { + 'level': 'DEBUG' if debug else 'ERROR', + 'handlers': ['file', 'tty'] if not quiet else ['file'], + 'propagate': False, + }, + 'moulinette.interface.api': { + 'level': 'DEBUG', + 'handlers': [], + 'propagate': True, + }, }, 'root': { 'level': 'DEBUG', From fcf9e58ce4d164dc2229664964056d6283fa2ace Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 31 Jan 2021 16:01:38 +0100 Subject: [PATCH 003/131] Rework logging configuration --- src/yunohost/__init__.py | 195 +++++++++++++++------------------------ 1 file changed, 74 insertions(+), 121 deletions(-) diff --git a/src/yunohost/__init__.py b/src/yunohost/__init__.py index bda2cb994..29c4b7bb7 100644 --- a/src/yunohost/__init__.py +++ b/src/yunohost/__init__.py @@ -93,129 +93,82 @@ def init_logging(interface="cli", if not os.path.isdir(logdir): os.makedirs(logdir, 0o750) - # ####################################################################### # + logging_configuration = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'console': { + 'format': '%(relativeCreated)-5d %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' + }, + 'tty-debug': { + 'format': '%(relativeCreated)-4d %(fmessage)s' + }, + 'precise': { + 'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' + }, + }, + 'filters': { + 'action': { + '()': 'moulinette.utils.log.ActionFilter', + }, + }, + 'handlers': { + 'cli': { + 'level': 'DEBUG' if debug else 'INFO', + 'class': 'moulinette.interfaces.cli.TTYHandler', + 'formatter': 'tty-debug' if debug else '', + }, + 'api': { + 'level': 'DEBUG' if debug else 'INFO', + 'class': 'moulinette.interfaces.api.APIQueueHandler', + }, + 'file': { + 'class': 'logging.FileHandler', + 'formatter': 'precise', + 'filename': logfile, + 'filters': ['action'], + }, + }, + 'loggers': { + 'yunohost': { + 'level': 'DEBUG', + 'handlers': ['file', interface] if not quiet else ['file'], + 'propagate': False, + }, + 'moulinette': { + 'level': 'DEBUG', + 'handlers': ['file', interface] if not quiet else ['file'], + 'propagate': False, + }, + }, + 'root': { + 'level': 'DEBUG', + 'handlers': ['file', interface] if debug else ['file'], + }, + } + # Logging configuration for CLI (or any other interface than api...) # - # ####################################################################### # if interface != "api": - configure_logging({ - 'version': 1, - 'main_logger': "yunohost", - 'disable_existing_loggers': True, - 'formatters': { - 'tty-debug': { - 'format': '%(relativeCreated)-4d %(fmessage)s' - }, - 'precise': { - 'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' - }, - }, - 'filters': { - 'action': { - '()': 'moulinette.utils.log.ActionFilter', - }, - }, - 'handlers': { - 'tty': { - 'level': 'DEBUG' if debug else 'INFO', - 'class': 'moulinette.interfaces.cli.TTYHandler', - 'formatter': 'tty-debug' if debug else '', - }, - 'file': { - 'class': 'logging.FileHandler', - 'formatter': 'precise', - 'filename': logfile, - 'filters': ['action'], - }, - }, - 'loggers': { - 'yunohost': { - 'level': 'DEBUG', - 'handlers': ['file', 'tty'] if not quiet else ['file'], - 'propagate': False, - }, - 'moulinette': { - 'level': 'DEBUG', - 'handlers': [], - 'propagate': True, - }, - 'moulinette.interface': { - 'level': 'DEBUG', - 'handlers': ['file', 'tty'] if not quiet else ['file'], - 'propagate': False, - }, - 'moulinette.core': { - 'level': 'DEBUG' if debug else 'ERROR', - 'handlers': ['file', 'tty'] if not quiet else ['file'], - 'propagate': False, - }, - }, - 'root': { - 'level': 'DEBUG', - 'handlers': ['file', 'tty'] if debug else ['file'], - }, - }) - # ####################################################################### # + + logging_configuration["main_logger"] = "yunohost" + + configure_logging(logging_configuration) + # Logging configuration for API # - # ####################################################################### # else: - configure_logging({ - 'version': 1, - 'disable_existing_loggers': True, - 'formatters': { - 'console': { - 'format': '%(relativeCreated)-5d %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' - }, - 'precise': { - 'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' - }, + # We use a WatchedFileHandler instead of regular FileHandler to possibly support log rotation etc + logging_configuration["handlers"]["file"]["class"] = 'logging.handlers.WatchedFileHandler' + + # This is for when launching yunohost-api in debug mode, we want to display stuff in the console + if debug: + logging_configuration["handlers"]["console"] = { + 'class': 'logging.StreamHandler', + 'formatter': 'console', + 'stream': 'ext://sys.stdout', + 'filters': ['action'], }, - 'filters': { - 'action': { - '()': 'moulinette.utils.log.ActionFilter', - }, - }, - 'handlers': { - 'api': { - 'level': 'DEBUG' if debug else 'INFO', - 'class': 'moulinette.interfaces.api.APIQueueHandler', - }, - 'file': { - 'class': 'logging.handlers.WatchedFileHandler', - 'formatter': 'precise', - 'filename': logfile, - 'filters': ['action'], - }, - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'console', - 'stream': 'ext://sys.stdout', - 'filters': ['action'], - }, - }, - 'loggers': { - 'yunohost': { - 'level': 'DEBUG', - 'handlers': ['file', 'api'] + (['console'] if debug else []), - 'propagate': False, - }, - 'moulinette': { - 'level': 'DEBUG', - 'handlers': [], - 'propagate': True, - }, - 'moulinette.core': { - 'level': 'DEBUG' if debug else 'ERROR', - 'handlers': ['file', 'tty'] if not quiet else ['file'], - 'propagate': False, - }, - 'moulinette.interface.api': { - 'level': 'DEBUG', - 'handlers': [], - 'propagate': True, - }, - }, - 'root': { - 'level': 'DEBUG', - 'handlers': ['file'] + (['console'] if debug else []), - }, - }) + logging_configuration["loggers"]["yunohost"]["handlers"].append("console") + logging_configuration["loggers"]["moulinette"]["handlers"].append("console") + logging_configuration["root"]["handlers"].append("console") + + configure_logging(logging_configuration) From 2ab330a0e2a1c699a6d09510b18b73505f821d11 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 31 Jan 2021 16:08:07 +0100 Subject: [PATCH 004/131] I think we don't need this hack anymore --- src/yunohost/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/yunohost/__init__.py b/src/yunohost/__init__.py index 29c4b7bb7..c536ba255 100644 --- a/src/yunohost/__init__.py +++ b/src/yunohost/__init__.py @@ -149,9 +149,6 @@ def init_logging(interface="cli", # Logging configuration for CLI (or any other interface than api...) # if interface != "api": - - logging_configuration["main_logger"] = "yunohost" - configure_logging(logging_configuration) # Logging configuration for API # From 06185a2392d6c9b247ddfb43fdb1f8a876dc6055 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 2 Feb 2021 03:45:13 +0100 Subject: [PATCH 005/131] Use jq / output-as json to get info from yunohost commands instead of scraping with grep --- data/helpers.d/backup | 15 ++++++++++++--- data/helpers.d/permission | 6 ++++-- data/helpers.d/user | 7 +++---- data/helpers.d/utils | 7 +------ 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/data/helpers.d/backup b/data/helpers.d/backup index 5557cbc42..33a6db4e2 100644 --- a/data/helpers.d/backup +++ b/data/helpers.d/backup @@ -399,6 +399,15 @@ ynh_delete_file_checksum () { ynh_app_setting_delete --app=$app --key=$checksum_setting_name } +# Checks a backup archive exists +# +# [internal] +# +ynh_backup_archive_exists () { + yunohost backup list --output-as json --quiet \ + | jq -e --arg archive "$1" '.archives | index($archive)' >/dev/null +} + # Make a backup in case of failed upgrade # # usage: @@ -423,7 +432,7 @@ ynh_backup_before_upgrade () { if [ "$NO_BACKUP_UPGRADE" -eq 0 ] then # Check if a backup already exists with the prefix 1 - if yunohost backup list | grep --quiet $app_bck-pre-upgrade1 + if ynh_backup_archive_exists "$app_bck-pre-upgrade1" then # Prefix becomes 2 to preserve the previous backup backup_number=2 @@ -435,7 +444,7 @@ ynh_backup_before_upgrade () { if [ "$?" -eq 0 ] then # If the backup succeeded, remove the previous backup - if yunohost backup list | grep --quiet $app_bck-pre-upgrade$old_backup_number + if ynh_backup_archive_exists "$app_bck-pre-upgrade$old_backup_number" then # Remove the previous backup only if it exists yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null @@ -467,7 +476,7 @@ ynh_restore_upgradebackup () { if [ "$NO_BACKUP_UPGRADE" -eq 0 ] then # Check if an existing backup can be found before removing and restoring the application. - if yunohost backup list | grep --quiet $app_bck-pre-upgrade$backup_number + if ynh_backup_archive_exists "$app_bck-pre-upgrade$backup_number" then # Remove the application then restore it yunohost app remove $app diff --git a/data/helpers.d/permission b/data/helpers.d/permission index 1791425b5..f4e200019 100644 --- a/data/helpers.d/permission +++ b/data/helpers.d/permission @@ -185,7 +185,8 @@ ynh_permission_exists() { local permission ynh_handle_getopts_args "$@" - yunohost user permission list --short | grep --word-regexp --quiet "$app.$permission" + yunohost user permission list --output-as json --quiet \ + | jq -e --arg perm "$app.$permission" '.permissions[$perm]' >/dev/null } # Redefine the url associated to a permission @@ -366,7 +367,8 @@ ynh_permission_has_user() { return 1 fi - yunohost user permission info "$app.$permission" | grep --word-regexp --quiet "$user" + yunohost user permission info "$app.$permission" --output-as json --quiet \ + | jq -e --arg user $user '.corresponding_users | index($user)' >/dev/null } # Check if a legacy permissions exist diff --git a/data/helpers.d/user b/data/helpers.d/user index f5d4b1680..bb2af6b55 100644 --- a/data/helpers.d/user +++ b/data/helpers.d/user @@ -17,7 +17,7 @@ ynh_user_exists() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - yunohost user list --output-as json | grep --quiet "\"username\": \"${username}\"" + yunohost user list --output-as json --quiet | jq -e ".users.${username}" >/dev/null } # Retrieve a YunoHost user information @@ -39,7 +39,7 @@ ynh_user_get_info() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - yunohost user info "$username" --output-as plain | ynh_get_plain_key "$key" + yunohost user info "$username" --output-as json --quiet | jq -r ".$key" } # Get the list of YunoHost users @@ -51,8 +51,7 @@ ynh_user_get_info() { # # Requires YunoHost version 2.4.0 or higher. ynh_user_list() { - yunohost user list --output-as plain --quiet \ - | awk '/^##username$/{getline; print}' + yunohost user list --output-as json --quiet | jq -r ".users | keys[]" } # Check if a user exists on the system diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 13f84424e..d696effdc 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -504,12 +504,7 @@ ynh_secure_remove () { # # [internal] # -# example: yunohost user info tata --output-as plain | ynh_get_plain_key mail -# -# usage: ynh_get_plain_key key [subkey [subsubkey ...]] -# | ret: string - the key's value -# -# Requires YunoHost version 2.2.4 or higher. +# (Deprecated, use --output-as json and jq instead) ynh_get_plain_key() { local prefix="#" local founded=0 From 958c052f1ec72a4445dc342a50f0741380278b25 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Thu, 11 Feb 2021 18:35:35 +0100 Subject: [PATCH 006/131] [fix] Avoid admin part of apps to be reachable from visitors --- src/yunohost/utils/legacy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/utils/legacy.py b/src/yunohost/utils/legacy.py index c84817f98..7479d12c4 100644 --- a/src/yunohost/utils/legacy.py +++ b/src/yunohost/utils/legacy.py @@ -280,7 +280,7 @@ def migrate_legacy_permission_settings(app=None): auth_header=True, label=legacy_permission_label(app, "protected"), show_tile=False, - allowed=user_permission_list()["permissions"][app + ".main"]["allowed"], + allowed=[], protected=True, sync_perm=False, ) From 6d625d457d4beeb2ac983353b58ae917b261c38e Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Thu, 11 Feb 2021 19:42:55 +0100 Subject: [PATCH 007/131] [fix] Unused import --- src/yunohost/utils/legacy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/yunohost/utils/legacy.py b/src/yunohost/utils/legacy.py index 7479d12c4..728fcaefc 100644 --- a/src/yunohost/utils/legacy.py +++ b/src/yunohost/utils/legacy.py @@ -13,7 +13,6 @@ from yunohost.app import ( ) from yunohost.permission import ( permission_create, - user_permission_list, user_permission_update, permission_sync_to_user, ) From 8003288a67536212e5ff9c54461e8cc4cc036b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Tue, 16 Feb 2021 14:14:40 +0100 Subject: [PATCH 008/131] Enhance the jinja template for bash helpers --- doc/helper_doc_template.md | 51 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/doc/helper_doc_template.md b/doc/helper_doc_template.md index 1ae6095a3..1b9fa873d 100644 --- a/doc/helper_doc_template.md +++ b/doc/helper_doc_template.md @@ -12,45 +12,46 @@ Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{{ {% for category, helpers in data.helpers %} ### {{ category.upper() }} {% for h in helpers %} -**{{ h.name }}** +**{{ h.name }}**
[details summary="{{ h.brief }}" class="helper-card-subtitle text-muted"]

**Usage**: `{{ h.usage }}` - {% if h.args %} +{%- if h.args %} -**Arguments**: - {% for infos in h.args %} - {% if infos|length == 2 %} +**Arguments**: + {%- for infos in h.args %} + {%- if infos|length == 2 %} - `{{ infos[0] }}`: {{ infos[1] }} - {% else %} + {%- else %} - `{{ infos[0] }}`, `{{ infos[1] }}`: {{ infos[2] }} - {% endif %} - {% endfor %} - {% endif %} - {% if h.ret %} + {%- endif %} + {%- endfor %} +{%- endif %} +{%- if h.ret %} **Returns**: {{ h.ret }} - {% endif %} - {% if "example" in h.keys() %} +{%- endif %} +{%- if "example" in h.keys() %} + **Example**: `{{ h.example }}` - {% endif %} - {% if "examples" in h.keys() %} +{%- endif %} +{%- if "examples" in h.keys() %} -**Examples**: - {% for example in h.examples %} - {% if not example.strip().startswith("# ") %} +**Examples**: + {% for example in h.examples %} + {% if not example.strip().startswith("# ") %} - `{{ example }}` - {% else %} + {% else %} - `{{ example.strip("# ") }}` - {% endif %} - {% endfor %} - {% endif %} - {% if h.details %} + {% endif %} + {% endfor %} +{%- endif %} +{%- if h.details %} -**Details**: -{{ h.details.replace('\n', '
').replace('_', '\_') }} - {% endif %} +**Details**:
+{{ h.details }} +{%- endif %} [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/{{ current_commit }}/data/helpers.d/{{ category }}#L{{ h.line + 1 }}) [/details] From aa92954f1b07a23c38abf277638cddf171b44e1b Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 20 Feb 2021 17:07:38 +0100 Subject: [PATCH 009/131] Translation typo.. --- locales/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index 29f1db1e9..9f8f6a167 100644 --- a/locales/it.json +++ b/locales/it.json @@ -591,7 +591,7 @@ "log_user_permission_update": "Aggiorna gli accessi del permesso '{}'", "log_user_group_update": "Aggiorna il gruppo '{}'", "log_user_group_delete": "Cancella il gruppo '{}'", - "log_user_group_create": "Crea il gruppo '[}'", + "log_user_group_create": "Crea il gruppo '{}'", "log_permission_url": "Aggiorna l'URL collegato al permesso '{}'", "log_permission_delete": "Cancella permesso '{}'", "log_permission_create": "Crea permesso '{}'", From c7c1eaca4ed8086439bb2d528318ff2223790611 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 21 Feb 2021 05:03:07 +0100 Subject: [PATCH 010/131] Mysql is a fucking joke (... trying to fix the mysql issue on RPi ...) --- data/hooks/conf_regen/34-mysql | 63 ++++++++++++++-------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/data/hooks/conf_regen/34-mysql b/data/hooks/conf_regen/34-mysql index ac2395f34..d9374bbf5 100755 --- a/data/hooks/conf_regen/34-mysql +++ b/data/hooks/conf_regen/34-mysql @@ -15,6 +15,31 @@ do_pre_regen() { do_post_regen() { regen_conf_files=$1 + if [[ ! -d /var/lib/mysql/mysql ]] + then + # dpkg-reconfigure will initialize mysql (if it ain't already) + # It enabled auth_socket for root, so no need to define any root password... + # c.f. : cat /var/lib/dpkg/info/mariadb-server-10.3.postinst | grep install_db -C3 + dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 + + systemctl -q is-active mariadb.service \ + || systemctl start mariadb + + sleep 5 + + echo "" | mysql && echo "Can't connect to mysql using unix_socket auth ... something went wrong during initial configuration of mysql !?" + fi + + if [ ! -e /etc/yunohost/mysql ] + then + # Dummy password that's not actually used nor meaningful ... + # (because mysql is supposed to be configured to use unix_socket on new setups) + # but keeping it for legacy + # until we merge https://github.com/YunoHost/yunohost/pull/912 ... + ynh_string_random 10 > /etc/yunohost/mysql + chmod 400 /etc/yunohost/mysql + fi + # mysql is supposed to be an alias to mariadb... but in some weird case is not # c.f. https://forum.yunohost.org/t/mysql-ne-fonctionne-pas/11661 # Playing with enable/disable allows to recreate the proper symlinks. @@ -27,44 +52,6 @@ do_post_regen() { systemctl is-active mariadb -q || systemctl start mariadb fi - if [ ! -f /etc/yunohost/mysql ]; then - - # ensure that mysql is running - systemctl -q is-active mysql.service \ - || service mysql start - - # generate and set new root password - mysql_password=$(ynh_string_random 10) - mysqladmin -s -u root -pyunohost password "$mysql_password" || { - if [ $FORCE -eq 1 ]; then - echo "It seems that you have already configured MySQL." \ - "YunoHost needs to have a root access to MySQL to runs its" \ - "applications, and is going to reset the MySQL root password." \ - "You can find this new password in /etc/yunohost/mysql." >&2 - - # set new password with debconf - debconf-set-selections << EOF -$MYSQL_PKG mysql-server/root_password password $mysql_password -$MYSQL_PKG mysql-server/root_password_again password $mysql_password -EOF - - # reconfigure Debian package - dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 - else - echo "It seems that you have already configured MySQL." \ - "YunoHost needs to have a root access to MySQL to runs its" \ - "applications, but the MySQL root password is unknown." \ - "You must either pass --force to reset the password or" \ - "put the current one into the file /etc/yunohost/mysql." >&2 - exit 1 - fi - } - - # store new root password - echo "$mysql_password" | tee /etc/yunohost/mysql - chmod 400 /etc/yunohost/mysql - fi - [[ -z "$regen_conf_files" ]] \ || service mysql restart } From 0f8a44028c4283248267991759eef59c20864724 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 21 Feb 2021 05:12:38 +0100 Subject: [PATCH 011/131] Replace \t in conf.json.persistent... --- src/yunohost/utils/legacy.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yunohost/utils/legacy.py b/src/yunohost/utils/legacy.py index c84817f98..0067fe05e 100644 --- a/src/yunohost/utils/legacy.py +++ b/src/yunohost/utils/legacy.py @@ -308,6 +308,9 @@ def translate_legacy_rules_in_ssowant_conf_json_persistent(): if not os.path.exists(persistent_file_name): return + # Ugly hack because for some reason so many people have tabs in their conf.json.persistent ... + os.system(r"sed -i 's/\t/ /g' /etc/ssowat/conf.json.persistent") + # Ugly hack to try not to misarably fail migration persistent = read_yaml(persistent_file_name) From 29bd3c4a26c3d77c2a09f126c9720867678b0300 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Thu, 11 Feb 2021 18:35:35 +0100 Subject: [PATCH 012/131] [fix] Avoid admin part of apps to be reachable from visitors --- src/yunohost/utils/legacy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/utils/legacy.py b/src/yunohost/utils/legacy.py index f3269cce1..ebc7b65de 100644 --- a/src/yunohost/utils/legacy.py +++ b/src/yunohost/utils/legacy.py @@ -189,7 +189,7 @@ def migrate_legacy_permission_settings(app=None): if protected_urls != []: permission_create(app + ".legacy_protected_uris", additional_urls=protected_urls, auth_header=True, label=legacy_permission_label(app, "protected"), - show_tile=False, allowed=user_permission_list()['permissions'][app + ".main"]['allowed'], + show_tile=False, allowed=[], protected=True, sync_perm=False) legacy_permission_settings = [ From cd4fdb2b61a64d99c270a370bb33cdebd1cd07c9 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 21 Feb 2021 05:03:07 +0100 Subject: [PATCH 013/131] Mysql is a fucking joke (... trying to fix the mysql issue on RPi ...) --- data/hooks/conf_regen/34-mysql | 63 ++++++++++++++-------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/data/hooks/conf_regen/34-mysql b/data/hooks/conf_regen/34-mysql index ac2395f34..d9374bbf5 100755 --- a/data/hooks/conf_regen/34-mysql +++ b/data/hooks/conf_regen/34-mysql @@ -15,6 +15,31 @@ do_pre_regen() { do_post_regen() { regen_conf_files=$1 + if [[ ! -d /var/lib/mysql/mysql ]] + then + # dpkg-reconfigure will initialize mysql (if it ain't already) + # It enabled auth_socket for root, so no need to define any root password... + # c.f. : cat /var/lib/dpkg/info/mariadb-server-10.3.postinst | grep install_db -C3 + dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 + + systemctl -q is-active mariadb.service \ + || systemctl start mariadb + + sleep 5 + + echo "" | mysql && echo "Can't connect to mysql using unix_socket auth ... something went wrong during initial configuration of mysql !?" + fi + + if [ ! -e /etc/yunohost/mysql ] + then + # Dummy password that's not actually used nor meaningful ... + # (because mysql is supposed to be configured to use unix_socket on new setups) + # but keeping it for legacy + # until we merge https://github.com/YunoHost/yunohost/pull/912 ... + ynh_string_random 10 > /etc/yunohost/mysql + chmod 400 /etc/yunohost/mysql + fi + # mysql is supposed to be an alias to mariadb... but in some weird case is not # c.f. https://forum.yunohost.org/t/mysql-ne-fonctionne-pas/11661 # Playing with enable/disable allows to recreate the proper symlinks. @@ -27,44 +52,6 @@ do_post_regen() { systemctl is-active mariadb -q || systemctl start mariadb fi - if [ ! -f /etc/yunohost/mysql ]; then - - # ensure that mysql is running - systemctl -q is-active mysql.service \ - || service mysql start - - # generate and set new root password - mysql_password=$(ynh_string_random 10) - mysqladmin -s -u root -pyunohost password "$mysql_password" || { - if [ $FORCE -eq 1 ]; then - echo "It seems that you have already configured MySQL." \ - "YunoHost needs to have a root access to MySQL to runs its" \ - "applications, and is going to reset the MySQL root password." \ - "You can find this new password in /etc/yunohost/mysql." >&2 - - # set new password with debconf - debconf-set-selections << EOF -$MYSQL_PKG mysql-server/root_password password $mysql_password -$MYSQL_PKG mysql-server/root_password_again password $mysql_password -EOF - - # reconfigure Debian package - dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 - else - echo "It seems that you have already configured MySQL." \ - "YunoHost needs to have a root access to MySQL to runs its" \ - "applications, but the MySQL root password is unknown." \ - "You must either pass --force to reset the password or" \ - "put the current one into the file /etc/yunohost/mysql." >&2 - exit 1 - fi - } - - # store new root password - echo "$mysql_password" | tee /etc/yunohost/mysql - chmod 400 /etc/yunohost/mysql - fi - [[ -z "$regen_conf_files" ]] \ || service mysql restart } From f398f463f4ef2e72a9f7fddac91a3c9118f4ff43 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 21 Feb 2021 05:12:38 +0100 Subject: [PATCH 014/131] Replace \t in conf.json.persistent... --- src/yunohost/utils/legacy.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yunohost/utils/legacy.py b/src/yunohost/utils/legacy.py index ebc7b65de..c3f7ab5a9 100644 --- a/src/yunohost/utils/legacy.py +++ b/src/yunohost/utils/legacy.py @@ -215,6 +215,9 @@ def translate_legacy_rules_in_ssowant_conf_json_persistent(): if not os.path.exists(persistent_file_name): return + # Ugly hack because for some reason so many people have tabs in their conf.json.persistent ... + os.system(r"sed -i 's/\t/ /g' /etc/ssowat/conf.json.persistent") + # Ugly hack to try not to misarably fail migration persistent = read_yaml(persistent_file_name) From 1846c3a07b314d25f7a58e1fa79a92a1c8c12d99 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 21 Feb 2021 05:28:30 +0100 Subject: [PATCH 015/131] Update changelog for 4.1.7.2 --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index 4e893dee0..95cca2eb8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +yunohost (4.1.7.2) testing; urgency=low + + - [fix] When migration legacy protected permissions, all users were allowed on the new perm (29bd3c4a) + - [fix] Mysql is a fucking joke (... trying to fix the mysql issue on RPi ...) (cd4fdb2b) + - [fix] Replace \t when converting legacy conf.json.persistent... (f398f463) + + Thanks to all contributors <3 ! (ljf) + + -- Alexandre Aubin Sun, 21 Feb 2021 05:25:49 +0100 + yunohost (4.1.7.1) stable; urgency=low - [enh] helpers: Fix ynh_exec_as regression (ac38e53a7) From 1adff77e3ae241b18bd383ce27d9e04a1c12d099 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 3 Jan 2021 18:19:30 +0100 Subject: [PATCH 016/131] Add multimedia helpers and hooks --- data/helpers.d/multimedia | 87 ++++++++++++++++++++++ data/hooks/post_user_create/ynh_multimedia | 28 +++++++ data/hooks/post_user_delete/ynh_multimedia | 8 ++ debian/control | 1 + 4 files changed, 124 insertions(+) create mode 100644 data/helpers.d/multimedia create mode 100644 data/hooks/post_user_create/ynh_multimedia create mode 100644 data/hooks/post_user_delete/ynh_multimedia diff --git a/data/helpers.d/multimedia b/data/helpers.d/multimedia new file mode 100644 index 000000000..5517917b5 --- /dev/null +++ b/data/helpers.d/multimedia @@ -0,0 +1,87 @@ +readonly MEDIA_GROUP=multimedia +readonly MEDIA_DIRECTORY=/home/yunohost.multimedia + +# Initialize the multimedia directory system +# +# usage: ynh_multimedia_build_main_dir +ynh_multimedia_build_main_dir() { + + ## Création du groupe multimedia + groupadd -f $MEDIA_GROUP + + ## Création des dossiers génériques + mkdir -p "$MEDIA_DIRECTORY" + mkdir -p "$MEDIA_DIRECTORY/share" + mkdir -p "$MEDIA_DIRECTORY/share/Music" + mkdir -p "$MEDIA_DIRECTORY/share/Picture" + mkdir -p "$MEDIA_DIRECTORY/share/Video" + mkdir -p "$MEDIA_DIRECTORY/share/eBook" + + ## Création des dossiers utilisateurs + for user in $(yunohost user list --output-as json | jq -r '.users | keys[]') + do + mkdir -p "$MEDIA_DIRECTORY/$user" + mkdir -p "$MEDIA_DIRECTORY/$user/Music" + mkdir -p "$MEDIA_DIRECTORY/$user/Picture" + mkdir -p "$MEDIA_DIRECTORY/$user/Video" + mkdir -p "$MEDIA_DIRECTORY/$user/eBook" + ln -sfn "$MEDIA_DIRECTORY/share" "$MEDIA_DIRECTORY/$user/Share" + # Création du lien symbolique dans le home de l'utilisateur. + ln -sfn "$MEDIA_DIRECTORY/$user" "/home/$user/Multimedia" + # Propriétaires des dossiers utilisateurs. + chown -R $user "$MEDIA_DIRECTORY/$user" + done + # Default yunohost hooks for post_user_create,delete will take care + # of creating/deleting corresponding multimedia folders when users + # are created/deleted in the future... + + ## Application des droits étendus sur le dossier multimedia. + # Droit d'écriture pour le groupe et le groupe multimedia en acl et droit de lecture pour other: + setfacl -RnL -m g:$MEDIA_GROUP:rwX,g::rwX,o:r-X "$MEDIA_DIRECTORY" + # Application de la même règle que précédemment, mais par défaut pour les nouveaux fichiers. + setfacl -RnL -m d:g:$MEDIA_GROUP:rwX,g::rwX,o:r-X "$MEDIA_DIRECTORY" + # Réglage du masque par défaut. Qui garantie (en principe...) un droit maximal à rwx. Donc pas de restriction de droits par l'acl. + setfacl -RL -m m::rwx "$MEDIA_DIRECTORY" +} + +# Add a directory in yunohost.multimedia +# This "directory" will be a symbolic link to a existing directory. +# +# usage: ynh_multimedia_addfolder "Source directory" "Destination directory" +# +# | arg: -s, --source_dir= - Source directory - The real directory which contains your medias. +# | arg: -d, --dest_dir= - Destination directory - The name and the place of the symbolic link, relative to "/home/yunohost.multimedia" +ynh_multimedia_addfolder() { + + # Declare an array to define the options of this helper. + declare -Ar args_array=( [s]=source_dir= [d]=dest_dir= ) + local source_dir + local dest_dir + + # Ajout d'un lien symbolique vers le dossier à partager + ln -sfn "$source_dir" "$MEDIA_DIRECTORY/$dest_dir" + + ## Application des droits étendus sur le dossier ajouté + # Droit d'écriture pour le groupe et le groupe multimedia en acl et droit de lecture pour other: + setfacl -RnL -m g:$MEDIA_GROUP:rwX,g::rwX,o:r-X "$source_dir" + # Application de la même règle que précédemment, mais par défaut pour les nouveaux fichiers. + setfacl -RnL -m d:g:$MEDIA_GROUP:rwX,g::rwX,o:r-X "$source_dir" + # Réglage du masque par défaut. Qui garantie (en principe...) un droit maximal à rwx. Donc pas de restriction de droits par l'acl. + setfacl -RL -m m::rwx "$source_dir" +} + +# Allow an user to have an write authorisation in multimedia directories +# +# usage: ynh_multimedia_addaccess user_name +# +# | arg: -u, --user_name= - The name of the user which gain this access. +ynh_multimedia_addaccess () { + # Declare an array to define the options of this helper. + declare -Ar args_array=( [u]=user_name=) + local user_name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + groupadd -f multimedia + usermod -a -G multimedia $user_name +} diff --git a/data/hooks/post_user_create/ynh_multimedia b/data/hooks/post_user_create/ynh_multimedia new file mode 100644 index 000000000..560e6a293 --- /dev/null +++ b/data/hooks/post_user_create/ynh_multimedia @@ -0,0 +1,28 @@ +#!/bin/bash + +user=$1 + +readonly MEDIA_GROUP=multimedia +readonly MEDIA_DIRECTORY=/home/yunohost.multimedia + +# We only do this if multimedia directory is enabled (= the folder exists) +[ -e "$MEDIA_DIRECTORY" ] || exit + +mkdir -p "$MEDIA_DIRECTORY/$user" +mkdir -p "$MEDIA_DIRECTORY/$user/Music" +mkdir -p "$MEDIA_DIRECTORY/$user/Picture" +mkdir -p "$MEDIA_DIRECTORY/$user/Video" +mkdir -p "$MEDIA_DIRECTORY/$user/eBook" +ln -sfn "$MEDIA_DIRECTORY/share" "$MEDIA_DIRECTORY/$user/Share" +# Création du lien symbolique dans le home de l'utilisateur. +ln -sfn "$MEDIA_DIRECTORY/$user" "/home/$user/Multimedia" +# Propriétaires des dossiers utilisateurs. +chown -R $user "$MEDIA_DIRECTORY/$user" + +## Application des droits étendus sur le dossier multimedia. +# Droit d'écriture pour le groupe et le groupe multimedia en acl et droit de lecture pour other: +setfacl -RnL -m g:$MEDIA_GROUP:rwX,g::rwX,o:r-X "$MEDIA_DIRECTORY/$user" +# Application de la même règle que précédemment, mais par défaut pour les nouveaux fichiers. +setfacl -RnL -m d:g:$MEDIA_GROUP:rwX,g::rwX,o:r-X "$MEDIA_DIRECTORY/$user" +# Réglage du masque par défaut. Qui garantie (en principe...) un droit maximal à rwx. Donc pas de restriction de droits par l'acl. +setfacl -RL -m m::rwx "$MEDIA_DIRECTORY/$user" diff --git a/data/hooks/post_user_delete/ynh_multimedia b/data/hooks/post_user_delete/ynh_multimedia new file mode 100644 index 000000000..af06e1637 --- /dev/null +++ b/data/hooks/post_user_delete/ynh_multimedia @@ -0,0 +1,8 @@ +#!/bin/bash + +user=$1 +MEDIA_DIRECTORY=/home/yunohost.multimedia + +if [ -n "$user" ] && [ -e "$MEDIA_DIRECTORY/$user" ]; then + sudo rm -r "$MEDIA_DIRECTORY/$user" +fi diff --git a/debian/control b/debian/control index d95b17f4e..7275cb7b1 100644 --- a/debian/control +++ b/debian/control @@ -26,6 +26,7 @@ Depends: ${python3:Depends}, ${misc:Depends} , rspamd, opendkim-tools, postsrsd, procmail, mailutils , redis-server , metronome (>=3.14.0) + , acl , git, curl, wget, cron, unzip, jq, bc , lsb-release, haveged, fake-hwclock, equivs, lsof, whois Recommends: yunohost-admin From 29b511f5e375beb313aa9cf3d37e1ff840cdca2f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Feb 2021 23:42:52 +0100 Subject: [PATCH 017/131] Fix multimedia hook if not media directory yet --- data/hooks/post_user_create/ynh_multimedia | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/hooks/post_user_create/ynh_multimedia b/data/hooks/post_user_create/ynh_multimedia index 560e6a293..441212bbc 100644 --- a/data/hooks/post_user_create/ynh_multimedia +++ b/data/hooks/post_user_create/ynh_multimedia @@ -6,7 +6,7 @@ readonly MEDIA_GROUP=multimedia readonly MEDIA_DIRECTORY=/home/yunohost.multimedia # We only do this if multimedia directory is enabled (= the folder exists) -[ -e "$MEDIA_DIRECTORY" ] || exit +[ -e "$MEDIA_DIRECTORY" ] || exit 0 mkdir -p "$MEDIA_DIRECTORY/$user" mkdir -p "$MEDIA_DIRECTORY/$user/Music" From 59da04e92b172de23f19f1c8546aa20c8be63e26 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Feb 2021 23:46:12 +0100 Subject: [PATCH 018/131] Gotta escape \ during ynh_replace_vars --- data/helpers.d/utils | 1 + 1 file changed, 1 insertion(+) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 13f84424e..a23d06d2c 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -401,6 +401,7 @@ ynh_replace_vars () { match_string="__${one_var^^}__" match_string=${match_string//${delimit}/"\\${delimit}"} replace_string="${!one_var}" + replace_string=${replace_string//\\/\\\\} replace_string=${replace_string//${delimit}/"\\${delimit}"} # Actually replace (sed is used instead of ynh_replace_string to avoid triggering an epic amount of debug logs) From acfea3d76d0a675815e8bf5019e3c69013af58a1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 23 Feb 2021 02:17:04 +0100 Subject: [PATCH 019/131] Define YNH_APP_BASEDIR to be able to properly point to conf folder depending on the app script we're running --- data/helpers.d/fail2ban | 8 ++++---- data/helpers.d/nginx | 6 +++--- data/helpers.d/php | 19 ++++++++----------- data/helpers.d/systemd | 2 +- data/helpers.d/utils | 15 +++++---------- src/yunohost/backup.py | 10 ++++------ 6 files changed, 25 insertions(+), 35 deletions(-) diff --git a/data/helpers.d/fail2ban b/data/helpers.d/fail2ban index da090d2f9..c41226e14 100644 --- a/data/helpers.d/fail2ban +++ b/data/helpers.d/fail2ban @@ -87,7 +87,7 @@ port = __PORTS__ filter = __APP__ logpath = __LOGPATH__ maxretry = __MAX_RETRY__ -" > ../conf/f2b_jail.conf +" > $YNH_APP_BASEDIR/conf/f2b_jail.conf echo " [INCLUDES] @@ -95,11 +95,11 @@ before = common.conf [Definition] failregex = __FAILREGEX__ ignoreregex = -" > ../conf/f2b_filter.conf +" > $YNH_APP_BASEDIR/conf/f2b_filter.conf fi - ynh_add_config --template="../conf/f2b_jail.conf" --destination="/etc/fail2ban/jail.d/$app.conf" - ynh_add_config --template="../conf/f2b_filter.conf" --destination="/etc/fail2ban/filter.d/$app.conf" + ynh_add_config --template="$YNH_APP_BASEDIR/conf/f2b_jail.conf" --destination="/etc/fail2ban/jail.d/$app.conf" + ynh_add_config --template="$YNH_APP_BASEDIR/conf/f2b_filter.conf" --destination="/etc/fail2ban/filter.d/$app.conf" ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd diff --git a/data/helpers.d/nginx b/data/helpers.d/nginx index f7157cd8d..3c6254953 100644 --- a/data/helpers.d/nginx +++ b/data/helpers.d/nginx @@ -22,12 +22,12 @@ ynh_add_nginx_config () { if [ "${path_url:-}" != "/" ] then - ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="../conf/nginx.conf" + ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf" else - ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="../conf/nginx.conf" + ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf" fi - ynh_add_config --template="../conf/nginx.conf" --destination="$finalnginxconf" + ynh_add_config --template="$YNH_APP_BASEDIR/conf/nginx.conf" --destination="$finalnginxconf" ynh_systemd_action --service_name=nginx --action=reload diff --git a/data/helpers.d/php b/data/helpers.d/php index 0e1ac48b0..683f252be 100644 --- a/data/helpers.d/php +++ b/data/helpers.d/php @@ -153,10 +153,7 @@ ynh_add_fpm_config () { if [ $use_template -eq 1 ] then # Usage 1, use the template in conf/php-fpm.conf - local phpfpm_path="../conf/php-fpm.conf" - if [ ! -e "$phpfpm_path" ]; then - phpfpm_path="../settings/conf/php-fpm.conf" # Into the restore script, the PHP-FPM template is not at the same place - fi + local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf" # Make sure now that the template indeed exists [ -e "$phpfpm_path" ] || ynh_die --message="Unable to find template to configure PHP-FPM." else @@ -169,7 +166,7 @@ ynh_add_fpm_config () { # Define the values to use for the configuration of PHP. ynh_get_scalable_phpfpm --usage=$usage --footprint=$footprint - local phpfpm_path="../conf/php-fpm.conf" + local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf" echo " [__APP__] @@ -204,18 +201,18 @@ pm.process_idle_timeout = 10s fi # Concatene the extra config. - if [ -e ../conf/extra_php-fpm.conf ]; then - cat ../conf/extra_php-fpm.conf >> "$phpfpm_path" + if [ -e $YNH_APP_BASEDIR/conf/extra_php-fpm.conf ]; then + cat $YNH_APP_BASEDIR/conf/extra_php-fpm.conf >> "$phpfpm_path" fi fi local finalphpconf="$fpm_config_dir/pool.d/$app.conf" ynh_add_config --template="$phpfpm_path" --destination="$finalphpconf" - if [ -e "../conf/php-fpm.ini" ] + if [ -e "$YNH_APP_BASEDIR/conf/php-fpm.ini" ] then ynh_print_warn --message="Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead." - ynh_add_config --template="../conf/php-fpm.ini" --destination="$fpm_config_dir/conf.d/20-$app.ini" + ynh_add_config --template="$YNH_APP_BASEDIR/conf/php-fpm.ini" --destination="$fpm_config_dir/conf.d/20-$app.ini" fi if [ $dedicated_service -eq 1 ] @@ -228,7 +225,7 @@ pid = /run/php/php__PHPVERSION__-fpm-__APP__.pid error_log = /var/log/php/fpm-php.__APP__.log syslog.ident = php-fpm-__APP__ include = __FINALPHPCONF__ -" > ../conf/php-fpm-$app.conf +" > $YNH_APP_BASEDIR/conf/php-fpm-$app.conf ynh_add_config --template="../config/php-fpm-$app.conf" --destination="$globalphpconf" @@ -245,7 +242,7 @@ ExecReload=/bin/kill -USR2 \$MAINPID [Install] WantedBy=multi-user.target -" > ../conf/$fpm_service +" > $YNH_APP_BASEDIR/conf/$fpm_service # Create this dedicated PHP-FPM service ynh_add_systemd_config --service=$fpm_service --template=$fpm_service diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index 493a724a9..b416e5745 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -22,7 +22,7 @@ ynh_add_systemd_config () { local service="${service:-$app}" local template="${template:-systemd.service}" - ynh_add_config --template="../conf/$template" --destination="/etc/systemd/system/$service.service" + ynh_add_config --template="$YNH_APP_BASEDIR/conf/$template" --destination="/etc/systemd/system/$service.service" systemctl enable $service --quiet systemctl daemon-reload diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 13f84424e..1bdbc98cd 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -1,5 +1,7 @@ #!/bin/bash +YNH_APP_BASEDIR=$([[ "$(basename $0)" =~ ^backup|restore$ ]] && echo '../settings' || echo '..') + # Handle script crashes / failures # # [internal] @@ -112,12 +114,7 @@ ynh_setup_source () { ynh_handle_getopts_args "$@" source_id="${source_id:-app}" # If the argument is not given, source_id equals "app" - local src_file_path="$YNH_CWD/../conf/${source_id}.src" - # In case of restore script the src file is in an other path. - # So try to use the restore path if the general path point to no file. - if [ ! -e "$src_file_path" ]; then - src_file_path="$YNH_CWD/../settings/conf/${source_id}.src" - fi + local src_file_path="$YNH_APP_BASEDIR/conf/${source_id}.src" # Load value from configuration file (see above for a small doc about this file # format) @@ -309,10 +306,8 @@ ynh_add_config () { ynh_handle_getopts_args "$@" local template_path - if [ -f "../conf/$template" ]; then - template_path="../conf/$template" - elif [ -f "../settings/conf/$template" ]; then - template_path="../settings/conf/$template" + if [ -f "$YNH_APP_BASEDIR/conf/$template" ]; then + template_path="$YNH_APP_BASEDIR/conf/$template" elif [ -f "$template" ]; then template_path=$template else diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 50765ba5f..408cd6f15 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -704,9 +704,7 @@ class BackupManager: settings_dir = os.path.join(self.work_dir, "apps", app, "settings") logger.info(m18n.n("app_start_backup", app=app)) - tmp_script = ( - None # This is to make sure the var exists later in the 'finally' ... - ) + tmp_folder = tempfile.mkdtemp() try: # Prepare backup directory for the app filesystem.mkdir(tmp_app_bkp_dir, 0o750, True, uid="admin") @@ -715,8 +713,8 @@ class BackupManager: shutil.copytree(app_setting_path, settings_dir) # Copy app backup script in a temporary folder and execute it - _, tmp_script = tempfile.mkstemp(prefix="backup_") app_script = os.path.join(app_setting_path, "scripts/backup") + tmp_script = os.path.join(tmp_folder, "backup") subprocess.call(["install", "-Dm555", app_script, tmp_script]) hook_exec( @@ -752,8 +750,8 @@ class BackupManager: # Remove tmp files in all situations finally: - if tmp_script: - filesystem.rm(tmp_script, force=True) + if tmp_folder and os.path.exists(tmp_folder): + shutil.rmtree(tmp_folder) filesystem.rm(env_dict["YNH_BACKUP_CSV"], force=True) # From 4168a9d19348232beacf03b05a5f1e1705b7e3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20Kroul=C3=ADk?= Date: Sat, 23 Jan 2021 20:58:00 +0000 Subject: [PATCH 020/131] Translated using Weblate (Czech) Currently translated at 0.1% (1 of 631 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/cs/ --- locales/cs.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/cs.json b/locales/cs.json index 0967ef424..eafada5e6 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -1 +1,3 @@ -{} +{ + "password_too_simple_1": "Heslo musí být aspoň 8 znaků dlouhé" +} From 7f8a4c16aef87cb7ccf0a9e70704cbc1a2d65787 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Mon, 25 Jan 2021 19:26:28 +0000 Subject: [PATCH 021/131] Translated using Weblate (German) Currently translated at 63.3% (400 of 631 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/de.json b/locales/de.json index efc25f7c5..982de116b 100644 --- a/locales/de.json +++ b/locales/de.json @@ -60,14 +60,14 @@ "dyndns_key_generating": "Generierung des DNS-Schlüssels..., das könnte eine Weile dauern.", "dyndns_registered": "DynDNS Domain registriert", "dyndns_registration_failed": "DynDNS Domain konnte nicht registriert werden: {error:s}", - "dyndns_unavailable": "DynDNS Subdomain ist nicht verfügbar", + "dyndns_unavailable": "Die Domäne {domain:s} ist nicht verfügbar.", "executing_command": "Führe den Behfehl '{command:s}' aus…", "executing_script": "Skript '{script:s}' wird ausgeührt…", - "extracting": "Wird entpackt…", + "extracting": "Wird entpackt...", "field_invalid": "Feld '{:s}' ist unbekannt", "firewall_reload_failed": "Die Firewall konnte nicht neu geladen werden", "firewall_reloaded": "Die Firewall wurde neu geladen", - "firewall_rules_cmd_failed": "Einzelne Firewallregeln konnten nicht übernommen werden. Mehr Informationen sind im Log zu finden.", + "firewall_rules_cmd_failed": "Einige Befehle für die Firewallregeln konnten nicht ausgeführt werden. Mehr Informationen sind im Log zu finden.", "hook_exec_failed": "Skriptausführung fehlgeschlagen: {path:s}", "hook_exec_not_terminated": "Skriptausführung noch nicht beendet: {path:s}", "hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks", @@ -204,10 +204,10 @@ "app_change_url_success": "{app:s} URL ist nun {domain:s}{path:s}", "backup_applying_method_borg": "Sende alle Dateien zur Sicherung ins borg-backup repository...", "global_settings_bad_type_for_setting": "Falscher Typ für Einstellung {setting:s}. Empfangen: {received_type:s}, aber erwartet: {expected_type:s}", - "global_settings_bad_choice_for_enum": "Falsche Wahl für die Einstellung {setting:s}. Habe '{choice:s}' erhalten, aber es stehen nur folgende Auswahlmöglichkeiten zur Verfügung: {available_choices:s}", + "global_settings_bad_choice_for_enum": "Der Wert dieses Einstellungsparameters {setting:s} ist ungültig. Der Wert den Sie eingegeben haben: '{choice:s}', die gültigen Werte für diese Einstellung: {available_choices:s}", "file_does_not_exist": "Die Datei {path:s} existiert nicht.", "experimental_feature": "Warnung: Diese Funktion ist experimentell und gilt nicht als stabil. Sie sollten sie nur verwenden, wenn Sie wissen, was Sie tun.", - "dyndns_domain_not_provided": "Der DynDNS-Anbieter {provider:s} kann die Domain(s) {domain:s} nicht bereitstellen.", + "dyndns_domain_not_provided": "Der DynDNS-Anbieter {provider:s} kann die Domäne(n) {domain:s} nicht bereitstellen.", "dyndns_could_not_check_available": "Konnte nicht überprüfen, ob {domain:s} auf {provider:s} verfügbar ist.", "dyndns_could_not_check_provide": "Konnte nicht überprüft, ob {provider:s} die Domain(s) {domain:s} bereitstellen kann.", "domain_dns_conf_is_just_a_recommendation": "Dieser Befehl zeigt Ihnen die * empfohlene * Konfiguration. Die DNS-Konfiguration wird NICHT für Sie eingerichtet. Es liegt in Ihrer Verantwortung, Ihre DNS-Zone in Ihrem Registrar gemäß dieser Empfehlung zu konfigurieren.", From 7d4ef2b14224328b763fa0bdf6e6ebd9745997b1 Mon Sep 17 00:00:00 2001 From: Mathieu Massaviol Date: Thu, 28 Jan 2021 09:44:51 +0000 Subject: [PATCH 022/131] Translated using Weblate (French) Currently translated at 100.0% (631 of 631 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index b65268fb7..dfe2e372e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -54,7 +54,7 @@ "domain_dyndns_already_subscribed": "Vous avez déjà souscris à un domaine DynDNS", "domain_dyndns_root_unknown": "Domaine DynDNS principal inconnu", "domain_exists": "Le domaine existe déjà", - "domain_uninstall_app_first": "Ces applications sont toujours installées sur votre domaine :\n{apps}\n\nAfin de pouvoir procéder à la suppression du domaine, vous devez préalablement :\n- soit désinstaller toutes ces applications avec la commande 'yunohost app remove nom-de-l-application' ;\n- soit déplacer toutes ces applications vers un autre domaine avec la commande 'yunohost app change-url nom-de-l-application'", + "domain_uninstall_app_first": "Ces applications sont toujours installées sur votre domaine :\n{apps}\n\nVeuillez les désinstaller avec la commande 'yunohost app remove nom-de-l-application' ou les déplacer vers un autre domaine avec la commande 'yunohost app change-url nom-de-l-application' avant de procéder à la suppression du domaine", "domain_unknown": "Domaine inconnu", "done": "Terminé", "downloading": "Téléchargement en cours …", @@ -327,7 +327,7 @@ "password_too_simple_3": "Le mot de passe doit comporter au moins 8 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "password_too_simple_4": "Le mot de passe doit comporter au moins 12 caractères et contenir des chiffres, des majuscules, des minuscules et des caractères spéciaux", "root_password_desynchronized": "Le mot de passe administrateur a été changé, mais YunoHost n’a pas pu le propager au mot de passe root !", - "aborting": "Annulation.", + "aborting": "Annulation en cours.", "app_not_upgraded": "L’application {failed_app} n’a pas été mise à jour et par conséquence les applications suivantes n’ont pas été mises à jour : {apps}", "app_start_install": "Installation de {app}...", "app_start_remove": "Suppression de {app}...", From c6974932b44bc07ff3cf0a1f874d47ec6175db9b Mon Sep 17 00:00:00 2001 From: ppr Date: Thu, 28 Jan 2021 09:41:44 +0000 Subject: [PATCH 023/131] Translated using Weblate (French) Currently translated at 100.0% (631 of 631 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index dfe2e372e..7d016a70e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -650,7 +650,7 @@ "migration_description_0018_xtable_to_nftable": "Migrer les anciennes règles de trafic réseau vers le nouveau système basé sur nftables", "service_description_php7.3-fpm": "Exécute les applications écrites en PHP avec NGINX", "migration_0018_failed_to_reset_legacy_rules": "La réinitialisation des règles iptable par défaut a échoué : {error}", - "migration_0018_failed_to_migrate_iptables_rules": "La migration des règles iptables héritées vers nftables a échoué: {error}", + "migration_0018_failed_to_migrate_iptables_rules": "Échec de la migration des anciennes règles iptables vers nftables : {error}", "migration_0017_not_enough_space": "Laissez suffisamment d'espace disponible dans {path} avant de lancer la migration.", "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 est installé mais pas posgreSQL 11 ? Il s'est sans doute passé quelque chose d'étrange sur votre système :(...", "migration_0017_postgresql_96_not_installed": "PostgreSQL n'a pas été installé sur votre système. Aucune opération à effectuer.", From 6880a6f01741f3f88a7aeff0bf42db0002d3b66d Mon Sep 17 00:00:00 2001 From: Yifei Ding Date: Sun, 31 Jan 2021 09:36:34 +0000 Subject: [PATCH 024/131] Translated using Weblate (Chinese (Simplified)) Currently translated at 2.2% (14 of 631 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/zh_Hans/ --- locales/zh_Hans.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/zh_Hans.json b/locales/zh_Hans.json index d11e570d0..e72cd52da 100644 --- a/locales/zh_Hans.json +++ b/locales/zh_Hans.json @@ -2,7 +2,7 @@ "password_too_simple_1": "密码长度至少为8个字符", "backup_created": "备份已创建", "app_start_remove": "正在删除{app}……", - "admin_password_change_failed": "不能修改密码", + "admin_password_change_failed": "无法修改密码", "admin_password_too_long": "请选择一个小于127个字符的密码", "app_upgrade_failed": "不能升级{app:s}:{error}", "app_id_invalid": "无效 app ID", From a7152e2c69ac07aaaed15b1f78303164d3d1f6c7 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Mon, 1 Feb 2021 19:22:02 +0000 Subject: [PATCH 025/131] Translated using Weblate (German) Currently translated at 63.6% (402 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 982de116b..23f9bc217 100644 --- a/locales/de.json +++ b/locales/de.json @@ -489,5 +489,7 @@ "global_settings_setting_smtp_relay_port": "SMTP Relay Port", "global_settings_setting_smtp_allow_ipv6": "Erlaube die Nutzung von IPv6 um Mails zu empfangen und zu versenden", "global_settings_setting_pop3_enabled": "Aktiviere das POP3 Protokoll für den Mailserver", - "domain_cannot_remove_main_add_new_one": "Du kannst \"{domain:s}\" nicht entfernen da es die Hauptdomain und deine einzige Domain ist, erst musst erst eine andere Domain hinzufügen indem du eingibst \"yunohost domain add \", setze es dann als deine Hauptdomain indem du eingibst \"yunohost domain main-domain -n \", erst jetzt kannst du die domain \"{domain:s}\" entfernen." + "domain_cannot_remove_main_add_new_one": "Du kannst \"{domain:s}\" nicht entfernen da es die Hauptdomain und deine einzige Domain ist, erst musst erst eine andere Domain hinzufügen indem du eingibst \"yunohost domain add \", setze es dann als deine Hauptdomain indem du eingibst \"yunohost domain main-domain -n \", erst jetzt kannst du die domain \"{domain:s}\" entfernen.", + "diagnosis_rootfstotalspace_critical": "Das Root-Filesystem hat noch freien Speicher von {space}. Das ist besorngiserregend! Der Speicher wird schnell aufgebraucht sein. 16 GB für das Root-Filesystem werden empfohlen.", + "diagnosis_rootfstotalspace_warning": "Das Root-Filesystem hat noch freien Speicher von {space}. Möglich, dass das in Ordnung ist. Vielleicht ist er aber auch schneller aufgebraucht. 16 GB für das Root-Filesystem werden empfohlen." } From d5f82856c6c0db3665fbdffcb76ff21b08f9eae8 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Tue, 2 Feb 2021 11:15:12 +0000 Subject: [PATCH 026/131] Translated using Weblate (German) Currently translated at 63.6% (402 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/de.json b/locales/de.json index 23f9bc217..13534f5f3 100644 --- a/locales/de.json +++ b/locales/de.json @@ -170,9 +170,9 @@ "certmanager_certificate_fetching_or_enabling_failed": "Die Aktivierung des neuen Zertifikats für die {domain:s} ist fehlgeschlagen...", "certmanager_attempt_to_renew_nonLE_cert": "Das Zertifikat der Domain '{domain:s}' wurde nicht von Let's Encrypt ausgestellt. Es kann nicht automatisch erneuert werden!", "certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain:s} läuft nicht in Kürze ab! (Benutze --force um diese Nachricht zu umgehen)", - "certmanager_domain_http_not_working": "Die Domäne {domain:s} scheint über HTTP nicht erreichbar zu sein. Für weitere Informationen überprüfen Sie bitte die Kategorie 'Web' im Diagnose-Bereich. (Wenn Sie wißen was Sie tun, nutzen Sie '--no-checks' um die Überprüfung zu überspringen.)", + "certmanager_domain_http_not_working": "Es scheint so, dass die Domain {domain:s} nicht über HTTP erreicht werden kann. Bitte überprüfe, ob deine DNS und nginx Konfiguration in Ordnung ist. (Wenn du weißt was du tust, nutze \"--no-checks\" um die überprüfung zu überspringen.)", "certmanager_error_no_A_record": "Kein DNS 'A' Eintrag für die Domain {domain:s} gefunden. Dein Domainname muss auf diese Maschine weitergeleitet werden, um ein Let's Encrypt Zertifikat installieren zu können! (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )", - "certmanager_domain_dns_ip_differs_from_public_ip": "Die DNS-Einträge der Domäne {domain:s} unterscheiden sich von der IP dieses Servers. Wenn Sie gerade Ihren A-Eintrag verändert haben, warten Sie bitte etwas, damit die Änderungen wirksam werden (Sie können die DNS Propagation mittels Website überprüfen) (Wenn Sie wißen was Sie tun, können Sie --no-checks benutzen, um diese Überprüfung zu überspringen. )", + "certmanager_domain_dns_ip_differs_from_public_ip": "Der DNS 'A' Eintrag der Domain {domain:s} unterscheidet sich von dieser Server-IP. Für weitere Informationen überprüfe bitte die 'DNS records' (basic) Kategorie in der Diagnose. Wenn du gerade deinen A Eintrag verändert hast, warte bitte etwas, damit die Änderungen wirksam werden (du kannst die DNS Propagation mittels Website überprüfen) (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )", "certmanager_cannot_read_cert": "Es ist ein Fehler aufgetreten, als es versucht wurde das aktuelle Zertifikat für die Domain {domain:s} zu öffnen (Datei: {file:s}), Grund: {reason:s}", "certmanager_cert_install_success_selfsigned": "Ein selbstsigniertes Zertifikat für die Domain {domain:s} wurde erfolgreich installiert", "certmanager_cert_install_success": "Für die Domain {domain:s} wurde erfolgreich ein Let's Encrypt Zertifikat installiert.", @@ -377,7 +377,7 @@ "service_reloaded_or_restarted": "Der Dienst '{service:s}' wurde erfolgreich neu geladen oder gestartet", "service_restarted": "Der Dienst '{service:s}' wurde neu gestartet", "service_regen_conf_is_deprecated": "'yunohost service regen-conf' ist veraltet! Bitte verwenden Sie stattdessen 'yunohost tools regen-conf'.", - "certmanager_warning_subdomain_dns_record": "Die Subdomain '{subdomain:s}' löst nicht dieselbe IP wie '{domain:s} auf. Einige Funktionen werden nicht verfügbar sein, solange Sie dies nicht beheben und das Zertifikat erneuern.", + "certmanager_warning_subdomain_dns_record": "Die Subdomäne \"{subdomain:s}\" löst nicht zur gleichen IP Adresse auf wie \"{domain:s}\". Einige Funktionen sind nicht verfügbar bis du dies behebst und die Zertifikate neu erzeugst.", "diagnosis_ports_ok": "Port {port} ist von außen erreichbar.", "diagnosis_ram_verylow": "Das System hat nur {available} ({available_percent}%) RAM zur Verfügung! (von insgesamt {total})", "diagnosis_mail_outgoing_port_25_blocked_details": "Sie sollten zuerst versuchen den ausgehenden Port 25 auf Ihrer Router-Konfigurationsoberfläche oder Ihrer Hosting-Anbieter-Konfigurationsoberfläche zu öffnen. (Bei einigen Hosting-Anbieter kann es sein, daß Sie verlangen, daß man dafür ein Support-Ticket sendet).", From 0ff75e1e2274747fe7ee027ed811c078629a89cc Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 3 Feb 2021 06:40:20 +0000 Subject: [PATCH 027/131] Translated using Weblate (German) Currently translated at 64.5% (408 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/locales/de.json b/locales/de.json index 13534f5f3..a979031b3 100644 --- a/locales/de.json +++ b/locales/de.json @@ -65,9 +65,9 @@ "executing_script": "Skript '{script:s}' wird ausgeührt…", "extracting": "Wird entpackt...", "field_invalid": "Feld '{:s}' ist unbekannt", - "firewall_reload_failed": "Die Firewall konnte nicht neu geladen werden", - "firewall_reloaded": "Die Firewall wurde neu geladen", - "firewall_rules_cmd_failed": "Einige Befehle für die Firewallregeln konnten nicht ausgeführt werden. Mehr Informationen sind im Log zu finden.", + "firewall_reload_failed": "Firewall konnte nicht neu geladen werden", + "firewall_reloaded": "Firewall neu geladen", + "firewall_rules_cmd_failed": "Einige Befehle für die Firewallregeln sind gescheitert. Mehr Informationen im Log.", "hook_exec_failed": "Skriptausführung fehlgeschlagen: {path:s}", "hook_exec_not_terminated": "Skriptausführung noch nicht beendet: {path:s}", "hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks", @@ -203,10 +203,10 @@ "backup_archive_writing_error": "Die Dateien '{source:s} (im Ordner '{dest:s}') konnten nicht in das komprimierte Archiv-Backup '{archive:s}' hinzugefügt werden", "app_change_url_success": "{app:s} URL ist nun {domain:s}{path:s}", "backup_applying_method_borg": "Sende alle Dateien zur Sicherung ins borg-backup repository...", - "global_settings_bad_type_for_setting": "Falscher Typ für Einstellung {setting:s}. Empfangen: {received_type:s}, aber erwartet: {expected_type:s}", - "global_settings_bad_choice_for_enum": "Der Wert dieses Einstellungsparameters {setting:s} ist ungültig. Der Wert den Sie eingegeben haben: '{choice:s}', die gültigen Werte für diese Einstellung: {available_choices:s}", - "file_does_not_exist": "Die Datei {path:s} existiert nicht.", - "experimental_feature": "Warnung: Diese Funktion ist experimentell und gilt nicht als stabil. Sie sollten sie nur verwenden, wenn Sie wissen, was Sie tun.", + "global_settings_bad_type_for_setting": "Falscher Typ der Einstellung {setting:s}. Empfangen: {received_type:s}, aber erwarteter Typ: {expected_type:s}", + "global_settings_bad_choice_for_enum": "Wert des Einstellungsparameters {setting:s} ungültig. Der Wert den Sie eingegeben haben: '{choice:s}', die gültigen Werte für diese Einstellung: {available_choices:s}", + "file_does_not_exist": "Die Datei {path: s} existiert nicht.", + "experimental_feature": "Warnung: Der Maintainer hat diese Funktion als experimentell gekennzeichnet. Sie ist nicht stabil. Sie sollten sie nur verwenden, wenn Sie wissen, was Sie tun.", "dyndns_domain_not_provided": "Der DynDNS-Anbieter {provider:s} kann die Domäne(n) {domain:s} nicht bereitstellen.", "dyndns_could_not_check_available": "Konnte nicht überprüfen, ob {domain:s} auf {provider:s} verfügbar ist.", "dyndns_could_not_check_provide": "Konnte nicht überprüft, ob {provider:s} die Domain(s) {domain:s} bereitstellen kann.", @@ -491,5 +491,6 @@ "global_settings_setting_pop3_enabled": "Aktiviere das POP3 Protokoll für den Mailserver", "domain_cannot_remove_main_add_new_one": "Du kannst \"{domain:s}\" nicht entfernen da es die Hauptdomain und deine einzige Domain ist, erst musst erst eine andere Domain hinzufügen indem du eingibst \"yunohost domain add \", setze es dann als deine Hauptdomain indem du eingibst \"yunohost domain main-domain -n \", erst jetzt kannst du die domain \"{domain:s}\" entfernen.", "diagnosis_rootfstotalspace_critical": "Das Root-Filesystem hat noch freien Speicher von {space}. Das ist besorngiserregend! Der Speicher wird schnell aufgebraucht sein. 16 GB für das Root-Filesystem werden empfohlen.", - "diagnosis_rootfstotalspace_warning": "Das Root-Filesystem hat noch freien Speicher von {space}. Möglich, dass das in Ordnung ist. Vielleicht ist er aber auch schneller aufgebraucht. 16 GB für das Root-Filesystem werden empfohlen." + "diagnosis_rootfstotalspace_warning": "Das Root-Filesystem hat noch freien Speicher von {space}. Möglich, dass das in Ordnung ist. Vielleicht ist er aber auch schneller aufgebraucht. 16 GB für das Root-Filesystem werden empfohlen.", + "global_settings_setting_smtp_relay_host": "Zu verwendender SMTP-Relay-Host um E-Mails zu versenden. Er wird anstelle dieser YunoHost-Instanz verwendet. Nützlich, wenn Sie in einer der folgenden Situationen sind: Ihr ISP- oder VPS-Provider hat Ihren Port 25 geblockt, eine Ihrer residentiellen IPs ist auf DUHL gelistet, Sie können keinen Reverse-DNS konfigurieren oder dieser Server ist nicht direkt mit dem Internet verbunden und Sie möchten einen anderen verwenden, um E-Mails zu versenden." } From def4115fd7b46b64fdab5ca426348b88cdbabbd7 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 3 Feb 2021 19:24:11 +0000 Subject: [PATCH 028/131] Translated using Weblate (German) Currently translated at 64.7% (409 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index a979031b3..0bacbc39a 100644 --- a/locales/de.json +++ b/locales/de.json @@ -492,5 +492,6 @@ "domain_cannot_remove_main_add_new_one": "Du kannst \"{domain:s}\" nicht entfernen da es die Hauptdomain und deine einzige Domain ist, erst musst erst eine andere Domain hinzufügen indem du eingibst \"yunohost domain add \", setze es dann als deine Hauptdomain indem du eingibst \"yunohost domain main-domain -n \", erst jetzt kannst du die domain \"{domain:s}\" entfernen.", "diagnosis_rootfstotalspace_critical": "Das Root-Filesystem hat noch freien Speicher von {space}. Das ist besorngiserregend! Der Speicher wird schnell aufgebraucht sein. 16 GB für das Root-Filesystem werden empfohlen.", "diagnosis_rootfstotalspace_warning": "Das Root-Filesystem hat noch freien Speicher von {space}. Möglich, dass das in Ordnung ist. Vielleicht ist er aber auch schneller aufgebraucht. 16 GB für das Root-Filesystem werden empfohlen.", - "global_settings_setting_smtp_relay_host": "Zu verwendender SMTP-Relay-Host um E-Mails zu versenden. Er wird anstelle dieser YunoHost-Instanz verwendet. Nützlich, wenn Sie in einer der folgenden Situationen sind: Ihr ISP- oder VPS-Provider hat Ihren Port 25 geblockt, eine Ihrer residentiellen IPs ist auf DUHL gelistet, Sie können keinen Reverse-DNS konfigurieren oder dieser Server ist nicht direkt mit dem Internet verbunden und Sie möchten einen anderen verwenden, um E-Mails zu versenden." + "global_settings_setting_smtp_relay_host": "Zu verwendender SMTP-Relay-Host um E-Mails zu versenden. Er wird anstelle dieser YunoHost-Instanz verwendet. Nützlich, wenn Sie in einer der folgenden Situationen sind: Ihr ISP- oder VPS-Provider hat Ihren Port 25 geblockt, eine Ihrer residentiellen IPs ist auf DUHL gelistet, Sie können keinen Reverse-DNS konfigurieren oder dieser Server ist nicht direkt mit dem Internet verbunden und Sie möchten einen anderen verwenden, um E-Mails zu versenden.", + "global_settings_setting_backup_compress_tar_archives": "Beim Erstellen von Backups die Archive komprimieren (.tar.gz) anstelle von unkomprimierten Archiven (.tar). N.B. : Diese Option ergibt leichtere Backup-Archive, aber das initiale Backupprozedere wird länger dauern und mehr CPU brauchen." } From eacc571cc3b4bef24d4a614c02457e831ec73d4e Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Fri, 5 Feb 2021 07:17:42 +0000 Subject: [PATCH 029/131] Translated using Weblate (German) Currently translated at 68.3% (432 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/locales/de.json b/locales/de.json index 0bacbc39a..48de3df5f 100644 --- a/locales/de.json +++ b/locales/de.json @@ -68,12 +68,12 @@ "firewall_reload_failed": "Firewall konnte nicht neu geladen werden", "firewall_reloaded": "Firewall neu geladen", "firewall_rules_cmd_failed": "Einige Befehle für die Firewallregeln sind gescheitert. Mehr Informationen im Log.", - "hook_exec_failed": "Skriptausführung fehlgeschlagen: {path:s}", - "hook_exec_not_terminated": "Skriptausführung noch nicht beendet: {path:s}", - "hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks", + "hook_exec_failed": "Konnte Skript nicht ausführen: {path:s}", + "hook_exec_not_terminated": "Skript ist nicht normal beendet worden: {path:s}", + "hook_list_by_invalid": "Dieser Wert kann nicht verwendet werden, um Hooks anzuzeigen", "hook_name_unknown": "Hook '{name:s}' ist nicht bekannt", "installation_complete": "Installation vollständig", - "installation_failed": "Installation fehlgeschlagen", + "installation_failed": "Etwas ist mit der Installation falsch gelaufen", "ip6tables_unavailable": "ip6tables kann nicht verwendet werden. Du befindest dich entweder in einem Container oder es wird nicht vom Kernel unterstützt", "iptables_unavailable": "iptables kann nicht verwendet werden. Du befindest dich entweder in einem Container oder es wird nicht vom Kernel unterstützt", "ldap_initialized": "LDAP wurde initialisiert", @@ -253,14 +253,14 @@ "backup_copying_to_organize_the_archive": "Kopieren von {size:s} MB, um das Archiv zu organisieren", "global_settings_setting_security_ssh_compatibility": "Kompatibilität vs. Sicherheitskompromiss für den SSH-Server. Beeinflusst die Chiffren (und andere sicherheitsrelevante Aspekte)", "group_deleted": "Gruppe '{group}' gelöscht", - "group_deletion_failed": "Kann Gruppe '{group}' nicht löschen", + "group_deletion_failed": "Konnte Gruppe '{group}' nicht löschen", "dyndns_provider_unreachable": "DynDNS-Anbieter {provider} kann nicht erreicht werden: Entweder ist dein YunoHost nicht korrekt mit dem Internet verbunden oder der Dynette-Server ist ausgefallen.", "group_created": "Gruppe '{group}' angelegt", - "group_creation_failed": "Kann Gruppe '{group}' nicht anlegen", + "group_creation_failed": "Konnte Gruppe '{group}' nicht anlegen", "group_unknown": "Die Gruppe '{group:s}' ist unbekannt", "group_updated": "Gruppe '{group:s}' erneuert", "group_update_failed": "Kann Gruppe '{group:s}' nicht aktualisieren: {error}", - "log_does_exists": "Es gibt kein Operationsprotokoll mit dem Namen'{log}', verwende'yunohost log list', um alle verfügbaren Operationsprotokolle anzuzeigen", + "log_does_exists": "Es gibt kein Operationsprotokoll mit dem Namen'{log}', verwende 'yunohost log list', um alle verfügbaren Operationsprotokolle anzuzeigen", "log_operation_unit_unclosed_properly": "Die Operationseinheit wurde nicht richtig geschlossen", "global_settings_setting_security_postfix_compatibility": "Kompatibilität vs. Sicherheitskompromiss für den Postfix-Server. Beeinflusst die Chiffren (und andere sicherheitsrelevante Aspekte)", "log_category_404": "Die Log-Kategorie '{category}' existiert nicht", @@ -274,28 +274,28 @@ "backup_php5_to_php7_migration_may_fail": "Dein Archiv konnte nicht für PHP 7 konvertiert werden, Du kannst deine PHP-Anwendungen möglicherweise nicht wiederherstellen (Grund: {error:s})", "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Erlaubt die Verwendung eines (veralteten) DSA-Hostkeys für die SSH-Daemon-Konfiguration", "global_settings_setting_example_string": "Beispiel einer string Option", - "log_app_remove": "Entferne die Anwendung '{}'", + "log_app_remove": "Entferne die Applikation '{}'", "global_settings_setting_example_int": "Beispiel einer int Option", "global_settings_cant_open_settings": "Einstellungsdatei konnte nicht geöffnet werden, Grund: {reason:s}", "global_settings_cant_write_settings": "Einstellungsdatei konnte nicht gespeichert werden, Grund: {reason:s}", - "log_app_install": "Installiere die Anwendung '{}'", + "log_app_install": "Installiere die Applikation '{}'", "global_settings_reset_success": "Frühere Einstellungen werden nun auf {path:s} gesichert", - "log_app_upgrade": "Upgrade der Anwendung '{}'", - "good_practices_about_admin_password": "Sie sind nun dabei, ein neues Administrationspasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - obwohl es sinnvoll ist, ein längeres Passwort (z.B. eine Passphrase) und/oder eine Variation von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", + "log_app_upgrade": "Upgrade der Applikation '{}'", + "good_practices_about_admin_password": "Sie sind nun dabei, ein neues Administrationspasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein, obwohl es sinnvoll ist, ein längeres Passwort (z.B. eine Passphrase) und/oder eine Variation von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", "log_corrupted_md_file": "Die mit Protokollen verknüpfte YAML-Metadatendatei ist beschädigt: '{md_file}\nFehler: {error}''", "global_settings_cant_serialize_settings": "Einstellungsdaten konnten nicht serialisiert werden, Grund: {reason:s}", "log_help_to_get_failed_log": "Der Vorgang'{desc}' konnte nicht abgeschlossen werden. Bitte teile das vollständige Protokoll dieser Operation mit dem Befehl 'yunohost log share {name}', um Hilfe zu erhalten", "backup_no_uncompress_archive_dir": "Dieses unkomprimierte Archivverzeichnis gibt es nicht", - "log_app_change_url": "Ändere die URL der Anwendung '{}'", + "log_app_change_url": "Ändere die URL der Applikation '{}'", "global_settings_setting_security_password_user_strength": "Stärke des Benutzerpassworts", - "good_practices_about_user_password": "Du bist nun dabei, ein neues Benutzerpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - obwohl es ratsam ist, ein längeres Passwort (z.B. eine Passphrase) und/oder eine Variation von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", + "good_practices_about_user_password": "Sie sind dabei, ein neues Benutzerpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein, obwohl es ratsam ist, ein längeres Passwort (z.B. eine Passphrase) und/oder eine Variation von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", "global_settings_setting_example_enum": "Beispiel einer enum Option", "log_link_to_failed_log": "Der Vorgang konnte nicht abgeschlossen werden '{desc}'. Bitte gib das vollständige Protokoll dieser Operation mit Klicken Sie hier an, um Hilfe zu erhalten", "backup_cant_mount_uncompress_archive": "Das unkomprimierte Archiv konnte nicht als schreibgeschützt gemountet werden", "backup_csv_addition_failed": "Es konnten keine Dateien zur Sicherung in die CSV-Datei hinzugefügt werden", "global_settings_setting_security_password_admin_strength": "Stärke des Admin-Passworts", "global_settings_key_doesnt_exists": "Der Schlüssel'{settings_key:s}' existiert nicht in den globalen Einstellungen, du kannst alle verfügbaren Schlüssel sehen, indem du 'yunohost settings list' ausführst", - "log_app_makedefault": "Mache '{}' zur Standard-Anwendung", + "log_app_makedefault": "Mache '{}' zur Standard-Applikation", "hook_json_return_error": "Konnte die Rückkehr vom Einsprungpunkt {path:s} nicht lesen. Fehler: {msg:s}. Unformatierter Inhalt: {raw_content}", "app_full_domain_unavailable": "Es tut uns leid, aber diese Anwendung erfordert die Installation auf einer eigenen Domain, aber einige andere Anwendungen sind bereits auf der Domäne'{domain}' installiert. Eine mögliche Lösung ist das Hinzufügen und Verwenden einer Subdomain, die dieser Anwendung zugeordnet ist.", "app_install_failed": "{app} kann nicht installiert werden: {error}", @@ -493,5 +493,13 @@ "diagnosis_rootfstotalspace_critical": "Das Root-Filesystem hat noch freien Speicher von {space}. Das ist besorngiserregend! Der Speicher wird schnell aufgebraucht sein. 16 GB für das Root-Filesystem werden empfohlen.", "diagnosis_rootfstotalspace_warning": "Das Root-Filesystem hat noch freien Speicher von {space}. Möglich, dass das in Ordnung ist. Vielleicht ist er aber auch schneller aufgebraucht. 16 GB für das Root-Filesystem werden empfohlen.", "global_settings_setting_smtp_relay_host": "Zu verwendender SMTP-Relay-Host um E-Mails zu versenden. Er wird anstelle dieser YunoHost-Instanz verwendet. Nützlich, wenn Sie in einer der folgenden Situationen sind: Ihr ISP- oder VPS-Provider hat Ihren Port 25 geblockt, eine Ihrer residentiellen IPs ist auf DUHL gelistet, Sie können keinen Reverse-DNS konfigurieren oder dieser Server ist nicht direkt mit dem Internet verbunden und Sie möchten einen anderen verwenden, um E-Mails zu versenden.", - "global_settings_setting_backup_compress_tar_archives": "Beim Erstellen von Backups die Archive komprimieren (.tar.gz) anstelle von unkomprimierten Archiven (.tar). N.B. : Diese Option ergibt leichtere Backup-Archive, aber das initiale Backupprozedere wird länger dauern und mehr CPU brauchen." + "global_settings_setting_backup_compress_tar_archives": "Beim Erstellen von Backups die Archive komprimieren (.tar.gz) anstelle von unkomprimierten Archiven (.tar). N.B. : Diese Option ergibt leichtere Backup-Archive, aber das initiale Backupprozedere wird länger dauern und mehr CPU brauchen.", + "log_remove_on_failed_restore": "'{}' entfernen nach einer fehlerhaften Wiederherstellung aus einem Backup-Archiv", + "log_backup_restore_app": "'{}' aus einem Backup-Archiv wiederherstellen", + "log_backup_restore_system": "System aus einem Backup-Archiv wiederherstellen", + "log_available_on_yunopaste": "Das Protokoll ist nun via {url} verfügbar", + "log_app_config_apply": "Wende die Konfiguration auf die Applikation '{}' an", + "log_app_config_show_panel": "Zeige das Konfigurations-Panel der Applikation '{}'", + "log_app_action_run": "Führe Aktion der Applikation '{}' aus", + "invalid_regex": "Ungültige Regex:'{regex:s}'" } From 46ceef146770310ee91f55c60f4d96aba01e2a89 Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Mon, 8 Feb 2021 19:09:26 +0000 Subject: [PATCH 030/131] Translated using Weblate (Catalan) Currently translated at 100.0% (632 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ca.json b/locales/ca.json index 7924193d0..b6888d391 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -714,5 +714,8 @@ "additional_urls_already_removed": "URL addicional «{url:s}» ja ha estat eliminada per al permís «{permission:s}»", "additional_urls_already_added": "URL addicional «{url:s}» ja ha estat afegida per al permís «{permission:s}»", "diagnosis_backports_in_sources_list": "Sembla que apt (el gestor de paquets) està configurat per utilitzar el repositori backports. A menys de saber el que esteu fent, recomanem fortament no instal·lar paquets de backports, ja que poder causar inestabilitats o conflictes en el sistema.", - "diagnosis_basesystem_hardware_model": "El model del servidor és {model}" + "diagnosis_basesystem_hardware_model": "El model del servidor és {model}", + "postinstall_low_rootfsspace": "El sistema de fitxers arrel té un total de menys de 10 GB d'espai, el que es preocupant! És molt probable que us quedeu sense espai ràpidament! Es recomana tenir un mínim de 16 GB per al sistema de fitxers arrel. Si voleu instal·lar YunoHost tot i aquest avís, torneu a executar la postinstal·lació amb --force-diskspace", + "diagnosis_rootfstotalspace_critical": "El sistema de fitxers arrel només té {space} en total i és preocupant! És molt probable que us quedeu sense espai ràpidament! Es recomanar tenir un mínim de 16 GB per al sistema de fitxers arrel.", + "diagnosis_rootfstotalspace_warning": "El sistema de fitxers arrel només té {space} en total. Això no hauria de causar cap problema, però haureu de parar atenció ja que us podrieu quedar sense espai ràpidament… Es recomanar tenir un mínim de 16 GB per al sistema de fitxers arrel." } From 351928f566d06ca4aa9add30563a8cfe65bbf8ec Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 10 Feb 2021 19:25:35 +0000 Subject: [PATCH 031/131] Translated using Weblate (German) Currently translated at 72.1% (456 of 632 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/locales/de.json b/locales/de.json index 48de3df5f..40d7ec5e7 100644 --- a/locales/de.json +++ b/locales/de.json @@ -172,7 +172,7 @@ "certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain:s} läuft nicht in Kürze ab! (Benutze --force um diese Nachricht zu umgehen)", "certmanager_domain_http_not_working": "Es scheint so, dass die Domain {domain:s} nicht über HTTP erreicht werden kann. Bitte überprüfe, ob deine DNS und nginx Konfiguration in Ordnung ist. (Wenn du weißt was du tust, nutze \"--no-checks\" um die überprüfung zu überspringen.)", "certmanager_error_no_A_record": "Kein DNS 'A' Eintrag für die Domain {domain:s} gefunden. Dein Domainname muss auf diese Maschine weitergeleitet werden, um ein Let's Encrypt Zertifikat installieren zu können! (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )", - "certmanager_domain_dns_ip_differs_from_public_ip": "Der DNS 'A' Eintrag der Domain {domain:s} unterscheidet sich von dieser Server-IP. Für weitere Informationen überprüfe bitte die 'DNS records' (basic) Kategorie in der Diagnose. Wenn du gerade deinen A Eintrag verändert hast, warte bitte etwas, damit die Änderungen wirksam werden (du kannst die DNS Propagation mittels Website überprüfen) (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )", + "certmanager_domain_dns_ip_differs_from_public_ip": "Der DNS-A-Eintrag der Domain {domain:s} unterscheidet sich von dieser Server-IP. Für weitere Informationen überprüfen Sie bitte die 'DNS records' (basic) Kategorie in der Diagnose. Wenn Sie gerade Ihren A-Eintrag verändert haben, warten Sie bitte etwas, damit die Änderungen wirksam werden (Sie können die DNS-Propagation mittels Website überprüfen) (Wenn Sie wissen was Sie tun, können Sie --no-checks benutzen, um diese Überprüfung zu überspringen.)", "certmanager_cannot_read_cert": "Es ist ein Fehler aufgetreten, als es versucht wurde das aktuelle Zertifikat für die Domain {domain:s} zu öffnen (Datei: {file:s}), Grund: {reason:s}", "certmanager_cert_install_success_selfsigned": "Ein selbstsigniertes Zertifikat für die Domain {domain:s} wurde erfolgreich installiert", "certmanager_cert_install_success": "Für die Domain {domain:s} wurde erfolgreich ein Let's Encrypt Zertifikat installiert.", @@ -501,5 +501,29 @@ "log_app_config_apply": "Wende die Konfiguration auf die Applikation '{}' an", "log_app_config_show_panel": "Zeige das Konfigurations-Panel der Applikation '{}'", "log_app_action_run": "Führe Aktion der Applikation '{}' aus", - "invalid_regex": "Ungültige Regex:'{regex:s}'" + "invalid_regex": "Ungültige Regex:'{regex:s}'", + "migration_description_0016_php70_to_php73_pools": "Migrieren der php7.0-fpm-Konfigurationsdateien zu php7.3", + "mailbox_disabled": "E-Mail für Benutzer {user:s} deaktiviert", + "log_tools_reboot": "Server neustarten", + "log_tools_shutdown": "Server ausschalten", + "log_tools_upgrade": "Systempakete aktualisieren", + "log_tools_postinstall": "Post-Installation des YunoHost-Servers durchführen", + "log_tools_migrations_migrate_forward": "Migrationen durchführen", + "log_domain_main_domain": "Mache '{}' zur Hauptdomäne", + "log_user_permission_reset": "Zurücksetzen der Berechtigung '{}'", + "log_user_permission_update": "Aktualisiere Zugriffe für Berechtigung '{}'", + "log_user_update": "Aktualisiere Information für Benutzer '{}'", + "log_user_group_update": "Aktualisiere Gruppe '{}'", + "log_user_group_delete": "Lösche Gruppe '{}'", + "log_user_group_create": "Erstelle Gruppe '{}'", + "log_user_delete": "Lösche Benutzer '{}'", + "log_user_create": "Füge Benutzer '{}' hinzu", + "log_permission_url": "Aktualisiere URL, die mit der Berechtigung '{}' verknüpft ist", + "log_permission_delete": "Lösche Berechtigung '{}'", + "log_permission_create": "Erstelle Berechtigung '{}'", + "log_dyndns_update": "Die IP, die mit der YunoHost-Subdomain '{}' verbunden ist, aktualisieren", + "log_dyndns_subscribe": "Für eine YunoHost-Subdomain registrieren '{}'", + "log_domain_remove": "Entfernen der Domäne '{}' aus der Systemkonfiguration", + "log_domain_add": "Hinzufügen der Domäne '{}' zur Systemkonfiguration", + "log_remove_on_failed_install": "Entfernen von '{}' nach einer fehlgeschlagenen Installation" } From 5e6f77c8f724ae8b0fdfe2db7f2d165868ad04da Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Mon, 15 Feb 2021 06:31:00 +0000 Subject: [PATCH 032/131] Translated using Weblate (German) Currently translated at 73.4% (465 of 633 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 40d7ec5e7..2699ebe74 100644 --- a/locales/de.json +++ b/locales/de.json @@ -525,5 +525,14 @@ "log_dyndns_subscribe": "Für eine YunoHost-Subdomain registrieren '{}'", "log_domain_remove": "Entfernen der Domäne '{}' aus der Systemkonfiguration", "log_domain_add": "Hinzufügen der Domäne '{}' zur Systemkonfiguration", - "log_remove_on_failed_install": "Entfernen von '{}' nach einer fehlgeschlagenen Installation" + "log_remove_on_failed_install": "Entfernen von '{}' nach einer fehlgeschlagenen Installation", + "migration_0015_still_on_stretch_after_main_upgrade": "Etwas ist schiefgelaufen während dem Haupt-Upgrade. Das System scheint immer noch auf Debian Stretch zu laufen", + "migration_0015_yunohost_upgrade": "Beginne YunoHost-Core-Upgrade...", + "migration_description_0019_extend_permissions_features": "Erweitern und überarbeiten des Applikationsberechtigungs-Managementsystems", + "migrating_legacy_permission_settings": "Migrieren der Legacy-Berechtigungseinstellungen...", + "migration_description_0017_postgresql_9p6_to_11": "Migrieren der Datenbanken von PostgreSQL 9.6 nach 11", + "migration_0015_main_upgrade": "Beginne Haupt-Upgrade...", + "migration_0015_not_stretch": "Die aktuelle Debian-Distribution ist nicht Stretch!", + "migration_0015_not_enough_free_space": "Der freie Speicher in /var/ ist sehr gering! Sie sollten minimal 1GB frei haben, um diese Migration durchzuführen.", + "domain_remove_confirm_apps_removal": "Wenn Sie diese Domäne löschen, werden folgende Applikationen entfernt:\n{apps}\n\nSind Sie sicher? [{answers}]" } From b050a35b8a27750afcb2f45cb6812ead44965ffc Mon Sep 17 00:00:00 2001 From: MrMorals Date: Fri, 19 Feb 2021 16:46:19 +0000 Subject: [PATCH 033/131] Translated using Weblate (Dutch) Currently translated at 8.3% (53 of 633 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/nl/ --- locales/nl.json | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/locales/nl.json b/locales/nl.json index dfee556b2..63ec7bd6d 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -3,15 +3,15 @@ "admin_password": "Administrator wachtwoord", "admin_password_changed": "Het administratie wachtwoord werd gewijzigd", "app_already_installed": "{app:s} is al geïnstalleerd", - "app_argument_invalid": "'{name:s}' bevat ongeldige waarde: {error:s}", + "app_argument_invalid": "Kies een geldige waarde voor '{name:s}': {error:s}", "app_argument_required": "Het '{name:s}' moet ingevuld worden", "app_extraction_failed": "Kan installatiebestanden niet uitpakken", "app_id_invalid": "Ongeldige app-id", - "app_install_files_invalid": "Ongeldige installatiebestanden", + "app_install_files_invalid": "Deze bestanden kunnen niet worden geïnstalleerd", "app_manifest_invalid": "Ongeldig app-manifest", "app_not_installed": "{app:s} is niet geïnstalleerd", "app_removed": "{app:s} succesvol verwijderd", - "app_sources_fetch_failed": "Kan bronbestanden niet ophalen", + "app_sources_fetch_failed": "Kan bronbestanden niet ophalen, klopt de URL?", "app_unknown": "Onbekende app", "app_upgrade_failed": "Kan app {app:s} niet updaten", "app_upgraded": "{app:s} succesvol geüpgraded", @@ -82,7 +82,7 @@ "app_argument_choice_invalid": "Ongeldige keuze voor argument '{name:s}'. Het moet een van de volgende keuzes zijn {choices:s}", "app_not_correctly_installed": "{app:s} schijnt niet juist geïnstalleerd te zijn", "app_not_properly_removed": "{app:s} werd niet volledig verwijderd", - "app_requirements_checking": "Controleer noodzakelijke pakketten...", + "app_requirements_checking": "Noodzakelijke pakketten voor {app} aan het controleren...", "app_requirements_unmeet": "Er wordt niet aan de aanvorderingen voldaan, het pakket {pkgname} ({version}) moet {spec} zijn", "app_unsupported_remote_type": "Niet ondersteund besturings type voor de app", "ask_main_domain": "Hoofd-domein", @@ -101,5 +101,25 @@ "already_up_to_date": "Er is niets te doen, alles is al up-to-date.", "admin_password_too_long": "Gelieve een wachtwoord te kiezen met minder dan 127 karakters", "app_action_cannot_be_ran_because_required_services_down": "De volgende diensten moeten actief zijn om deze actie uit te voeren: {services}. Probeer om deze te herstarten om verder te gaan (en om eventueel te onderzoeken waarom ze niet werken).", - "aborting": "Annulatie." -} \ No newline at end of file + "aborting": "Annulatie.", + "app_upgrade_app_name": "Bezig {app} te upgraden...", + "app_make_default_location_already_used": "Kan '{app}' niet de standaardapp maken op het domein, '{domein}' wordt al gebruikt door '{other_app}'", + "app_install_failed": "Kan {app} niet installeren: {error}", + "app_remove_after_failed_install": "Bezig de app te verwijderen na gefaalde installatie...", + "app_manifest_install_ask_domain": "Kies het domein waar deze app op geïnstalleerd moet worden", + "app_manifest_install_ask_path": "Kies het pad waar deze app geïnstalleerd moet worden", + "app_manifest_install_ask_admin": "Kies een administrator voor deze app", + "app_change_url_failed_nginx_reload": "Kon NGINX niet opnieuw laden. Hier is de output van 'nginx -t':\n{nginx_errors:s}", + "app_change_url_success": "{app:s} URL is nu {domain:s}{path:s}", + "app_full_domain_unavailable": "Sorry, deze app moet op haar eigen domein geïnstalleerd worden, maar andere apps zijn al geïnstalleerd op het domein '{domain}'. U kunt wel een subdomein aan deze app toewijden.", + "app_install_script_failed": "Er is een fout opgetreden in het installatiescript van de app", + "app_location_unavailable": "Deze URL is niet beschikbaar of is in conflict met de al geïnstalleerde app(s):\n{apps:s}", + "app_manifest_install_ask_password": "Kies een administratiewachtwoord voor deze app", + "app_manifest_install_ask_is_public": "Moet deze app zichtbaar zijn voor anomieme bezoekers?", + "app_not_upgraded": "De app '{failed_app}' kon niet upgraden en daardoor zijn de upgrades van de volgende apps geannuleerd: {apps}", + "app_start_install": "{app} installeren...", + "app_start_remove": "{app} verwijderen...", + "app_start_backup": "Bestanden aan het verzamelen voor de backup van {app}...", + "app_start_restore": "{app} herstellen...", + "app_upgrade_several_apps": "De volgende apps zullen worden geüpgraded: {apps}" +} From dc844b5d73167ea923960e6594a08d487039e75b Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Mon, 22 Feb 2021 06:45:23 +0000 Subject: [PATCH 034/131] Translated using Weblate (German) Currently translated at 74.7% (473 of 633 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 2699ebe74..36f710f07 100644 --- a/locales/de.json +++ b/locales/de.json @@ -534,5 +534,13 @@ "migration_0015_main_upgrade": "Beginne Haupt-Upgrade...", "migration_0015_not_stretch": "Die aktuelle Debian-Distribution ist nicht Stretch!", "migration_0015_not_enough_free_space": "Der freie Speicher in /var/ ist sehr gering! Sie sollten minimal 1GB frei haben, um diese Migration durchzuführen.", - "domain_remove_confirm_apps_removal": "Wenn Sie diese Domäne löschen, werden folgende Applikationen entfernt:\n{apps}\n\nSind Sie sicher? [{answers}]" + "domain_remove_confirm_apps_removal": "Wenn Sie diese Domäne löschen, werden folgende Applikationen entfernt:\n{apps}\n\nSind Sie sicher? [{answers}]", + "migration_0015_cleaning_up": "Bereinigung des Cache und der Pakete, welche nicht mehr benötigt werden...", + "migration_0017_postgresql_96_not_installed": "PostgreSQL wurde auf ihrem System nicht installiert. Nichts zu tun.", + "migration_0015_system_not_fully_up_to_date": "Ihr System ist nicht vollständig auf dem neuesten Stand. Bitte führen Sie ein reguläres Upgrade durch, bevor Sie die Migration auf Buster durchführen.", + "migration_0015_modified_files": "Bitte beachten Sie, dass die folgenden Dateien als manuell bearbeitet erkannt wurden und beim nächsten Upgrade überschrieben werden könnten: {manually_modified_files}", + "migration_0015_general_warning": "Bitte beachten Sie, dass diese Migration eine heikle Angelegenheit darstellt. Das YunoHost-Team hat alles unternommen, um sie zu testen und zu überarbeiten. Dennoch ist es möglich, dass diese Migration Teile des Systems oder Applikationen beschädigen könnte.\n\nDeshalb ist folgendes zu empfehlen:\n…- Führen Sie ein Backup aller kritischen Daten und Applikationen durch. Mehr unter https://yunohost.org/backup;\n…- Seien Sie geduldig nachdem Sie die Migration gestartet haben: Abhängig von Ihrer Internetverbindung und Ihrer Hardware kann es einige Stunden dauern, bis das Upgrade fertig ist.", + "migration_0015_problematic_apps_warning": "Bitte beachten Sie, dass folgende möglicherweise problematischen Applikationen auf Ihrer Installation erkannt wurden. Es scheint, als ob sie nicht aus dem YunoHost-Applikationskatalog installiert oder nicht als 'working' gekennzeichnet worden sind. Folglich kann nicht garantiert werden, dass sie nach dem Upgrade immer noch funktionieren: {problematic_apps}", + "migration_0015_specific_upgrade": "Start des Upgrades der Systempakete, deren Upgrade separat durchgeführt werden muss...", + "migration_0015_weak_certs": "Die folgenden Zertifikate verwenden immer noch schwache Signierungsalgorithmen und müssen aktualisiert werden um mit der nächsten Version von nginx kompatibel zu sein: {certs}" } From 2ea7b026533055f94848787fc84b950b1ba6d740 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Mon, 22 Feb 2021 19:23:24 +0000 Subject: [PATCH 035/131] Translated using Weblate (German) Currently translated at 78.9% (500 of 633 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 36f710f07..77b4fad49 100644 --- a/locales/de.json +++ b/locales/de.json @@ -542,5 +542,32 @@ "migration_0015_general_warning": "Bitte beachten Sie, dass diese Migration eine heikle Angelegenheit darstellt. Das YunoHost-Team hat alles unternommen, um sie zu testen und zu überarbeiten. Dennoch ist es möglich, dass diese Migration Teile des Systems oder Applikationen beschädigen könnte.\n\nDeshalb ist folgendes zu empfehlen:\n…- Führen Sie ein Backup aller kritischen Daten und Applikationen durch. Mehr unter https://yunohost.org/backup;\n…- Seien Sie geduldig nachdem Sie die Migration gestartet haben: Abhängig von Ihrer Internetverbindung und Ihrer Hardware kann es einige Stunden dauern, bis das Upgrade fertig ist.", "migration_0015_problematic_apps_warning": "Bitte beachten Sie, dass folgende möglicherweise problematischen Applikationen auf Ihrer Installation erkannt wurden. Es scheint, als ob sie nicht aus dem YunoHost-Applikationskatalog installiert oder nicht als 'working' gekennzeichnet worden sind. Folglich kann nicht garantiert werden, dass sie nach dem Upgrade immer noch funktionieren: {problematic_apps}", "migration_0015_specific_upgrade": "Start des Upgrades der Systempakete, deren Upgrade separat durchgeführt werden muss...", - "migration_0015_weak_certs": "Die folgenden Zertifikate verwenden immer noch schwache Signierungsalgorithmen und müssen aktualisiert werden um mit der nächsten Version von nginx kompatibel zu sein: {certs}" + "migration_0015_weak_certs": "Die folgenden Zertifikate verwenden immer noch schwache Signierungsalgorithmen und müssen aktualisiert werden um mit der nächsten Version von nginx kompatibel zu sein: {certs}", + "migrations_pending_cant_rerun": "Diese Migrationen sind immer noch anstehend und können deshalb nicht erneut durchgeführt werden: {ids}", + "migration_0019_add_new_attributes_in_ldap": "Hinzufügen neuer Attribute für die Berechtigungen in der LDAP-Datenbank", + "migration_0019_can_not_backup_before_migration": "Das Backup des Systems konnte nicht abgeschlossen werden bevor die Migration fehlschlug. Fehlermeldung: {error}", + "migration_0019_migration_failed_trying_to_rollback": "Konnte nicht migrieren... versuche ein Rollback des Systems.", + "migrations_not_pending_cant_skip": "Diese Migrationen sind nicht anstehend und können deshalb nicht übersprungen werden: {ids}", + "migration_0018_failed_to_reset_legacy_rules": "Zurücksetzen der veralteten iptables-Regeln fehlgeschlagen: {error}", + "migration_0019_rollback_success": "Rollback des Systems durchgeführt.", + "migration_0019_slapd_config_will_be_overwritten": "Es schaut aus, als ob Sie die slapd-Konfigurationsdatei manuell bearbeitet haben. Für diese kritische Migration muss das Update der slapd-Konfiguration erzwungen werden. Von der Originaldatei wird ein Backup gemacht in {conf_backup_folder}.", + "migrations_success_forward": "Migration {id} abgeschlossen", + "migrations_cant_reach_migration_file": "Die Migrationsdateien konnten nicht aufgerufen werden im Verzeichnis '%s'", + "migrations_dependencies_not_satisfied": "Führen Sie diese Migrationen aus: '{dependencies_id}', vor der Migration {id}.", + "migrations_failed_to_load_migration": "Konnte Migration nicht laden {id}: {error}", + "migrations_list_conflict_pending_done": "Sie können nicht '--previous' und '--done' gleichzeitig benützen.", + "migrations_already_ran": "Diese Migrationen wurden bereits durchgeführt: {ids}", + "migrations_loading_migration": "Lade Migrationen {id}...", + "migrations_migration_has_failed": "Migration {id} gescheitert mit der Ausnahme {exception}: Abbruch", + "migrations_must_provide_explicit_targets": "Sie müssen konkrete Ziele angeben, wenn Sie '--skip' oder '--force-rerun' verwenden", + "migrations_need_to_accept_disclaimer": "Um die Migration {id} durchzuführen, müssen Sie den Disclaimer akzeptieren.\n---\n{disclaimer}\n---\n Wenn Sie bestätigen, dass Sie die Migration durchführen wollen, wiederholen Sie bitte den Befehl mit der Option '--accept-disclaimer'.", + "migrations_no_migrations_to_run": "Keine Migrationen durchzuführen", + "migration_0017_postgresql_11_not_installed": "PostgreSQL 9.6 ist installiert aber nicht postgreSQL 11? Etwas komisches ist Ihrem System zugestossen :(...", + "migration_0017_not_enough_space": "Stellen Siea ausreichend Speicherplatz im Verzeichnis {path} zur Verfügung um die Migration durchzuführen.", + "migration_0018_failed_to_migrate_iptables_rules": "Migration der veralteten iptables-Regeln zu nftables fehlgeschlagen: {error}", + "migration_0019_backup_before_migration": "Ein Backup der LDAP-Datenbank und der Applikationseinstellungen erstellen vor der Migration.", + "migrations_exclusive_options": "'--auto', '--skip' und '--force-rerun' sind Optionen, die sich gegenseitig ausschliessen.", + "migrations_no_such_migration": "Es existiert keine Migration genannt '{id}'", + "migrations_running_forward": "Durchführen der Migrationen {id}...", + "migrations_skip_migration": "Überspringe Migrationen {id}..." } From a0cd4d3ca50b2fdcbeda5b5884d78d547434395f Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 24 Feb 2021 06:52:40 +0000 Subject: [PATCH 036/131] Translated using Weblate (German) Currently translated at 79.7% (505 of 633 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 77b4fad49..536bdd842 100644 --- a/locales/de.json +++ b/locales/de.json @@ -569,5 +569,10 @@ "migrations_exclusive_options": "'--auto', '--skip' und '--force-rerun' sind Optionen, die sich gegenseitig ausschliessen.", "migrations_no_such_migration": "Es existiert keine Migration genannt '{id}'", "migrations_running_forward": "Durchführen der Migrationen {id}...", - "migrations_skip_migration": "Überspringe Migrationen {id}..." + "migrations_skip_migration": "Überspringe Migrationen {id}...", + "password_too_simple_2": "Dieses Passwort gehört zu den meistverwendeten der Welt. Bitte nehmen Sie etwas einzigartigeres.", + "password_listed": "Dieses Passwort gehört zu den meistverwendeten der Welt. Bitte nehmen Sie etwas einzigartigeres.", + "operation_interrupted": "Wurde die Operation manuell unterbrochen?", + "invalid_number": "Muss eine Zahl sein", + "migrations_to_be_ran_manually": "Die Migration {id} muss manuell durchgeführt werden. Bitte gehen Sie zu Werkzeuge → Migrationen auf der Webadmin-Seite oder führen Sie 'yunohost tools migrations run' aus." } From a5038b5cc0a4cedffa0bc39ad001b75ced11bd6a Mon Sep 17 00:00:00 2001 From: Nils Van Zuijlen Date: Tue, 23 Feb 2021 14:20:24 +0000 Subject: [PATCH 037/131] Translated using Weblate (French) Currently translated at 99.5% (630 of 633 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 7d016a70e..47bae6407 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -692,5 +692,9 @@ "invalid_number": "Doit être un nombre", "migration_description_0019_extend_permissions_features": "Étendre et retravailler le système de gestion des permissions applicatives", "diagnosis_basesystem_hardware_model": "Le modèle du serveur est {model}", - "diagnosis_backports_in_sources_list": "Il semble qu'apt (le gestionnaire de paquets) soit configuré pour utiliser le dépôt des rétroportages (backports). A moins que vous ne sachiez vraiment ce que vous faites, nous vous déconseillons fortement d'installer des paquets provenant des rétroportages, car cela risque de créer des instabilités ou des conflits sur votre système." + "diagnosis_backports_in_sources_list": "Il semble qu'apt (le gestionnaire de paquets) soit configuré pour utiliser le dépôt des rétroportages (backports). A moins que vous ne sachiez vraiment ce que vous faites, nous vous déconseillons fortement d'installer des paquets provenant des rétroportages, car cela risque de créer des instabilités ou des conflits sur votre système.", + "postinstall_low_rootfsspace": "Le système de fichiers racine ne fait que {space} ! Vous allez certainement les remplir très rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers. Si vous voulez installer YunoHost malgré cet avertissement, relancez le postinstall avec --force-diskspace", + "domain_remove_confirm_apps_removal": "Le retrait de ce domaine retirera aussi ces applications :\n{apps}\n\nÊtes vous sûr de vouloir cela ? [{answers}]", + "diagnosis_rootfstotalspace_critical": "Le système de fichiers racine ne fait que {space} ! Vous allez certainement les remplir très rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers.", + "diagnosis_rootfstotalspace_warning": "Le système de fichiers racine n'est que de {space}. Ça peut suffire, mais faites attention car vous risquez de les remplire rapidement... Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers." } From fdba94e2e5e0d18686f86efb1d8249accb995042 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 05:17:36 +0100 Subject: [PATCH 038/131] Fix fr translation --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 47bae6407..8982d7ccc 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -693,7 +693,7 @@ "migration_description_0019_extend_permissions_features": "Étendre et retravailler le système de gestion des permissions applicatives", "diagnosis_basesystem_hardware_model": "Le modèle du serveur est {model}", "diagnosis_backports_in_sources_list": "Il semble qu'apt (le gestionnaire de paquets) soit configuré pour utiliser le dépôt des rétroportages (backports). A moins que vous ne sachiez vraiment ce que vous faites, nous vous déconseillons fortement d'installer des paquets provenant des rétroportages, car cela risque de créer des instabilités ou des conflits sur votre système.", - "postinstall_low_rootfsspace": "Le système de fichiers racine ne fait que {space} ! Vous allez certainement les remplir très rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers. Si vous voulez installer YunoHost malgré cet avertissement, relancez le postinstall avec --force-diskspace", + "postinstall_low_rootfsspace": "Le système de fichiers racine a une taille totale inférieure à 10 GB, ce qui est inquiétant ! Vous allez certainement arriver à court d'espace disque rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers. Si vous voulez installer YunoHost malgré cet avertissement, relancez le postinstall avec --force-diskspace", "domain_remove_confirm_apps_removal": "Le retrait de ce domaine retirera aussi ces applications :\n{apps}\n\nÊtes vous sûr de vouloir cela ? [{answers}]", "diagnosis_rootfstotalspace_critical": "Le système de fichiers racine ne fait que {space} ! Vous allez certainement les remplir très rapidement ! Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers.", "diagnosis_rootfstotalspace_warning": "Le système de fichiers racine n'est que de {space}. Ça peut suffire, mais faites attention car vous risquez de les remplire rapidement... Il est recommandé d'avoir au moins 16 GB pour ce système de fichiers." From a8b315b873e745dc8a5d039b92456f499e9513d8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 05:18:21 +0100 Subject: [PATCH 039/131] Fix nl translation --- locales/nl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/nl.json b/locales/nl.json index 63ec7bd6d..59de95f58 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -103,7 +103,7 @@ "app_action_cannot_be_ran_because_required_services_down": "De volgende diensten moeten actief zijn om deze actie uit te voeren: {services}. Probeer om deze te herstarten om verder te gaan (en om eventueel te onderzoeken waarom ze niet werken).", "aborting": "Annulatie.", "app_upgrade_app_name": "Bezig {app} te upgraden...", - "app_make_default_location_already_used": "Kan '{app}' niet de standaardapp maken op het domein, '{domein}' wordt al gebruikt door '{other_app}'", + "app_make_default_location_already_used": "Kan '{app}' niet de standaardapp maken op het domein, '{domain}' wordt al gebruikt door '{other_app}'", "app_install_failed": "Kan {app} niet installeren: {error}", "app_remove_after_failed_install": "Bezig de app te verwijderen na gefaalde installatie...", "app_manifest_install_ask_domain": "Kies het domein waar deze app op geïnstalleerd moet worden", From 8f7ced35a5ee7f1493dcbbbcb42256b8b36a78df Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 25 Feb 2021 11:16:34 +0100 Subject: [PATCH 040/131] fix ynh_systemd_action in case of service fails --- data/helpers.d/systemd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index b416e5745..f8e21bfbd 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -58,7 +58,7 @@ ynh_remove_systemd_config () { # usage: ynh_systemd_action [--service_name=service_name] [--action=action] [ [--line_match="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ] # | arg: -n, --service_name= - Name of the service to start. Default : $app # | arg: -a, --action= - Action to perform with systemctl. Default: start -# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. WARNING: When using --line_match, you should always add `ynh_clean_check_starting` into your `ynh_clean_setup` at the beginning of the script. Otherwise, tail will not stop in case of failure of the script. The script will then hang forever. +# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. # | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log # | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds. # | arg: -e, --length= - Length of the error log : Default : 20 @@ -117,6 +117,7 @@ ynh_systemd_action() { then ynh_exec_err tail --lines=$length "$log_path" fi + ynh_clean_check_starting return 1 fi @@ -161,9 +162,8 @@ ynh_systemd_action() { } # Clean temporary process and file used by ynh_check_starting -# (usually used in ynh_clean_setup scripts) # -# usage: ynh_clean_check_starting +# [internal] # # Requires YunoHost version 3.5.0 or higher. ynh_clean_check_starting () { @@ -174,7 +174,7 @@ ynh_clean_check_starting () { fi if [ -n "$templog" ] then - ynh_secure_remove "$templog" 2>&1 + ynh_secure_remove --file="$templog" 2>&1 fi } From 1d3380415eca14ea9291d3b29fbf326111077e68 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 25 Feb 2021 11:17:46 +0100 Subject: [PATCH 041/131] add missing getops --- data/helpers.d/apt | 6 +++--- data/helpers.d/fail2ban | 8 ++++---- data/helpers.d/network | 2 +- data/helpers.d/php | 6 +++--- data/helpers.d/postgresql | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/data/helpers.d/apt b/data/helpers.d/apt index 6abaf20a2..bfdeffe7b 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -459,11 +459,11 @@ ynh_remove_extra_repo () { ynh_handle_getopts_args "$@" name="${name:-$app}" - ynh_secure_remove "/etc/apt/sources.list.d/$name.list" + ynh_secure_remove --file="/etc/apt/sources.list.d/$name.list" # Sury pinning is managed by the regenconf in the core... [[ "$name" == "extra_php_version" ]] || ynh_secure_remove "/etc/apt/preferences.d/$name" - ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.gpg" > /dev/null - ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.asc" > /dev/null + ynh_secure_remove --file="/etc/apt/trusted.gpg.d/$name.gpg" > /dev/null + ynh_secure_remove --file="/etc/apt/trusted.gpg.d/$name.asc" > /dev/null # Update the list of package to exclude the old repo ynh_package_update diff --git a/data/helpers.d/fail2ban b/data/helpers.d/fail2ban index c41226e14..c9322d067 100644 --- a/data/helpers.d/fail2ban +++ b/data/helpers.d/fail2ban @@ -77,8 +77,8 @@ ynh_add_fail2ban_config () { if [ $use_template -ne 1 ] then # Usage 1, no template. Build a config file from scratch. - test -n "$logpath" || ynh_die "ynh_add_fail2ban_config expects a logfile path as first argument and received nothing." - test -n "$failregex" || ynh_die "ynh_add_fail2ban_config expects a failure regex as second argument and received nothing." + test -n "$logpath" || ynh_die --message="ynh_add_fail2ban_config expects a logfile path as first argument and received nothing." + test -n "$failregex" || ynh_die --message="ynh_add_fail2ban_config expects a failure regex as second argument and received nothing." echo " [__APP__] @@ -117,7 +117,7 @@ ignoreregex = # # Requires YunoHost version 3.5.0 or higher. ynh_remove_fail2ban_config () { - ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf" - ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf" + ynh_secure_remove --file="/etc/fail2ban/jail.d/$app.conf" + ynh_secure_remove --file="/etc/fail2ban/filter.d/$app.conf" ynh_systemd_action --service_name=fail2ban --action=reload } diff --git a/data/helpers.d/network b/data/helpers.d/network index 4f108422b..0760909c6 100644 --- a/data/helpers.d/network +++ b/data/helpers.d/network @@ -27,7 +27,7 @@ ynh_find_port () { # Test if a port is available # -# example: ynh_port_available --port=1234 || ynh_die "Port 1234 is needs to be available for this app" +# example: ynh_port_available --port=1234 || ynh_die --message="Port 1234 is needs to be available for this app" # # usage: ynh_find_port --port=XYZ # | arg: -p, --port= - port to check diff --git a/data/helpers.d/php b/data/helpers.d/php index 683f252be..5c050cc88 100644 --- a/data/helpers.d/php +++ b/data/helpers.d/php @@ -337,7 +337,7 @@ ynh_install_php () { if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ] then - ynh_die "Do not use ynh_install_php to install php$YNH_DEFAULT_PHP_VERSION" + ynh_die --message="Do not use ynh_install_php to install php$YNH_DEFAULT_PHP_VERSION" fi # Create the file if doesn't exist already @@ -611,9 +611,9 @@ ynh_install_composer () { curl -sS https://getcomposer.org/installer \ | COMPOSER_HOME="$workdir/.composer" \ php${phpversion} -- --quiet --install-dir="$workdir" --version=$composerversion \ - || ynh_die "Unable to install Composer." + || ynh_die --message="Unable to install Composer." # install dependencies ynh_composer_exec --phpversion="${phpversion}" --workdir="$workdir" --commands="install --no-dev $install_args" \ - || ynh_die "Unable to install core dependencies with Composer." + || ynh_die --message="Unable to install core dependencies with Composer." } diff --git a/data/helpers.d/postgresql b/data/helpers.d/postgresql index 11b9c0fed..f2f427842 100644 --- a/data/helpers.d/postgresql +++ b/data/helpers.d/postgresql @@ -295,10 +295,10 @@ ynh_psql_remove_db() { ynh_psql_test_if_first_run() { # Make sure postgresql is indeed installed - dpkg --list | grep -q "ii postgresql-$PSQL_VERSION" || ynh_die "postgresql-$PSQL_VERSION is not installed !?" + dpkg --list | grep -q "ii postgresql-$PSQL_VERSION" || ynh_die --message="postgresql-$PSQL_VERSION is not installed !?" # Check for some weird issue where postgresql could be installed but etc folder would not exist ... - [ -e "/etc/postgresql/$PSQL_VERSION" ] || ynh_die "It looks like postgresql was not properly configured ? /etc/postgresql/$PSQL_VERSION is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist" + [ -e "/etc/postgresql/$PSQL_VERSION" ] || ynh_die --message="It looks like postgresql was not properly configured ? /etc/postgresql/$PSQL_VERSION is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist" # Make sure postgresql is started and enabled # (N.B. : to check the active state, we check the cluster state because From 47420c623252c98f2efc65498abde32ba90a3dec Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 25 Feb 2021 12:40:49 +0100 Subject: [PATCH 042/131] fix multimedia helper --- data/helpers.d/multimedia | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/multimedia b/data/helpers.d/multimedia index 5517917b5..f7c9d5974 100644 --- a/data/helpers.d/multimedia +++ b/data/helpers.d/multimedia @@ -1,3 +1,5 @@ +#!/bin/bash + readonly MEDIA_GROUP=multimedia readonly MEDIA_DIRECTORY=/home/yunohost.multimedia @@ -53,10 +55,13 @@ ynh_multimedia_build_main_dir() { # | arg: -d, --dest_dir= - Destination directory - The name and the place of the symbolic link, relative to "/home/yunohost.multimedia" ynh_multimedia_addfolder() { - # Declare an array to define the options of this helper. - declare -Ar args_array=( [s]=source_dir= [d]=dest_dir= ) + # Declare an array to define the options of this helper. + local legacy_args=sd + local -A args_array=( [s]=source_dir= [d]=dest_dir= ) local source_dir local dest_dir + # Manage arguments with getopts + ynh_handle_getopts_args "$@" # Ajout d'un lien symbolique vers le dossier à partager ln -sfn "$source_dir" "$MEDIA_DIRECTORY/$dest_dir" @@ -77,6 +82,7 @@ ynh_multimedia_addfolder() { # | arg: -u, --user_name= - The name of the user which gain this access. ynh_multimedia_addaccess () { # Declare an array to define the options of this helper. + local legacy_args=u declare -Ar args_array=( [u]=user_name=) local user_name # Manage arguments with getopts From 33f291be962333b2a455ac6e4a7162cf5aee8a8b Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 16:36:28 +0100 Subject: [PATCH 043/131] Fix ynh_replace_vars again, mystical bash is mystic... --- data/helpers.d/utils | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index bd9e6a87b..96609c7dc 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -389,8 +389,11 @@ ynh_replace_vars () { for one_var in "${uniques_vars[@]}" do # Validate that one_var is indeed defined - # Explanation for the weird '+x' syntax: https://stackoverflow.com/a/13864829 - test -n "${one_var+x}" || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file" + # -v checks if the variable is defined, for example: + # -v FOO tests if $FOO is defined + # -v $FOO tests if ${!FOO} is defined + # More info: https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash/17538964#comment96392525_17538964 + [[ -v "${one_var:-}" ]] || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file" # Escape delimiter in match/replace string match_string="__${one_var^^}__" From 0dd033745089316ad6d03be1985942ec76bb81bf Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 16:44:55 +0100 Subject: [PATCH 044/131] Don't redact empty string... --- src/yunohost/log.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 24ecc6713..763967b38 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -399,7 +399,11 @@ class RedactingFormatter(Formatter): msg = super(RedactingFormatter, self).format(record) self.identify_data_to_redact(msg) for data in self.data_to_redact: - msg = msg.replace(data, "**********") + # we check that data is not empty string, + # otherwise this may lead to super epic stuff + # (try to run "foo".replace("", "bar")) + if data: + msg = msg.replace(data, "**********") return msg def identify_data_to_redact(self, record): From 675c4d0eeaea772703b951c78e12bbefae855913 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 16:57:57 +0100 Subject: [PATCH 045/131] Fix permission helper doc format --- data/helpers.d/permission | 47 +++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/data/helpers.d/permission b/data/helpers.d/permission index f4e200019..ba2b22a53 100644 --- a/data/helpers.d/permission +++ b/data/helpers.d/permission @@ -25,19 +25,14 @@ # usage: ynh_permission_create --permission="permission" [--url="url"] [--additional_urls="second-url" [ "third-url" ]] [--auth_header=true|false] # [--allowed=group1 [ group2 ]] [--label="label"] [--show_tile=true|false] # [--protected=true|false] -# | arg: -p, permission= - the name for the permission (by default a permission named "main" already exist) -# | arg: -u, url= - (optional) URL for which access will be allowed/forbidden. -# | Not that if 'show_tile' is enabled, this URL will be the URL of the tile. -# | arg: -A, additional_urls= - (optional) List of additional URL for which access will be allowed/forbidden -# | arg: -h, auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application. Default is true -# | arg: -a, allowed= - (optional) A list of group/user to allow for the permission -# | arg: -l, label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. -# | Default is "APP_LABEL (permission name)". -# | arg: -t, show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. -# | Default is false (for the permission different than 'main'). -# | arg: -P, protected= - (optional) Define if this permission is protected. If it is protected the administrator -# | won't be able to add or remove the visitors group of this permission. -# | By default it's 'false' +# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist) +# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden. Note that if 'show_tile' is enabled, this URL will be the URL of the tile. +# | arg: -A, --additional_urls= - (optional) List of additional URL for which access will be allowed/forbidden +# | arg: -h, --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application. Default is true +# | arg: -a, --allowed= - (optional) A list of group/user to allow for the permission +# | arg: -l, --label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. Default is "APP_LABEL (permission name)". +# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. Defaults to false for the permission different than 'main'. +# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. Defaults to 'false'. # # If provided, 'url' or 'additional_urls' is assumed to be relative to the app domain/path if they # start with '/'. For example: @@ -193,13 +188,12 @@ ynh_permission_exists() { # # usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]] # [--auth_header=true|false] [--clear_urls] -# | arg: -p, permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed) -# | arg: -u, url= - (optional) URL for which access will be allowed/forbidden. -# | Note that if you want to remove url you can pass an empty sting as arguments (""). -# | arg: -a, add_url= - (optional) List of additional url to add for which access will be allowed/forbidden. -# | arg: -r, remove_url= - (optional) List of additional url to remove for which access will be allowed/forbidden -# | arg: -h, auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application -# | arg: -c, clear_urls - (optional) Clean all urls (url and additional_urls) +# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed) +# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden. Note that if you want to remove url you can pass an empty sting as arguments (""). +# | arg: -a, --add_url= - (optional) List of additional url to add for which access will be allowed/forbidden. +# | arg: -r, --remove_url= - (optional) List of additional url to remove for which access will be allowed/forbidden +# | arg: -h, --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application +# | arg: -c, --clear_urls - (optional) Clean all urls (url and additional_urls) # # Requires YunoHost version 3.7.0 or higher. ynh_permission_url() { @@ -269,13 +263,12 @@ ynh_permission_url() { # # usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]] # [--label="label"] [--show_tile=true|false] [--protected=true|false] -# | arg: -p, permission= - the name for the permission (by default a permission named "main" already exist) -# | arg: -a, add= - the list of group or users to enable add to the permission -# | arg: -r, remove= - the list of group or users to remove from the permission -# | arg: -l, label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. -# | arg: -t, show_tile= - (optional) Define if a tile will be shown in the SSO -# | arg: -P, protected= - (optional) Define if this permission is protected. If it is protected the administrator -# | won't be able to add or remove the visitors group of this permission. +# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist) +# | arg: -a, --add= - the list of group or users to enable add to the permission +# | arg: -r, --remove= - the list of group or users to remove from the permission +# | arg: -l, --label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. +# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO +# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. # # Requires YunoHost version 3.7.0 or higher. ynh_permission_update() { From 7efc6dcd07d08b8c3923165d1378d8d7490c1754 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 22 Jan 2021 02:56:09 +0100 Subject: [PATCH 046/131] Handle the dyndns cron from the regenconf --- data/hooks/conf_regen/01-yunohost | 11 +++++++++++ src/yunohost/dyndns.py | 26 +++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index 9da2d91ca..8b7a7c6fc 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -86,6 +86,17 @@ SHELL=/bin/bash 0 7,19 * * * root : YunoHost Automatic Diagnosis; sleep \$((RANDOM\\%1200)); yunohost diagnosis run --email > /dev/null 2>/dev/null || echo "Running the automatic diagnosis failed miserably" EOF + # If we subscribed to a dyndns domain, add the corresponding cron + # - delay between 0 and 60 secs to spread the check over a 1 min window + # - do not run the command if some process already has the lock, to avoid queuing hundreds of commands... + if ls -l /etc/yunohost/dyndns/K*.private 2>/dev/null + then + cat > $pending_dir/etc/cron.d/yunohost-dyndns << EOF +SHELL=/bin/bash +*/10 * * * * root : YunoHost DynDNS update; sleep \$((RANDOM\\%60)); test -e /var/run/moulinette_yunohost.lock || yunohost dyndns update >> /dev/null +EOF + fi + # legacy stuff to avoid yunohost reporting etckeeper as manually modified # (this make sure that the hash is null / file is flagged as to-delete) mkdir -p $pending_dir/etc/etckeeper diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index d94748881..ce5ebfc5e 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -40,6 +40,7 @@ from yunohost.utils.error import YunohostError from yunohost.domain import _get_maindomain, _build_dns_conf from yunohost.utils.network import get_public_ip, dig from yunohost.log import is_unit_operation +from yunohost.regenconf import regen_conf logger = getActionLogger("yunohost.dyndns") @@ -121,10 +122,9 @@ def dyndns_subscribe( subscribe_host -- Dynette HTTP API to subscribe to """ - if len(glob.glob("/etc/yunohost/dyndns/*.key")) != 0 or os.path.exists( - "/etc/cron.d/yunohost-dyndns" - ): - raise YunohostError("domain_dyndns_already_subscribed") + + if _guess_current_dyndns_domain(dyn_host) != (None, None): + raise YunohostError('domain_dyndns_already_subscribed') if domain is None: domain = _get_maindomain() @@ -186,9 +186,17 @@ def dyndns_subscribe( error = 'Server error, code: %s. (Message: "%s")' % (r.status_code, r.text) raise YunohostError("dyndns_registration_failed", error=error) - logger.success(m18n.n("dyndns_registered")) + # Yunohost regen conf will add the dyndns cron job if a private key exists + # in /etc/yunohost/dyndns + regen_conf("yunohost") - dyndns_installcron() + # Add some dyndns update in 2 and 4 minutes from now such that user should + # not have to wait 10ish minutes for the conf to propagate + cmd = "at -M now + {t} >/dev/null 2>&1 <<< \"/bin/bash -c 'yunohost dyndns update'\"" + subprocess.check_call(cmd.format(t="2 min"), shell=True) + subprocess.check_call(cmd.format(t="4 min"), shell=True) + + logger.success(m18n.n('dyndns_registered')) @is_unit_operation() @@ -220,6 +228,10 @@ def dyndns_update( # If domain is not given, try to guess it from keys available... if domain is None: (domain, key) = _guess_current_dyndns_domain(dyn_host) + + if domain is None: + raise YunohostError('dyndns_no_domain_registered') + # If key is not given, pick the first file we find with the domain given else: if key is None: @@ -414,4 +426,4 @@ def _guess_current_dyndns_domain(dyn_host): else: return (_domain, path) - raise YunohostError("dyndns_no_domain_registered") + return (None, None) From 2752a8e485dfcffed761f93309829ba31cd74188 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 22 Jan 2021 02:56:36 +0100 Subject: [PATCH 047/131] Deprecate yunohost dyndns installcron/removecron --- data/actionsmap/yunohost.yml | 6 ++---- locales/en.json | 3 --- src/yunohost/dyndns.py | 22 ++-------------------- 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 33b8b5cfe..290952aa3 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -1363,13 +1363,11 @@ dyndns: ### dyndns_installcron() installcron: - action_help: Install IP update cron - api: POST /dyndns/cron + deprecated: true ### dyndns_removecron() removecron: - action_help: Remove IP update cron - api: DELETE /dyndns/cron + deprecated: true ############################# diff --git a/locales/en.json b/locales/en.json index 7e3de2341..199c21b66 100644 --- a/locales/en.json +++ b/locales/en.json @@ -291,9 +291,6 @@ "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", "dyndns_could_not_check_provide": "Could not check if {provider:s} can provide {domain:s}.", "dyndns_could_not_check_available": "Could not check if {domain:s} is available on {provider:s}.", - "dyndns_cron_installed": "DynDNS cron job created", - "dyndns_cron_remove_failed": "Could not remove the DynDNS cron job because: {error}", - "dyndns_cron_removed": "DynDNS cron job removed", "dyndns_ip_update_failed": "Could not update IP address to DynDNS", "dyndns_ip_updated": "Updated your IP on DynDNS", "dyndns_key_generating": "Generating DNS key... It may take a while.", diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index ce5ebfc5e..6545d33c7 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -373,29 +373,11 @@ def dyndns_update( def dyndns_installcron(): - """ - Install IP update cron - - - """ - with open("/etc/cron.d/yunohost-dyndns", "w+") as f: - f.write("*/2 * * * * root yunohost dyndns update >> /dev/null\n") - - logger.success(m18n.n("dyndns_cron_installed")) + logger.warning("This command is deprecated. The dyndns cron job should automatically be added/removed by the regenconf depending if there's a private key in /etc/yunohost/dyndns. You can run the regenconf yourself with 'yunohost tools regen-conf yunohost'.") def dyndns_removecron(): - """ - Remove IP update cron - - - """ - try: - os.remove("/etc/cron.d/yunohost-dyndns") - except Exception as e: - raise YunohostError("dyndns_cron_remove_failed", error=e) - - logger.success(m18n.n("dyndns_cron_removed")) + logger.warning("This command is deprecated. The dyndns cron job should automatically be added/removed by the regenconf depending if there's a private key in /etc/yunohost/dyndns. You can run the regenconf yourself with 'yunohost tools regen-conf yunohost'.") def _guess_current_dyndns_domain(dyn_host): From a8e11c19db6d8b21f5d6d90512cc4d5471ce3bd6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 22 Jan 2021 03:01:05 +0100 Subject: [PATCH 048/131] Delete dyndns key during domain removal if any --- src/yunohost/domain.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index cc9980549..95d9ee7b0 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -245,6 +245,9 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False): os.system("rm -rf /etc/yunohost/certs/%s" % domain) + # Delete dyndns keys for this domain (if any) + os.system('rm -rf /etc/yunohost/dyndns/K%s.+*' % domain) + # Sometime we have weird issues with the regenconf where some files # appears as manually modified even though they weren't touched ... # There are a few ideas why this happens (like backup/restore nginx From cc6cc1860add2c44d9af2a47329acef2c3a48dd7 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 22 Jan 2021 03:02:04 +0100 Subject: [PATCH 049/131] Do not backup damn cron jobs ... they will automatically be regenerated by the regenconf --- data/hooks/backup/42-conf_ynh_dyndns | 1 - data/hooks/restore/42-conf_ynh_dyndns | 1 - 2 files changed, 2 deletions(-) diff --git a/data/hooks/backup/42-conf_ynh_dyndns b/data/hooks/backup/42-conf_ynh_dyndns index 3dbcc2780..6343f9086 100644 --- a/data/hooks/backup/42-conf_ynh_dyndns +++ b/data/hooks/backup/42-conf_ynh_dyndns @@ -8,4 +8,3 @@ cd "$YNH_CWD" # Backup the configuration ynh_exec_warn_less ynh_backup --src_path="/etc/yunohost/dyndns" --not_mandatory -ynh_exec_warn_less ynh_backup --src_path="/etc/cron.d/yunohost-dyndns" --not_mandatory diff --git a/data/hooks/restore/42-conf_ynh_dyndns b/data/hooks/restore/42-conf_ynh_dyndns index d16d7a67c..8ed4941ef 100644 --- a/data/hooks/restore/42-conf_ynh_dyndns +++ b/data/hooks/restore/42-conf_ynh_dyndns @@ -7,4 +7,3 @@ cd "$YNH_CWD" # Restore file if exists ynh_restore_file --origin_path="/etc/yunohost/dyndns" --not_mandatory -ynh_restore_file --origin_path="/etc/cron.d/yunohost-dyndns" --not_mandatory From 071732dd7f78f96d4d4f8f2973082f308f841335 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 22 Jan 2021 03:04:56 +0100 Subject: [PATCH 050/131] Improve check that a dyndns domain already exists --- src/yunohost/domain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 95d9ee7b0..1198ef473 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -119,11 +119,11 @@ def domain_add(operation_logger, domain, dyndns=False): # DynDNS domain if dyndns: - # Do not allow to subscribe to multiple dyndns domains... - if os.path.exists("/etc/cron.d/yunohost-dyndns"): - raise YunohostError("domain_dyndns_already_subscribed") + from yunohost.dyndns import dyndns_subscribe, _dyndns_provides, _guess_current_dyndns_domain - from yunohost.dyndns import dyndns_subscribe, _dyndns_provides + # Do not allow to subscribe to multiple dyndns domains... + if _guess_current_dyndns_domain("dyndns.yunohost.org") != (None, None): + raise YunohostError('domain_dyndns_already_subscribed') # Check that this domain can effectively be provided by # dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st) From 64a1b4cad2ad8b871db88f820e30ddfe59e21edd Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 26 Feb 2021 00:20:39 +0100 Subject: [PATCH 051/131] Misc fixes after testing --- debian/control | 2 +- src/yunohost/dyndns.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/debian/control b/debian/control index 7275cb7b1..ef5061fe7 100644 --- a/debian/control +++ b/debian/control @@ -27,7 +27,7 @@ Depends: ${python3:Depends}, ${misc:Depends} , redis-server , metronome (>=3.14.0) , acl - , git, curl, wget, cron, unzip, jq, bc + , git, curl, wget, cron, unzip, jq, bc, at , lsb-release, haveged, fake-hwclock, equivs, lsof, whois Recommends: yunohost-admin , ntp, inetutils-ping | iputils-ping diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index 6545d33c7..a921cfb5c 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -123,7 +123,7 @@ def dyndns_subscribe( """ - if _guess_current_dyndns_domain(dyn_host) != (None, None): + if _guess_current_dyndns_domain(subscribe_host) != (None, None): raise YunohostError('domain_dyndns_already_subscribed') if domain is None: @@ -169,7 +169,7 @@ def dyndns_subscribe( try: r = requests.post( "https://%s/key/%s?key_algo=hmac-sha512" - % (subscribe_host, base64.b64encode(key)), + % (subscribe_host, base64.b64encode(key.encode()).decode()), data={"subdomain": domain}, timeout=30, ) @@ -188,13 +188,14 @@ def dyndns_subscribe( # Yunohost regen conf will add the dyndns cron job if a private key exists # in /etc/yunohost/dyndns - regen_conf("yunohost") + regen_conf(["yunohost"]) # Add some dyndns update in 2 and 4 minutes from now such that user should # not have to wait 10ish minutes for the conf to propagate cmd = "at -M now + {t} >/dev/null 2>&1 <<< \"/bin/bash -c 'yunohost dyndns update'\"" - subprocess.check_call(cmd.format(t="2 min"), shell=True) - subprocess.check_call(cmd.format(t="4 min"), shell=True) + # For some reason subprocess doesn't like the redirections so we have to use bash -c explicity... + subprocess.check_call(["bash", "-c", cmd.format(t="2 min")]) + subprocess.check_call(["bash", "-c", cmd.format(t="4 min")]) logger.success(m18n.n('dyndns_registered')) From c6d14219cc5b5cc47ca9e367bdec085d71404967 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sat, 27 Feb 2021 20:39:55 +0100 Subject: [PATCH 052/131] Force destination to be replaced --- data/helpers.d/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 96609c7dc..d4797c8a0 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -316,7 +316,7 @@ ynh_add_config () { ynh_backup_if_checksum_is_different --file="$destination" - cp "$template_path" "$destination" + cp -f "$template_path" "$destination" chown root: "$destination" ynh_replace_vars --file="$destination" From fcea5a6af0d0d29d8d57c030c7c0836b8fdbb462 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sun, 28 Feb 2021 13:38:10 +0100 Subject: [PATCH 053/131] Make grep lazy --- data/helpers.d/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index d4797c8a0..af8464279 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -382,7 +382,7 @@ ynh_replace_vars () { # Replace others variables # List other unique (__ __) variables in $file - local uniques_vars=( $(grep -o '__[A-Z0-9_]*__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) + local uniques_vars=( $(grep -oP '__[A-Z0-9_]+?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) # Do the replacement local delimit=@ From 4131ddb0706ccd6121e0d542cc2b6d84c665f0ab Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 28 Feb 2021 17:00:48 +0100 Subject: [PATCH 054/131] Fix cases where we want to test if translation exists for a key --- src/yunohost/diagnosis.py | 3 +-- src/yunohost/service.py | 11 ++++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/yunohost/diagnosis.py b/src/yunohost/diagnosis.py index 93ece21fc..5666afb07 100644 --- a/src/yunohost/diagnosis.py +++ b/src/yunohost/diagnosis.py @@ -449,9 +449,8 @@ class Diagnoser(): @staticmethod def get_description(id_): key = "diagnosis_description_" + id_ - descr = m18n.n(key) # If no description available, fallback to id - return descr if descr != key else id_ + return m18n.n(key) if m18n.key_exists(key) else id_ @staticmethod def i18n(report, force_remove_html_tags=False): diff --git a/src/yunohost/service.py b/src/yunohost/service.py index 347932add..211d7bf56 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -352,14 +352,11 @@ def _get_and_format_service_status(service, infos): # If no description was there, try to get it from the .json locales if not description: - translation_key = "service_description_%s" % service - description = m18n.n(translation_key) - # If descrption is still equal to the translation key, - # that mean that we don't have a translation for this string - # that's the only way to test for that for now - # if we don't have it, uses the one provided by systemd - if description == translation_key: + translation_key = "service_description_%s" % service + if m18n.key_exists(translation_key): + description = m18n.key_exists(translation_key) + else: description = str(raw_status.get("Description", "")) output = { From c86d4327832dc85a559a71d28e50405875bbed0a Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sun, 28 Feb 2021 18:56:30 +0100 Subject: [PATCH 055/131] Fixing ___APP__ --- data/helpers.d/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index af8464279..487ec41db 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -382,7 +382,7 @@ ynh_replace_vars () { # Replace others variables # List other unique (__ __) variables in $file - local uniques_vars=( $(grep -oP '__[A-Z0-9_]+?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) + local uniques_vars=( $(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) # Do the replacement local delimit=@ From 0884a0c162af28ac71f5d1cdf6878349b0f6ffc1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 1 Mar 2021 18:06:43 +0100 Subject: [PATCH 056/131] Further simplify logging configuration by using the 'cli' handler when running yunohost-api in debug mode instead of creating a 'console' handler which is pretty much the same --- src/yunohost/__init__.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/yunohost/__init__.py b/src/yunohost/__init__.py index 04b2115b2..04caefc7a 100644 --- a/src/yunohost/__init__.py +++ b/src/yunohost/__init__.py @@ -154,14 +154,8 @@ def init_logging(interface="cli", debug=False, quiet=False, logdir="/var/log/yun # This is for when launching yunohost-api in debug mode, we want to display stuff in the console if debug: - logging_configuration["handlers"]["console"] = { - 'class': 'logging.StreamHandler', - 'formatter': 'console', - 'stream': 'ext://sys.stdout', - 'filters': ['action'], - }, - logging_configuration["loggers"]["yunohost"]["handlers"].append("console") - logging_configuration["loggers"]["moulinette"]["handlers"].append("console") - logging_configuration["root"]["handlers"].append("console") + logging_configuration["loggers"]["yunohost"]["handlers"].append("cli") + logging_configuration["loggers"]["moulinette"]["handlers"].append("cli") + logging_configuration["root"]["handlers"].append("cli") configure_logging(logging_configuration) From d763247df445a0e485746f49453a024e5285e660 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 1 Mar 2021 19:11:41 +0100 Subject: [PATCH 057/131] No need for mysql root password (#912) * Get rid of /etc/yunohost/mysql * Get rid of restore hook for mysql password * Tab -> spaces * declare->local lost while merging conflicts etc * Gotta keep that var --- data/helpers.d/mysql | 26 +++++++++------------- data/hooks/conf_regen/34-mysql | 33 +++++++++++++++++++--------- data/hooks/restore/11-conf_ynh_mysql | 5 ----- src/yunohost/tests/test_apps.py | 15 ++++--------- 4 files changed, 37 insertions(+), 42 deletions(-) delete mode 100644 data/hooks/restore/11-conf_ynh_mysql diff --git a/data/helpers.d/mysql b/data/helpers.d/mysql index 05f75e0a2..6808441b7 100644 --- a/data/helpers.d/mysql +++ b/data/helpers.d/mysql @@ -1,7 +1,5 @@ #!/bin/bash -MYSQL_ROOT_PWD_FILE=/etc/yunohost/mysql - # Open a connection as a user # # example: ynh_mysql_connect_as --user="user" --password="pass" <<< "UPDATE ...;" @@ -49,8 +47,7 @@ ynh_mysql_execute_as_root() { database="--database=$database" fi - ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \ - $database <<< "$sql" + mysql -B "$database" <<< "$sql" } # Execute a command from a file as root user @@ -75,9 +72,7 @@ ynh_mysql_execute_file_as_root() { database="--database=$database" fi - - ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \ - $database < "$file" + mysql -B "$database" < "$file" } # Create a database and grant optionnaly privilegies to a user @@ -140,7 +135,7 @@ ynh_mysql_dump_db() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - mysqldump --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" --single-transaction --skip-dump-date "$database" + mysqldump --single-transaction --skip-dump-date "$database" } # Create a user @@ -214,12 +209,13 @@ ynh_mysql_setup_db () { # Manage arguments with getopts ynh_handle_getopts_args "$@" - local new_db_pwd=$(ynh_string_random) # Generate a random password + # Generate a random password + local new_db_pwd=$(ynh_string_random) # If $db_pwd is not provided, use new_db_pwd instead for db_pwd db_pwd="${db_pwd:-$new_db_pwd}" - ynh_mysql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database - ynh_app_setting_set --app=$app --key=mysqlpwd --value=$db_pwd # Store the password in the app's config + ynh_mysql_create_db "$db_name" "$db_user" "$db_pwd" + ynh_app_setting_set --app=$app --key=mysqlpwd --value=$db_pwd } # Remove a database if it exists, and the associated user @@ -232,16 +228,14 @@ ynh_mysql_setup_db () { ynh_mysql_remove_db () { # Declare an array to define the options of this helper. local legacy_args=un - local -A args_array=( [u]=db_user= [n]=db_name= ) + local -Ar args_array=( [u]=db_user= [n]=db_name= ) local db_user local db_name # Manage arguments with getopts ynh_handle_getopts_args "$@" - local mysql_root_password=$(cat $MYSQL_ROOT_PWD_FILE) - if mysqlshow --user=root --password=$mysql_root_password | grep --quiet "^| $db_name" - then # Check if the database exists - ynh_mysql_drop_db $db_name # Remove the database + if mysqlshow | grep -q "^| $db_name "; then + ynh_mysql_drop_db $db_name else ynh_print_warn --message="Database $db_name not found" fi diff --git a/data/hooks/conf_regen/34-mysql b/data/hooks/conf_regen/34-mysql index d9374bbf5..6c9694796 100755 --- a/data/hooks/conf_regen/34-mysql +++ b/data/hooks/conf_regen/34-mysql @@ -1,7 +1,6 @@ #!/bin/bash set -e -MYSQL_PKG="$(dpkg --list | sed -ne 's/^ii \(mariadb-server-[[:digit:].]\+\) .*$/\1/p')" . /usr/share/yunohost/helpers do_pre_regen() { @@ -20,6 +19,7 @@ do_post_regen() { # dpkg-reconfigure will initialize mysql (if it ain't already) # It enabled auth_socket for root, so no need to define any root password... # c.f. : cat /var/lib/dpkg/info/mariadb-server-10.3.postinst | grep install_db -C3 + MYSQL_PKG="$(dpkg --list | sed -ne 's/^ii \(mariadb-server-[[:digit:].]\+\) .*$/\1/p')" dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 systemctl -q is-active mariadb.service \ @@ -27,17 +27,30 @@ do_post_regen() { sleep 5 - echo "" | mysql && echo "Can't connect to mysql using unix_socket auth ... something went wrong during initial configuration of mysql !?" + echo "" | mysql && echo "Can't connect to mysql using unix_socket auth ... something went wrong during initial configuration of mysql !?" >&2 fi - if [ ! -e /etc/yunohost/mysql ] - then - # Dummy password that's not actually used nor meaningful ... - # (because mysql is supposed to be configured to use unix_socket on new setups) - # but keeping it for legacy - # until we merge https://github.com/YunoHost/yunohost/pull/912 ... - ynh_string_random 10 > /etc/yunohost/mysql - chmod 400 /etc/yunohost/mysql + # Legacy code to get rid of /etc/yunohost/mysql ... + # Nowadays, we can simply run mysql while being run as root of unix_socket/auth_socket is enabled... + if [ -f /etc/yunohost/mysql ]; then + + # This is a trick to check if we're able to use mysql without password + # Expect instances installed in stretch to already have unix_socket + #configured, but not old instances from the jessie/wheezy era + if ! echo "" | mysql + then + password="$(cat /etc/yunohost/mysql)" + # Enable plugin unix_socket for root on localhost + mysql -u root -p"$password" <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED WITH unix_socket WITH GRANT OPTION;" + fi + + # If now we're able to login without password, drop the mysql password + if echo "" | mysql + then + rm /etc/yunohost/mysql + else + echo "Can't connect to mysql using unix_socket auth ... something went wrong while trying to get rid of mysql password !?" >&2 + fi fi # mysql is supposed to be an alias to mariadb... but in some weird case is not diff --git a/data/hooks/restore/11-conf_ynh_mysql b/data/hooks/restore/11-conf_ynh_mysql deleted file mode 100644 index 11353425a..000000000 --- a/data/hooks/restore/11-conf_ynh_mysql +++ /dev/null @@ -1,5 +0,0 @@ -# We don't backup/restore mysql password anymore -# c.f. https://github.com/YunoHost/yunohost/pull/912 - -# This is a dummy empty file as a workaround for -# https://github.com/YunoHost/issues/issues/1553 until it is fixed diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index ae8a4829b..b9e9e7530 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -55,18 +55,11 @@ def clean(): for folderpath in glob.glob("/var/www/*%s*" % test_app): shutil.rmtree(folderpath, ignore_errors=True) - os.system( - "bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE %s' \"" - % test_app - ) - os.system( - "bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER %s@localhost'\"" - % test_app - ) + os.system("bash -c \"mysql -B 2>/dev/null <<< 'DROP DATABASE %s' \"" % test_app) + os.system("bash -c \"mysql -B 2>/dev/null <<< 'DROP USER %s@localhost'\"" % test_app) - os.system( - "systemctl reset-failed nginx" - ) # Reset failed quota for service to avoid running into start-limit rate ? + # Reset failed quota for service to avoid running into start-limit rate ? + os.system("systemctl reset-failed nginx") os.system("systemctl start nginx") # Clean permissions From 01058aca281a2bcde3092d9fb35a548505370867 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 2 Mar 2021 01:49:23 +0100 Subject: [PATCH 058/131] Catch more secrets not redacted --- src/yunohost/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 763967b38..1b7d66c44 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -415,7 +415,7 @@ class RedactingFormatter(Formatter): # (the secret part being at least 3 chars to avoid catching some lines like just "db_pwd=") # Some names like "key" or "manifest_key" are ignored, used in helpers like ynh_app_setting_set or ynh_read_manifest match = re.search( - r"(pwd|pass|password|secret|\w+key|token)=(\S{3,})$", record.strip() + r"(pwd|pass|password|secret\w*|\w+key|token)=(\S{3,})$", record.strip() ) if ( match From 0c172cd3f95799f20d3ab55faa9d3d02437a35d4 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 2 Mar 2021 01:49:23 +0100 Subject: [PATCH 059/131] Catch more secrets not redacted --- src/yunohost/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 7e9ae18e6..c51628c50 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -387,7 +387,7 @@ class RedactingFormatter(Formatter): # This matches stuff like db_pwd=the_secret or admin_password=other_secret # (the secret part being at least 3 chars to avoid catching some lines like just "db_pwd=") # Some names like "key" or "manifest_key" are ignored, used in helpers like ynh_app_setting_set or ynh_read_manifest - match = re.search(r'(pwd|pass|password|secret|\w+key|token)=(\S{3,})$', record.strip()) + match = re.search(r'(pwd|pass|password|secret\w*|\w+key|token)=(\S{3,})$', record.strip()) if match and match.group(2) not in self.data_to_redact and match.group(1) not in ["key", "manifest_key"]: self.data_to_redact.append(match.group(2)) except Exception as e: From a43cd72c72524b2f9eb22fa86a2edac0465ab432 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 16:36:28 +0100 Subject: [PATCH 060/131] Fix ynh_replace_vars again, mystical bash is mystic... --- data/helpers.d/utils | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 5e02ca762..c67e1fae1 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -393,8 +393,11 @@ ynh_replace_vars () { for one_var in "${uniques_vars[@]}" do # Validate that one_var is indeed defined - # Explanation for the weird '+x' syntax: https://stackoverflow.com/a/13864829 - test -n "${one_var+x}" || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file" + # -v checks if the variable is defined, for example: + # -v FOO tests if $FOO is defined + # -v $FOO tests if ${!FOO} is defined + # More info: https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash/17538964#comment96392525_17538964 + [[ -v "${one_var:-}" ]] || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file" # Escape delimiter in match/replace string match_string="__${one_var^^}__" From 2728801d1798be9eff25294dc85dbce2c4bb02ad Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sat, 27 Feb 2021 20:39:55 +0100 Subject: [PATCH 061/131] Force destination to be replaced --- data/helpers.d/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index c67e1fae1..fee7e009b 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -321,7 +321,7 @@ ynh_add_config () { ynh_backup_if_checksum_is_different --file="$destination" - cp "$template_path" "$destination" + cp -f "$template_path" "$destination" ynh_replace_vars --file="$destination" From 9bbc3b72ae30092b717af7095359b16975700ca6 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sun, 28 Feb 2021 13:38:10 +0100 Subject: [PATCH 062/131] Make grep lazy --- data/helpers.d/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index fee7e009b..b1b265b8b 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -386,7 +386,7 @@ ynh_replace_vars () { # Replace others variables # List other unique (__ __) variables in $file - local uniques_vars=( $(grep -o '__[A-Z0-9_]*__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) + local uniques_vars=( $(grep -oP '__[A-Z0-9_]+?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) # Do the replacement local delimit=@ From 2402a1db39bf3a294459e1c0123b254e36c9f19c Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sun, 28 Feb 2021 18:56:30 +0100 Subject: [PATCH 063/131] Fixing ___APP__ --- data/helpers.d/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index b1b265b8b..53a7ea3b7 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -386,7 +386,7 @@ ynh_replace_vars () { # Replace others variables # List other unique (__ __) variables in $file - local uniques_vars=( $(grep -oP '__[A-Z0-9_]+?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) + local uniques_vars=( $(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g" )) # Do the replacement local delimit=@ From 88b414c8f3e0d3192a057f18260b65b9e3b1b23e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 16:44:55 +0100 Subject: [PATCH 064/131] Don't redact empty string... --- src/yunohost/log.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index c51628c50..a5501557d 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -376,7 +376,11 @@ class RedactingFormatter(Formatter): msg = super(RedactingFormatter, self).format(record) self.identify_data_to_redact(msg) for data in self.data_to_redact: - msg = msg.replace(data, "**********") + # we check that data is not empty string, + # otherwise this may lead to super epic stuff + # (try to run "foo".replace("", "bar")) + if data: + msg = msg.replace(data, "**********") return msg def identify_data_to_redact(self, record): From d12f403fe3235364f80f33c0522fb56e1998cb26 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 25 Feb 2021 16:57:57 +0100 Subject: [PATCH 065/131] Fix permission helper doc format --- data/helpers.d/permission | 47 +++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/data/helpers.d/permission b/data/helpers.d/permission index 1791425b5..4b51902eb 100644 --- a/data/helpers.d/permission +++ b/data/helpers.d/permission @@ -25,19 +25,14 @@ # usage: ynh_permission_create --permission="permission" [--url="url"] [--additional_urls="second-url" [ "third-url" ]] [--auth_header=true|false] # [--allowed=group1 [ group2 ]] [--label="label"] [--show_tile=true|false] # [--protected=true|false] -# | arg: -p, permission= - the name for the permission (by default a permission named "main" already exist) -# | arg: -u, url= - (optional) URL for which access will be allowed/forbidden. -# | Not that if 'show_tile' is enabled, this URL will be the URL of the tile. -# | arg: -A, additional_urls= - (optional) List of additional URL for which access will be allowed/forbidden -# | arg: -h, auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application. Default is true -# | arg: -a, allowed= - (optional) A list of group/user to allow for the permission -# | arg: -l, label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. -# | Default is "APP_LABEL (permission name)". -# | arg: -t, show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. -# | Default is false (for the permission different than 'main'). -# | arg: -P, protected= - (optional) Define if this permission is protected. If it is protected the administrator -# | won't be able to add or remove the visitors group of this permission. -# | By default it's 'false' +# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist) +# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden. Note that if 'show_tile' is enabled, this URL will be the URL of the tile. +# | arg: -A, --additional_urls= - (optional) List of additional URL for which access will be allowed/forbidden +# | arg: -h, --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application. Default is true +# | arg: -a, --allowed= - (optional) A list of group/user to allow for the permission +# | arg: -l, --label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. Default is "APP_LABEL (permission name)". +# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. Defaults to false for the permission different than 'main'. +# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. Defaults to 'false'. # # If provided, 'url' or 'additional_urls' is assumed to be relative to the app domain/path if they # start with '/'. For example: @@ -192,13 +187,12 @@ ynh_permission_exists() { # # usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]] # [--auth_header=true|false] [--clear_urls] -# | arg: -p, permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed) -# | arg: -u, url= - (optional) URL for which access will be allowed/forbidden. -# | Note that if you want to remove url you can pass an empty sting as arguments (""). -# | arg: -a, add_url= - (optional) List of additional url to add for which access will be allowed/forbidden. -# | arg: -r, remove_url= - (optional) List of additional url to remove for which access will be allowed/forbidden -# | arg: -h, auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application -# | arg: -c, clear_urls - (optional) Clean all urls (url and additional_urls) +# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed) +# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden. Note that if you want to remove url you can pass an empty sting as arguments (""). +# | arg: -a, --add_url= - (optional) List of additional url to add for which access will be allowed/forbidden. +# | arg: -r, --remove_url= - (optional) List of additional url to remove for which access will be allowed/forbidden +# | arg: -h, --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application +# | arg: -c, --clear_urls - (optional) Clean all urls (url and additional_urls) # # Requires YunoHost version 3.7.0 or higher. ynh_permission_url() { @@ -268,13 +262,12 @@ ynh_permission_url() { # # usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]] # [--label="label"] [--show_tile=true|false] [--protected=true|false] -# | arg: -p, permission= - the name for the permission (by default a permission named "main" already exist) -# | arg: -a, add= - the list of group or users to enable add to the permission -# | arg: -r, remove= - the list of group or users to remove from the permission -# | arg: -l, label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. -# | arg: -t, show_tile= - (optional) Define if a tile will be shown in the SSO -# | arg: -P, protected= - (optional) Define if this permission is protected. If it is protected the administrator -# | won't be able to add or remove the visitors group of this permission. +# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist) +# | arg: -a, --add= - the list of group or users to enable add to the permission +# | arg: -r, --remove= - the list of group or users to remove from the permission +# | arg: -l, --label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. +# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO +# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. # # Requires YunoHost version 3.7.0 or higher. ynh_permission_update() { From 05969184feda1cb6c554ff0be2857229d140fde9 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 25 Feb 2021 11:16:34 +0100 Subject: [PATCH 066/131] fix ynh_systemd_action in case of service fails --- data/helpers.d/systemd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index b0e175d4d..7f316cf2b 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -92,7 +92,7 @@ ynh_remove_systemd_config () { # usage: ynh_systemd_action [--service_name=service_name] [--action=action] [ [--line_match="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ] # | arg: -n, --service_name= - Name of the service to start. Default : $app # | arg: -a, --action= - Action to perform with systemctl. Default: start -# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. WARNING: When using --line_match, you should always add `ynh_clean_check_starting` into your `ynh_clean_setup` at the beginning of the script. Otherwise, tail will not stop in case of failure of the script. The script will then hang forever. +# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. # | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log # | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds. # | arg: -e, --length= - Length of the error log : Default : 20 @@ -151,6 +151,7 @@ ynh_systemd_action() { then ynh_exec_err tail --lines=$length "$log_path" fi + ynh_clean_check_starting return 1 fi @@ -195,9 +196,8 @@ ynh_systemd_action() { } # Clean temporary process and file used by ynh_check_starting -# (usually used in ynh_clean_setup scripts) # -# usage: ynh_clean_check_starting +# [internal] # # Requires YunoHost version 3.5.0 or higher. ynh_clean_check_starting () { @@ -208,7 +208,7 @@ ynh_clean_check_starting () { fi if [ -n "$templog" ] then - ynh_secure_remove "$templog" 2>&1 + ynh_secure_remove --file="$templog" 2>&1 fi } From 6ce02270ae9b6f5ad0c14b790769795b80aa0afa Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Feb 2021 23:46:12 +0100 Subject: [PATCH 067/131] Gotta escape \ during ynh_replace_vars --- data/helpers.d/utils | 1 + 1 file changed, 1 insertion(+) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 53a7ea3b7..e26cac5ba 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -403,6 +403,7 @@ ynh_replace_vars () { match_string="__${one_var^^}__" match_string=${match_string//${delimit}/"\\${delimit}"} replace_string="${!one_var}" + replace_string=${replace_string//\\/\\\\} replace_string=${replace_string//${delimit}/"\\${delimit}"} # Actually replace (sed is used instead of ynh_replace_string to avoid triggering an epic amount of debug logs) From bd8644a651a77b16713aec2d83ca04468c31b5b5 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 20 Feb 2021 17:07:38 +0100 Subject: [PATCH 068/131] Translation typo.. --- locales/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index 9b5d18f1a..0a5095b9e 100644 --- a/locales/it.json +++ b/locales/it.json @@ -591,7 +591,7 @@ "log_user_permission_update": "Aggiorna gli accessi del permesso '{}'", "log_user_group_update": "Aggiorna il gruppo '{}'", "log_user_group_delete": "Cancella il gruppo '{}'", - "log_user_group_create": "Crea il gruppo '[}'", + "log_user_group_create": "Crea il gruppo '{}'", "log_permission_url": "Aggiorna l'URL collegato al permesso '{}'", "log_permission_delete": "Cancella permesso '{}'", "log_permission_create": "Crea permesso '{}'", From 234ae15d771b620b1239236c789cd5be66f7062f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 2 Mar 2021 02:07:58 +0100 Subject: [PATCH 069/131] Update changelog for 4.1.7.3 --- debian/changelog | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 95cca2eb8..5fb0e563d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,17 @@ -yunohost (4.1.7.2) testing; urgency=low +yunohost (4.1.7.3) stable; urgency=low + + - [fix] log: Some secrets were not redacted (0c172cd3) + - [fix] log: For some reason sometimes we were redacting 'empty string' which made everything explode (88b414c8) + - [fix] helpers: Various fixes for ynh_add_config / ynh_replace_vars (a43cd72c, 2728801d, 9bbc3b72, 2402a1db, 6ce02270) + - [fix] helpers: Fix permission helpers doc format (d12f403f) + - [fix] helpers: ynh_systemd_action did not properly clean the 'tail' process when service action failed (05969184) + - [fix] i18n: Translation typo in italian translation ... (bd8644a6) + + Thanks to all contributors <3 ! (Kay0u, yalh76) + + -- Alexandre Aubin Tue, 02 Mar 2021 02:03:35 +0100 + +yunohost (4.1.7.2) stable; urgency=low - [fix] When migration legacy protected permissions, all users were allowed on the new perm (29bd3c4a) - [fix] Mysql is a fucking joke (... trying to fix the mysql issue on RPi ...) (cd4fdb2b) From 9b13c95f77f1d2929841ec889d5c46173bc9033b Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 2 Mar 2021 19:54:24 +0100 Subject: [PATCH 070/131] Re-add --others_var in fail2ban and systemd helpers for backward compatibility... --- data/helpers.d/fail2ban | 7 +++++-- data/helpers.d/systemd | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/data/helpers.d/fail2ban b/data/helpers.d/fail2ban index c9322d067..f8b2b1761 100644 --- a/data/helpers.d/fail2ban +++ b/data/helpers.d/fail2ban @@ -61,12 +61,13 @@ # Requires YunoHost version 3.5.0 or higher. ynh_add_fail2ban_config () { # Declare an array to define the options of this helper. - local legacy_args=lrmpt - local -A args_array=( [l]=logpath= [r]=failregex= [m]=max_retry= [p]=ports= [t]=use_template) + local legacy_args=lrmptv + local -A args_array=( [l]=logpath= [r]=failregex= [m]=max_retry= [p]=ports= [t]=use_template [v]=others_var=) local logpath local failregex local max_retry local ports + local others_var local use_template # Manage arguments with getopts ynh_handle_getopts_args "$@" @@ -74,6 +75,8 @@ ynh_add_fail2ban_config () { ports=${ports:-http,https} use_template="${use_template:-0}" + [[ -z "$others_var" ]] || ynh_print_warn --message="Packagers: using --others_var is unecessary since Yunohost 4.2" + if [ $use_template -ne 1 ] then # Usage 1, no template. Build a config file from scratch. diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index f8e21bfbd..b43b593fa 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -13,15 +13,18 @@ # Requires YunoHost version 2.7.11 or higher. ynh_add_systemd_config () { # Declare an array to define the options of this helper. - local legacy_args=st - local -A args_array=( [s]=service= [t]=template=) + local legacy_args=stv + local -A args_array=( [s]=service= [t]=template= [v]=others_var=) local service local template + local others_var # Manage arguments with getopts ynh_handle_getopts_args "$@" local service="${service:-$app}" local template="${template:-systemd.service}" + [[ -z "$others_var" ]] || ynh_print_warn --message="Packagers: using --others_var is unecessary since Yunohost 4.2" + ynh_add_config --template="$YNH_APP_BASEDIR/conf/$template" --destination="/etc/systemd/system/$service.service" systemctl enable $service --quiet From 4603697ac5e37efc6cd0c734dec260019301d96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Tue, 16 Feb 2021 14:39:24 +0100 Subject: [PATCH 071/131] helper doc fixes : permission --- data/helpers.d/permission | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/data/helpers.d/permission b/data/helpers.d/permission index ba2b22a53..995bff0eb 100644 --- a/data/helpers.d/permission +++ b/data/helpers.d/permission @@ -2,15 +2,17 @@ # Create a new permission for the app # -# example 1: ynh_permission_create --permission=admin --url=/admin --additional_urls=domain.tld/admin /superadmin --allowed=alice bob \ -# --label="My app admin" --show_tile=true +# Example 1: `ynh_permission_create --permission=admin --url=/admin --additional_urls=domain.tld/admin /superadmin --allowed=alice bob \ +# --label="My app admin" --show_tile=true` # # This example will create a new permission permission with this following effect: # - A tile named "My app admin" in the SSO will be available for the users alice and bob. This tile will point to the relative url '/admin'. # - Only the user alice and bob will have the access to theses following url: /admin, domain.tld/admin, /superadmin # # -# example 2: ynh_permission_create --permission=api --url=domain.tld/api --auth_header=false --allowed=visitors \ +# Example 2: +# +# ynh_permission_create --permission=api --url=domain.tld/api --auth_header=false --allowed=visitors \ # --label="MyApp API" --protected=true # # This example will create a new protected permission. So the admin won't be able to add/remove the visitors group of this permission. @@ -18,7 +20,7 @@ # With this permission all client will be allowed to access to the url 'domain.tld/api'. # Note that in this case no tile will be show on the SSO. # Note that the auth_header parameter is to 'false'. So no authentication header will be passed to the application. -# Generally the API is requested by an application and enabling the auth_header has no advantage and could bring some issues in some case. +# Generally the API is requested by an application and enabling the auth_header has no advantage and could bring some issues in some case. # So in this case it's better to disable this option for all API. # # @@ -36,14 +38,14 @@ # # If provided, 'url' or 'additional_urls' is assumed to be relative to the app domain/path if they # start with '/'. For example: -# / -> domain.tld/app -# /admin -> domain.tld/app/admin -# domain.tld/app/api -> domain.tld/app/api +# / -> domain.tld/app +# /admin -> domain.tld/app/admin +# domain.tld/app/api -> domain.tld/app/api # # 'url' or 'additional_urls' can be treated as a PCRE (not lua) regex if it starts with "re:". # For example: -# re:/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ -# re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ +# re:/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ +# re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ # # Note that globally the parameter 'url' and 'additional_urls' are same. The only difference is: # - 'url' is only one url, 'additional_urls' can be a list of urls. There are no limitation of 'additional_urls' @@ -56,7 +58,7 @@ # - "Remote-User": username # - "Email": user email # -# Generally this feature is usefull to authenticate automatically the user in the application but in some case the application don't work with theses header and theses header need to be disabled to have the application to work correctly. +# Generally this feature is usefull to authenticate automatically the user in the application but in some case the application don't work with theses header and theses header need to be disabled to have the application to work correctly. # See https://github.com/YunoHost/issues/issues/1420 for more informations # # @@ -186,7 +188,7 @@ ynh_permission_exists() { # Redefine the url associated to a permission # -# usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]] +# usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]] # [--auth_header=true|false] [--clear_urls] # | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed) # | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden. Note that if you want to remove url you can pass an empty sting as arguments (""). From e6f3adfa08a08373e5ab1b4e75a8fc88e7f00dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:58:06 +0100 Subject: [PATCH 072/131] helper doc fixes : apt --- data/helpers.d/apt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/data/helpers.d/apt b/data/helpers.d/apt index bfdeffe7b..1b5ab982f 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -47,10 +47,11 @@ ynh_wait_dpkg_free() { # Check either a package is installed or not # -# example: ynh_package_is_installed --package=yunohost && echo "ok" +# example: ynh_package_is_installed --package=yunohost && echo "installed" # # usage: ynh_package_is_installed --package=name # | arg: -p, --package= - the package name to check +# | ret: 0 if the package is installed, 1 else. # # Requires YunoHost version 2.2.4 or higher. ynh_package_is_installed() { @@ -180,7 +181,7 @@ ynh_package_install_from_equivs () { # Build and install the package local TMPDIR=$(mktemp --directory) - # Force the compatibility level at 10, levels below are deprecated + # Force the compatibility level at 10, levels below are deprecated echo 10 > /usr/share/equivs/template/debian/compat # Note that the cd executes into a sub shell @@ -194,7 +195,7 @@ ynh_package_install_from_equivs () { LC_ALL=C dpkg --force-depends --install "./${pkgname}_${pkgversion}_all.deb" 2>&1 | tee ./dpkg_log) ynh_package_install --fix-broken || \ - { # If the installation failed + { # If the installation failed # (the following is ran inside { } to not start a subshell otherwise ynh_die wouldnt exit the original process) # Parse the list of problematic dependencies from dpkg's log ... # (relevant lines look like: "foo-ynh-deps depends on bar; however:") @@ -216,7 +217,8 @@ ynh_package_install_from_equivs () { # example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5" # # usage: ynh_install_app_dependencies dep [dep [...]] -# | arg: dep - the package name to install in dependence. Writing "dep3|dep4|dep5" can be used to specify alternatives. For example : dep1 dep2 "dep3|dep4|dep5" will require to install dep1 and dep 2 and (dep3 or dep4 or dep5). +# | arg: dep - the package name to install in dependence. +# | arg: "dep1|dep2|…" - You can specify alternatives. It will require to install (dep1 or dep2, etc). # # Requires YunoHost version 2.6.4 or higher. ynh_install_app_dependencies () { @@ -253,7 +255,7 @@ ynh_install_app_dependencies () { # Epic ugly hack to fix the goddamn dependency nightmare of sury # Sponsored by the "Djeezusse Fokin Kraiste Why Do Adminsys Has To Be So Fucking Complicated I Should Go Grow Potatoes Instead Of This Shit" collective # https://github.com/YunoHost/issues/issues/1407 - # + # # If we require to install php dependency if echo $dependencies | grep --quiet 'php' then From d69f031d8fffedbfe916f91f493c32ea5d627ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:58:34 +0100 Subject: [PATCH 073/131] helper doc fixes : backup --- data/helpers.d/backup | 79 ++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/data/helpers.d/backup b/data/helpers.d/backup index 33a6db4e2..17da0fb2e 100644 --- a/data/helpers.d/backup +++ b/data/helpers.d/backup @@ -13,13 +13,13 @@ CAN_BIND=${CAN_BIND:-1} # # This helper can be used both in a system backup hook, and in an app backup script # -# Details: ynh_backup writes SRC and the relative DEST into a CSV file. And it +# `ynh_backup` writes `src_path` and the relative `dest_path` into a CSV file, and it # creates the parent destination directory # -# If DEST is ended by a slash it complete this path with the basename of SRC. -# -# Example in the context of a wordpress app +# If `dest_path` is ended by a slash it complete this path with the basename of `src_path`. # +# Example in the context of a wordpress app : +# ``` # ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" # # => This line will be added into CSV file # # "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/etc/nginx/conf.d/$domain.d/$app.conf" @@ -40,26 +40,28 @@ CAN_BIND=${CAN_BIND:-1} # ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "/conf/" # # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf/$app.conf" # +# ``` # -# How to use --is_big: -# --is_big is used to specify that this part of the backup can be quite huge. +# How to use `--is_big`: +# +# `--is_big` is used to specify that this part of the backup can be quite huge. # So, you don't want that your package does backup that part during ynh_backup_before_upgrade. # In the same way, an user may doesn't want to backup this big part of the app for -# each of his backup. And so handle that part differently. -# -# As this part of your backup may not be done, your restore script has to handle it. -# In your restore script, use --not_mandatory with ynh_restore_file -# As well in your remove script, you should not remove those data ! Or an user may end up with -# a failed upgrade restoring an app without data anymore ! +# each of his backup. And so handle that part differently. # -# To have the benefit of --is_big while doing a backup, you can whether set the environement -# variable BACKUP_CORE_ONLY to 1 (BACKUP_CORE_ONLY=1) before the backup command. It will affect -# only that backup command. -# Or set the config do_not_backup_data to 1 into the settings.yml of the app. This will affect -# all backups for this app until the setting is removed. +# As this part of your backup may not be done, your restore script has to handle it. +# In your restore script, use `--not_mandatory` with `ynh_restore_file` +# As well in your remove script, you should not remove those data ! Or an user may end up with +# a failed upgrade restoring an app without data anymore ! +# +# To have the benefit of `--is_big` while doing a backup, you can whether set the environement +# variable `BACKUP_CORE_ONLY` to 1 (`BACKUP_CORE_ONLY=1`) before the backup command. It will affect +# only that backup command. +# Or set the config `do_not_backup_data` to 1 into the `settings.yml` of the app. This will affect +# all backups for this app until the setting is removed. # # Requires YunoHost version 2.4.0 or higher. -# Requires YunoHost version 3.5.0 or higher for the argument --not_mandatory +# Requires YunoHost version 3.5.0 or higher for the argument `--not_mandatory` ynh_backup() { # TODO find a way to avoid injection by file strange naming ! @@ -81,7 +83,7 @@ ynh_backup() { # If backing up core only (used by ynh_backup_before_upgrade), # don't backup big data items - if [ $is_big -eq 1 ] && ( [ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ] ) + if [ $is_big -eq 1 ] && ( [ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ] ) then if [ $BACKUP_CORE_ONLY -eq 1 ] then @@ -221,26 +223,25 @@ with open(sys.argv[1], 'r') as backup_file: # Restore a file or a directory # -# Use the registered path in backup_list by ynh_backup to restore the file at -# the right place. -# # usage: ynh_restore_file --origin_path=origin_path [--dest_path=dest_path] [--not_mandatory] # | arg: -o, --origin_path= - Path where was located the file or the directory before to be backuped or relative path to $YNH_CWD where it is located in the backup archive -# | arg: -d, --dest_path= - Path where restore the file or the dir, if unspecified, the destination will be ORIGIN_PATH or if the ORIGIN_PATH doesn't exist in the archive, the destination will be searched into backup.csv +# | arg: -d, --dest_path= - Path where restore the file or the dir. If unspecified, the destination will be `ORIGIN_PATH` or if the `ORIGIN_PATH` doesn't exist in the archive, the destination will be searched into `backup.csv` # | arg: -m, --not_mandatory - Indicate that if the file is missing, the restore process can ignore it. # +# Use the registered path in backup_list by ynh_backup to restore the file at the right place. +# # examples: -# ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" +# ynh_restore_file -o "/etc/nginx/conf.d/$domain.d/$app.conf" # # You can also use relative paths: -# ynh_restore_file "conf/nginx.conf" +# ynh_restore_file -o "conf/nginx.conf" # -# If DEST_PATH already exists and is lighter than 500 Mo, a backup will be made in -# /home/yunohost.conf/backup/. Otherwise, the existing file is removed. +# If `DEST_PATH` already exists and is lighter than 500 Mo, a backup will be made in +# `/home/yunohost.conf/backup/`. Otherwise, the existing file is removed. # -# if apps/wordpress/etc/nginx/conf.d/$domain.d/$app.conf exists, restore it into -# /etc/nginx/conf.d/$domain.d/$app.conf +# if `apps/$app/etc/nginx/conf.d/$domain.d/$app.conf` exists, restore it into +# `/etc/nginx/conf.d/$domain.d/$app.conf` # if no, search for a match in the csv (eg: conf/nginx.conf) and restore it into -# /etc/nginx/conf.d/$domain.d/$app.conf +# `/etc/nginx/conf.d/$domain.d/$app.conf` # # Requires YunoHost version 2.6.4 or higher. # Requires YunoHost version 3.5.0 or higher for the argument --not_mandatory @@ -345,14 +346,14 @@ ynh_store_file_checksum () { } # Verify the checksum and backup the file if it's different -# -# This helper is primarily meant to allow to easily backup personalised/manually -# modified config files. # # usage: ynh_backup_if_checksum_is_different --file=file # | arg: -f, --file= - The file on which the checksum test will be perfomed. # | ret: the name of a backup file, or nothing # +# This helper is primarily meant to allow to easily backup personalised/manually +# modified config files. +# # Requires YunoHost version 2.6.4 or higher. ynh_backup_if_checksum_is_different () { # Declare an array to define the options of this helper. @@ -410,12 +411,16 @@ ynh_backup_archive_exists () { # Make a backup in case of failed upgrade # -# usage: +# usage: ynh_backup_before_upgrade +# +# Usage in a package script: +# ``` # ynh_backup_before_upgrade # ynh_clean_setup () { # ynh_restore_upgradebackup # } # ynh_abort_if_errors +# ``` # # Requires YunoHost version 2.7.2 or higher. ynh_backup_before_upgrade () { @@ -459,12 +464,16 @@ ynh_backup_before_upgrade () { # Restore a previous backup if the upgrade process failed # -# usage: +# usage: ynh_restore_upgradebackup +# +# Usage in a package script: +# ``` # ynh_backup_before_upgrade # ynh_clean_setup () { # ynh_restore_upgradebackup # } # ynh_abort_if_errors +# ``` # # Requires YunoHost version 2.7.2 or higher. ynh_restore_upgradebackup () { From 8f294916d9ea0af8318635c0588cb5ac4155cf84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:58:44 +0100 Subject: [PATCH 074/131] helper doc fixes : fail2ban --- data/helpers.d/fail2ban | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/data/helpers.d/fail2ban b/data/helpers.d/fail2ban index f8b2b1761..756f4b84a 100644 --- a/data/helpers.d/fail2ban +++ b/data/helpers.d/fail2ban @@ -12,15 +12,14 @@ # # usage 2: ynh_add_fail2ban_config --use_template [--others_var="list of others variables to replace"] # | arg: -t, --use_template - Use this helper in template mode -# | arg: -v, --others_var= - List of others variables to replace separeted by a space -# | for example : 'var_1 var_2 ...' +# | arg: -v, --others_var= - List of others variables to replace separeted by a space for example : 'var_1 var_2 ...' # -# This will use a template in ../conf/f2b_jail.conf and ../conf/f2b_filter.conf -# See the documentation of ynh_add_config for a description of the template +# This will use a template in `../conf/f2b_jail.conf` and `../conf/f2b_filter.conf` +# See the documentation of `ynh_add_config` for a description of the template # format and how placeholders are replaced with actual variables. # # Generally your template will look like that by example (for synapse): -# +# ``` # f2b_jail.conf: # [__APP__] # enabled = true @@ -28,7 +27,8 @@ # filter = __APP__ # logpath = /var/log/__APP__/logfile.log # maxretry = 3 -# +# ``` +# ``` # f2b_filter.conf: # [INCLUDES] # before = common.conf @@ -41,22 +41,25 @@ # failregex = ^%(__synapse_start_line)s INFO \- POST\-(\d+)\- \- \d+ \- Received request\: POST /_matrix/client/r0/login\??%(__synapse_start_line)s INFO \- POST\-\1\- Got login request with identifier: \{u'type': u'm.id.user', u'user'\: u'(.+?)'\}, medium\: None, address: None, user\: u'\5'%(__synapse_start_line)s WARNING \- \- (Attempted to login as @\5\:.+ but they do not exist|Failed password login for user @\5\:.+)$ # # ignoreregex = +# ``` # # ----------------------------------------------------------------------------- # # Note about the "failregex" option: -# regex to match the password failure messages in the logfile. The -# host must be matched by a group named "host". The tag "" can -# be used for standard IP/hostname matching and is only an alias for -# (?:::f{4,6}:)?(?P[\w\-.^_]+) # -# You can find some more explainations about how to make a regex here : -# https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters +# regex to match the password failure messages in the logfile. The host must be +# matched by a group named "`host`". The tag "``" can be used for standard +# IP/hostname matching and is only an alias for `(?:::f{4,6}:)?(?P[\w\-.^_]+)` +# +# You can find some more explainations about how to make a regex here : +# https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters # # Note that the logfile need to exist before to call this helper !! # # To validate your regex you can test with this command: +# ``` # fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf +# ``` # # Requires YunoHost version 3.5.0 or higher. ynh_add_fail2ban_config () { From 966cd2ff165c1d2de5d999eb5b5a4e42657c4983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:58:53 +0100 Subject: [PATCH 075/131] helper doc fixes : hardware --- data/helpers.d/hardware | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/helpers.d/hardware b/data/helpers.d/hardware index 0771c81d8..6d1c314fa 100644 --- a/data/helpers.d/hardware +++ b/data/helpers.d/hardware @@ -7,7 +7,7 @@ # | arg: -t, --total - Count total RAM+swap # | arg: -s, --ignore_swap - Ignore swap, consider only real RAM # | arg: -o, --only_swap - Ignore real RAM, consider only swap -# | ret: the amount of free ram +# | ret: the amount of free ram, in MB (MegaBytes) # # Requires YunoHost version 3.8.1 or higher. ynh_get_ram () { @@ -35,7 +35,7 @@ ynh_get_ram () { local free_ram=$(vmstat --stats --unit M | grep "free memory" | awk '{print $1}') local free_swap=$(vmstat --stats --unit M | grep "free swap" | awk '{print $1}') local free_ram_swap=$(( free_ram + free_swap )) - + # Use the total amount of free ram local ram=$free_ram_swap if [ $ignore_swap -eq 1 ] @@ -52,7 +52,7 @@ ynh_get_ram () { local total_ram=$(vmstat --stats --unit M | grep "total memory" | awk '{print $1}') local total_swap=$(vmstat --stats --unit M | grep "total swap" | awk '{print $1}') local total_ram_swap=$(( total_ram + total_swap )) - + local ram=$total_ram_swap if [ $ignore_swap -eq 1 ] then @@ -70,13 +70,13 @@ ynh_get_ram () { # Return 0 or 1 depending if the system has a given amount of RAM+swap free or total # -# usage: ynh_require_ram --required=RAM required in Mb [--free|--total] [--ignore_swap|--only_swap] -# | arg: -r, --required= - The amount to require, in Mb +# usage: ynh_require_ram --required=RAM [--free|--total] [--ignore_swap|--only_swap] +# | arg: -r, --required= - The amount to require, in MB # | arg: -f, --free - Count free RAM+swap # | arg: -t, --total - Count total RAM+swap # | arg: -s, --ignore_swap - Ignore swap, consider only real RAM # | arg: -o, --only_swap - Ignore real RAM, consider only swap -# | exit: Return 1 if the ram is under the requirement, 0 otherwise. +# | ret: 1 if the ram is under the requirement, 0 otherwise. # # Requires YunoHost version 3.8.1 or higher. ynh_require_ram () { From 33f8337f11af0a3d9809483cdae5e7e3d78ad1aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:28 +0100 Subject: [PATCH 076/131] helper doc fixes : logging --- data/helpers.d/logging | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/data/helpers.d/logging b/data/helpers.d/logging index dc32ecba9..0505117b7 100644 --- a/data/helpers.d/logging +++ b/data/helpers.d/logging @@ -102,8 +102,7 @@ ynh_print_err () { # Execute a command and print the result as an error # -# usage: ynh_exec_err your_command -# usage: ynh_exec_err "your_command | other_command" +# usage: ynh_exec_err "your_command [ | other_command ]" # | arg: command - command to execute # # When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. @@ -117,8 +116,7 @@ ynh_exec_err () { # Execute a command and print the result as a warning # -# usage: ynh_exec_warn your_command -# usage: ynh_exec_warn "your_command | other_command" +# usage: ynh_exec_warn "your_command [ | other_command ]" # | arg: command - command to execute # # When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. @@ -132,8 +130,7 @@ ynh_exec_warn () { # Execute a command and force the result to be printed on stdout # -# usage: ynh_exec_warn_less your_command -# usage: ynh_exec_warn_less "your_command | other_command" +# usage: ynh_exec_warn_less "your_command [ | other_command ]" # | arg: command - command to execute # # When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. @@ -147,8 +144,7 @@ ynh_exec_warn_less () { # Execute a command and redirect stdout in /dev/null # -# usage: ynh_exec_quiet your_command -# usage: ynh_exec_quiet "your_command | other_command" +# usage: ynh_exec_quiet "your_command [ | other_command ]" # | arg: command - command to execute # # When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. @@ -162,8 +158,7 @@ ynh_exec_quiet () { # Execute a command and redirect stdout and stderr in /dev/null # -# usage: ynh_exec_fully_quiet your_command -# usage: ynh_exec_fully_quiet "your_command | other_command" +# usage: ynh_exec_fully_quiet "your_command [ | other_command ]" # | arg: command - command to execute # # When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. @@ -363,8 +358,7 @@ ynh_debug () { # Execute a command and print the result as debug # -# usage: ynh_debug_exec your_command -# usage: ynh_debug_exec "your_command | other_command" +# usage: ynh_debug_exec "your_command [ | other_command ]" # | arg: command - command to execute # # When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. From 0dde41fe4aaac5bd56c1d091df9a0a00c4532856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:28 +0100 Subject: [PATCH 077/131] helper doc fixes : logrotate --- data/helpers.d/logrotate | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/data/helpers.d/logrotate b/data/helpers.d/logrotate index d5384264c..2d9ab6b72 100644 --- a/data/helpers.d/logrotate +++ b/data/helpers.d/logrotate @@ -7,16 +7,14 @@ # | arg: -n, --nonappend - (optional) Replace the config file instead of appending this new config. # | arg: -u, --specific_user= - run logrotate as the specified user and group. If not specified logrotate is runned as root. # -# If no --logfile is provided, /var/log/${app} will be used as default. -# logfile can be just a directory, or a full path to a logfile : -# /parentdir/logdir -# /parentdir/logdir/logfile.log +# If no `--logfile` is provided, `/var/log/$app` will be used as default. +# `logfile` can point to a directory or a file. # # It's possible to use this helper multiple times, each config will be added to -# the same logrotate config file. Unless you use the option --non-append +# the same logrotate config file. Unless you use the option `--non-append` # # Requires YunoHost version 2.6.4 or higher. -# Requires YunoHost version 3.2.0 or higher for the argument --specific_user +# Requires YunoHost version 3.2.0 or higher for the argument `--specific_user` ynh_use_logrotate () { # Declare an array to define the options of this helper. local legacy_args=lnuya From 27caab72345bd9f27fa304ca23b4b48ff3b5380c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 078/131] helper doc fixes : multimedia --- data/helpers.d/multimedia | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/multimedia b/data/helpers.d/multimedia index f7c9d5974..7b379ad0f 100644 --- a/data/helpers.d/multimedia +++ b/data/helpers.d/multimedia @@ -47,12 +47,14 @@ ynh_multimedia_build_main_dir() { } # Add a directory in yunohost.multimedia -# This "directory" will be a symbolic link to a existing directory. # -# usage: ynh_multimedia_addfolder "Source directory" "Destination directory" +# usage: ynh_multimedia_addfolder --source_dir="source_dir" --dest_dir="dest_dir" # # | arg: -s, --source_dir= - Source directory - The real directory which contains your medias. # | arg: -d, --dest_dir= - Destination directory - The name and the place of the symbolic link, relative to "/home/yunohost.multimedia" +# +# This "directory" will be a symbolic link to a existing directory. +# ynh_multimedia_addfolder() { # Declare an array to define the options of this helper. @@ -80,6 +82,7 @@ ynh_multimedia_addfolder() { # usage: ynh_multimedia_addaccess user_name # # | arg: -u, --user_name= - The name of the user which gain this access. +# ynh_multimedia_addaccess () { # Declare an array to define the options of this helper. local legacy_args=u From 75539472ea9d28ce76d1a298fb85aa25a946b1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 079/131] helper doc fixes : mysql --- data/helpers.d/mysql | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/data/helpers.d/mysql b/data/helpers.d/mysql index 6808441b7..091dfaf40 100644 --- a/data/helpers.d/mysql +++ b/data/helpers.d/mysql @@ -2,14 +2,15 @@ # Open a connection as a user # -# example: ynh_mysql_connect_as --user="user" --password="pass" <<< "UPDATE ...;" -# example: ynh_mysql_connect_as --user="user" --password="pass" < /path/to/file.sql -# # usage: ynh_mysql_connect_as --user=user --password=password [--database=database] # | arg: -u, --user= - the user name to connect as # | arg: -p, --password= - the user password # | arg: -d, --database= - the database to connect to # +# examples: +# ynh_mysql_connect_as --user="user" --password="pass" <<< "UPDATE ...;" +# ynh_mysql_connect_as --user="user" --password="pass" < /path/to/file.sql +# # Requires YunoHost version 2.2.4 or higher. ynh_mysql_connect_as() { # Declare an array to define the options of this helper. @@ -120,11 +121,11 @@ ynh_mysql_drop_db() { # Dump a database # -# example: ynh_mysql_dump_db --database=roundcube > ./dump.sql -# # usage: ynh_mysql_dump_db --database=database # | arg: -d, --database= - the database name to dump -# | ret: the mysqldump output +# | ret: The mysqldump output +# +# example: ynh_mysql_dump_db --database=roundcube > ./dump.sql # # Requires YunoHost version 2.2.4 or higher. ynh_mysql_dump_db() { @@ -156,7 +157,7 @@ ynh_mysql_create_user() { # # usage: ynh_mysql_user_exists --user=user # | arg: -u, --user= - the user for which to check existence -# | exit: Return 1 if the user doesn't exist, 0 otherwise. +# | ret: 0 if the user exists, 1 otherwise. # # Requires YunoHost version 2.2.4 or higher. ynh_mysql_user_exists() @@ -195,8 +196,8 @@ ynh_mysql_drop_user() { # | arg: -n, --db_name= - Name of the database # | arg: -p, --db_pwd= - Password of the database. If not provided, a password will be generated # -# After executing this helper, the password of the created database will be available in $db_pwd -# It will also be stored as "mysqlpwd" into the app settings. +# After executing this helper, the password of the created database will be available in `$db_pwd` +# It will also be stored as "`mysqlpwd`" into the app settings. # # Requires YunoHost version 2.6.4 or higher. ynh_mysql_setup_db () { From 94097d1153a40261a6d7b9df654e8f9a9cd66716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 080/131] helper doc fixes : network --- data/helpers.d/network | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/data/helpers.d/network b/data/helpers.d/network index 0760909c6..702757534 100644 --- a/data/helpers.d/network +++ b/data/helpers.d/network @@ -2,12 +2,12 @@ # Find a free port and return it # -# example: port=$(ynh_find_port --port=8080) -# # usage: ynh_find_port --port=begin_port # | arg: -p, --port= - port to start to search # | ret: the port number # +# example: port=$(ynh_find_port --port=8080) +# # Requires YunoHost version 2.6.4 or higher. ynh_find_port () { # Declare an array to define the options of this helper. @@ -27,11 +27,11 @@ ynh_find_port () { # Test if a port is available # -# example: ynh_port_available --port=1234 || ynh_die --message="Port 1234 is needs to be available for this app" -# # usage: ynh_find_port --port=XYZ # | arg: -p, --port= - port to check -# | exit: Return 1 if the port is already used by another process. +# | ret: 0 if the port is available, 1 if it is already used by another process. +# +# example: ynh_port_available --port=1234 || ynh_die --message="Port 1234 is needs to be available for this app" # # Requires YunoHost version 3.8.0 or higher. ynh_port_available () { @@ -89,12 +89,12 @@ EOF # Validate an IPv4 address # -# example: ynh_validate_ip4 111.222.333.444 -# # usage: ynh_validate_ip4 --ip_address=ip_address # | arg: -i, --ip_address= - the ipv4 address to check # | ret: 0 for valid ipv4 addresses, 1 otherwise # +# example: ynh_validate_ip4 111.222.333.444 +# # Requires YunoHost version 2.2.4 or higher. ynh_validate_ip4() { @@ -111,12 +111,12 @@ ynh_validate_ip4() # Validate an IPv6 address # -# example: ynh_validate_ip6 2000:dead:beef::1 -# # usage: ynh_validate_ip6 --ip_address=ip_address -# | arg: -i, --ip_address= - the ipv6 address to check +# | arg: -i, --ip_address= - the ipv6 address to check # | ret: 0 for valid ipv6 addresses, 1 otherwise # +# example: ynh_validate_ip6 2000:dead:beef::1 +# # Requires YunoHost version 2.2.4 or higher. ynh_validate_ip6() { From 52cc5949da252c9c3ec807c303aac6365c86a41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 081/131] helper doc fixes : nginx --- data/helpers.d/nginx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/helpers.d/nginx b/data/helpers.d/nginx index 3c6254953..7214b1e26 100644 --- a/data/helpers.d/nginx +++ b/data/helpers.d/nginx @@ -4,13 +4,13 @@ # # usage: ynh_add_nginx_config # -# This will use a template in ../conf/nginx.conf -# See the documentation of ynh_add_config for a description of the template +# This will use a template in `../conf/nginx.conf` +# See the documentation of `ynh_add_config` for a description of the template # format and how placeholders are replaced with actual variables. # # Additionally, ynh_add_nginx_config will replace: -# - #sub_path_only by empty string if path_url is not '/' -# - #root_path_only by empty string if path_url *is* '/' +# - `#sub_path_only` by empty string if `path_url` is not `'/'` +# - `#root_path_only` by empty string if `path_url` *is* `'/'` # # This allows to enable/disable specific behaviors dependenging on the install # location From 3844b48962d58116d89ccb8d58c343ab3b391c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 082/131] helper doc fixes : nodejs --- data/helpers.d/nodejs | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/data/helpers.d/nodejs b/data/helpers.d/nodejs index 2e1c787cf..f78a53fd5 100644 --- a/data/helpers.d/nodejs +++ b/data/helpers.d/nodejs @@ -28,11 +28,14 @@ SOURCE_SUM=2933855140f980fc6d1d6103ea07cd4d915b17dea5e17e43921330ea89978b5b" > " # Load the version of node for an app, and set variables. # -# ynh_use_nodejs has to be used in any app scripts before using node for the first time. +# usage: ynh_use_nodejs +# +# `ynh_use_nodejs` has to be used in any app scripts before using node for the first time. # This helper will provide alias and variables to use in your scripts. # -# To use npm or node, use the alias `ynh_npm` and `ynh_node` -# Those alias will use the correct version installed for the app +# To use npm or node, use the alias `ynh_npm` and `ynh_node`. +# +# Those alias will use the correct version installed for the app. # For example: use `ynh_npm install` instead of `npm install` # # With `sudo` or `ynh_exec_as`, use instead the fallback variables `$ynh_npm` and `$ynh_node` @@ -40,30 +43,32 @@ SOURCE_SUM=2933855140f980fc6d1d6103ea07cd4d915b17dea5e17e43921330ea89978b5b" > " # Exemple: `ynh_exec_as $app $ynh_node_load_PATH $ynh_npm install` # # $PATH contains the path of the requested version of node. -# However, $PATH is duplicated into $node_PATH to outlast any manipulation of $PATH +# However, $PATH is duplicated into $node_PATH to outlast any manipulation of `$PATH` # You can use the variable `$ynh_node_load_PATH` to quickly load your node version -# in $PATH for an usage into a separate script. +# in $PATH for an usage into a separate script. # Exemple: $ynh_node_load_PATH $final_path/script_that_use_npm.sh` # # # Finally, to start a nodejs service with the correct version, 2 solutions # Either the app is dependent of node or npm, but does not called it directly. -# In such situation, you need to load PATH -# `Environment="__NODE_ENV_PATH__"` -# `ExecStart=__FINALPATH__/my_app` -# You will replace __NODE_ENV_PATH__ with $ynh_node_load_PATH +# In such situation, you need to load PATH : +# ``` +# Environment="__NODE_ENV_PATH__" +# ExecStart=__FINALPATH__/my_app +# ``` +# You will replace __NODE_ENV_PATH__ with $ynh_node_load_PATH. # # Or node start the app directly, then you don't need to load the PATH variable -# `ExecStart=__YNH_NODE__ my_app run` -# You will replace __YNH_NODE__ with $ynh_node +# ``` +# ExecStart=__YNH_NODE__ my_app run +# ``` +# You will replace __YNH_NODE__ with $ynh_node # # # 2 other variables are also available # - $nodejs_path: The absolute path to node binaries for the chosen version. # - $nodejs_version: Just the version number of node for this app. Stored as 'nodejs_version' in settings.yml. # -# usage: ynh_use_nodejs -# # Requires YunoHost version 2.7.12 or higher. ynh_use_nodejs () { nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version) @@ -97,10 +102,10 @@ ynh_use_nodejs () { # usage: ynh_install_nodejs --nodejs_version=nodejs_version # | arg: -n, --nodejs_version= - Version of node to install. When possible, your should prefer to use major version number (e.g. 8 instead of 8.10.0). The crontab will then handle the update of minor versions when needed. # -# n (Node version management) uses the PATH variable to store the path of the version of node it is going to use. +# `n` (Node version management) uses the `PATH` variable to store the path of the version of node it is going to use. # That's how it changes the version # -# Refer to ynh_use_nodejs for more information about available commands and variables +# Refer to `ynh_use_nodejs` for more information about available commands and variables # # Requires YunoHost version 2.7.12 or higher. ynh_install_nodejs () { @@ -177,12 +182,12 @@ ynh_install_nodejs () { # Remove the version of node used by the app. # -# This helper will check if another app uses the same version of node, -# if not, this version of node will be removed. -# If no other app uses node, n will be also removed. -# # usage: ynh_remove_nodejs # +# This helper will check if another app uses the same version of node. +# - If not, this version of node will be removed. +# - If no other app uses node, n will be also removed. +# # Requires YunoHost version 2.7.12 or higher. ynh_remove_nodejs () { nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version) From 706dbe723e9852943596de38c26202ac4367d36f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 083/131] helper doc fixes : php --- data/helpers.d/php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/helpers.d/php b/data/helpers.d/php index 5c050cc88..a590da3dd 100644 --- a/data/helpers.d/php +++ b/data/helpers.d/php @@ -569,6 +569,7 @@ YNH_COMPOSER_VERSION=${YNH_COMPOSER_VERSION:-$YNH_DEFAULT_COMPOSER_VERSION} # | arg: -v, --phpversion - PHP version to use with composer # | arg: -w, --workdir - The directory from where the command will be executed. Default $final_path. # | arg: -c, --commands - Commands to execute. +# ynh_composer_exec () { # Declare an array to define the options of this helper. local legacy_args=vwc @@ -593,6 +594,7 @@ ynh_composer_exec () { # | arg: -w, --workdir - The directory from where the command will be executed. Default $final_path. # | arg: -a, --install_args - Additional arguments provided to the composer install. Argument --no-dev already include # | arg: -c, --composerversion - Composer version to install +# ynh_install_composer () { # Declare an array to define the options of this helper. local legacy_args=vwac From dc27fd3ec3ab2a1c67102f023c4d1413723b4ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 084/131] helper doc fixes : postgresql --- data/helpers.d/postgresql | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/data/helpers.d/postgresql b/data/helpers.d/postgresql index f2f427842..12738a922 100644 --- a/data/helpers.d/postgresql +++ b/data/helpers.d/postgresql @@ -5,15 +5,15 @@ PSQL_VERSION=11 # Open a connection as a user # -# examples: -# ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;" -# ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql -# # usage: ynh_psql_connect_as --user=user --password=password [--database=database] # | arg: -u, --user= - the user name to connect as # | arg: -p, --password= - the user password # | arg: -d, --database= - the database to connect to # +# examples: +# ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;" +# ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql +# # Requires YunoHost version 3.5.0 or higher. ynh_psql_connect_as() { # Declare an array to define the options of this helper. @@ -127,12 +127,12 @@ ynh_psql_drop_db() { # Dump a database # -# example: ynh_psql_dump_db 'roundcube' > ./dump.sql -# # usage: ynh_psql_dump_db --database=database # | arg: -d, --database= - the database name to dump # | ret: the psqldump output # +# example: ynh_psql_dump_db 'roundcube' > ./dump.sql +# # Requires YunoHost version 3.5.0 or higher. ynh_psql_dump_db() { # Declare an array to define the options of this helper. @@ -243,7 +243,7 @@ ynh_psql_setup_db() { local new_db_pwd=$(ynh_string_random) # Generate a random password # If $db_pwd is not provided, use new_db_pwd instead for db_pwd db_pwd="${db_pwd:-$new_db_pwd}" - + ynh_psql_create_user "$db_user" "$db_pwd" elif [ -z $db_pwd ]; then ynh_die --message="The user $db_user exists, please provide his password" @@ -286,11 +286,12 @@ ynh_psql_remove_db() { } # Create a master password and set up global settings -# It also make sure that postgresql is installed and running -# Please always call this script in install and restore scripts # # usage: ynh_psql_test_if_first_run # +# It also make sure that postgresql is installed and running +# Please always call this script in install and restore scripts +# # Requires YunoHost version 2.7.13 or higher. ynh_psql_test_if_first_run() { From 305a70a8d5a60fb10aad807a0af71c82e059afc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 085/131] helper doc fixes : setting --- data/helpers.d/setting | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index a66e0d1ea..2950b3829 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -77,7 +77,7 @@ ynh_app_setting_delete() { # [internal] # ynh_app_setting() -{ +{ set +o xtrace # set +x ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python3 - < Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 086/131] helper doc fixes : string --- data/helpers.d/string | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data/helpers.d/string b/data/helpers.d/string index a0bcdbfaf..7036b3b3c 100644 --- a/data/helpers.d/string +++ b/data/helpers.d/string @@ -2,12 +2,12 @@ # Generate a random string # -# example: pwd=$(ynh_string_random --length=8) -# # usage: ynh_string_random [--length=string_length] # | arg: -l, --length= - the string length to generate (default: 24) # | ret: the generated string # +# example: pwd=$(ynh_string_random --length=8) +# # Requires YunoHost version 2.2.4 or higher. ynh_string_random() { # Declare an array to define the options of this helper. @@ -30,9 +30,8 @@ ynh_string_random() { # | arg: -r, --replace_string= - String that will replace matches # | arg: -f, --target_file= - File in which the string will be replaced. # -# As this helper is based on sed command, regular expressions and -# references to sub-expressions can be used -# (see sed manual page for more information) +# As this helper is based on sed command, regular expressions and references to +# sub-expressions can be used (see sed manual page for more information) # # Requires YunoHost version 2.6.4 or higher. ynh_replace_string () { @@ -86,14 +85,15 @@ ynh_replace_special_string () { } # Sanitize a string intended to be the name of a database -# (More specifically : replace - and . by _) -# -# example: dbname=$(ynh_sanitize_dbid $app) # # usage: ynh_sanitize_dbid --db_name=name # | arg: -n, --db_name= - name to correct/sanitize # | ret: the corrected name # +# example: dbname=$(ynh_sanitize_dbid $app) +# +# Underscorify the string (replace - and . by _) +# # Requires YunoHost version 2.2.4 or higher. ynh_sanitize_dbid () { # Declare an array to define the options of this helper. From f0d7eba64a9d087d5d44c3472014301937c408ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 087/131] helper doc fixes : systemd --- data/helpers.d/systemd | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index b43b593fa..16dee928a 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -3,11 +3,12 @@ # Create a dedicated systemd config # # usage: ynh_add_systemd_config [--service=service] [--template=template] -# | arg: -s, --service= - Service name (optionnal, $app by default) -# | arg: -t, --template= - Name of template file (optionnal, this is 'systemd' by default, meaning ./conf/systemd.service will be used as template) +# | arg: -s, --service= - Service name (optionnal, `$app` by default) +# | arg: -t, --template= - Name of template file (optionnal, this is 'systemd' by default, meaning `../conf/systemd.service` will be used as template) # -# This will use the template ../conf/.service -# See the documentation of ynh_add_config for a description of the template +# This will use the template `../conf/.service`. +# +# See the documentation of `ynh_add_config` for a description of the template # format and how placeholders are replaced with actual variables. # # Requires YunoHost version 2.7.11 or higher. @@ -59,10 +60,10 @@ ynh_remove_systemd_config () { # Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started # # usage: ynh_systemd_action [--service_name=service_name] [--action=action] [ [--line_match="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ] -# | arg: -n, --service_name= - Name of the service to start. Default : $app +# | arg: -n, --service_name= - Name of the service to start. Default : `$app` # | arg: -a, --action= - Action to perform with systemctl. Default: start # | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. -# | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log +# | arg: -p, --log_path= - Log file - Path to the log file. Default : `/var/log/$app/$app.log` # | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds. # | arg: -e, --length= - Length of the error log : Default : 20 # @@ -180,4 +181,3 @@ ynh_clean_check_starting () { ynh_secure_remove --file="$templog" 2>&1 fi } - From 36996482659bfd711a715a5403a0871ed7d7266e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 088/131] helper doc fixes : user --- data/helpers.d/user | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/data/helpers.d/user b/data/helpers.d/user index 4d2d9ad65..c12b4656e 100644 --- a/data/helpers.d/user +++ b/data/helpers.d/user @@ -2,11 +2,11 @@ # Check if a YunoHost user exists # -# example: ynh_user_exists 'toto' || exit 1 -# # usage: ynh_user_exists --username=username # | arg: -u, --username= - the username to check -# | exit: Return 1 if the user doesn't exist, 0 otherwise +# | ret: 0 if the user exists, 1 otherwise. +# +# example: ynh_user_exists 'toto' || echo "User does not exist" # # Requires YunoHost version 2.2.4 or higher. ynh_user_exists() { @@ -22,12 +22,12 @@ ynh_user_exists() { # Retrieve a YunoHost user information # -# example: mail=$(ynh_user_get_info 'toto' 'mail') -# # usage: ynh_user_get_info --username=username --key=key # | arg: -u, --username= - the username to retrieve info from # | arg: -k, --key= - the key to retrieve -# | ret: string - the key's value +# | ret: the value associate to that key +# +# example: mail=$(ynh_user_get_info 'toto' 'mail') # # Requires YunoHost version 2.2.4 or higher. ynh_user_get_info() { @@ -44,10 +44,10 @@ ynh_user_get_info() { # Get the list of YunoHost users # -# example: for u in $(ynh_user_list); do ... -# # usage: ynh_user_list -# | ret: string - one username per line +# | ret: one username per line as strings +# +# example: for u in $(ynh_user_list); do ... ; done # # Requires YunoHost version 2.4.0 or higher. ynh_user_list() { @@ -58,7 +58,7 @@ ynh_user_list() { # # usage: ynh_system_user_exists --username=username # | arg: -u, --username= - the username to check -# | exit: Return 1 if the user doesn't exist, 0 otherwise +# | ret: 0 if the user exists, 1 otherwise. # # Requires YunoHost version 2.2.4 or higher. ynh_system_user_exists() { @@ -76,7 +76,7 @@ ynh_system_user_exists() { # # usage: ynh_system_group_exists --group=group # | arg: -g, --group= - the group to check -# | exit: Return 1 if the group doesn't exist, 0 otherwise +# | ret: 0 if the group exists, 1 otherwise. # # Requires YunoHost version 3.5.0.2 or higher. ynh_system_group_exists() { @@ -92,17 +92,20 @@ ynh_system_group_exists() { # Create a system user # -# examples: -# # Create a nextcloud user with no home directory and /usr/sbin/nologin login shell (hence no login capability) -# ynh_system_user_create --username=nextcloud -# # Create a discourse user using /var/www/discourse as home directory and the default login shell -# ynh_system_user_create --username=discourse --home_dir=/var/www/discourse --use_shell -# # usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell] # | arg: -u, --username= - Name of the system user that will be create # | arg: -h, --home_dir= - Path of the home dir for the user. Usually the final path of the app. If this argument is omitted, the user will be created without home # | arg: -s, --use_shell - Create a user using the default login shell if present. If this argument is omitted, the user will be created with /usr/sbin/nologin shell # +# Create a nextcloud user with no home directory and /usr/sbin/nologin login shell (hence no login capability) : +# ``` +# ynh_system_user_create --username=nextcloud +# ``` +# Create a discourse user using /var/www/discourse as home directory and the default login shell : +# ``` +# ynh_system_user_create --username=discourse --home_dir=/var/www/discourse --use_shell +# ``` +# # Requires YunoHost version 2.6.4 or higher. ynh_system_user_create () { # Declare an array to define the options of this helper. From 72da2ad8e3a40f2237f37af911eb069b14b356aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Wed, 3 Mar 2021 10:59:29 +0100 Subject: [PATCH 089/131] helper doc fixes : utils --- data/helpers.d/utils | 135 ++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 71 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 487ec41db..28b1e5a1d 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -48,9 +48,8 @@ ynh_exit_properly () { # usage: ynh_abort_if_errors # # This configure the rest of the script execution such that, if an error occurs -# or if an empty variable is used, the execution of the script stops -# immediately and a call to `ynh_clean_setup` is triggered if it has been -# defined by your script. +# or if an empty variable is used, the execution of the script stops immediately +# and a call to `ynh_clean_setup` is triggered if it has been defined by your script. # # Requires YunoHost version 2.6.4 or higher. ynh_abort_if_errors () { @@ -63,45 +62,37 @@ ynh_abort_if_errors () { # # usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] # | arg: -d, --dest_dir= - Directory where to setup sources -# | arg: -s, --source_id= - Name of the app, if the package contains more than one app +# | arg: -s, --source_id= - Name of the source, defaults to `app` # -# The file conf/app.src need to contains: +# This helper will read `conf/${source_id}.src`, download and install the sources. # +# The src file need to contains: +# ``` # SOURCE_URL=Address to download the app archive # SOURCE_SUM=Control sum -# # (Optional) Program to check the integrity (sha256sum, md5sum...) -# # default: sha256 +# # (Optional) Program to check the integrity (sha256sum, md5sum...). Default: sha256 # SOURCE_SUM_PRG=sha256 -# # (Optional) Archive format -# # default: tar.gz +# # (Optional) Archive format. Default: tar.gz # SOURCE_FORMAT=tar.gz -# # (Optional) Put false if sources are directly in the archive root -# # default: true -# # Instead of true, SOURCE_IN_SUBDIR could be the number of sub directories -# # to remove. +# # (Optional) Put false if sources are directly in the archive root. Default: true +# # Instead of true, SOURCE_IN_SUBDIR could be the number of sub directories to remove. # SOURCE_IN_SUBDIR=false -# # (Optionnal) Name of the local archive (offline setup support) -# # default: ${src_id}.${src_format} +# # (Optionnal) Name of the local archive (offline setup support). Default: ${src_id}.${src_format} # SOURCE_FILENAME=example.tar.gz -# # (Optional) If it set as false don't extract the source. +# # (Optional) If it set as false don't extract the source. Default: true # # (Useful to get a debian package or a python wheel.) -# # default: true # SOURCE_EXTRACT=(true|false) +# ``` # -# Details: -# This helper downloads sources from SOURCE_URL if there is no local source -# archive in /opt/yunohost-apps-src/APP_ID/SOURCE_FILENAME -# -# Next, it checks the integrity with "SOURCE_SUM_PRG -c --status" command. -# -# If it's ok, the source archive will be uncompressed in $dest_dir. If the -# SOURCE_IN_SUBDIR is true, the first level directory of the archive will be -# removed. -# If SOURCE_IN_SUBDIR is a numeric value, 2 for example, the 2 first level -# directories will be removed -# -# Finally, patches named sources/patches/${src_id}-*.patch and extra files in -# sources/extra_files/$src_id will be applied to dest_dir +# The helper will: +# - Check if there is a local source archive in `/opt/yunohost-apps-src/$APP_ID/$SOURCE_FILENAME` +# - Download `$SOURCE_URL` if there is no local archive +# - Check the integrity with `$SOURCE_SUM_PRG -c --status` +# - Uncompress the archive to `$dest_dir`. +# - If `$SOURCE_IN_SUBDIR` is true, the first level directory of the archive will be removed. +# - If `$SOURCE_IN_SUBDIR` is a numeric value, the N first level directories will be removed. +# - Patches named `sources/patches/${src_id}-*.patch` will be applied to `$dest_dir` +# - Extra files in `sources/extra_files/$src_id` will be copied to dest_dir # # Requires YunoHost version 2.6.4 or higher. ynh_setup_source () { @@ -211,17 +202,17 @@ ynh_setup_source () { # Curl abstraction to help with POST requests to local pages (such as installation forms) # -# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2" -# # usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ... -# | arg: page_uri - Path (relative to $path_url) of the page where POST data will be sent +# | arg: page_uri - Path (relative to `$path_url`) of the page where POST data will be sent # | arg: key1=value1 - (Optionnal) POST key and corresponding value # | arg: key2=value2 - (Optionnal) Another POST key and corresponding value # | arg: ... - (Optionnal) More POST keys and values # +# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2" +# # For multiple calls, cookies are persisted between each call for the same app # -# $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?)) +# `$domain` and `$path_url` should be defined externally (and correspond to the domain.tld and the /path (of the app?)) # # Requires YunoHost version 2.6.4 or higher. ynh_local_curl () { @@ -250,7 +241,7 @@ ynh_local_curl () { # Wait untils nginx has fully reloaded (avoid curl fail with http2) sleep 2 - + local cookiefile=/tmp/ynh-$app-cookie.txt touch $cookiefile chown root $cookiefile @@ -262,20 +253,22 @@ ynh_local_curl () { # Create a dedicated config file from a template # +# usage: ynh_add_config --template="template" --destination="destination" +# | arg: -t, --template= - Template config file to use +# | arg: -d, --destination= - Destination of the config file +# # examples: # ynh_add_config --template=".env" --destination="$final_path/.env" # ynh_add_config --template="../conf/.env" --destination="$final_path/.env" # ynh_add_config --template="/etc/nginx/sites-available/default" --destination="etc/nginx/sites-available/mydomain.conf" # -# usage: ynh_add_config --template="template" --destination="destination" -# | arg: -t, --template= - Template config file to use -# | arg: -d, --destination= - Destination of the config file -# # The template can be by default the name of a file in the conf directory -# of a YunoHost Package, a relative path or an absolute path -# The helper will use the template $template to generate a config file -# $destination by replacing the following keywords with global variables +# of a YunoHost Package, a relative path or an absolute path. +# +# The helper will use the template `template` to generate a config file +# `destination` by replacing the following keywords with global variables # that should be defined before calling this helper : +# ``` # __PATH__ by $path_url # __NAME__ by $app # __NAMETOCHANGE__ by $app @@ -283,15 +276,18 @@ ynh_local_curl () { # __FINALPATH__ by $final_path # __PHPVERSION__ by $YNH_PHP_VERSION # __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH -# +# ``` # And any dynamic variables that should be defined before calling this helper like: +# ``` # __DOMAIN__ by $domain # __APP__ by $app # __VAR_1__ by $var_1 # __VAR_2__ by $var_2 +# ``` # # The helper will verify the checksum and backup the destination file # if it's different before applying the new template. +# # And it will calculate and store the destination file checksum # into the app settings when configuration is done. # @@ -556,16 +552,17 @@ ynh_read_manifest () { jq ".$manifest_key" "$manifest" --raw-output } -# Read the upstream version from the manifest, or from the env variable $YNH_APP_MANIFEST_VERSION if not given +# Read the upstream version from the manifest or `$YNH_APP_MANIFEST_VERSION` # # usage: ynh_app_upstream_version [--manifest="manifest.json"] # | arg: -m, --manifest= - Path of the manifest to read # | ret: the version number of the upstream app # -# The version number in the manifest is defined by ~ynh -# For example : 4.3-2~ynh3 -# This include the number before ~ynh -# In the last example it return 4.3-2 +# If the `manifest` is not specified, the envvar `$YNH_APP_MANIFEST_VERSION` will be used. +# +# The version number in the manifest is defined by `~ynh`. +# +# For example, if the manifest contains `4.3-2~ynh3` the function will return `4.3-2` # # Requires YunoHost version 3.5.0 or higher. ynh_app_upstream_version () { @@ -593,10 +590,9 @@ ynh_app_upstream_version () { # | arg: -m, --manifest= - Path of the manifest to read # | ret: the version number of the package # -# The version number in the manifest is defined by ~ynh -# For example : 4.3-2~ynh3 -# This include the number after ~ynh -# In the last example it return 3 +# The version number in the manifest is defined by `~ynh`. +# +# For example, if the manifest contains `4.3-2~ynh3` the function will return `3` # # Requires YunoHost version 3.5.0 or higher. ynh_app_package_version () { @@ -613,18 +609,16 @@ ynh_app_package_version () { # Checks the app version to upgrade with the existing app version and returns: # -# - UPGRADE_PACKAGE if only the YunoHost package has changed -# - UPGRADE_APP otherwise +# usage: ynh_check_app_version_changed +# | ret: `UPGRADE_APP` if the upstream version changed, `UPGRADE_PACKAGE` otherwise. # # This helper should be used to avoid an upgrade of an app, or the upstream part # of it, when it's not needed # -# To force an upgrade, even if the package is up to date, -# you have to use the parameter --force (or -F). -# example: sudo yunohost app upgrade MyApp --force -# -# usage: ynh_check_app_version_changed -# +# You can force an upgrade, even if the package is up to date, with the `--force` (or `-F`) argument : +# ``` +# sudo yunohost app upgrade --force +# ``` # Requires YunoHost version 3.5.0 or higher. ynh_check_app_version_changed () { local return_value=${YNH_APP_UPGRADE_TYPE} @@ -638,24 +632,23 @@ ynh_check_app_version_changed () { } # Compare the current package version against another version given as an argument. -# This is really useful when we need to do some actions only for some old package versions. +# +# usage: ynh_compare_current_package_version --comparison (lt|le|eq|ne|ge|gt) --version +# | arg: --comparison - Comparison type. Could be : `lt` (lower than), `le` (lower or equal), `eq` (equal), `ne` (not equal), `ge` (greater or equal), `gt` (greater than) +# | arg: --version - The version to compare. Need to be a version in the yunohost package version type (like `2.3.1~ynh4`) +# | ret: 0 if the evaluation is true, 1 if false. # # example: ynh_compare_current_package_version --comparison lt --version 2.3.2~ynh1 -# This example will check if the installed version is lower than (lt) the version 2.3.2~ynh1 # -# Generally you might probably use it as follow in the upgrade script +# This helper is usually used when we need to do some actions only for some old package versions. # +# Generally you might probably use it as follow in the upgrade script : +# ``` # if ynh_compare_current_package_version --comparison lt --version 2.3.2~ynh1 # then # # Do something that is needed for the package version older than 2.3.2~ynh1 # fi -# -# usage: ynh_compare_current_package_version --comparison lt|le|eq|ne|ge|gt -# | arg: --comparison - Comparison type. Could be : lt (lower than), le (lower or equal), -# | eq (equal), ne (not equal), ge (greater or equal), gt (greater than) -# | arg: --version - The version to compare. Need to be a version in the yunohost package version type (like 2.3.1~ynh4) -# -# Return 0 if the evaluation is true. 1 if false. +# ``` # # Requires YunoHost version 3.8.0 or higher. ynh_compare_current_package_version() { From 5539751ca4bfadb2dfc3a1864a81736d28017c54 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Mon, 8 Mar 2021 17:38:10 +0100 Subject: [PATCH 090/131] fix others_var --- data/helpers.d/fail2ban | 1 + data/helpers.d/systemd | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/fail2ban b/data/helpers.d/fail2ban index f8b2b1761..aa2c8d3c0 100644 --- a/data/helpers.d/fail2ban +++ b/data/helpers.d/fail2ban @@ -73,6 +73,7 @@ ynh_add_fail2ban_config () { ynh_handle_getopts_args "$@" max_retry=${max_retry:-3} ports=${ports:-http,https} + others_var="${others_var:-}" use_template="${use_template:-0}" [[ -z "$others_var" ]] || ynh_print_warn --message="Packagers: using --others_var is unecessary since Yunohost 4.2" diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index b43b593fa..4c7bd31d1 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -20,8 +20,9 @@ ynh_add_systemd_config () { local others_var # Manage arguments with getopts ynh_handle_getopts_args "$@" - local service="${service:-$app}" - local template="${template:-systemd.service}" + service="${service:-$app}" + template="${template:-systemd.service}" + others_var="${others_var:-}" [[ -z "$others_var" ]] || ynh_print_warn --message="Packagers: using --others_var is unecessary since Yunohost 4.2" From 9e7eda681bcf82fac70a0b6cb481c5fbda3b689c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 8 Mar 2021 18:37:53 +0100 Subject: [PATCH 091/131] ynh_install_n: put the source descriptor file in the appropriate dir during backup/restore --- data/helpers.d/nodejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/nodejs b/data/helpers.d/nodejs index 2e1c787cf..200e5ecbd 100644 --- a/data/helpers.d/nodejs +++ b/data/helpers.d/nodejs @@ -18,7 +18,7 @@ ynh_install_n () { # Build an app.src for n mkdir --parents "../conf" echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz -SOURCE_SUM=2933855140f980fc6d1d6103ea07cd4d915b17dea5e17e43921330ea89978b5b" > "../conf/n.src" +SOURCE_SUM=2933855140f980fc6d1d6103ea07cd4d915b17dea5e17e43921330ea89978b5b" > "$YNH_APP_BASEDIR/conf/n.src" # Download and extract n ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n # Install n From db93b82b23d0470a8dcde3393e67002e2d975fd8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 8 Mar 2021 18:41:54 +0100 Subject: [PATCH 092/131] ynh_setup_source: add a check that we could actually parse SOURCE_URL --- data/helpers.d/utils | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 487ec41db..8246b9986 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -135,12 +135,15 @@ ynh_setup_source () { if [ "$src_filename" = "" ]; then src_filename="${source_id}.${src_format}" fi - local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}" + # (Unused?) mecanism where one can have the file in a special local cache to not have to download it... + local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}" if test -e "$local_src" - then # Use the local source file if it is present + then cp $local_src $src_filename - else # If not, download the source + else + [ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?" + # NB. we have to declare the var as local first, # otherwise 'local foo=$(false) || echo 'pwet'" does'nt work # because local always return 0 ... From ad602ee0a13d59bb3c79c289e34ab294e4bb26f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Mon, 8 Mar 2021 20:55:45 +0100 Subject: [PATCH 093/131] Upgrade n (#1178) Co-authored-by: Alexandre Aubin --- data/helpers.d/nodejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/nodejs b/data/helpers.d/nodejs index 200e5ecbd..d4122c1c6 100644 --- a/data/helpers.d/nodejs +++ b/data/helpers.d/nodejs @@ -1,6 +1,6 @@ #!/bin/bash -n_version=7.0.0 +n_version=7.0.2 n_install_dir="/opt/node_n" node_version_path="$n_install_dir/n/versions/node" # N_PREFIX is the directory of n, it needs to be loaded as a environment variable. @@ -18,7 +18,7 @@ ynh_install_n () { # Build an app.src for n mkdir --parents "../conf" echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz -SOURCE_SUM=2933855140f980fc6d1d6103ea07cd4d915b17dea5e17e43921330ea89978b5b" > "$YNH_APP_BASEDIR/conf/n.src" +SOURCE_SUM=fa80a8685f0fb1b4187fc0a1228b44f0ea2f244e063fe8f443b8913ea595af89" > "$YNH_APP_BASEDIR/conf/n.src" # Download and extract n ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n # Install n From b85d959d7e0dd6f287d9121dba5adc9bd2caa490 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 8 Mar 2021 20:56:32 +0100 Subject: [PATCH 094/131] ynh_install_n: No need to mkdir ../conf --- data/helpers.d/nodejs | 1 - 1 file changed, 1 deletion(-) diff --git a/data/helpers.d/nodejs b/data/helpers.d/nodejs index d4122c1c6..c2f374a56 100644 --- a/data/helpers.d/nodejs +++ b/data/helpers.d/nodejs @@ -16,7 +16,6 @@ export N_PREFIX="$n_install_dir" ynh_install_n () { ynh_print_info --message="Installation of N - Node.js version management" # Build an app.src for n - mkdir --parents "../conf" echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz SOURCE_SUM=fa80a8685f0fb1b4187fc0a1228b44f0ea2f244e063fe8f443b8913ea595af89" > "$YNH_APP_BASEDIR/conf/n.src" # Download and extract n From 01ccab52529a55e8d40fe3676f2d7023c112aef1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 11 Mar 2021 01:39:52 +0100 Subject: [PATCH 095/131] Add semantic of YunohostValidationError for all exceptions which are related to validating stuff --- src/yunohost/app.py | 74 +++++++++---------- src/yunohost/backup.py | 28 +++---- src/yunohost/certificate.py | 24 +++--- .../0017_postgresql_9p6_to_11.py | 4 +- src/yunohost/diagnosis.py | 18 ++--- src/yunohost/domain.py | 29 ++++---- src/yunohost/dyndns.py | 12 +-- src/yunohost/firewall.py | 4 +- src/yunohost/hook.py | 8 +- src/yunohost/log.py | 2 +- src/yunohost/permission.py | 24 +++--- src/yunohost/service.py | 12 +-- src/yunohost/settings.py | 22 +++--- src/yunohost/ssh.py | 6 +- src/yunohost/tools.py | 36 ++++----- src/yunohost/user.py | 52 ++++++------- src/yunohost/utils/error.py | 4 + src/yunohost/utils/password.py | 4 +- tests/test_i18n_keys.py | 2 + 19 files changed, 187 insertions(+), 178 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 3d1d16f3c..613ca21df 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -54,7 +54,7 @@ from moulinette.utils.filesystem import ( from yunohost.service import service_status, _run_service_command from yunohost.utils import packages -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.log import is_unit_operation, OperationLogger logger = getActionLogger("yunohost.app") @@ -192,7 +192,7 @@ def app_info(app, full=False): from yunohost.permission import user_permission_list if not _is_installed(app): - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) @@ -321,7 +321,7 @@ def app_map(app=None, raw=False, user=None): if app is not None: if not _is_installed(app): - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) apps = [ @@ -421,14 +421,14 @@ def app_change_url(operation_logger, app, domain, path): installed = _is_installed(app) if not installed: - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) if not os.path.exists( os.path.join(APPS_SETTING_PATH, app, "scripts", "change_url") ): - raise YunohostError("app_change_url_no_script", app_name=app) + raise YunohostValidationError("app_change_url_no_script", app_name=app) old_domain = app_setting(app, "domain") old_path = app_setting(app, "path") @@ -438,7 +438,7 @@ def app_change_url(operation_logger, app, domain, path): domain, path = _normalize_domain_path(domain, path) if (domain, path) == (old_domain, old_path): - raise YunohostError( + raise YunohostValidationError( "app_change_url_identical_domains", domain=domain, path=path ) @@ -551,12 +551,12 @@ def app_upgrade(app=[], url=None, file=None, force=False): # Abort if any of those app is in fact not installed.. for app in [app_ for app_ in apps if not _is_installed(app_)]: - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) if len(apps) == 0: - raise YunohostError("apps_already_up_to_date") + raise YunohostValidationError("apps_already_up_to_date") if len(apps) > 1: logger.info(m18n.n("app_upgrade_several_apps", apps=", ".join(apps))) @@ -880,11 +880,11 @@ def app_install( confirm_install("thirdparty") manifest, extracted_app_folder = _extract_app_from_file(app) else: - raise YunohostError("app_unknown") + raise YunohostValidationError("app_unknown") # Check ID if "id" not in manifest or "__" in manifest["id"]: - raise YunohostError("app_id_invalid") + raise YunohostValidationError("app_id_invalid") app_id = manifest["id"] label = label if label else manifest["name"] @@ -897,7 +897,7 @@ def app_install( instance_number = _installed_instance_number(app_id, last=True) + 1 if instance_number > 1: if "multi_instance" not in manifest or not is_true(manifest["multi_instance"]): - raise YunohostError("app_already_installed", app=app_id) + raise YunohostValidationError("app_already_installed", app=app_id) # Change app_id to the forked app id app_instance_name = app_id + "__" + str(instance_number) @@ -1209,7 +1209,7 @@ def app_remove(operation_logger, app): ) if not _is_installed(app): - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) @@ -1372,10 +1372,10 @@ def app_makedefault(operation_logger, app, domain=None): domain = app_domain operation_logger.related_to.append(("domain", domain)) elif domain not in domain_list()["domains"]: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) if "/" in app_map(raw=True)[domain]: - raise YunohostError( + raise YunohostValidationError( "app_make_default_location_already_used", app=app, domain=app_domain, @@ -1578,7 +1578,7 @@ def app_register_url(app, domain, path): if _is_installed(app): settings = _get_app_settings(app) if "path" in settings.keys() and "domain" in settings.keys(): - raise YunohostError("app_already_installed_cant_change_url") + raise YunohostValidationError("app_already_installed_cant_change_url") # Check the url is available _assert_no_conflicting_apps(domain, path) @@ -1694,7 +1694,7 @@ def app_change_label(app, new_label): installed = _is_installed(app) if not installed: - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) logger.warning(m18n.n("app_label_deprecated")) @@ -1730,7 +1730,7 @@ def app_action_run(operation_logger, app, action, args=None): actions = {x["id"]: x for x in actions} if action not in actions: - raise YunohostError( + raise YunohostValidationError( "action '%s' not available for app '%s', available actions are: %s" % (action, app, ", ".join(actions.keys())), raw_msg=True, @@ -1884,7 +1884,7 @@ def app_config_apply(operation_logger, app, args): installed = _is_installed(app) if not installed: - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app, all_apps=_get_all_installed_apps_id() ) @@ -2199,7 +2199,7 @@ def _get_app_settings(app_id): """ if not _is_installed(app_id): - raise YunohostError( + raise YunohostValidationError( "app_not_installed", app=app_id, all_apps=_get_all_installed_apps_id() ) try: @@ -2546,9 +2546,9 @@ def _fetch_app_from_git(app): app_id, _ = _parse_app_instance_name(app) if app_id not in app_dict: - raise YunohostError("app_unknown") + raise YunohostValidationError("app_unknown") elif "git" not in app_dict[app_id]: - raise YunohostError("app_unsupported_remote_type") + raise YunohostValidationError("app_unsupported_remote_type") app_info = app_dict[app_id] url = app_info["git"]["url"] @@ -2684,7 +2684,7 @@ def _check_manifest_requirements(manifest, app_instance_name): packaging_format = int(manifest.get("packaging_format", 0)) if packaging_format not in [0, 1]: - raise YunohostError("app_packaging_format_not_supported") + raise YunohostValidationError("app_packaging_format_not_supported") requirements = manifest.get("requirements", dict()) @@ -2697,7 +2697,7 @@ def _check_manifest_requirements(manifest, app_instance_name): for pkgname, spec in requirements.items(): if not packages.meets_version_specifier(pkgname, spec): version = packages.ynh_packages_version()[pkgname]["version"] - raise YunohostError( + raise YunohostValidationError( "app_requirements_unmeet", pkgname=pkgname, version=version, @@ -2796,7 +2796,7 @@ class YunoHostArgumentFormatParser(object): # we don't have an answer, check optional and default_value if question.value is None or question.value == "": if not question.optional and question.default is None: - raise YunohostError("app_argument_required", name=question.name) + raise YunohostValidationError("app_argument_required", name=question.name) else: question.value = ( getattr(self, "default_value", None) @@ -2816,7 +2816,7 @@ class YunoHostArgumentFormatParser(object): return (question.value, self.argument_type) def _raise_invalid_answer(self, question): - raise YunohostError( + raise YunohostValidationError( "app_argument_choice_invalid", name=question.name, choices=", ".join(question.choices), @@ -2854,13 +2854,13 @@ class PasswordArgumentParser(YunoHostArgumentFormatParser): ) if question.default is not None: - raise YunohostError("app_argument_password_no_default", name=question.name) + raise YunohostValidationError("app_argument_password_no_default", name=question.name) return question def _post_parse_value(self, question): if any(char in question.value for char in self.forbidden_chars): - raise YunohostError( + raise YunohostValidationError( "pattern_password_app", forbidden_chars=self.forbidden_chars ) @@ -2913,7 +2913,7 @@ class BooleanArgumentParser(YunoHostArgumentFormatParser): if str(question.value).lower() in ["0", "no", "n", "false"]: return 0 - raise YunohostError( + raise YunohostValidationError( "app_argument_choice_invalid", name=question.name, choices="yes, no, y, n, 1, 0", @@ -2938,7 +2938,7 @@ class DomainArgumentParser(YunoHostArgumentFormatParser): return question def _raise_invalid_answer(self, question): - raise YunohostError( + raise YunohostValidationError( "app_argument_invalid", name=question.name, error=m18n.n("domain_unknown") ) @@ -2964,7 +2964,7 @@ class UserArgumentParser(YunoHostArgumentFormatParser): return question def _raise_invalid_answer(self, question): - raise YunohostError( + raise YunohostValidationError( "app_argument_invalid", name=question.name, error=m18n.n("user_unknown", user=question.value), @@ -2992,7 +2992,7 @@ class NumberArgumentParser(YunoHostArgumentFormatParser): if isinstance(question.value, str) and question.value.isdigit(): return int(question.value) - raise YunohostError( + raise YunohostValidationError( "app_argument_invalid", name=question.name, error=m18n.n("invalid_number") ) @@ -3123,7 +3123,7 @@ def _get_conflicting_apps(domain, path, ignore_app=None): # Abort if domain is unknown if domain not in domain_list()["domains"]: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) # Fetch apps map apps_map = app_map(raw=True) @@ -3162,9 +3162,9 @@ def _assert_no_conflicting_apps(domain, path, ignore_app=None, full_domain=False ) if full_domain: - raise YunohostError("app_full_domain_unavailable", domain=domain) + raise YunohostValidationError("app_full_domain_unavailable", domain=domain) else: - raise YunohostError("app_location_unavailable", apps="\n".join(apps)) + raise YunohostValidationError("app_location_unavailable", apps="\n".join(apps)) def _make_environment_for_app_script(app, args={}, args_prefix="APP_ARG_"): @@ -3469,7 +3469,7 @@ def _assert_system_is_sane_for_app(manifest, when): faulty_services = [s for s in services if service_status(s)["status"] != "running"] if faulty_services: if when == "pre": - raise YunohostError( + raise YunohostValidationError( "app_action_cannot_be_ran_because_required_services_down", services=", ".join(faulty_services), ) @@ -3480,7 +3480,7 @@ def _assert_system_is_sane_for_app(manifest, when): if packages.dpkg_is_broken(): if when == "pre": - raise YunohostError("dpkg_is_broken") + raise YunohostValidationError("dpkg_is_broken") elif when == "post": raise YunohostError("this_action_broke_dpkg") @@ -3659,7 +3659,7 @@ def _patch_legacy_helpers(app_folder): # couldn't patch the deprecated helper in the previous lines. In # that case, abort the install or whichever step is performed if helper in content and infos["important"]: - raise YunohostError( + raise YunohostValidationError( "This app is likely pretty old and uses deprecated / outdated helpers that can't be migrated easily. It can't be installed anymore.", raw_msg=True, ) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 408cd6f15..b020c0f34 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -348,7 +348,7 @@ class BackupManager: # Try to recursively unmount stuff (from a previously failed backup ?) if not _recursive_umount(self.work_dir): - raise YunohostError("backup_output_directory_not_empty") + raise YunohostValidationError("backup_output_directory_not_empty") else: # If umount succeeded, remove the directory (we checked that # we're in /home/yunohost.backup/tmp so that should be okay... @@ -1027,7 +1027,7 @@ class RestoreManager: already_installed = [app for app in to_be_restored if _is_installed(app)] if already_installed != []: if already_installed == to_be_restored: - raise YunohostError( + raise YunohostValidationError( "restore_already_installed_apps", apps=", ".join(already_installed) ) else: @@ -1133,14 +1133,14 @@ class RestoreManager: return True elif free_space > needed_space: # TODO Add --force options to avoid the error raising - raise YunohostError( + raise YunohostValidationError( "restore_may_be_not_enough_disk_space", free_space=free_space, needed_space=needed_space, margin=margin, ) else: - raise YunohostError( + raise YunohostValidationError( "restore_not_enough_disk_space", free_space=free_space, needed_space=needed_space, @@ -1729,7 +1729,7 @@ class BackupMethod(object): free_space, backup_size, ) - raise YunohostError("not_enough_disk_space", path=self.repo) + raise YunohostValidationError("not_enough_disk_space", path=self.repo) def _organize_files(self): """ @@ -2186,7 +2186,7 @@ def backup_create( # Validate there is no archive with the same name if name and name in backup_list()["archives"]: - raise YunohostError("backup_archive_name_exists") + raise YunohostValidationError("backup_archive_name_exists") # By default we backup using the tar method if not methods: @@ -2201,14 +2201,14 @@ def backup_create( r"^/(|(bin|boot|dev|etc|lib|root|run|sbin|sys|usr|var)(|/.*))$", output_directory, ): - raise YunohostError("backup_output_directory_forbidden") + raise YunohostValidationError("backup_output_directory_forbidden") if "copy" in methods: if not output_directory: - raise YunohostError("backup_output_directory_required") + raise YunohostValidationError("backup_output_directory_required") # Check that output directory is empty elif os.path.isdir(output_directory) and os.listdir(output_directory): - raise YunohostError("backup_output_directory_not_empty") + raise YunohostValidationError("backup_output_directory_not_empty") # If no --system or --apps given, backup everything if system is None and apps is None: @@ -2381,7 +2381,7 @@ def backup_download(name): if not os.path.lexists(archive_file): archive_file += ".gz" if not os.path.lexists(archive_file): - raise YunohostError("backup_archive_name_unknown", name=name) + raise YunohostValidationError("backup_archive_name_unknown", name=name) # If symlink, retrieve the real path if os.path.islink(archive_file): @@ -2389,7 +2389,7 @@ def backup_download(name): # Raise exception if link is broken (e.g. on unmounted external storage) if not os.path.exists(archive_file): - raise YunohostError("backup_archive_broken_link", path=archive_file) + raise YunohostValidationError("backup_archive_broken_link", path=archive_file) # We return a raw bottle HTTPresponse (instead of serializable data like # list/dict, ...), which is gonna be picked and used directly by moulinette @@ -2415,7 +2415,7 @@ def backup_info(name, with_details=False, human_readable=False): if not os.path.lexists(archive_file): archive_file += ".gz" if not os.path.lexists(archive_file): - raise YunohostError("backup_archive_name_unknown", name=name) + raise YunohostValidationError("backup_archive_name_unknown", name=name) # If symlink, retrieve the real path if os.path.islink(archive_file): @@ -2423,7 +2423,7 @@ def backup_info(name, with_details=False, human_readable=False): # Raise exception if link is broken (e.g. on unmounted external storage) if not os.path.exists(archive_file): - raise YunohostError("backup_archive_broken_link", path=archive_file) + raise YunohostValidationError("backup_archive_broken_link", path=archive_file) info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name) @@ -2531,7 +2531,7 @@ def backup_delete(name): """ if name not in backup_list()["archives"]: - raise YunohostError("backup_archive_name_unknown", name=name) + raise YunohostValidationError("backup_archive_name_unknown", name=name) hook_callback("pre_backup_delete", args=[name]) diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index c48af2c07..56ea70a04 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -37,7 +37,7 @@ from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import read_file from yunohost.vendor.acme_tiny.acme_tiny import get_crt as sign_certificate -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.network import get_public_ip from yunohost.diagnosis import Diagnoser @@ -90,7 +90,7 @@ def certificate_status(domain_list, full=False): for domain in domain_list: # Is it in Yunohost domain list? if domain not in yunohost_domains_list: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) certificates = {} @@ -166,7 +166,7 @@ def _certificate_install_selfsigned(domain_list, force=False): status = _get_status(domain) if status["summary"]["code"] in ("good", "great"): - raise YunohostError( + raise YunohostValidationError( "certmanager_attempt_to_replace_valid_cert", domain=domain ) @@ -267,12 +267,12 @@ def _certificate_install_letsencrypt( for domain in domain_list: yunohost_domains_list = yunohost.domain.domain_list()["domains"] if domain not in yunohost_domains_list: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) # Is it self-signed? status = _get_status(domain) if not force and status["CA_type"]["code"] != "self-signed": - raise YunohostError( + raise YunohostValidationError( "certmanager_domain_cert_not_selfsigned", domain=domain ) @@ -370,25 +370,25 @@ def certificate_renew( # Is it in Yunohost dmomain list? if domain not in yunohost.domain.domain_list()["domains"]: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) status = _get_status(domain) # Does it expire soon? if status["validity"] > VALIDITY_LIMIT and not force: - raise YunohostError( + raise YunohostValidationError( "certmanager_attempt_to_renew_valid_cert", domain=domain ) # Does it have a Let's Encrypt cert? if status["CA_type"]["code"] != "lets-encrypt": - raise YunohostError( + raise YunohostValidationError( "certmanager_attempt_to_renew_nonLE_cert", domain=domain ) # Check ACME challenge configured for given domain if not _check_acme_challenge_configuration(domain): - raise YunohostError( + raise YunohostValidationError( "certmanager_acme_not_configured_for_domain", domain=domain ) @@ -898,20 +898,20 @@ def _check_domain_is_ready_for_ACME(domain): ) if not dnsrecords or not httpreachable: - raise YunohostError("certmanager_domain_not_diagnosed_yet", domain=domain) + raise YunohostValidationError("certmanager_domain_not_diagnosed_yet", domain=domain) # Check if IP from DNS matches public IP if not dnsrecords.get("status") in [ "SUCCESS", "WARNING", ]: # Warning is for missing IPv6 record which ain't critical for ACME - raise YunohostError( + raise YunohostValidationError( "certmanager_domain_dns_ip_differs_from_public_ip", domain=domain ) # Check if domain seems to be accessible through HTTP? if not httpreachable.get("status") == "SUCCESS": - raise YunohostError("certmanager_domain_http_not_working", domain=domain) + raise YunohostValidationError("certmanager_domain_http_not_working", domain=domain) # FIXME / TODO : ideally this should not be needed. There should be a proper diff --git a/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py b/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py index 728ae443f..0526c025d 100644 --- a/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py +++ b/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py @@ -23,7 +23,7 @@ class MyMigration(Migration): return if not self.package_is_installed("postgresql-11"): - raise YunohostError("migration_0017_postgresql_11_not_installed") + raise YunohostValidationError("migration_0017_postgresql_11_not_installed") # Make sure there's a 9.6 cluster try: @@ -37,7 +37,7 @@ class MyMigration(Migration): if not space_used_by_directory( "/var/lib/postgresql/9.6" ) > free_space_in_directory("/var/lib/postgresql"): - raise YunohostError( + raise YunohostValidationError( "migration_0017_not_enough_space", path="/var/lib/postgresql/" ) diff --git a/src/yunohost/diagnosis.py b/src/yunohost/diagnosis.py index d01d56613..cc0035755 100644 --- a/src/yunohost/diagnosis.py +++ b/src/yunohost/diagnosis.py @@ -37,7 +37,7 @@ from moulinette.utils.filesystem import ( write_to_yaml, ) -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.hook import hook_list, hook_exec logger = log.getActionLogger("yunohost.diagnosis") @@ -59,11 +59,11 @@ def diagnosis_get(category, item): all_categories_names = [c for c, _ in all_categories] if category not in all_categories_names: - raise YunohostError("diagnosis_unknown_categories", categories=category) + raise YunohostValidationError("diagnosis_unknown_categories", categories=category) if isinstance(item, list): if any("=" not in criteria for criteria in item): - raise YunohostError( + raise YunohostValidationError( "Criterias should be of the form key=value (e.g. domain=yolo.test)" ) @@ -91,7 +91,7 @@ def diagnosis_show( else: unknown_categories = [c for c in categories if c not in all_categories_names] if unknown_categories: - raise YunohostError( + raise YunohostValidationError( "diagnosis_unknown_categories", categories=", ".join(unknown_categories) ) @@ -181,7 +181,7 @@ def diagnosis_run( else: unknown_categories = [c for c in categories if c not in all_categories_names] if unknown_categories: - raise YunohostError( + raise YunohostValidationError( "diagnosis_unknown_categories", categories=", ".join(unknown_categories) ) @@ -270,14 +270,14 @@ def diagnosis_ignore(add_filter=None, remove_filter=None, list=False): # Sanity checks for the provided arguments if len(filter_) == 0: - raise YunohostError( + raise YunohostValidationError( "You should provide at least one criteria being the diagnosis category to ignore" ) category = filter_[0] if category not in all_categories_names: - raise YunohostError("%s is not a diagnosis category" % category) + raise YunohostValidationError("%s is not a diagnosis category" % category) if any("=" not in criteria for criteria in filter_[1:]): - raise YunohostError( + raise YunohostValidationError( "Criterias should be of the form key=value (e.g. domain=yolo.test)" ) @@ -331,7 +331,7 @@ def diagnosis_ignore(add_filter=None, remove_filter=None, list=False): configuration["ignore_filters"][category] = [] if criterias not in configuration["ignore_filters"][category]: - raise YunohostError("This filter does not exists.") + raise YunohostValidationError("This filter does not exists.") configuration["ignore_filters"][category].remove(criterias) _diagnosis_write_configuration(configuration) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 1198ef473..fdf247f89 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -101,16 +101,14 @@ def domain_add(operation_logger, domain, dyndns=False): from yunohost.utils.ldap import _get_ldap_interface if domain.startswith("xmpp-upload."): - raise YunohostError("domain_cannot_add_xmpp_upload") + raise YunohostValidationError("domain_cannot_add_xmpp_upload") ldap = _get_ldap_interface() try: ldap.validate_uniqueness({"virtualdomain": domain}) except MoulinetteError: - raise YunohostError("domain_exists") - - operation_logger.start() + raise YunohostValidationError("domain_exists") # Lower domain to avoid some edge cases issues # See: https://forum.yunohost.org/t/invalid-domain-causes-diagnosis-web-to-fail-fr-on-demand/11765 @@ -119,17 +117,21 @@ def domain_add(operation_logger, domain, dyndns=False): # DynDNS domain if dyndns: - from yunohost.dyndns import dyndns_subscribe, _dyndns_provides, _guess_current_dyndns_domain + from yunohost.dyndns import _dyndns_provides, _guess_current_dyndns_domain # Do not allow to subscribe to multiple dyndns domains... if _guess_current_dyndns_domain("dyndns.yunohost.org") != (None, None): - raise YunohostError('domain_dyndns_already_subscribed') + raise YunohostValidationError('domain_dyndns_already_subscribed') # Check that this domain can effectively be provided by # dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st) if not _dyndns_provides("dyndns.yunohost.org", domain): - raise YunohostError("domain_dyndns_root_unknown") + raise YunohostValidationError("domain_dyndns_root_unknown") + operation_logger.start() + + if dyndns: + from yunohost.dyndns import dndns_subscribe # Actually subscribe dyndns_subscribe(domain=domain) @@ -197,7 +199,7 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False): # we don't want to check the domain exists because the ldap add may have # failed if not force and domain not in domain_list()['domains']: - raise YunohostError('domain_name_unknown', domain=domain) + raise YunohostValidationError('domain_name_unknown', domain=domain) # Check domain is not the main domain if domain == _get_maindomain(): @@ -205,13 +207,13 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False): other_domains.remove(domain) if other_domains: - raise YunohostError( + raise YunohostValidationError( "domain_cannot_remove_main", domain=domain, other_domains="\n * " + ("\n * ".join(other_domains)), ) else: - raise YunohostError("domain_cannot_remove_main_add_new_one", domain=domain) + raise YunohostValidationError("domain_cannot_remove_main_add_new_one", domain=domain) # Check if apps are installed on the domain apps_on_that_domain = [] @@ -234,9 +236,10 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False): for app, _ in apps_on_that_domain: app_remove(app) else: - raise YunohostError('domain_uninstall_app_first', apps="\n".join([x[1] for x in apps_on_that_domain])) + raise YunohostValidationError('domain_uninstall_app_first', apps="\n".join([x[1] for x in apps_on_that_domain])) operation_logger.start() + ldap = _get_ldap_interface() try: ldap.remove("virtualdomain=" + domain + ",ou=domains") @@ -288,7 +291,7 @@ def domain_dns_conf(domain, ttl=None): """ if domain not in domain_list()["domains"]: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) ttl = 3600 if ttl is None else ttl @@ -345,7 +348,7 @@ def domain_main_domain(operation_logger, new_main_domain=None): # Check domain exists if new_main_domain not in domain_list()["domains"]: - raise YunohostError("domain_name_unknown", domain=new_main_domain) + raise YunohostValidationError("domain_name_unknown", domain=new_main_domain) operation_logger.related_to.append(("domain", new_main_domain)) operation_logger.start() diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index a921cfb5c..b2ac3de6d 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -36,7 +36,7 @@ from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import write_to_file, read_file from moulinette.utils.network import download_json -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.domain import _get_maindomain, _build_dns_conf from yunohost.utils.network import get_public_ip, dig from yunohost.log import is_unit_operation @@ -124,7 +124,7 @@ def dyndns_subscribe( """ if _guess_current_dyndns_domain(subscribe_host) != (None, None): - raise YunohostError('domain_dyndns_already_subscribed') + raise YunohostValidationError('domain_dyndns_already_subscribed') if domain is None: domain = _get_maindomain() @@ -132,13 +132,13 @@ def dyndns_subscribe( # Verify if domain is provided by subscribe_host if not _dyndns_provides(subscribe_host, domain): - raise YunohostError( + raise YunohostValidationError( "dyndns_domain_not_provided", domain=domain, provider=subscribe_host ) # Verify if domain is available if not _dyndns_available(subscribe_host, domain): - raise YunohostError("dyndns_unavailable", domain=domain) + raise YunohostValidationError("dyndns_unavailable", domain=domain) operation_logger.start() @@ -231,7 +231,7 @@ def dyndns_update( (domain, key) = _guess_current_dyndns_domain(dyn_host) if domain is None: - raise YunohostError('dyndns_no_domain_registered') + raise YunohostValidationError('dyndns_no_domain_registered') # If key is not given, pick the first file we find with the domain given else: @@ -239,7 +239,7 @@ def dyndns_update( keys = glob.glob("/etc/yunohost/dyndns/K{0}.+*.private".format(domain)) if not keys: - raise YunohostError("dyndns_key_not_found") + raise YunohostValidationError("dyndns_key_not_found") key = keys[0] diff --git a/src/yunohost/firewall.py b/src/yunohost/firewall.py index 1b708a626..bc21f1948 100644 --- a/src/yunohost/firewall.py +++ b/src/yunohost/firewall.py @@ -28,7 +28,7 @@ import yaml import miniupnpc from moulinette import m18n -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils import process from moulinette.utils.log import getActionLogger from moulinette.utils.text import prependlines @@ -366,7 +366,7 @@ def firewall_upnp(action="status", no_refresh=False): if action == "status": no_refresh = True else: - raise YunohostError("action_invalid", action=action) + raise YunohostValidationError("action_invalid", action=action) # Refresh port mapping using UPnP if not no_refresh: diff --git a/src/yunohost/hook.py b/src/yunohost/hook.py index e9857e4f9..493ad2c35 100644 --- a/src/yunohost/hook.py +++ b/src/yunohost/hook.py @@ -32,7 +32,7 @@ from glob import iglob from importlib import import_module from moulinette import m18n, msettings -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils import log from moulinette.utils.filesystem import read_json @@ -117,7 +117,7 @@ def hook_info(action, name): ) if not hooks: - raise YunohostError("hook_name_unknown", name=name) + raise YunohostValidationError("hook_name_unknown", name=name) return { "action": action, "name": name, @@ -186,7 +186,7 @@ def hook_list(action, list_by="name", show_info=False): d.add(name) else: - raise YunohostError("hook_list_by_invalid") + raise YunohostValidationError("hook_list_by_invalid") def _append_folder(d, folder): # Iterate over and add hook from a folder @@ -273,7 +273,7 @@ def hook_callback( try: hl = hooks_names[n] except KeyError: - raise YunohostError("hook_name_unknown", n) + raise YunohostValidationError("hook_name_unknown", n) # Iterate over hooks with this name for h in hl: # Update hooks dict diff --git a/src/yunohost/log.py b/src/yunohost/log.py index e5a53d466..1260cd98d 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -191,7 +191,7 @@ def log_show( log_path = base_path + LOG_FILE_EXT if not os.path.exists(md_path) and not os.path.exists(log_path): - raise YunohostError("log_does_exists", log=path) + raise YunohostValidationError("log_does_exists", log=path) infos = {} diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 3cd67b148..e0a3c6be8 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -31,7 +31,7 @@ import random from moulinette import m18n from moulinette.utils.log import getActionLogger -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.log import is_unit_operation logger = getActionLogger("yunohost.user") @@ -175,14 +175,14 @@ def user_permission_update( # Refuse to add "visitors" to mail, xmpp ... they require an account to make sense. if add and "visitors" in add and permission.split(".")[0] in SYSTEM_PERMS: - raise YunohostError("permission_require_account", permission=permission) + raise YunohostValidationError("permission_require_account", permission=permission) # Refuse to add "visitors" to protected permission if ( (add and "visitors" in add and existing_permission["protected"]) or (remove and "visitors" in remove and existing_permission["protected"]) ) and not force: - raise YunohostError("permission_protected", permission=permission) + raise YunohostValidationError("permission_protected", permission=permission) # Fetch currently allowed groups for this permission @@ -198,7 +198,7 @@ def user_permission_update( groups_to_add = [add] if not isinstance(add, list) else add for group in groups_to_add: if group not in all_existing_groups: - raise YunohostError("group_unknown", group=group) + raise YunohostValidationError("group_unknown", group=group) if group in current_allowed_groups: logger.warning( m18n.n( @@ -326,7 +326,7 @@ def user_permission_info(permission): permission, None ) if existing_permission is None: - raise YunohostError("permission_not_found", permission=permission) + raise YunohostValidationError("permission_not_found", permission=permission) return existing_permission @@ -391,7 +391,7 @@ def permission_create( if ldap.get_conflict( {"cn": permission}, base_dn="ou=permission,dc=yunohost,dc=org" ): - raise YunohostError("permission_already_exist", permission=permission) + raise YunohostValidationError("permission_already_exist", permission=permission) # Get random GID all_gid = {x.gr_gid for x in grp.getgrall()} @@ -427,7 +427,7 @@ def permission_create( all_existing_groups = user_group_list()["groups"].keys() for group in allowed or []: if group not in all_existing_groups: - raise YunohostError("group_unknown", group=group) + raise YunohostValidationError("group_unknown", group=group) operation_logger.related_to.append(("app", permission.split(".")[0])) operation_logger.start() @@ -594,7 +594,7 @@ def permission_delete(operation_logger, permission, force=False, sync_perm=True) permission = permission + ".main" if permission.endswith(".main") and not force: - raise YunohostError("permission_cannot_remove_main") + raise YunohostValidationError("permission_cannot_remove_main") from yunohost.utils.ldap import _get_ldap_interface @@ -861,7 +861,7 @@ def _validate_and_sanitize_permission_url(url, app_base_path, app): try: re.compile(regex) except Exception: - raise YunohostError("invalid_regex", regex=regex) + raise YunohostValidationError("invalid_regex", regex=regex) if url.startswith("re:"): @@ -874,12 +874,12 @@ def _validate_and_sanitize_permission_url(url, app_base_path, app): # regex with domain if "/" not in url: - raise YunohostError("regex_with_only_domain") + raise YunohostValidationError("regex_with_only_domain") domain, path = url[3:].split("/", 1) path = "/" + path if domain.replace("%", "").replace("\\", "") not in domains: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) validate_regex(path) @@ -914,7 +914,7 @@ def _validate_and_sanitize_permission_url(url, app_base_path, app): sanitized_url = domain + path if domain not in domains: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) _assert_no_conflicting_apps(domain, path, ignore_app=app) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index 2de395131..3a0450bce 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -34,7 +34,7 @@ from glob import glob from datetime import datetime from moulinette import m18n -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils.process import check_output from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import read_file, append_to_file, write_to_file @@ -145,7 +145,7 @@ def service_remove(name): services = _get_services() if name not in services: - raise YunohostError("service_unknown", service=name) + raise YunohostValidationError("service_unknown", service=name) del services[name] try: @@ -325,7 +325,7 @@ def service_status(names=[]): # Validate service names requested for name in names: if name not in services.keys(): - raise YunohostError("service_unknown", service=name) + raise YunohostValidationError("service_unknown", service=name) # Filter only requested servivces services = {k: v for k, v in services.items() if k in names} @@ -484,7 +484,7 @@ def service_log(name, number=50): number = int(number) if name not in services.keys(): - raise YunohostError("service_unknown", service=name) + raise YunohostValidationError("service_unknown", service=name) log_list = services[name].get("log", []) @@ -545,7 +545,7 @@ def service_regen_conf( for name in names: if name not in services.keys(): - raise YunohostError("service_unknown", service=name) + raise YunohostValidationError("service_unknown", service=name) if names is []: names = list(services.keys()) @@ -568,7 +568,7 @@ def _run_service_command(action, service): """ services = _get_services() if service not in services.keys(): - raise YunohostError("service_unknown", service=service) + raise YunohostValidationError("service_unknown", service=service) possible_actions = [ "start", diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index 9bf75ff1d..9d1a6d11f 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -6,7 +6,7 @@ from datetime import datetime from collections import OrderedDict from moulinette import m18n -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils.log import getActionLogger from yunohost.regenconf import regen_conf @@ -109,7 +109,7 @@ def settings_get(key, full=False): settings = _get_settings() if key not in settings: - raise YunohostError("global_settings_key_doesnt_exists", settings_key=key) + raise YunohostValidationError("global_settings_key_doesnt_exists", settings_key=key) if full: return settings[key] @@ -137,7 +137,7 @@ def settings_set(key, value): settings = _get_settings() if key not in settings: - raise YunohostError("global_settings_key_doesnt_exists", settings_key=key) + raise YunohostValidationError("global_settings_key_doesnt_exists", settings_key=key) key_type = settings[key]["type"] @@ -146,7 +146,7 @@ def settings_set(key, value): if boolean_value[0]: value = boolean_value[1] else: - raise YunohostError( + raise YunohostValidationError( "global_settings_bad_type_for_setting", setting=key, received_type=type(value).__name__, @@ -158,14 +158,14 @@ def settings_set(key, value): try: value = int(value) except Exception: - raise YunohostError( + raise YunohostValidationError( "global_settings_bad_type_for_setting", setting=key, received_type=type(value).__name__, expected_type=key_type, ) else: - raise YunohostError( + raise YunohostValidationError( "global_settings_bad_type_for_setting", setting=key, received_type=type(value).__name__, @@ -173,7 +173,7 @@ def settings_set(key, value): ) elif key_type == "string": if not isinstance(value, str): - raise YunohostError( + raise YunohostValidationError( "global_settings_bad_type_for_setting", setting=key, received_type=type(value).__name__, @@ -181,14 +181,14 @@ def settings_set(key, value): ) elif key_type == "enum": if value not in settings[key]["choices"]: - raise YunohostError( + raise YunohostValidationError( "global_settings_bad_choice_for_enum", setting=key, choice=str(value), available_choices=", ".join(settings[key]["choices"]), ) else: - raise YunohostError( + raise YunohostValidationError( "global_settings_unknown_type", setting=key, unknown_type=key_type ) @@ -214,7 +214,7 @@ def settings_reset(key): settings = _get_settings() if key not in settings: - raise YunohostError("global_settings_key_doesnt_exists", settings_key=key) + raise YunohostValidationError("global_settings_key_doesnt_exists", settings_key=key) settings[key]["value"] = settings[key]["default"] _save_settings(settings) @@ -304,7 +304,7 @@ def _get_settings(): ) unknown_settings[key] = value except Exception as e: - raise YunohostError("global_settings_cant_open_settings", reason=e) + raise YunohostValidationError("global_settings_cant_open_settings", reason=e) if unknown_settings: try: diff --git a/src/yunohost/ssh.py b/src/yunohost/ssh.py index f7c6fcbb1..e9e7e1831 100644 --- a/src/yunohost/ssh.py +++ b/src/yunohost/ssh.py @@ -5,7 +5,7 @@ import os import pwd import subprocess -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils.filesystem import read_file, write_to_file, chown, chmod, mkdir SSHD_CONFIG_PATH = "/etc/ssh/sshd_config" @@ -21,7 +21,7 @@ def user_ssh_allow(username): # TODO it would be good to support different kind of shells if not _get_user_for_ssh(username): - raise YunohostError("user_unknown", user=username) + raise YunohostValidationError("user_unknown", user=username) from yunohost.utils.ldap import _get_ldap_interface @@ -43,7 +43,7 @@ def user_ssh_disallow(username): # TODO it would be good to support different kind of shells if not _get_user_for_ssh(username): - raise YunohostError("user_unknown", user=username) + raise YunohostValidationError("user_unknown", user=username) from yunohost.utils.ldap import _get_ldap_interface diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index e1ebe1307..e5699dede 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -51,7 +51,7 @@ from yunohost.utils.packages import ( _list_upgradable_apt_packages, ynh_packages_version, ) -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.log import is_unit_operation, OperationLogger # FIXME this is a duplicate from apps.py @@ -156,7 +156,7 @@ def tools_adminpw(new_password, check_strength=True): # UNIX seems to not like password longer than 127 chars ... # e.g. SSH login gets broken (or even 'su admin' when entering the password) if len(new_password) >= 127: - raise YunohostError("admin_password_too_long") + raise YunohostValidationError("admin_password_too_long") new_hash = _hash_user_password(new_password) @@ -285,10 +285,10 @@ def tools_postinstall( # Do some checks at first if os.path.isfile("/etc/yunohost/installed"): - raise YunohostError("yunohost_already_installed") + raise YunohostValidationError("yunohost_already_installed") if os.path.isdir("/etc/yunohost/apps") and os.listdir("/etc/yunohost/apps") != []: - raise YunohostError( + raise YunohostValidationError( "It looks like you're trying to re-postinstall a system that was already working previously ... If you recently had some bug or issues with your installation, please first discuss with the team on how to fix the situation instead of savagely re-running the postinstall ...", raw_msg=True, ) @@ -301,7 +301,7 @@ def tools_postinstall( ) GB = 1024 ** 3 if not force_diskspace and main_space < 10 * GB: - raise YunohostError("postinstall_low_rootfsspace") + raise YunohostValidationError("postinstall_low_rootfsspace") # Check password if not force_password: @@ -331,14 +331,14 @@ def tools_postinstall( dyndns = True # If not, abort the postinstall else: - raise YunohostError("dyndns_unavailable", domain=domain) + raise YunohostValidationError("dyndns_unavailable", domain=domain) else: dyndns = False else: dyndns = False if os.system("iptables -V >/dev/null 2>/dev/null") != 0: - raise YunohostError( + raise YunohostValidationError( "iptables/nftables does not seems to be working on your setup. You may be in a container or your kernel does have the proper modules loaded. Sometimes, rebooting the machine may solve the issue.", raw_msg=True, ) @@ -530,17 +530,17 @@ def tools_upgrade( from yunohost.utils import packages if packages.dpkg_is_broken(): - raise YunohostError("dpkg_is_broken") + raise YunohostValidationError("dpkg_is_broken") # Check for obvious conflict with other dpkg/apt commands already running in parallel if not packages.dpkg_lock_available(): - raise YunohostError("dpkg_lock_not_available") + raise YunohostValidationError("dpkg_lock_not_available") if system is not False and apps is not None: - raise YunohostError("tools_upgrade_cant_both") + raise YunohostValidationError("tools_upgrade_cant_both") if system is False and apps is None: - raise YunohostError("tools_upgrade_at_least_one") + raise YunohostValidationError("tools_upgrade_at_least_one") # # Apps @@ -825,7 +825,7 @@ def tools_migrations_list(pending=False, done=False): # Check for option conflict if pending and done: - raise YunohostError("migrations_list_conflict_pending_done") + raise YunohostValidationError("migrations_list_conflict_pending_done") # Get all migrations migrations = _get_migrations_list() @@ -875,17 +875,17 @@ def tools_migrations_run( if m.id == target or m.name == target or m.id.split("_")[0] == target: return m - raise YunohostError("migrations_no_such_migration", id=target) + raise YunohostValidationError("migrations_no_such_migration", id=target) # auto, skip and force are exclusive options if auto + skip + force_rerun > 1: - raise YunohostError("migrations_exclusive_options") + raise YunohostValidationError("migrations_exclusive_options") # If no target specified if not targets: # skip, revert or force require explicit targets if skip or force_rerun: - raise YunohostError("migrations_must_provide_explicit_targets") + raise YunohostValidationError("migrations_must_provide_explicit_targets") # Otherwise, targets are all pending migrations targets = [m for m in all_migrations if m.state == "pending"] @@ -897,11 +897,11 @@ def tools_migrations_run( pending = [t.id for t in targets if t.state == "pending"] if skip and done: - raise YunohostError("migrations_not_pending_cant_skip", ids=", ".join(done)) + raise YunohostValidationError("migrations_not_pending_cant_skip", ids=", ".join(done)) if force_rerun and pending: - raise YunohostError("migrations_pending_cant_rerun", ids=", ".join(pending)) + raise YunohostValidationError("migrations_pending_cant_rerun", ids=", ".join(pending)) if not (skip or force_rerun) and done: - raise YunohostError("migrations_already_ran", ids=", ".join(done)) + raise YunohostValidationError("migrations_already_ran", ids=", ".join(done)) # So, is there actually something to do ? if not targets: diff --git a/src/yunohost/user.py b/src/yunohost/user.py index f1fab786a..089f2ba0e 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -37,7 +37,7 @@ from moulinette import msignals, msettings, m18n from moulinette.utils.log import getActionLogger from moulinette.utils.process import check_output -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.service import service_status from yunohost.log import is_unit_operation @@ -125,7 +125,7 @@ def user_create( # Validate domain used for email address/xmpp account if domain is None: if msettings.get("interface") == "api": - raise YunohostError("Invalide usage, specify domain argument") + raise YunohostValidationError("Invalid usage, you should specify a domain argument") else: # On affiche les differents domaines possibles msignals.display(m18n.n("domains_available")) @@ -141,24 +141,24 @@ def user_create( # Check that the domain exists if domain not in domain_list()["domains"]: - raise YunohostError("domain_name_unknown", domain=domain) + raise YunohostValidationError("domain_name_unknown", domain=domain) mail = username + "@" + domain ldap = _get_ldap_interface() if username in user_list()["users"]: - raise YunohostError("user_already_exists", user=username) + raise YunohostValidationError("user_already_exists", user=username) # Validate uniqueness of username and mail in LDAP try: ldap.validate_uniqueness({"uid": username, "mail": mail, "cn": username}) except Exception as e: - raise YunohostError("user_creation_failed", user=username, error=e) + raise YunohostValidationError("user_creation_failed", user=username, error=e) # Validate uniqueness of username in system users all_existing_usernames = {x.pw_name for x in pwd.getpwall()} if username in all_existing_usernames: - raise YunohostError("system_username_exists") + raise YunohostValidationError("system_username_exists") main_domain = _get_maindomain() aliases = [ @@ -170,7 +170,7 @@ def user_create( ] if mail in aliases: - raise YunohostError("mail_unavailable") + raise YunohostValidationError("mail_unavailable") operation_logger.start() @@ -264,7 +264,7 @@ def user_delete(operation_logger, username, purge=False): from yunohost.utils.ldap import _get_ldap_interface if username not in user_list()["users"]: - raise YunohostError("user_unknown", user=username) + raise YunohostValidationError("user_unknown", user=username) operation_logger.start() @@ -347,7 +347,7 @@ def user_update( attrs=attrs_to_fetch, ) if not result: - raise YunohostError("user_unknown", user=username) + raise YunohostValidationError("user_unknown", user=username) user = result[0] env_dict = {"YNH_USER_USERNAME": username} @@ -396,13 +396,13 @@ def user_update( try: ldap.validate_uniqueness({"mail": mail}) except Exception as e: - raise YunohostError("user_update_failed", user=username, error=e) + raise YunohostValidationError("user_update_failed", user=username, error=e) if mail[mail.find("@") + 1 :] not in domains: - raise YunohostError( + raise YunohostValidationError( "mail_domain_unknown", domain=mail[mail.find("@") + 1 :] ) if mail in aliases: - raise YunohostError("mail_unavailable") + raise YunohostValidationError("mail_unavailable") del user["mail"][0] new_attr_dict["mail"] = [mail] + user["mail"] @@ -414,9 +414,9 @@ def user_update( try: ldap.validate_uniqueness({"mail": mail}) except Exception as e: - raise YunohostError("user_update_failed", user=username, error=e) + raise YunohostValidationError("user_update_failed", user=username, error=e) if mail[mail.find("@") + 1 :] not in domains: - raise YunohostError( + raise YunohostValidationError( "mail_domain_unknown", domain=mail[mail.find("@") + 1 :] ) user["mail"].append(mail) @@ -429,7 +429,7 @@ def user_update( if len(user["mail"]) > 1 and mail in user["mail"][1:]: user["mail"].remove(mail) else: - raise YunohostError("mail_alias_remove_failed", mail=mail) + raise YunohostValidationError("mail_alias_remove_failed", mail=mail) new_attr_dict["mail"] = user["mail"] if "mail" in new_attr_dict: @@ -451,7 +451,7 @@ def user_update( if len(user["maildrop"]) > 1 and mail in user["maildrop"][1:]: user["maildrop"].remove(mail) else: - raise YunohostError("mail_forward_remove_failed", mail=mail) + raise YunohostValidationError("mail_forward_remove_failed", mail=mail) new_attr_dict["maildrop"] = user["maildrop"] if "maildrop" in new_attr_dict: @@ -500,7 +500,7 @@ def user_info(username): if result: user = result[0] else: - raise YunohostError("user_unknown", user=username) + raise YunohostValidationError("user_unknown", user=username) result_dict = { "username": user["uid"][0], @@ -638,7 +638,7 @@ def user_group_create( {"cn": groupname}, base_dn="ou=groups,dc=yunohost,dc=org" ) if conflict: - raise YunohostError("group_already_exist", group=groupname) + raise YunohostValidationError("group_already_exist", group=groupname) # Validate uniqueness of groupname in system group all_existing_groupnames = {x.gr_name for x in grp.getgrall()} @@ -651,7 +651,7 @@ def user_group_create( "sed --in-place '/^%s:/d' /etc/group" % groupname, shell=True ) else: - raise YunohostError("group_already_exist_on_system", group=groupname) + raise YunohostValidationError("group_already_exist_on_system", group=groupname) if not gid: # Get random GID @@ -705,7 +705,7 @@ def user_group_delete(operation_logger, groupname, force=False, sync_perm=True): existing_groups = list(user_group_list()["groups"].keys()) if groupname not in existing_groups: - raise YunohostError("group_unknown", group=groupname) + raise YunohostValidationError("group_unknown", group=groupname) # Refuse to delete primary groups of a user (e.g. group 'sam' related to user 'sam') # without the force option... @@ -714,7 +714,7 @@ def user_group_delete(operation_logger, groupname, force=False, sync_perm=True): existing_users = list(user_list()["users"].keys()) undeletable_groups = existing_users + ["all_users", "visitors"] if groupname in undeletable_groups and not force: - raise YunohostError("group_cannot_be_deleted", group=groupname) + raise YunohostValidationError("group_cannot_be_deleted", group=groupname) operation_logger.start() ldap = _get_ldap_interface() @@ -756,11 +756,11 @@ def user_group_update( # We also can't edit "all_users" without the force option because that's a special group... if not force: if groupname == "all_users": - raise YunohostError("group_cannot_edit_all_users") + raise YunohostValidationError("group_cannot_edit_all_users") elif groupname == "visitors": - raise YunohostError("group_cannot_edit_visitors") + raise YunohostValidationError("group_cannot_edit_visitors") elif groupname in existing_users: - raise YunohostError("group_cannot_edit_primary_group", group=groupname) + raise YunohostValidationError("group_cannot_edit_primary_group", group=groupname) # We extract the uid for each member of the group to keep a simple flat list of members current_group = user_group_info(groupname)["members"] @@ -771,7 +771,7 @@ def user_group_update( for user in users_to_add: if user not in existing_users: - raise YunohostError("user_unknown", user=user) + raise YunohostValidationError("user_unknown", user=user) if user in current_group: logger.warning( @@ -843,7 +843,7 @@ def user_group_info(groupname): ) if not result: - raise YunohostError("group_unknown", group=groupname) + raise YunohostValidationError("group_unknown", group=groupname) infos = result[0] diff --git a/src/yunohost/utils/error.py b/src/yunohost/utils/error.py index 3000a52f8..e78beb2c9 100644 --- a/src/yunohost/utils/error.py +++ b/src/yunohost/utils/error.py @@ -49,3 +49,7 @@ class YunohostError(MoulinetteError): return super(YunohostError, self).content() else: return {"error": self.strerror, "log_ref": self.log_ref} + + +class YunohostValidationError(YunohostError): + pass diff --git a/src/yunohost/utils/password.py b/src/yunohost/utils/password.py index dce337f84..9e693d8cd 100644 --- a/src/yunohost/utils/password.py +++ b/src/yunohost/utils/password.py @@ -90,11 +90,11 @@ class PasswordValidator(object): # on top (at least not the moulinette ones) # because the moulinette needs to be correctly initialized # as well as modules available in python's path. - from yunohost.utils.error import YunohostError + from yunohost.utils.error import YunohostValidationError status, msg = self.validation_summary(password) if status == "error": - raise YunohostError(msg) + raise YunohostValidationError(msg) def validation_summary(self, password): """ diff --git a/tests/test_i18n_keys.py b/tests/test_i18n_keys.py index 6876cbcd8..799dc0d0c 100644 --- a/tests/test_i18n_keys.py +++ b/tests/test_i18n_keys.py @@ -25,9 +25,11 @@ def find_expected_string_keys(): # Try to find : # m18n.n( "foo" # YunohostError("foo" + # YunohostValidationError("foo" # # i18n: foo p1 = re.compile(r"m18n\.n\(\n*\s*[\"\'](\w+)[\"\']") p2 = re.compile(r"YunohostError\(\n*\s*[\'\"](\w+)[\'\"]") + p2 = re.compile(r"YunohostValidationError\(\n*\s*[\'\"](\w+)[\'\"]") p3 = re.compile(r"# i18n: [\'\"]?(\w+)[\'\"]?") python_files = glob.glob("src/yunohost/*.py") From 41b5a1239336ff51868a3ec7cff7385e1d8ab88b Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 11 Mar 2021 03:07:16 +0100 Subject: [PATCH 096/131] Enforce permissions for /home/yunohost.backup and .conf --- data/hooks/conf_regen/01-yunohost | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index c4120d487..1dd2705e1 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -94,6 +94,22 @@ do_post_regen() { # Enfore permissions # ###################### + if [ -d /home/yunohost.backup ] + then + chmod 750 /home/yunohost.backup + chown admin:root /home/yunohost.backup + fi + if [ -d /home/yunohost.backup/archives ] + then + chmod 750 /home/yunohost.backup/archives + chown admin:root /home/yunohost.backup/archives + fi + if [ -d /home/yunohost.conf ] + then + chmod 750 /home/yunohost.conf + chown root:root /home/yunohost.conf + fi + # Certs # We do this with find because there could be a lot of them... chown -R root:ssl-cert /etc/yunohost/certs From 4a7129e69b4e4a0d2096f3f8029cb425488a8bbe Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 11 Mar 2021 03:08:41 +0100 Subject: [PATCH 097/131] Update changelog for 4.1.7.4 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 5fb0e563d..51eed275b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +yunohost (4.1.7.4) stable; urgency=low + + - [fix] sec: Enforce permissions for /home/yunohost.backup and .conf (41b5a123) + + -- Alexandre Aubin Thu, 11 Mar 2021 03:08:10 +0100 + yunohost (4.1.7.3) stable; urgency=low - [fix] log: Some secrets were not redacted (0c172cd3) From 37f0c30ddc8cf50a0fc7839026d6e604bff32810 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 11 Mar 2021 03:57:15 +0100 Subject: [PATCH 098/131] Inject log_ref into all is_unit_operation failures --- src/yunohost/app.py | 3 +-- src/yunohost/log.py | 10 +++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 613ca21df..f214824aa 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1124,8 +1124,7 @@ def app_install( raise YunohostError( failure_message_with_debug_instructions, - raw_msg=True, - log_ref=operation_logger.name, + raw_msg=True ) # Clean hooks and add new ones diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 1260cd98d..3f5fa8e71 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -35,7 +35,7 @@ from logging import FileHandler, getLogger, Formatter from moulinette import m18n, msettings from moulinette.core import MoulinetteError -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.packages import get_ynh_package_version from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import read_file, read_yaml @@ -635,6 +635,14 @@ class OperationLogger(object): return if error is not None and not isinstance(error, str): error = str(error) + + # When the error happen's in the is_unit_operation try/except, + # we want to inject the log ref in the exception, such that it may be + # transmitted to the webadmin which can then redirect to the appropriate + # log page + if isinstance(error, Exception) and not isinstance(error, YunohostValidationError): + error.log_ref = operation_logger.name + self.ended_at = datetime.utcnow() self._error = error self._success = error is None From 1a0ef941099ad6d9d2befa24b41fd5dfdc1bc2c8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 12 Mar 2021 04:24:27 +0100 Subject: [PATCH 099/131] Define HTTP codes for Yunohost Errors --- src/yunohost/utils/error.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/yunohost/utils/error.py b/src/yunohost/utils/error.py index e78beb2c9..c0ff2690c 100644 --- a/src/yunohost/utils/error.py +++ b/src/yunohost/utils/error.py @@ -25,6 +25,8 @@ from moulinette import m18n class YunohostError(MoulinetteError): + http_code = 500 + """ Yunohost base exception @@ -52,4 +54,5 @@ class YunohostError(MoulinetteError): class YunohostValidationError(YunohostError): - pass + + http_code = 400 From ce04570bfda75291a06727d1607641c13fcdfbfa Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 12 Mar 2021 23:18:16 +0100 Subject: [PATCH 100/131] helpers: Simplify manifest path / parsing --- data/helpers.d/apt | 9 +++------ data/helpers.d/utils | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/data/helpers.d/apt b/data/helpers.d/apt index bfdeffe7b..f0c650ace 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -224,13 +224,10 @@ ynh_install_app_dependencies () { # Add a comma for each space between packages. But not add a comma if the space separate a version specification. (See below) dependencies="$(echo "$dependencies" | sed 's/\([^\<=\>]\)\ \([^(]\)/\1, \2/g')" local 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 manifest_path="$YNH_APP_BASEDIR/manifest.json" - local version=$(grep '\"version\": ' "$manifest_path" | cut --delimiter='"' --fields=4) # Retrieve the version number in the manifest file. - if [ ${#version} -eq 0 ]; then + local version=$(jq -r '.version' "$manifest_path") + if [ -z "${version}" ] || [ "$version" == "null" ]; then version="1.0" fi local dep_app=${app//_/-} # Replace all '_' by '-' diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 8246b9986..c5ebdcb96 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -553,7 +553,7 @@ ynh_read_manifest () { if [ ! -e "$manifest" ]; then # If the manifest isn't found, try the common place for backup and restore script. - manifest="../settings/manifest.json" + manifest="$YNH_APP_BASEDIR/manifest.json" fi jq ".$manifest_key" "$manifest" --raw-output From 721f6f265e1c69d3fcadf0eb27f61918c65cb8f8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 14 Mar 2021 18:45:36 +0100 Subject: [PATCH 101/131] Typo ... --- src/yunohost/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 3d1d16f3c..fadc16b6e 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1069,7 +1069,7 @@ def app_install( env_dict_remove["YNH_APP_ID"] = app_id env_dict_remove["YNH_APP_INSTANCE_NAME"] = app_instance_name env_dict_remove["YNH_APP_INSTANCE_NUMBER"] = str(instance_number) - env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?") + env_dict_remove["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?") # Execute remove script operation_logger_remove = OperationLogger( From 07f8d6d7af437af38a23899aa1abb731dfff11db Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 14 Mar 2021 18:47:33 +0100 Subject: [PATCH 102/131] ynh_clean_check_starting: Let's not trigger an error when vars aren't set --- data/helpers.d/systemd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index 4c7bd31d1..1b620e991 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -171,12 +171,12 @@ ynh_systemd_action() { # # Requires YunoHost version 3.5.0 or higher. ynh_clean_check_starting () { - if [ -n "$pid_tail" ] + if [ -n "${pid_tail:-}" ] then # Stop the execution of tail. kill -SIGTERM $pid_tail 2>&1 fi - if [ -n "$templog" ] + if [ -n "${templog:-}" ] then ynh_secure_remove --file="$templog" 2>&1 fi From 7a947dbce1684bbade4aeb22c33500543a6aa8d8 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 15 Mar 2021 00:03:31 +0100 Subject: [PATCH 103/131] [fix] True instead of description (#1189) --- src/yunohost/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index 2de395131..6ba271ea6 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -400,7 +400,7 @@ def _get_and_format_service_status(service, infos): translation_key = "service_description_%s" % service if m18n.key_exists(translation_key): - description = m18n.key_exists(translation_key) + description = m18n.n(translation_key) else: description = str(raw_status.get("Description", "")) From dc6033c3993023162869d770029b5ee8baab1c03 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Mon, 15 Mar 2021 14:10:13 +0100 Subject: [PATCH 104/131] python3 way to get a list of dict keys --- data/hooks/diagnosis/14-ports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index 6faf29053..7581a1ac6 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -43,7 +43,7 @@ class PortsDiagnoser(Diagnoser): for ipversion in ipversions: try: r = Diagnoser.remote_diagnosis( - "check-ports", data={"ports": ports.keys()}, ipversion=ipversion + "check-ports", data={"ports": list(ports)}, ipversion=ipversion ) results[ipversion] = r["ports"] except Exception as e: From 4a19a60b44a81ab5f80e4547a05b64694b169154 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 10 Mar 2021 11:24:11 +0100 Subject: [PATCH 105/131] dirty patch to wait for services to finish reloading --- src/yunohost/app.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index fadc16b6e..9d53df815 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -3465,6 +3465,14 @@ def _assert_system_is_sane_for_app(manifest, when): if "fail2ban" not in services: services.append("fail2ban") + # Wait if a service is reloading + test_nb = 0 + while test_nb < 10: + if not any(s for s in services if service_status(s)["status"] == "reloading"): + break + time.sleep(0.5) + test_nb+=1 + # List services currently down and raise an exception if any are found faulty_services = [s for s in services if service_status(s)["status"] != "running"] if faulty_services: From c2506f362c476558e1dc4410c365e2bf79e88726 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Fri, 26 Feb 2021 18:49:26 +0000 Subject: [PATCH 106/131] Translated using Weblate (German) Currently translated at 80.9% (510 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 536bdd842..019781e91 100644 --- a/locales/de.json +++ b/locales/de.json @@ -574,5 +574,13 @@ "password_listed": "Dieses Passwort gehört zu den meistverwendeten der Welt. Bitte nehmen Sie etwas einzigartigeres.", "operation_interrupted": "Wurde die Operation manuell unterbrochen?", "invalid_number": "Muss eine Zahl sein", - "migrations_to_be_ran_manually": "Die Migration {id} muss manuell durchgeführt werden. Bitte gehen Sie zu Werkzeuge → Migrationen auf der Webadmin-Seite oder führen Sie 'yunohost tools migrations run' aus." + "migrations_to_be_ran_manually": "Die Migration {id} muss manuell durchgeführt werden. Bitte gehen Sie zu Werkzeuge → Migrationen auf der Webadmin-Seite oder führen Sie 'yunohost tools migrations run' aus.", + "permission_already_up_to_date": "Die Berechtigung wurde nicht aktualisiert, weil die Anfragen für Hinzufügen/Entfernen stimmen mit dem aktuellen Status bereits überein", + "permission_already_exist": "Berechtigung '{permission}' existiert bereits", + "permission_already_disallowed": "Für die Gruppe '{group}' wurde die Berechtigung '{permission}' deaktiviert", + "permission_already_allowed": "Die Gruppe '{group}' hat die Berechtigung '{permission}' bereits erhalten", + "pattern_password_app": "Entschuldigen Sie bitte! Passwörter dürfen folgende Zeichen nicht enthalten: {forbidden_chars}", + "pattern_email_forward": "Es muss sich um eine gültige E-Mail-Adresse handeln. Das Symbol '+' wird akzeptiert (zum Beispiel : maxmuster@beispiel.com oder maxmuster+yunohost@beispiel.com)", + "password_too_simple_4": "Dass Passwort muss mindestens 12 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten", + "password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten" } From 394fd90383f826bc918b611e466ca1b30be66839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Sat, 27 Feb 2021 20:20:48 +0000 Subject: [PATCH 107/131] Translated using Weblate (Occitan) Currently translated at 53.9% (340 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/oc/ --- locales/oc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/oc.json b/locales/oc.json index 07d841579..1849b3f3b 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -340,8 +340,8 @@ "migration_0005_not_enough_space": "I a pas pro d’espaci disponible sus {path} per lançar la migracion d’aquela passa :(.", "service_description_php7.0-fpm": "executa d’aplicacions escrichas en PHP amb nginx", "users_available": "Lista dels utilizaires disponibles :", - "good_practices_about_admin_password": "Sètz per definir un nòu senhal per l’administracion. Lo senhal deu almens conténer 8 caractèrs - encara que siá de bon far d’utilizar un senhal mai long qu’aquò (ex. una passafrasa) e/o d’utilizar mantun tipes de caractèrs (majuscula, minuscula, nombre e caractèrs especials).", - "good_practices_about_user_password": "Sètz a mand de definir un nòu senhal d’utilizaire. Lo nòu senhal deu conténer almens 8 caractèrs, es de bon far d’utilizar un senhal mai long (es a dire una frasa de senhal) e/o utilizar mantuns tipes de caractèrs (majusculas, minusculas, nombres e caractèrs especials).", + "good_practices_about_admin_password": "Sètz per definir un nòu senhal per l’administracion. Lo senhal deu almens conténer 8 caractèrs - encara que siá de bon far d’utilizar un senhal mai long qu’aquò (ex. una passafrasa) e/o d’utilizar mantun tipe de caractèrs (majuscula, minuscula, nombre e caractèrs especials).", + "good_practices_about_user_password": "Sètz a mand de definir un nòu senhal d’utilizaire. Lo nòu senhal deu conténer almens 8 caractèrs, es de bon far d’utilizar un senhal mai long (es a dire una frasa de senhal) e/o utilizar mantun tipe de caractèrs (majusculas, minusculas, nombres e caractèrs especials).", "migration_description_0006_sync_admin_and_root_passwords": "Sincronizar los senhals admin e root", "migration_0006_disclaimer": "Ara YunoHost s’espèra que los senhals admin e root sián sincronizats. En lançant aquesta migracion, vòstre senhal root serà remplaçat pel senhal admin.", "password_listed": "Aqueste senhal es un dels mai utilizats al monde. Se vos plai utilizatz-ne un mai unic.", From 56321d41c4c666ff1fde30970d4507bfcb493597 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Sun, 28 Feb 2021 22:31:09 +0000 Subject: [PATCH 108/131] Translated using Weblate (German) Currently translated at 81.1% (511 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 019781e91..58b791d06 100644 --- a/locales/de.json +++ b/locales/de.json @@ -79,7 +79,7 @@ "ldap_initialized": "LDAP wurde initialisiert", "mail_alias_remove_failed": "E-Mail Alias '{mail:s}' konnte nicht entfernt werden", "mail_domain_unknown": "Die Domäne '{domain:s}' dieser E-Mail-Adresse ist ungültig. Wähle bitte eine Domäne, welche durch diesen Server verwaltet wird.", - "mail_forward_remove_failed": "Mailweiterleitung '{mail:s}' konnte nicht entfernt werden", + "mail_forward_remove_failed": "Mailweiterleitung für '{mail:s}' konnte nicht deaktiviert werden", "main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden", "main_domain_changed": "Die Hauptdomain wurde geändert", "no_internet_connection": "Der Server ist nicht mit dem Internet verbunden", From 74a9512d8ea8e6de9f70271e2b33549686e5ea4f Mon Sep 17 00:00:00 2001 From: Scapharnaum Date: Sun, 28 Feb 2021 21:48:41 +0000 Subject: [PATCH 109/131] Translated using Weblate (German) Currently translated at 81.1% (511 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/de.json b/locales/de.json index 58b791d06..a86ba681a 100644 --- a/locales/de.json +++ b/locales/de.json @@ -176,7 +176,7 @@ "certmanager_cannot_read_cert": "Es ist ein Fehler aufgetreten, als es versucht wurde das aktuelle Zertifikat für die Domain {domain:s} zu öffnen (Datei: {file:s}), Grund: {reason:s}", "certmanager_cert_install_success_selfsigned": "Ein selbstsigniertes Zertifikat für die Domain {domain:s} wurde erfolgreich installiert", "certmanager_cert_install_success": "Für die Domain {domain:s} wurde erfolgreich ein Let's Encrypt Zertifikat installiert.", - "certmanager_cert_renew_success": "Das Let's Encrypt Zertifikat für die Domain {domain:s} wurde erfolgreich erneuert.", + "certmanager_cert_renew_success": "Das Let's Encrypt Zertifikat für die Domain {domain:s} wurde erfolgreich erneuert", "certmanager_hit_rate_limit": "Es wurden innerhalb kurzer Zeit zu viele Zertifikate für dieselbe Domain {domain:s} ausgestellt. Bitte versuchen Sie es später nochmal. Besuchen Sie https://letsencrypt.org/docs/rate-limits/ für mehr Informationen", "certmanager_cert_signing_failed": "Das neue Zertifikat konnte nicht signiert werden", "certmanager_no_cert_file": "Die Zertifikatsdatei für die Domain {domain:s} (Datei: {file:s}) konnte nicht gelesen werden", @@ -337,7 +337,7 @@ "diagnosis_found_errors": "Habe {errors} erhebliche(s) Problem(e) in Verbindung mit {category} gefunden!", "diagnosis_found_warnings": "Habe {warnings} Ding(e) gefunden, die verbessert werden könnten für {category}.", "diagnosis_ip_dnsresolution_working": "Domänen-Namens-Auflösung funktioniert!", - "diagnosis_ip_weird_resolvconf": "DNS Auflösung scheint zu funktionieren, aber seien Sie vorsichtig wenn Sie eine eigene /etc/resolv.conf verwendest.", + "diagnosis_ip_weird_resolvconf": "DNS Auflösung scheint zu funktionieren, aber seien Sie vorsichtig wenn Sie Ihren eigenen /etc/resolv.conf verwenden.", "diagnosis_display_tip": "Um die gefundenen Probleme zu sehen, können Sie zum Diagnose-Bereich des webadmin gehen, oder 'yunohost diagnosis show --issues' in der Kommandozeile ausführen.", "backup_archive_corrupted": "Das Backup-Archiv '{archive}' scheint beschädigt: {error}", "backup_archive_cant_retrieve_info_json": "Die Informationen für das Archiv '{archive}' konnten nicht geladen werden... Die Datei info.json wurde nicht gefunden (oder ist kein gültiges json).", @@ -359,7 +359,7 @@ "diagnosis_domain_expiration_error": "Einige Domänen werden SEHR BALD ablaufen!", "diagnosis_domain_expiration_success": "Deine Domänen sind registriert und werden in nächster Zeit nicht ablaufen.", "diagnosis_domain_not_found_details": "Die Domäne {domain} existiert nicht in der WHOIS-Datenbank oder sie ist abgelaufen!", - "diagnosis_domain_expiration_not_found": "Konnte die Ablaufdaten für einige Domänen nicht überprüfen.", + "diagnosis_domain_expiration_not_found": "Das Ablaufdatum einiger Domains kann nicht überprüft werden", "diagnosis_dns_try_dyndns_update_force": "Die DNS-Konfiguration dieser Domäne sollte automatisch von Yunohost verwaltet werden. Andernfalls können Sie mittels yunohost dyndns update --force ein Update erzwingen.", "diagnosis_dns_point_to_doc": "Bitte schauen Sie in die Dokumentation unter https://yunohost.org/dns_config wenn Sie Hilfe bei der Konfiguration der DNS-Einträge brauchen.", "diagnosis_dns_discrepancy": "Der folgende DNS-Eintrag scheint nicht den empfohlenen Einstellungen zu entsprechen:
Typ: {type}
Name: {name}
Aktueller Wert: {current}
Erwarteter Wert: {value}", From acd4d223cbcfd54b5db8ca02420898bc2c71277b Mon Sep 17 00:00:00 2001 From: Scapharnaum Date: Mon, 1 Mar 2021 00:00:42 +0000 Subject: [PATCH 110/131] Translated using Weblate (German) Currently translated at 83.6% (527 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/locales/de.json b/locales/de.json index a86ba681a..18bb9068a 100644 --- a/locales/de.json +++ b/locales/de.json @@ -79,7 +79,7 @@ "ldap_initialized": "LDAP wurde initialisiert", "mail_alias_remove_failed": "E-Mail Alias '{mail:s}' konnte nicht entfernt werden", "mail_domain_unknown": "Die Domäne '{domain:s}' dieser E-Mail-Adresse ist ungültig. Wähle bitte eine Domäne, welche durch diesen Server verwaltet wird.", - "mail_forward_remove_failed": "Mailweiterleitung für '{mail:s}' konnte nicht deaktiviert werden", + "mail_forward_remove_failed": "Die Weiterleitungs-E-Mail '{mail:s}' konnte nicht gelöscht werden", "main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden", "main_domain_changed": "Die Hauptdomain wurde geändert", "no_internet_connection": "Der Server ist nicht mit dem Internet verbunden", @@ -582,5 +582,21 @@ "pattern_password_app": "Entschuldigen Sie bitte! Passwörter dürfen folgende Zeichen nicht enthalten: {forbidden_chars}", "pattern_email_forward": "Es muss sich um eine gültige E-Mail-Adresse handeln. Das Symbol '+' wird akzeptiert (zum Beispiel : maxmuster@beispiel.com oder maxmuster+yunohost@beispiel.com)", "password_too_simple_4": "Dass Passwort muss mindestens 12 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten", - "password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten" + "password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten", + "regenconf_file_manually_removed": "Die Konfigurationsdatei '{conf}' wurde manuell gelöscht und wird nicht erstellt", + "regenconf_file_manually_modified": "Die Konfigurationsdatei '{conf}' wurde manuell bearbeitet und wird nicht aktualisiert", + "regenconf_file_kept_back": "Die Konfigurationsdatei '{conf}' sollte von \"regen-conf\" (Kategorie {Kategorie}) gelöscht werden, wurde aber beibehalten.", + "regenconf_file_copy_failed": "Die neue Konfigurationsdatei '{new}' kann nicht nach '{conf}' kopiert werden", + "regenconf_file_backed_up": "Die Konfigurationsdatei '{conf}' wurde unter '{backup}' gespeichert", + "permission_require_account": "Berechtigung {permission} ist nur für Benutzer mit einem Konto sinnvoll und kann daher nicht für Besucher aktiviert werden.", + "permission_protected": "Die Berechtigung ist geschützt. Sie können die Besuchergruppe nicht zu dieser Berechtigung hinzufügen oder daraus entfernen.", + "permission_updated": "Berechtigung '{permission:s}' aktualisiert", + "permission_update_failed": "Die Berechtigung '{permission}' kann nicht aktualisiert werden : {error}", + "permission_not_found": "Berechtigung nicht gefunden", + "permission_deletion_failed": "Entfernung der Berechtigung nicht möglich '{permission}': {error}", + "permission_deleted": "Berechtigung gelöscht", + "permission_currently_allowed_for_all_users": "Diese Berechtigung wird derzeit allen Benutzern zusätzlich zu anderen Gruppen erteilt. Möglicherweise möchten Sie entweder die Berechtigung 'all_users' entfernen oder die anderen Gruppen entfernen, für die sie derzeit zulässig sind.", + "permission_creation_failed": "Berechtigungserstellung nicht möglich '{permission}' : {error}", + "permission_created": "Berechtigung '{permission: s}' erstellt", + "permission_cannot_remove_main": "Entfernung einer Hauptberechtigung nicht genehmigt" } From 4fadd4b68f4b9fe32847d152133de47e9229d30a Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 3 Mar 2021 21:56:17 +0000 Subject: [PATCH 111/131] Translated using Weblate (German) Currently translated at 84.2% (531 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 18bb9068a..2dc287db5 100644 --- a/locales/de.json +++ b/locales/de.json @@ -598,5 +598,9 @@ "permission_currently_allowed_for_all_users": "Diese Berechtigung wird derzeit allen Benutzern zusätzlich zu anderen Gruppen erteilt. Möglicherweise möchten Sie entweder die Berechtigung 'all_users' entfernen oder die anderen Gruppen entfernen, für die sie derzeit zulässig sind.", "permission_creation_failed": "Berechtigungserstellung nicht möglich '{permission}' : {error}", "permission_created": "Berechtigung '{permission: s}' erstellt", - "permission_cannot_remove_main": "Entfernung einer Hauptberechtigung nicht genehmigt" + "permission_cannot_remove_main": "Entfernung einer Hauptberechtigung nicht genehmigt", + "regenconf_file_updated": "Konfigurationsdatei '{conf}' aktualisiert", + "regenconf_file_removed": "Konfigurationsdatei '{conf}' entfernt", + "regenconf_file_remove_failed": "Konnte die Konfigurationsdatei '{conf}' nicht entfernen", + "postinstall_low_rootfsspace": "Das Root-Filesystem hat insgesamt weniger als 10GB freien Speicherplatz zur Verfügung, was ziemlich besorgniserregend ist! Sie werden sehr bald keinen freien Speicherplatz mehr haben! Für das Root-Filesystem werden mindestens 16GB empfohlen. Wenn Sie YunoHost trotz dieser Warnung installieren wollen, wiederholen Sie den Befehl mit --force-diskspace" } From 0b7e040ee2b378cbd411729b088795c32c9ee821 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Fri, 5 Mar 2021 06:50:41 +0000 Subject: [PATCH 112/131] Translated using Weblate (German) Currently translated at 84.6% (533 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 2dc287db5..4fcc7a7e3 100644 --- a/locales/de.json +++ b/locales/de.json @@ -602,5 +602,7 @@ "regenconf_file_updated": "Konfigurationsdatei '{conf}' aktualisiert", "regenconf_file_removed": "Konfigurationsdatei '{conf}' entfernt", "regenconf_file_remove_failed": "Konnte die Konfigurationsdatei '{conf}' nicht entfernen", - "postinstall_low_rootfsspace": "Das Root-Filesystem hat insgesamt weniger als 10GB freien Speicherplatz zur Verfügung, was ziemlich besorgniserregend ist! Sie werden sehr bald keinen freien Speicherplatz mehr haben! Für das Root-Filesystem werden mindestens 16GB empfohlen. Wenn Sie YunoHost trotz dieser Warnung installieren wollen, wiederholen Sie den Befehl mit --force-diskspace" + "postinstall_low_rootfsspace": "Das Root-Filesystem hat insgesamt weniger als 10GB freien Speicherplatz zur Verfügung, was ziemlich besorgniserregend ist! Sie werden sehr bald keinen freien Speicherplatz mehr haben! Für das Root-Filesystem werden mindestens 16GB empfohlen. Wenn Sie YunoHost trotz dieser Warnung installieren wollen, wiederholen Sie den Befehl mit --force-diskspace", + "regenconf_up_to_date": "Die Konfiguration ist bereits aktuell für die Kategorie '{category}'", + "regenconf_now_managed_by_yunohost": "Die Konfigurationsdatei '{conf}' wird jetzt von YunoHost (Kategorie {category}) verwaltet." } From 18cc2ecbc8a9e2c1494f8f1968b96bf5ef9e118b Mon Sep 17 00:00:00 2001 From: Radek S Date: Sat, 6 Mar 2021 13:22:33 +0000 Subject: [PATCH 113/131] Translated using Weblate (Czech) Currently translated at 1.7% (11 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/cs/ --- locales/cs.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/locales/cs.json b/locales/cs.json index eafada5e6..3df59e0fd 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -1,3 +1,13 @@ { - "password_too_simple_1": "Heslo musí být aspoň 8 znaků dlouhé" + "password_too_simple_1": "Heslo musí být aspoň 8 znaků dlouhé", + "app_already_installed": "{app:s} je již nainstalován/a", + "already_up_to_date": "Neprovedena žádná akce. Vše je již aktuální.", + "admin_password_too_long": "Zvolte prosím heslo kratší než 127 znaků", + "admin_password_changed": "Heslo správce bylo změněno", + "admin_password_change_failed": "Nebylo možné změnit heslo", + "admin_password": "Heslo správce", + "additional_urls_already_removed": "Dotatečný odkaz '{url:s}' byl již odebrán u oprávnění '{permission:s}'", + "additional_urls_already_added": "Dotatečný odkaz '{url:s}' byl již přidán v dodatečných odkazech pro oprávnění '{permission:s}'", + "action_invalid": "Nesprávné akce '{action:s}'", + "aborting": "Přerušení." } From ad4ca718f7131ab41e24c366393eba804d1b8e32 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 10 Mar 2021 19:07:07 +0000 Subject: [PATCH 114/131] Translated using Weblate (German) Currently translated at 84.7% (534 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 4fcc7a7e3..cdaa714eb 100644 --- a/locales/de.json +++ b/locales/de.json @@ -604,5 +604,6 @@ "regenconf_file_remove_failed": "Konnte die Konfigurationsdatei '{conf}' nicht entfernen", "postinstall_low_rootfsspace": "Das Root-Filesystem hat insgesamt weniger als 10GB freien Speicherplatz zur Verfügung, was ziemlich besorgniserregend ist! Sie werden sehr bald keinen freien Speicherplatz mehr haben! Für das Root-Filesystem werden mindestens 16GB empfohlen. Wenn Sie YunoHost trotz dieser Warnung installieren wollen, wiederholen Sie den Befehl mit --force-diskspace", "regenconf_up_to_date": "Die Konfiguration ist bereits aktuell für die Kategorie '{category}'", - "regenconf_now_managed_by_yunohost": "Die Konfigurationsdatei '{conf}' wird jetzt von YunoHost (Kategorie {category}) verwaltet." + "regenconf_now_managed_by_yunohost": "Die Konfigurationsdatei '{conf}' wird jetzt von YunoHost (Kategorie {category}) verwaltet.", + "regenconf_updated": "Konfiguration aktualisiert für '{category}'" } From f0827451caeba1d29de86bd1f9dbbaa84a837fa3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 17 Mar 2021 16:37:07 +0100 Subject: [PATCH 115/131] Fix translation inconsistency --- locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index cdaa714eb..67a1d1a2e 100644 --- a/locales/de.json +++ b/locales/de.json @@ -585,7 +585,7 @@ "password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten", "regenconf_file_manually_removed": "Die Konfigurationsdatei '{conf}' wurde manuell gelöscht und wird nicht erstellt", "regenconf_file_manually_modified": "Die Konfigurationsdatei '{conf}' wurde manuell bearbeitet und wird nicht aktualisiert", - "regenconf_file_kept_back": "Die Konfigurationsdatei '{conf}' sollte von \"regen-conf\" (Kategorie {Kategorie}) gelöscht werden, wurde aber beibehalten.", + "regenconf_file_kept_back": "Die Konfigurationsdatei '{conf}' sollte von \"regen-conf\" (Kategorie {category}) gelöscht werden, wurde aber beibehalten.", "regenconf_file_copy_failed": "Die neue Konfigurationsdatei '{new}' kann nicht nach '{conf}' kopiert werden", "regenconf_file_backed_up": "Die Konfigurationsdatei '{conf}' wurde unter '{backup}' gespeichert", "permission_require_account": "Berechtigung {permission} ist nur für Benutzer mit einem Konto sinnvoll und kann daher nicht für Besucher aktiviert werden.", From 9e032b04bc33dc8a3825adf5e7b5efd3460fd89c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Mar 2021 16:49:41 +0100 Subject: [PATCH 116/131] Fix i18n key tests --- tests/test_i18n_keys.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_i18n_keys.py b/tests/test_i18n_keys.py index 799dc0d0c..2ad56a34e 100644 --- a/tests/test_i18n_keys.py +++ b/tests/test_i18n_keys.py @@ -29,8 +29,8 @@ def find_expected_string_keys(): # # i18n: foo p1 = re.compile(r"m18n\.n\(\n*\s*[\"\'](\w+)[\"\']") p2 = re.compile(r"YunohostError\(\n*\s*[\'\"](\w+)[\'\"]") - p2 = re.compile(r"YunohostValidationError\(\n*\s*[\'\"](\w+)[\'\"]") - p3 = re.compile(r"# i18n: [\'\"]?(\w+)[\'\"]?") + p3 = re.compile(r"YunohostValidationError\(\n*\s*[\'\"](\w+)[\'\"]") + p4 = re.compile(r"# i18n: [\'\"]?(\w+)[\'\"]?") python_files = glob.glob("src/yunohost/*.py") python_files.extend(glob.glob("src/yunohost/utils/*.py")) @@ -49,6 +49,10 @@ def find_expected_string_keys(): continue yield m for m in p3.findall(content): + if m.endswith("_"): + continue + yield m + for m in p4.findall(content): yield m # For each diagnosis, try to find strings like "diagnosis_stuff_foo" (c.f. diagnosis summaries) From 09d306924ac3139999aad96b9fe874e97636ca74 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Mar 2021 17:46:32 +0100 Subject: [PATCH 117/131] Fix minor issue with main_space diagnosis: duplicated error/warning, missing / partition when it's on a /dev/loop --- data/hooks/diagnosis/50-systemresources.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/hooks/diagnosis/50-systemresources.py b/data/hooks/diagnosis/50-systemresources.py index 1e8e2201a..a8f3cb6df 100644 --- a/data/hooks/diagnosis/50-systemresources.py +++ b/data/hooks/diagnosis/50-systemresources.py @@ -77,7 +77,7 @@ class SystemResourcesDiagnoser(Diagnoser): # Ignore /dev/loop stuff which are ~virtual partitions ? (e.g. mounted to /snap/) disk_partitions = [ - d for d in disk_partitions if not d.device.startswith("/dev/loop") + d for d in disk_partitions if d.mountpoint in ["/", "/var"] or not d.device.startswith("/dev/loop") ] for disk_partition in disk_partitions: @@ -139,7 +139,7 @@ class SystemResourcesDiagnoser(Diagnoser): status="ERROR", summary="diagnosis_rootfstotalspace_critical", ) - if main_space < 14 * GB: + elif main_space < 14 * GB: yield dict( meta={"test": "rootfstotalspace"}, data={"space": human_size(main_space)}, From 11c50c018742647237315f5b7222e19a466125a4 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Mar 2021 18:49:25 +0100 Subject: [PATCH 118/131] Fix log_ref injection --- src/yunohost/log.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 3f5fa8e71..7a45565f8 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -631,17 +631,18 @@ class OperationLogger(object): """ Close properly the unit operation """ - if self.ended_at is not None or self.started_at is None: - return - if error is not None and not isinstance(error, str): - error = str(error) # When the error happen's in the is_unit_operation try/except, # we want to inject the log ref in the exception, such that it may be # transmitted to the webadmin which can then redirect to the appropriate # log page if isinstance(error, Exception) and not isinstance(error, YunohostValidationError): - error.log_ref = operation_logger.name + error.log_ref = self.name + + if self.ended_at is not None or self.started_at is None: + return + if error is not None and not isinstance(error, str): + error = str(error) self.ended_at = datetime.utcnow() self._error = error From 33fab1c99f1775da0a32dcf7072be13a5cbd3c59 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Mar 2021 20:45:03 +0100 Subject: [PATCH 119/131] Be more robust against non-int values for level in app catalog (e.g. for apps 'inprogress' for which level is '?') --- src/yunohost/app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 9d53df815..62e4ffd59 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -257,8 +257,9 @@ def _app_upgradable(app_infos): return "url_required" # Do not advertise upgrades for bad-quality apps + level = app_in_catalog.get("level", -1) if ( - not app_in_catalog.get("level", -1) >= 5 + not (isinstance(level, int) and level >= 5) or app_in_catalog.get("state") != "working" ): return "bad_quality" From ab454ff62f56e83d978f0a77995b1f578cb0fb4a Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Mar 2021 21:40:33 +0100 Subject: [PATCH 120/131] Missing decode() for Popen output in certificate.py --- src/yunohost/certificate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index c48af2c07..dade85285 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -197,6 +197,8 @@ def _certificate_install_selfsigned(domain_list, force=False): out, _ = p.communicate() + out = out.decode("utf-8") + if p.returncode != 0: logger.warning(out) raise YunohostError("domain_cert_gen_failed") From e63ca06d371e9e4eb5a724f11e6580404fec90a0 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Mar 2021 21:58:15 +0100 Subject: [PATCH 121/131] Missing import --- src/yunohost/backup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index b020c0f34..ba940058b 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -63,7 +63,7 @@ from yunohost.hook import ( from yunohost.tools import tools_postinstall from yunohost.regenconf import regen_conf from yunohost.log import OperationLogger -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.packages import ynh_packages_version from yunohost.settings import settings_get From a5fe21fd3864c818615f9c86e94f2e09c8844e86 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 23 Mar 2021 00:32:21 +0100 Subject: [PATCH 122/131] Zblerg multiple forgotten import / typo >_> --- src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py | 2 +- src/yunohost/domain.py | 4 ++-- src/yunohost/ssh.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py b/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py index 0526c025d..cbdfabb1f 100644 --- a/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py +++ b/src/yunohost/data_migrations/0017_postgresql_9p6_to_11.py @@ -1,7 +1,7 @@ import subprocess from moulinette import m18n -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils.log import getActionLogger from yunohost.tools import Migration diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index fdf247f89..8d8be57a0 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -28,7 +28,7 @@ import re from moulinette import m18n, msettings, msignals from moulinette.core import MoulinetteError -from yunohost.utils.error import YunohostError +from yunohost.utils.error import YunohostError, YunohostValidationError from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import write_to_file @@ -131,7 +131,7 @@ def domain_add(operation_logger, domain, dyndns=False): operation_logger.start() if dyndns: - from yunohost.dyndns import dndns_subscribe + from yunohost.dyndns import dyndns_subscribe # Actually subscribe dyndns_subscribe(domain=domain) diff --git a/src/yunohost/ssh.py b/src/yunohost/ssh.py index e9e7e1831..39d4b4287 100644 --- a/src/yunohost/ssh.py +++ b/src/yunohost/ssh.py @@ -5,7 +5,7 @@ import os import pwd import subprocess -from yunohost.utils.error import YunohostError, YunohostValidationError +from yunohost.utils.error import YunohostValidationError from moulinette.utils.filesystem import read_file, write_to_file, chown, chmod, mkdir SSHD_CONFIG_PATH = "/etc/ssh/sshd_config" From c45d1010d6ee0b3a0fd0da697234b10387f62c3f Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Fri, 19 Mar 2021 19:58:19 +0000 Subject: [PATCH 123/131] Translated using Weblate (German) Currently translated at 85.3% (538 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 67a1d1a2e..832fc1b91 100644 --- a/locales/de.json +++ b/locales/de.json @@ -605,5 +605,9 @@ "postinstall_low_rootfsspace": "Das Root-Filesystem hat insgesamt weniger als 10GB freien Speicherplatz zur Verfügung, was ziemlich besorgniserregend ist! Sie werden sehr bald keinen freien Speicherplatz mehr haben! Für das Root-Filesystem werden mindestens 16GB empfohlen. Wenn Sie YunoHost trotz dieser Warnung installieren wollen, wiederholen Sie den Befehl mit --force-diskspace", "regenconf_up_to_date": "Die Konfiguration ist bereits aktuell für die Kategorie '{category}'", "regenconf_now_managed_by_yunohost": "Die Konfigurationsdatei '{conf}' wird jetzt von YunoHost (Kategorie {category}) verwaltet.", - "regenconf_updated": "Konfiguration aktualisiert für '{category}'" + "regenconf_updated": "Konfiguration aktualisiert für '{category}'", + "regenconf_pending_applying": "Wende die anstehende Konfiguration für die Kategorie {category} an...", + "regenconf_failed": "Konnte die Konfiguration für die Kategorie(n) {categories} nicht neu erstellen", + "regenconf_dry_pending_applying": "Überprüfe die anstehende Konfiguration, welche für die Kategorie {category}' aktualisiert worden wäre…", + "regenconf_would_be_updated": "Die Konfiguration wäre für die Kategorie '{category}' aktualisiert worden" } From cf884b1149f231eea590e90a91a561a8b5561f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Wed, 17 Mar 2021 20:36:55 +0000 Subject: [PATCH 124/131] Translated using Weblate (Occitan) Currently translated at 57.6% (363 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/oc/ --- locales/oc.json | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/locales/oc.json b/locales/oc.json index 1849b3f3b..7fd423617 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -327,7 +327,7 @@ "log_user_delete": "Levar l’utilizaire « {} »", "log_user_update": "Actualizar las informacions de l’utilizaire « {} »", "log_domain_main_domain": "Far venir « {} » lo domeni màger", - "log_tools_migrations_migrate_forward": "Migrar", + "log_tools_migrations_migrate_forward": "Executar las migracions", "log_tools_postinstall": "Realizar la post installacion del servidor YunoHost", "log_tools_upgrade": "Actualizacion dels paquets sistèma", "log_tools_shutdown": "Atudar lo servidor", @@ -593,5 +593,19 @@ "app_argument_password_no_default": "Error pendent l’analisi de l’argument del senhal « {name} » : l’argument de senhal pòt pas aver de valor per defaut per de rason de seguretat", "app_label_deprecated": "Aquesta comanda es estada renduda obsolèta. Mercés d'utilizar lo nòva \"yunohost user permission update\" per gerir letiquetada de l'aplication", "additional_urls_already_removed": "URL addicionala {url:s} es ja estada elimida per la permission «#permission:s»", - "additional_urls_already_added": "URL addicionadal «{url:s}'» es ja estada aponduda per la permission «{permission:s}»" + "additional_urls_already_added": "URL addicionadal «{url:s}'» es ja estada aponduda per la permission «{permission:s}»", + "migration_0015_yunohost_upgrade": "Aviada de la mesa a jorn de YunoHost...", + "migration_0015_main_upgrade": "Aviada de la mesa a nivèl generala...", + "migration_0015_patching_sources_list": "Mesa a jorn del fichièr sources.lists...", + "migration_0015_start": "Aviar la migracion cap a Buster", + "migration_description_0017_postgresql_9p6_to_11": "Migrar las basas de donadas de PostgreSQL 9.6 cap a 11", + "migration_description_0016_php70_to_php73_pools": "Migrar los fichièrs de configuracion php7.0 cap a php7.3", + "migration_description_0015_migrate_to_buster": "Mesa a nivèl dels sistèmas Debian Buster e YunoHost 4.x", + "migrating_legacy_permission_settings": "Migracion dels paramètres de permission ancians...", + "log_app_config_apply": "Aplicar la configuracion a l’aplicacion « {} »", + "log_app_config_show_panel": "Mostrar lo panèl de configuracion de l’aplicacion « {} »", + "log_app_action_run": "Executar l’accion de l’aplicacion « {} »", + "diagnosis_basesystem_hardware_model": "Lo modèl del servidor es {model}", + "backup_archive_cant_retrieve_info_json": "Obtencion impossibla de las informacions de l’archiu « {archive} »... Se pòt pas recuperar lo fichièr info.json (o es pas un fichièr json valid).", + "app_packaging_format_not_supported": "Se pòt pas installar aquesta aplicacion pr’amor que son format es pas pres en carga per vòstra version de YunoHost. Deuriatz considerar actualizar lo sistèma." } From ea5971e355edca8d133431c00e2f1c538714a85e Mon Sep 17 00:00:00 2001 From: Krzysztof Nowakowski Date: Mon, 22 Mar 2021 21:50:28 +0000 Subject: [PATCH 125/131] Translated using Weblate (Polish) Currently translated at 1.5% (10 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pl/ --- locales/pl.json | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/locales/pl.json b/locales/pl.json index 7ff9fbcd2..76ce2f408 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -1,3 +1,12 @@ { - "password_too_simple_1": "Hasło musi mieć co najmniej 8 znaków" -} \ No newline at end of file + "password_too_simple_1": "Hasło musi mieć co najmniej 8 znaków", + "app_already_up_to_date": "{app:s} jest obecnie aktualna", + "app_already_installed": "{app:s} jest już zainstalowane", + "already_up_to_date": "Nic do zrobienia. Wszystko jest obecnie aktualne.", + "admin_password_too_long": "Proszę wybrać hasło krótsze niż 127 znaków", + "admin_password_changed": "Hasło administratora zostało zmienione", + "admin_password_change_failed": "Nie można zmienić hasła", + "admin_password": "Hasło administratora", + "action_invalid": "Nieprawidłowa operacja '{action:s}'", + "aborting": "Przerywanie." +} From 87b0b10e0e6853c79cb786ada4a28ddf1a747548 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 24 Mar 2021 20:24:31 +0100 Subject: [PATCH 126/131] Enforce permissions on /var/cache/yunohost --- data/hooks/conf_regen/01-yunohost | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index a6d672f57..30828c462 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -50,6 +50,8 @@ do_init_regen() { chown root:root /etc/ssowat/conf.json.persistent mkdir -p /var/cache/yunohost/repo + chown root:root /var/cache/yunohost + chmod 700 /var/cache/yunohost } do_pre_regen() { @@ -142,6 +144,9 @@ do_post_regen() { find /etc/yunohost/certs/ -type f -exec chmod 640 {} \; find /etc/yunohost/certs/ -type d -exec chmod 750 {} \; + chown root:root /var/cache/yunohost + chmod 700 /var/cache/yunohost + # Misc configuration / state files chown root:root $(ls /etc/yunohost/{*.yml,*.yaml,*.json,mysql,psql} 2>/dev/null) chmod 600 $(ls /etc/yunohost/{*.yml,*.yaml,*.json,mysql,psql} 2>/dev/null) From d98ec6ce35489af8b2de53c1e01ffd5f2b7c0825 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 24 Mar 2021 20:25:52 +0100 Subject: [PATCH 127/131] Download ynh_setup_source stuff to /var/cache/yunohost/download --- data/helpers.d/utils | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 28d2352fa..0f02630a4 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -21,6 +21,9 @@ YNH_APP_BASEDIR=$([[ "$(basename $0)" =~ ^backup|restore$ ]] && echo '../setting # Requires YunoHost version 2.6.4 or higher. ynh_exit_properly () { local exit_code=$? + + rm -rf "/var/cache/yunohost/download/" + if [ "$exit_code" -eq 0 ]; then exit 0 # Exit without error if the script ended correctly fi @@ -127,8 +130,13 @@ ynh_setup_source () { src_filename="${source_id}.${src_format}" fi + # (Unused?) mecanism where one can have the file in a special local cache to not have to download it... local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}" + + mkdir -p /var/cache/yunohost/download/${YNH_APP_ID}/ + src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${src_filename}" + if test -e "$local_src" then cp $local_src $src_filename @@ -672,7 +680,7 @@ ynh_compare_current_package_version() { # Check validity of the comparator if [[ ! $comparison =~ (lt|le|eq|ne|ge|gt) ]]; then - ynh_die --message="Invialid comparator must be : lt, le, eq, ne, ge, gt" + ynh_die --message="Invalid comparator must be : lt, le, eq, ne, ge, gt" fi # Return the return value of dpkg --compare-versions From e27ac6ff2c07117d7f9c0ab7f4830f185e7b0d83 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 24 Mar 2021 20:28:11 +0100 Subject: [PATCH 128/131] Rely on YNH_APP_BASEDIR to check the sources/ dir --- data/helpers.d/utils | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 0f02630a4..905b7b2ac 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -196,18 +196,18 @@ ynh_setup_source () { fi # Apply patches - if (( $(find $YNH_CWD/../sources/patches/ -type f -name "${source_id}-*.patch" 2> /dev/null | wc --lines) > "0" )) + if (( $(find $YNH_APP_BASEDIR/sources/patches/ -type f -name "${source_id}-*.patch" 2> /dev/null | wc --lines) > "0" )) then (cd "$dest_dir" - for p in $YNH_CWD/../sources/patches/${source_id}-*.patch + for p in $YNH_APP_BASEDIR/sources/patches/${source_id}-*.patch do patch --strip=1 < $p done) || ynh_die --message="Unable to apply patches" fi # Add supplementary files - if test -e "$YNH_CWD/../sources/extra_files/${source_id}"; then - cp --archive $YNH_CWD/../sources/extra_files/$source_id/. "$dest_dir" + if test -e "$YNH_APP_BASEDIR/sources/extra_files/${source_id}"; then + cp --archive $YNH_APP_BASEDIR/sources/extra_files/$source_id/. "$dest_dir" fi } From 44637237ce97cfaac21256384030fad04716c59e Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 24 Mar 2021 19:31:59 +0000 Subject: [PATCH 129/131] Translated using Weblate (German) Currently translated at 86.5% (545 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 832fc1b91..bfc9c36a4 100644 --- a/locales/de.json +++ b/locales/de.json @@ -609,5 +609,12 @@ "regenconf_pending_applying": "Wende die anstehende Konfiguration für die Kategorie {category} an...", "regenconf_failed": "Konnte die Konfiguration für die Kategorie(n) {categories} nicht neu erstellen", "regenconf_dry_pending_applying": "Überprüfe die anstehende Konfiguration, welche für die Kategorie {category}' aktualisiert worden wäre…", - "regenconf_would_be_updated": "Die Konfiguration wäre für die Kategorie '{category}' aktualisiert worden" + "regenconf_would_be_updated": "Die Konfiguration wäre für die Kategorie '{category}' aktualisiert worden", + "restore_system_part_failed": "Die Systemteile '{part:s}' konnten nicht wiederhergestellt werden", + "restore_removing_tmp_dir_failed": "Ein altes, temporäres Directory konnte nicht entfernt werden", + "restore_not_enough_disk_space": "Nicht genug Speicher (Speicher: {free_space:d} B, benötigter Speicher: {needed_space:d} B, Sicherheitspuffer: {margin:d} B)", + "restore_may_be_not_enough_disk_space": "Dein System scheint nicht genug Speicherplatz zu haben (frei: {free_space:d} B, benötigter Platz: {needed_space:d} B, Sicherheitspuffer: {margin:d} B)", + "restore_extracting": "Packe die benötigten Dateien aus dem Archiv aus…", + "restore_already_installed_apps": "Folgende Apps können nicht wiederhergestellt werden, weil sie schon installiert sind: {apps}", + "regex_with_only_domain": "Du kannst regex nicht als Domain verwenden, sondern nur als Pfad" } From c2af36a6529de465da9b0c6060644a286f5de1ce Mon Sep 17 00:00:00 2001 From: Flavio Cristoforetti Date: Wed, 24 Mar 2021 14:03:54 +0000 Subject: [PATCH 130/131] Translated using Weblate (Italian) Currently translated at 100.0% (630 of 630 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/it/ --- locales/it.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index 9f8f6a167..45b85d548 100644 --- a/locales/it.json +++ b/locales/it.json @@ -674,5 +674,9 @@ "diagnosis_mail_blacklist_reason": "Il motivo della blacklist è: {reason}", "diagnosis_mail_blacklist_listed_by": "Il tuo IP o dominio {item} è nella blacklist {blacklist_name}", "diagnosis_backports_in_sources_list": "Sembra che apt (il package manager) sia configurato per utilizzare le backport del repository. A meno che tu non sappia quello che stai facendo, scoraggiamo fortemente di installare pacchetti tramite esse, perché ci sono alte probabilità di creare conflitti con il tuo sistema.", - "diagnosis_basesystem_hardware_model": "Modello server: {model}" + "diagnosis_basesystem_hardware_model": "Modello server: {model}", + "postinstall_low_rootfsspace": "La radice del filesystem ha uno spazio totale inferiore ai 10 GB, ed è piuttosto preoccupante! Consumerai tutta la memoria molto velocemente! Raccomandiamo di avere almeno 16 GB per la radice del filesystem. Se vuoi installare YunoHost ignorando questo avviso, esegui nuovamente il postinstall con l'argomento --force-diskspace", + "domain_remove_confirm_apps_removal": "Rimuovere questo dominio rimuoverà anche le seguenti applicazioni:\n{apps}\n\nSei sicuro di voler continuare? [{answers}]", + "diagnosis_rootfstotalspace_critical": "La radice del filesystem ha un totale di solo {space}, ed è piuttosto preoccupante! Probabilmente consumerai tutta la memoria molto velocemente! Raccomandiamo di avere almeno 16 GB per la radice del filesystem.", + "diagnosis_rootfstotalspace_warning": "La radice del filesystem ha un totale di solo {space}. Potrebbe non essere un problema, ma stai attento perché potresti consumare tutta la memoria velocemente... Raccomandiamo di avere almeno 16 GB per la radice del filesystem." } From 8751dcdd1b2c9c5133dc1997419ef84861147097 Mon Sep 17 00:00:00 2001 From: Kayou Date: Thu, 25 Mar 2021 01:05:41 +0100 Subject: [PATCH 131/131] Update changelog for 4.2 (#1195) * Update changelog for 4.2 * changelog: Improving error semantic * Update changelog Co-authored-by: Alexandre Aubin --- debian/changelog | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0454553ae..f8211b82e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,39 @@ -yunohost (4.2) unstable; urgency=low +yunohost (4.2.0) testing; urgency=low - - Placeholder for 4.2 to satisfy CI / debian build during dev + - [mod] Python2 -> Python3 ([#1116](https://github.com/yunohost/yunohost/pull/1116), a97a9df3, 1387dff4, b53859db, f5ab4443, f9478b93, dc6033c3) + - [mod] refactoring: Drop legacy-way of passing arguments in hook_exec, prevent exposing secrets in command line args ([#1096](https://github.com/yunohost/yunohost/pull/1096)) + - [mod] refactoring: use regen_conf instead of service_regen_conf in settings.py (9c11fd58) + - [mod] refactoring: More consistent local CA management for simpler postinstall ([#1062](https://github.com/yunohost/yunohost/pull/1062)) + - [mod] refactoring: init folders during .deb install instead of regen conf ([#1063](https://github.com/yunohost/yunohost/pull/1063)) + - [mod] refactoring: init ldap before the postinstall ([#1064](https://github.com/yunohost/yunohost/pull/1064)) + - [mod] refactoring: simpler and more consistent logging initialization ([#1119](https://github.com/yunohost/yunohost/pull/1119), 0884a0c1) + - [mod] code-quality: add CI job to auto-format code, fix linter errors ([#1142](https://github.com/yunohost/yunohost/pull/1142), [#1161](https://github.com/yunohost/yunohost/pull/1161), 97f26015, [#1162](https://github.com/yunohost/yunohost/pull/1162)) + - [mod] misc: Prevent the installation of apache2 ... ([#1148](https://github.com/yunohost/yunohost/pull/1148)) + - [mod] misc: Drop old cache rules for .ms files, not relevant anymore ([#1150](https://github.com/yunohost/yunohost/pull/1150)) + - [fix] misc: Abort postinstall if /etc/yunohost/apps ain't empty ([#1147](https://github.com/yunohost/yunohost/pull/1147)) + - [mod] misc: No need for mysql root password anymore ([#912](https://github.com/YunoHost/yunohost/pull/912)) + - [fix] app operations: wait for services to finish reloading (4a19a60b) + - [enh] ux: Improve error semantic such that the webadmin can autoredirect to the proper log view ([#1077](https://github.com/yunohost/yunohost/pull/1077), [#1187](https://github.com/YunoHost/yunohost/pull/1187)) + - [mod] cli/api: Misc command and routes renaming / aliasing ([#1146](https://github.com/yunohost/yunohost/pull/1146)) + - [enh] cli: Add a new "yunohost app search" command ([#1070](https://github.com/yunohost/yunohost/pull/1070)) + - [enh] cli: Add '--remove-apps' (and '--force') options to "yunohost domain remove" ([#1125](https://github.com/yunohost/yunohost/pull/1125)) + - [enh] diagnosis: Report low total space for rootfs ([#1145](https://github.com/yunohost/yunohost/pull/1145)) + - [fix] upnp: Handle port closing ([#1154](https://github.com/yunohost/yunohost/pull/1154)) + - [fix] dyndns: clean old madness, improve update strategy, improve cron management, delete dyndns key upon domain removal ([#1149](https://github.com/yunohost/yunohost/pull/1149)) + - [enh] helpers: Adding composer helper ([#1090](https://github.com/yunohost/yunohost/pull/1090)) + - [enh] helpers: Upgrade n to v7.0.2 ([#1178](https://github.com/yunohost/yunohost/pull/1178)) + - [enh] helpers: Add multimedia helpers and hooks ([#1129](https://github.com/yunohost/yunohost/pull/1129), 47420c62) + - [enh] helpers: Normalize conf template handling for nginx, php-fpm, systemd and fail2ban using ynh_add_config ([#1118](https://github.com/yunohost/yunohost/pull/1118)) + - [fix] helpers, doc: Update template for the new doc (grav) ([#1167](https://github.com/yunohost/yunohost/pull/1167), [#1168](https://github.com/yunohost/yunohost/pull/1168), 59d3e387) + - [enh] helpers: Define YNH_APP_BASEDIR to be able to properly point to conf folder depending on the app script we're running ([#1172](https://github.com/yunohost/yunohost/pull/1172)) + - [enh] helpers: Use jq / output-as json to get info from yunohost commands instead of scraping with grep ([#1160](https://github.com/yunohost/yunohost/pull/1160)) + - [fix] helpers: Misc fixes/enh (b85d959d, db93b82b, ce04570b, 07f8d6d7) + - [fix] helpers: download ynh_setup_source stuff in /var/cache/yunohost to prevent situations where it ends up in /etc/yunohost/apps/ (d98ec6ce) + - [i18n] Translations updated for Catalan, Chinese (Simplified), Czech, Dutch, French, German, Italian, Occitan, Polish - -- Alexandre Aubin Wed, 20 Jan 2021 05:19:58 +0100 + Thanks to all contributors <3 ! (Bram, Christian W., Daniel, Dave, Éric G., Félix P., Flavio C., Kay0u, Krzysztof N., ljf, Mathieu M., Miloš K., MrMorals, Nils V.Z., penguin321, ppr, Quentí, Radek S, Scapharnaum, Sébastien M., xaloc33, yalh76, Yifei D.) + + -- Alexandre Aubin Thu, 25 Mar 2021 01:00:00 +0100 yunohost (4.1.7.4) stable; urgency=low