From 0e787acb5db3a03902ace597705fd1f0e76309ff Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Feb 2023 15:32:09 +0100 Subject: [PATCH 01/19] appv2: typo in ports resource doc x_x --- src/utils/resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 65c8ee8cd..586cb1583 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -755,7 +755,7 @@ class PortsResource(AppResource): ##### Example: ```toml - [resources.port] + [resources.ports] # (empty should be fine for most apps ... though you can customize stuff if absolutely needed) main.default = 12345 # if you really want to specify a prefered value .. but shouldnt matter in the majority of cases From 476908bdc2a02ea96a2e53dc647306a07fde1616 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Feb 2023 20:27:52 +0100 Subject: [PATCH 02/19] appsv2: fix permission provisioning for fulldomain apps + fix apps not properly getting removed after failed resources init --- src/app.py | 47 +++++++++++++++++++++++++++--------------- src/utils/resources.py | 10 +++++++++ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/app.py b/src/app.py index 6d754ab25..4e04c035a 100644 --- a/src/app.py +++ b/src/app.py @@ -1074,10 +1074,14 @@ def app_install( if packaging_format >= 2: from yunohost.utils.resources import AppResourceManager - AppResourceManager(app_instance_name, wanted=manifest, current={}).apply( - rollback_and_raise_exception_if_failure=True, - operation_logger=operation_logger, - ) + try: + AppResourceManager(app_instance_name, wanted=manifest, current={}).apply( + rollback_and_raise_exception_if_failure=True, + operation_logger=operation_logger, + ) + except (KeyboardInterrupt, EOFError, Exception) as e: + shutil.rmtree(app_setting_path) + raise e else: # Initialize the main permission for the app # The permission is initialized with no url associated, and with tile disabled @@ -2651,22 +2655,31 @@ def _guess_webapp_path_requirement(app_folder: str) -> str: if len(domain_questions) == 1 and len(path_questions) == 1: return "domain_and_path" if len(domain_questions) == 1 and len(path_questions) == 0: - # This is likely to be a full-domain app... - # Confirm that this is a full-domain app This should cover most cases - # ... though anyway the proper solution is to implement some mechanism - # in the manifest for app to declare that they require a full domain - # (among other thing) so that we can dynamically check/display this - # requirement on the webadmin form and not miserably fail at submit time + if manifest.get("packaging_format", 0) < 2: - # Full-domain apps typically declare something like path_url="/" or path=/ - # and use ynh_webpath_register or yunohost_app_checkurl inside the install script - install_script_content = read_file(os.path.join(app_folder, "scripts/install")) + # This is likely to be a full-domain app... - if re.search( - r"\npath(_url)?=[\"']?/[\"']?", install_script_content - ) and re.search(r"ynh_webpath_register", install_script_content): - return "full_domain" + # Confirm that this is a full-domain app This should cover most cases + # ... though anyway the proper solution is to implement some mechanism + # in the manifest for app to declare that they require a full domain + # (among other thing) so that we can dynamically check/display this + # requirement on the webadmin form and not miserably fail at submit time + + # Full-domain apps typically declare something like path_url="/" or path=/ + # and use ynh_webpath_register or yunohost_app_checkurl inside the install script + install_script_content = read_file(os.path.join(app_folder, "scripts/install")) + + if re.search( + r"\npath(_url)?=[\"']?/[\"']?", install_script_content + ) and re.search(r"ynh_webpath_register", install_script_content): + return "full_domain" + + else: + # For packaging v2 apps, check if there's a permission with url being a string + perm_resource = manifest.get("resources", {}).get("permissions") + if perm_resource is not None and isinstance(perm_resource.get("main", {}).get("url"), str): + return "full_domain" return "?" diff --git a/src/utils/resources.py b/src/utils/resources.py index 586cb1583..b1a31324c 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -320,6 +320,16 @@ class PermissionsResource(AppResource): # Delete legacy is_public setting if not already done self.delete_setting("is_public") + # Detect that we're using a full-domain app, + # in which case we probably need to automagically + # define the "path" setting with "/" + if ( + isinstance(self.permissions["main"]["url"], str) + and self.get_setting("domain") + and not self.get_setting("path") + ): + self.set_setting("path", "/") + existing_perms = user_permission_list(short=True, apps=[self.app])[ "permissions" ] From 9459aed65ebcce850a02895b53ca6781450f5614 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Feb 2023 20:43:42 +0100 Subject: [PATCH 03/19] Update changelog for 11.1.5.4 --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index db74b6d6a..85924f4e9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +yunohost (11.1.5.4) stable; urgency=low + + - appsv2: typo in ports resource doc x_x (0e787acb) + - appsv2: fix permission provisioning for fulldomain apps + fix apps not properly getting removed after failed resources init (476908bd) + + -- Alexandre Aubin Fri, 03 Feb 2023 20:43:04 +0100 + yunohost (11.1.5.3) stable; urgency=low - helpers/appsv2: replacement of __PHPVERSION__ should use the phpversion setting, not YNH_PHP_VERSION (13d4e16e) From 3bbba640e9384f54fbeca6133114d44fd462744e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Feb 2023 21:05:23 +0100 Subject: [PATCH 04/19] appsv2: ignore the old/ugly/legacy removal of apt deps when removing the php conf, because that's handled by the apt resource --- helpers/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/php b/helpers/php index 0149bc243..4522e65a9 100644 --- a/helpers/php +++ b/helpers/php @@ -283,7 +283,7 @@ ynh_remove_fpm_config() { # If the PHP version used is not the default version for YunoHost # The second part with YNH_APP_PURGE is an ugly hack to guess that we're inside the remove script # (we don't actually care about its value, we just check its not empty hence it exists) - if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ] && [ -n "${YNH_APP_PURGE:-}" ]; then + if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ] && [ -n "${YNH_APP_PURGE:-}" ] && dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then # Remove app dependencies ... but ideally should happen via an explicit call from packager ynh_remove_app_dependencies fi From 8485ebc75a9425ae90d44a466dbf81140112e21c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Feb 2023 21:13:17 +0100 Subject: [PATCH 05/19] admin->admins migration: try to handle boring case where the 'first' user cant be identified because it doesnt have the root@ alias --- src/migrations/0026_new_admins_group.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/migrations/0026_new_admins_group.py b/src/migrations/0026_new_admins_group.py index 98f2a54be..a260074fd 100644 --- a/src/migrations/0026_new_admins_group.py +++ b/src/migrations/0026_new_admins_group.py @@ -46,6 +46,19 @@ class MyMigration(Migration): new_admin_user = user break + # For some reason some system have no user with root@ alias, + # but the user does has admin / postmaster / ... alias + # ... try to find it instead otherwise this creashes the migration + # later because the admin@, postmaster@, .. aliases will already exist + if not new_admin_user: + for user in all_users: + aliases = user_info(user).get("mail-aliases", []) + if any(alias.startswith(f"admin@{main_domain}") for alias in aliases) \ + and any(alias.startswith(f"postmaster@{main_domain}") for alias in aliases): + new_admin_user = user + break + + self.ldap_migration_started = True if new_admin_user: From fb54da2e35f88e182ffc877c6e29a3209b022c5a Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Feb 2023 18:46:33 +0100 Subject: [PATCH 06/19] appsv2: moar fixes for v1->v2 upgrade not getting the proper env context --- src/utils/resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index b1a31324c..e76a6cc92 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -179,7 +179,7 @@ class AppResource: tmpdir = _make_tmp_workdir_for_app(app=self.app) env_ = _make_environment_for_app_script( - self.app, workdir=tmpdir, action=f"{action}_{self.type}" + self.app, workdir=tmpdir, action=f"{action}_{self.type}", include_app_settings=True, ) env_.update(env) From a0350246665f4dd1f5756fb4780e83c3c675cc8b Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 4 Feb 2023 18:51:35 +0100 Subject: [PATCH 07/19] Update changelog for 11.1.5.5 --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index 85924f4e9..42b3d9f1c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +yunohost (11.1.5.5) stable; urgency=low + + - admin->admins migration: try to handle boring case where the 'first' user cant be identified because it doesnt have the root@ alias (8485ebc7) + - appsv2: ignore the old/ugly/legacy removal of apt deps when removing the php conf, because that's handled by the apt resource (3bbba640) + - appsv2: moar fixes for v1->v2 upgrade not getting the proper env context (fb54da2e) + + -- Alexandre Aubin Sat, 04 Feb 2023 18:51:03 +0100 + yunohost (11.1.5.4) stable; urgency=low - appsv2: typo in ports resource doc x_x (0e787acb) From 4dee434e71f79d93eebc5ad98a5fde0fc37da665 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 5 Feb 2023 18:31:36 +0100 Subject: [PATCH 08/19] domains: add missing logic to inject translated 'help' keys in config panel like we do for global settings --- locales/en.json | 2 ++ share/config_domain.toml | 5 ----- src/domain.py | 20 +++++++++++++++++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/locales/en.json b/locales/en.json index b8ca0c229..3832cb6c0 100644 --- a/locales/en.json +++ b/locales/en.json @@ -345,9 +345,11 @@ "domain_config_cert_summary_selfsigned": "WARNING: Current certificate is self-signed. Browsers will display a spooky warning to new visitors!", "domain_config_cert_validity": "Validity", "domain_config_default_app": "Default app", + "domain_config_default_app_help": "People will automatically be redirected to this app when opening this domain. If no app is specified, people are redirected to the user portal login form.", "domain_config_mail_in": "Incoming emails", "domain_config_mail_out": "Outgoing emails", "domain_config_xmpp": "Instant messaging (XMPP)", + "domain_config_xmpp_help": "NB: some XMPP features will require that you update your DNS records and regenerate your Lets Encrypt certificate to be enabled", "domain_created": "Domain created", "domain_creation_failed": "Unable to create domain {domain}: {error}", "domain_deleted": "Domain deleted", diff --git a/share/config_domain.toml b/share/config_domain.toml index c67996d13..82ef90c32 100644 --- a/share/config_domain.toml +++ b/share/config_domain.toml @@ -9,8 +9,6 @@ name = "Features" type = "app" filter = "is_webapp" default = "_none" - # FIXME: i18n - help = "People will automatically be redirected to this app when opening this domain. If no app is specified, people are redirected to the user portal login form." [feature.mail] @@ -27,8 +25,6 @@ name = "Features" [feature.xmpp.xmpp] type = "boolean" default = 0 - # FIXME: i18n - help = "NB: some XMPP features will require that you update your DNS records and regenerate your Lets Encrypt certificate to be enabled" [dns] name = "DNS" @@ -67,7 +63,6 @@ name = "Certificate" visible = "acme_eligible == false || acme_eligible == null" [cert.cert.cert_no_checks] - ask = "Ignore diagnosis checks" type = "boolean" default = false visible = "acme_eligible == false || acme_eligible == null" diff --git a/src/domain.py b/src/domain.py index e83b5e3e8..7839b988d 100644 --- a/src/domain.py +++ b/src/domain.py @@ -624,14 +624,28 @@ class DomainConfigPanel(ConfigPanel): f"domain_config_cert_summary_{status['summary']}" ) - # Other specific strings used in config panels - # i18n: domain_config_cert_renew_help - # FIXME: Ugly hack to save the cert status and reinject it in _load_current_values ... self.cert_status = status return toml + def get(self, key="", mode="classic"): + result = super().get(key=key, mode=mode) + + if mode == "full": + for panel, section, option in self._iterate(): + # This injects: + # i18n: domain_config_cert_renew_help + # i18n: domain_config_default_app_help + # i18n: domain_config_xmpp_help + if m18n.key_exists(self.config["i18n"] + "_" + option["id"] + "_help"): + option["help"] = m18n.n( + self.config["i18n"] + "_" + option["id"] + "_help" + ) + return self.config + + return result + def _load_current_values(self): # TODO add mechanism to share some settings with other domains on the same zone super()._load_current_values() From f742bdf83217519339a4cd56710c2fabe2eeee9d Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 6 Feb 2023 13:26:36 +0100 Subject: [PATCH 09/19] [fix] Allow to do replace string with @ --- helpers/string | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/string b/helpers/string index 4dd5c0b4b..dc1658e3d 100644 --- a/helpers/string +++ b/helpers/string @@ -48,7 +48,7 @@ ynh_replace_string() { ynh_handle_getopts_args "$@" set +o xtrace # set +x - local delimit=@ + local delimit=$'\001' # Escape the delimiter if it's in the string. match_string=${match_string//${delimit}/"\\${delimit}"} replace_string=${replace_string//${delimit}/"\\${delimit}"} From 8241e26fc29978298d8251f60ac5330aabed9089 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 6 Feb 2023 13:51:32 +0100 Subject: [PATCH 10/19] [fix] Write var in files with redundants keys --- helpers/utils | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helpers/utils b/helpers/utils index a0efa2c45..4cd23da00 100644 --- a/helpers/utils +++ b/helpers/utils @@ -568,7 +568,7 @@ ynh_read_var_in_file() { var_part+='\s*' # Extract the part after assignation sign - local expression_with_comment="$(tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL | head -n1)" + local expression_with_comment="$((tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)" if [[ "$expression_with_comment" == "YNH_NULL" ]]; then set -o xtrace # set -x echo YNH_NULL @@ -647,7 +647,7 @@ ynh_write_var_in_file() { var_part+='\s*' # Extract the part after assignation sign - local expression_with_comment="$(tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL | head -n1)" + local expression_with_comment="$((tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)" if [[ "$expression_with_comment" == "YNH_NULL" ]]; then set -o xtrace # set -x return 1 From 9f686a115f1a15668940332d876cad306f7625d7 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 6 Feb 2023 14:28:06 +0100 Subject: [PATCH 11/19] [fix] Put a & into a config var --- helpers/utils | 1 + 1 file changed, 1 insertion(+) diff --git a/helpers/utils b/helpers/utils index 4cd23da00..04a3d1373 100644 --- a/helpers/utils +++ b/helpers/utils @@ -658,6 +658,7 @@ ynh_write_var_in_file() { endline=${expression_with_comment#"$expression"} endline="$(echo "$endline" | sed 's/\\/\\\\/g')" value="$(echo "$value" | sed 's/\\/\\\\/g')" + value=${value//&/"\&"} local first_char="${expression:0:1}" delimiter=$'\001' if [[ "$first_char" == '"' ]]; then From c179d4b88f4e756fa48693b09776e540cde01129 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 13:44:54 +0100 Subject: [PATCH 12/19] appsv2/group question: don't include primary groups in choices --- src/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/config.py b/src/utils/config.py index 534cddcb3..5704686c0 100644 --- a/src/utils/config.py +++ b/src/utils/config.py @@ -1359,7 +1359,7 @@ class GroupQuestion(Question): super().__init__(question, context) - self.choices = list(user_group_list(short=True)["groups"]) + self.choices = list(user_group_list(short=True, include_primary_groups=False)["groups"]) def _human_readable_group(g): # i18n: visitors From 71042f086065aec63de911c82f1177d9306c3dbf Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 14:31:57 +0100 Subject: [PATCH 13/19] appsv2: when initalizing permission, make sure to add 'all_users' when visitors is chosen --- src/utils/resources.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utils/resources.py b/src/utils/resources.py index e76a6cc92..771a0e1e1 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -348,6 +348,11 @@ class PermissionsResource(AppResource): or self.get_setting(f"init_{perm}_permission") or [] ) + + # If we're choosing 'visitors' from the init_{perm}_permission question, add all_users too + if not infos["allowed"] and init_allowed == "visitors": + init_allowed = ["visitors", "all_users"] + permission_create( perm_id, allowed=init_allowed, From ca0db0ec58ca6969b6454d4b94573f042f90bac2 Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 6 Feb 2023 15:44:50 +0100 Subject: [PATCH 14/19] [fix] ynh_write_var_in_file should replace one occurencies --- helpers/utils | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/helpers/utils b/helpers/utils index 04a3d1373..f80c22901 100644 --- a/helpers/utils +++ b/helpers/utils @@ -614,15 +614,14 @@ ynh_write_var_in_file() { set +o xtrace # set +x # Get the line number after which we search for the variable - local line_number=1 + local after_line_number=1 if [[ -n "$after" ]]; then - line_number=$(grep -m1 -n $after $file | cut -d: -f1) - if [[ -z "$line_number" ]]; then + after_line_number=$(grep -m1 -n $after $file | cut -d: -f1) + if [[ -z "$after_line_number" ]]; then set -o xtrace # set -x return 1 fi fi - local range="${line_number},\$ " local filename="$(basename -- "$file")" local ext="${filename##*.}" @@ -647,11 +646,14 @@ ynh_write_var_in_file() { var_part+='\s*' # Extract the part after assignation sign - local expression_with_comment="$((tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)" + local expression_with_comment="$((tail +$after_line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)" if [[ "$expression_with_comment" == "YNH_NULL" ]]; then set -o xtrace # set -x return 1 fi + local value_line_number="$(tail +$after_line_number ${file} | grep -m1 -n -i -P $var_part'\K.*$' | cut -d: -f1)" + value_line_number=$((after_line_number + value_line_number)) + local range="${after_line_number},${value_line_number} " # Remove comments if needed local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")" From 170eaf5d742e369645805b6ef725d21a1b818afb Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 15:46:04 +0100 Subject: [PATCH 15/19] backup/multimedia: test that /home/yunohots.multimedia does exists to avoid boring warning later --- hooks/backup/18-data_multimedia | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/backup/18-data_multimedia b/hooks/backup/18-data_multimedia index f80cff0b3..94162d517 100644 --- a/hooks/backup/18-data_multimedia +++ b/hooks/backup/18-data_multimedia @@ -9,7 +9,7 @@ source /usr/share/yunohost/helpers # Backup destination backup_dir="${1}/data/multimedia" -if [ -e "/home/yunohost.multimedia/.nobackup" ]; then +if [ ! -e "/home/yunohost.multimedia" ] || [ -e "/home/yunohost.multimedia/.nobackup" ]; then exit 0 fi From 0f24846e0b91d471062eb84e3b4c06b1ff152b8f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 16:15:22 +0100 Subject: [PATCH 16/19] backup: fix previou fix /o\, name is sometimes None --- src/backup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backup.py b/src/backup.py index 0727ad295..a3a24aa52 100644 --- a/src/backup.py +++ b/src/backup.py @@ -2295,7 +2295,7 @@ def backup_create( ) backup_manager.backup() - logger.success(m18n.n("backup_created", name=name)) + logger.success(m18n.n("backup_created", name=backup_manager.name)) operation_logger.success() return { From 29c6564f0900c3bb452e962b9e958adb4b743630 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 16:15:55 +0100 Subject: [PATCH 17/19] =?UTF-8?q?ci:=20fix=20backup=20test=20/=20gotta=20t?= =?UTF-8?q?ell=20the=20mocker=20about=20the=20new=20'name'=20arg=20for=20b?= =?UTF-8?q?ackup=20create=20messages=20=C3=A9=5F=C3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tests/test_backuprestore.py | 44 ++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/tests/test_backuprestore.py b/src/tests/test_backuprestore.py index 28646960c..413d44470 100644 --- a/src/tests/test_backuprestore.py +++ b/src/tests/test_backuprestore.py @@ -6,6 +6,8 @@ from mock import patch from .conftest import message, raiseYunohostError, get_test_apps_dir +from moulinette.utils.text import random_ascii + from yunohost.app import app_install, app_remove, app_ssowatconf from yunohost.app import _is_installed from yunohost.backup import ( @@ -236,8 +238,9 @@ def add_archive_system_from_4p2(): def test_backup_only_ldap(mocker): # Create the backup - with message(mocker, "backup_created"): - backup_create(system=["conf_ldap"], apps=None) + name = random_ascii(8) + with message(mocker, "backup_created", name=name): + backup_create(name=name, system=["conf_ldap"], apps=None) archives = backup_list()["archives"] assert len(archives) == 1 @@ -261,9 +264,10 @@ def test_backup_system_part_that_does_not_exists(mocker): def test_backup_and_restore_all_sys(mocker): + name = random_ascii(8) # Create the backup - with message(mocker, "backup_created"): - backup_create(system=[], apps=None) + with message(mocker, "backup_created", name=name): + backup_create(name=name, system=[], apps=None) archives = backup_list()["archives"] assert len(archives) == 1 @@ -294,9 +298,10 @@ def test_backup_and_restore_all_sys(mocker): @pytest.mark.with_system_archive_from_4p2 def test_restore_system_from_Ynh4p2(monkeypatch, mocker): + name = random_ascii(8) # Backup current system - with message(mocker, "backup_created"): - backup_create(system=[], apps=None) + with message(mocker, "backup_created", name=name): + backup_create(name=name, system=[], apps=None) archives = backup_list()["archives"] assert len(archives) == 2 @@ -393,16 +398,17 @@ def test_backup_app_with_no_restore_script(mocker): @pytest.mark.clean_opt_dir def test_backup_with_different_output_directory(mocker): + name = random_ascii(8) # Create the backup - with message(mocker, "backup_created"): + with message(mocker, "backup_created", name=name): backup_create( system=["conf_ynh_settings"], apps=None, output_directory="/opt/test_backup_output_directory", - name="backup", + name=name, ) - assert os.path.exists("/opt/test_backup_output_directory/backup.tar") + assert os.path.exists(f"/opt/test_backup_output_directory/{name}.tar") archives = backup_list()["archives"] assert len(archives) == 1 @@ -416,13 +422,14 @@ def test_backup_with_different_output_directory(mocker): @pytest.mark.clean_opt_dir def test_backup_using_copy_method(mocker): # Create the backup - with message(mocker, "backup_created"): + name = random_ascii(8) + with message(mocker, "backup_created", name=name): backup_create( system=["conf_ynh_settings"], apps=None, output_directory="/opt/test_backup_output_directory", methods=["copy"], - name="backup", + name=name, ) assert os.path.exists("/opt/test_backup_output_directory/info.json") @@ -565,8 +572,9 @@ def test_backup_and_restore_permission_app(mocker): def _test_backup_and_restore_app(mocker, app): # Create a backup of this app - with message(mocker, "backup_created"): - backup_create(system=None, apps=[app]) + name = random_ascii(8) + with message(mocker, "backup_created", name=name): + backup_create(name=name, system=None, apps=[app]) archives = backup_list()["archives"] assert len(archives) == 1 @@ -628,8 +636,9 @@ def test_restore_archive_with_custom_hook(mocker): os.system("touch %s/99-yolo" % custom_restore_hook_folder) # Backup with custom hook system - with message(mocker, "backup_created"): - backup_create(system=[], apps=None) + name = random_ascii(8) + with message(mocker, "backup_created", name=name): + backup_create(name=name, system=[], apps=None) archives = backup_list()["archives"] assert len(archives) == 1 @@ -666,5 +675,6 @@ def test_backup_binds_are_readonly(mocker, monkeypatch): ) # Create the backup - with message(mocker, "backup_created"): - backup_create(system=[]) + name = random_ascii(8) + with message(mocker, "backup_created", name=name): + backup_create(name=name, system=[]) From b5b69e952d70f0209b0e0579d0ad244a6bb19a1c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 16:26:01 +0100 Subject: [PATCH 18/19] domain/dns: don't miserably crash when the domain is known by lexicon but not in registrar_list.toml --- src/dns.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dns.py b/src/dns.py index d4c9b1380..eb0812c97 100644 --- a/src/dns.py +++ b/src/dns.py @@ -591,7 +591,10 @@ def _get_registrar_config_section(domain): # TODO : add a help tip with the link to the registar's API doc (c.f. Lexicon's README) registrar_list = read_toml(DOMAIN_REGISTRAR_LIST_PATH) - registrar_credentials = registrar_list[registrar] + registrar_credentials = registrar_list.get(registrar) + if registrar_credentials is None: + logger.warning(f"Registrar {registrar} unknown / Should be added to YunoHost's registrar_list.toml by the development team!") + registrar_credentials = {} for credential, infos in registrar_credentials.items(): infos["default"] = infos.get("default", "") infos["optional"] = infos.get("optional", "False") From 1e5203426b1764b94265cff373c60c6bae47699c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Feb 2023 17:28:08 +0100 Subject: [PATCH 19/19] admins migration: try to losen up even more the search for first admin user x_x --- src/migrations/0026_new_admins_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/migrations/0026_new_admins_group.py b/src/migrations/0026_new_admins_group.py index a260074fd..3b2207eb8 100644 --- a/src/migrations/0026_new_admins_group.py +++ b/src/migrations/0026_new_admins_group.py @@ -54,7 +54,7 @@ class MyMigration(Migration): for user in all_users: aliases = user_info(user).get("mail-aliases", []) if any(alias.startswith(f"admin@{main_domain}") for alias in aliases) \ - and any(alias.startswith(f"postmaster@{main_domain}") for alias in aliases): + or any(alias.startswith(f"postmaster@{main_domain}") for alias in aliases): new_admin_user = user break