From 4a1d6f225743b110623cb4ca89757a572f0273db Mon Sep 17 00:00:00 2001 From: ljf Date: Fri, 17 Sep 2021 03:15:01 +0200 Subject: [PATCH 01/19] [fix] Small fixes about file questions in config panel --- data/helpers.d/config | 5 ++++- src/yunohost/utils/config.py | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/data/helpers.d/config b/data/helpers.d/config index d12065220..7a2ccde46 100644 --- a/data/helpers.d/config +++ b/data/helpers.d/config @@ -123,7 +123,10 @@ _ynh_app_config_apply() { ynh_print_info --message="File '$bind_file' removed" else ynh_backup_if_checksum_is_different --file="$bind_file" - cp "${!short_setting}" "$bind_file" + if [[ "${!short_setting}" != "$bind_file" ]] + then + cp "${!short_setting}" "$bind_file" + fi ynh_store_file_checksum --file="$bind_file" --update_only ynh_print_info --message="File '$bind_file' overwrited with ${!short_setting}" fi diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index a84b4cafe..3fccd8cc5 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -927,11 +927,11 @@ class FileQuestion(Question): "content": self.value, "filename": user_answers.get(f"{self.name}[name]", self.name), } - # If path file are the same - if self.value and str(self.value) == self.current_value: - self.value = None def _prevalidate(self): + if self.value is None: + self.value = self.current_value + super()._prevalidate() if ( isinstance(self.value, str) @@ -966,7 +966,7 @@ class FileQuestion(Question): if not self.value: return self.value - if Moulinette.interface.type == "api": + if Moulinette.interface.type == "api" and isinstance(self.value, dict): upload_dir = tempfile.mkdtemp(prefix="tmp_configpanel_") FileQuestion.upload_dirs += [upload_dir] From 9eda00698c23a3fab06959081c408c112070510f Mon Sep 17 00:00:00 2001 From: ljf Date: Fri, 17 Sep 2021 04:36:05 +0200 Subject: [PATCH 02/19] [fix] Tags question --- src/yunohost/utils/config.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 8ec198d34..6b823452b 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -646,6 +646,12 @@ class TagsQuestion(Question): return ",".join(value) return value + @staticmethod + def normalize(value, option={}): + if isinstance(value, list): + return ",".join(value) + return value + def _prevalidate(self): values = self.value if isinstance(values, str): @@ -657,6 +663,11 @@ class TagsQuestion(Question): super()._prevalidate() self.value = values + def _post_parse_value(self): + if isinstance(self.value, list): + self.value = ",".join(self.value) + return super()._post_parse_value() + class PasswordQuestion(Question): hide_user_input_in_prompt = True From a631261cfff840604c01fa11c0ba2b32d5152f23 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Fri, 17 Sep 2021 03:33:35 +0000 Subject: [PATCH 03/19] [CI] Format code --- src/yunohost/app.py | 2 +- src/yunohost/log.py | 11 ++++++++--- src/yunohost/utils/config.py | 16 +++++++++++----- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 3ba7fd5e4..3145078cc 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1779,7 +1779,7 @@ ynh_app_config_run $1 "app_id": app_id, "app": self.app, "app_instance_nb": str(app_instance_nb), - "final_path": settings.get("final_path", "") + "final_path": settings.get("final_path", ""), } ) diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 3f25d7a7d..f40470063 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -75,7 +75,7 @@ def log_list(limit=None, with_details=False, with_suboperations=False): # If we displaying only parent, we are still gonna load up to limit * 5 logs # because many of them are suboperations which are not gonna be kept # Yet we still want to obtain ~limit number of logs - logs = logs[:limit * 5] + logs = logs[: limit * 5] for log in logs: @@ -186,12 +186,17 @@ def log_show( r"DEBUG - \+ exit (1|0)$", ] filters = [re.compile(f) for f in filters] - return [line for line in lines if not any(f.search(line.strip()) for f in filters)] + return [ + line + for line in lines + if not any(f.search(line.strip()) for f in filters) + ] + else: + def _filter(lines): return lines - # Normalize log/metadata paths and filenames abs_path = path log_path = None diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 6b823452b..27681e4d3 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -478,7 +478,7 @@ class Question(object): self.value = Moulinette.prompt( message=text, is_password=self.hide_user_input_in_prompt, - confirm=False, # We doesn't want to confirm this kind of password like in webadmin + confirm=False, # We doesn't want to confirm this kind of password like in webadmin prefill=prefill, is_multiline=(self.type == "text"), ) @@ -705,11 +705,17 @@ class PasswordQuestion(Question): def _format_text_for_user_input_in_cli(self): need_column = self.current_value or self.optional - text_for_user_input_in_cli = super()._format_text_for_user_input_in_cli(need_column) + text_for_user_input_in_cli = super()._format_text_for_user_input_in_cli( + need_column + ) if self.current_value: - text_for_user_input_in_cli += "\n - " + m18n.n("app_argument_password_help_keep") + text_for_user_input_in_cli += "\n - " + m18n.n( + "app_argument_password_help_keep" + ) if self.optional: - text_for_user_input_in_cli += "\n - " + m18n.n("app_argument_password_help_optional") + text_for_user_input_in_cli += "\n - " + m18n.n( + "app_argument_password_help_optional" + ) return text_for_user_input_in_cli @@ -832,7 +838,7 @@ class UserQuestion(Question): raise YunohostValidationError( "app_argument_invalid", name=self.name, - error="You should create a YunoHost user first." + error="You should create a YunoHost user first.", ) if self.default is None: From 12bc94f76e096202ed15d12015a69054e7095409 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 17 Sep 2021 12:55:23 +0200 Subject: [PATCH 04/19] config/question: broadcast data to redact to all OperationLogger instances --- src/yunohost/app.py | 2 -- src/yunohost/tests/test_questions.py | 49 +++++----------------------- src/yunohost/utils/config.py | 12 +++---- 3 files changed, 12 insertions(+), 51 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 3145078cc..70e55ceb0 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1723,8 +1723,6 @@ def app_config_set( config_ = AppConfigPanel(app) - Question.operation_logger = operation_logger - return config_.set(key, value, args, args_file, operation_logger=operation_logger) diff --git a/src/yunohost/tests/test_questions.py b/src/yunohost/tests/test_questions.py index 67b50769b..91372dffa 100644 --- a/src/yunohost/tests/test_questions.py +++ b/src/yunohost/tests/test_questions.py @@ -348,9 +348,7 @@ def test_question_password(): ] answers = {"some_password": "some_value"} expected_result = OrderedDict({"some_password": ("some_value", "password")}) - Question.operation_logger = MagicMock() - with patch.object(Question.operation_logger, "data_to_redact", create=True): - assert parse_args_in_yunohost_format(answers, questions) == expected_result + assert parse_args_in_yunohost_format(answers, questions) == expected_result def test_question_password_no_input(): @@ -375,13 +373,9 @@ def test_question_password_input(): } ] answers = {} - Question.operation_logger = {"data_to_redact": []} expected_result = OrderedDict({"some_password": ("some_value", "password")}) - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( + with patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( os, "isatty", return_value=True ): assert parse_args_in_yunohost_format(answers, questions) == expected_result @@ -397,10 +391,7 @@ def test_question_password_input_no_ask(): answers = {} expected_result = OrderedDict({"some_password": ("some_value", "password")}) - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( + with patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( os, "isatty", return_value=True ): assert parse_args_in_yunohost_format(answers, questions) == expected_result @@ -417,20 +408,14 @@ def test_question_password_no_input_optional(): answers = {} expected_result = OrderedDict({"some_password": ("", "password")}) - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(os, "isatty", return_value=False): + with patch.object(os, "isatty", return_value=False): assert parse_args_in_yunohost_format(answers, questions) == expected_result questions = [ {"name": "some_password", "type": "password", "optional": True, "default": ""} ] - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(os, "isatty", return_value=False): + with patch.object(os, "isatty", return_value=False): assert parse_args_in_yunohost_format(answers, questions) == expected_result @@ -446,10 +431,7 @@ def test_question_password_optional_with_input(): answers = {} expected_result = OrderedDict({"some_password": ("some_value", "password")}) - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( + with patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( os, "isatty", return_value=True ): assert parse_args_in_yunohost_format(answers, questions) == expected_result @@ -467,10 +449,7 @@ def test_question_password_optional_with_empty_input(): answers = {} expected_result = OrderedDict({"some_password": ("", "password")}) - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(Moulinette, "prompt", return_value=""), patch.object( + with patch.object(Moulinette, "prompt", return_value=""), patch.object( os, "isatty", return_value=True ): assert parse_args_in_yunohost_format(answers, questions) == expected_result @@ -487,10 +466,7 @@ def test_question_password_optional_with_input_without_ask(): answers = {} expected_result = OrderedDict({"some_password": ("some_value", "password")}) - Question.operation_logger = MagicMock() - with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( + with patch.object(Moulinette, "prompt", return_value="some_value"), patch.object( os, "isatty", return_value=True ): assert parse_args_in_yunohost_format(answers, questions) == expected_result @@ -540,10 +516,7 @@ def test_question_password_input_test_ask(): ] answers = {} - Question.operation_logger = MagicMock() with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object( Moulinette, "prompt", return_value="some_value" ) as prompt, patch.object( os, "isatty", return_value=True @@ -572,10 +545,7 @@ def test_question_password_input_test_ask_with_example(): ] answers = {} - Question.operation_logger = MagicMock() with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object( Moulinette, "prompt", return_value="some_value" ) as prompt, patch.object( os, "isatty", return_value=True @@ -599,10 +569,7 @@ def test_question_password_input_test_ask_with_help(): ] answers = {} - Question.operation_logger = MagicMock() with patch.object( - Question.operation_logger, "data_to_redact", create=True - ), patch.object( Moulinette, "prompt", return_value="some_value" ) as prompt, patch.object( os, "isatty", return_value=True diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 27681e4d3..447540e13 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -39,6 +39,7 @@ from moulinette.utils.filesystem import ( from yunohost.utils.i18n import _value_for_locale from yunohost.utils.error import YunohostError, YunohostValidationError +from yunohost.log import OperationLogger logger = getActionLogger("yunohost.config") CONFIG_PANEL_VERSION_SUPPORTED = 1.0 @@ -441,7 +442,6 @@ class ConfigPanel: class Question(object): hide_user_input_in_prompt = False - operation_logger = None pattern = None def __init__(self, question, user_answers): @@ -575,13 +575,9 @@ class Question(object): for data in data_to_redact if urllib.parse.quote(data) != data ] - if self.operation_logger: - self.operation_logger.data_to_redact.extend(data_to_redact) - elif data_to_redact: - raise YunohostError( - f"Can't redact {self.name} because no operation logger available in the context", - raw_msg=True, - ) + + for operation_logger in OperationLogger._instances: + operation_logger.data_to_redact.extend(data_to_redact) return self.value From 4503816a88ca2ba1f6ac76dd8cd823e63de748ac Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 14:39:14 +0200 Subject: [PATCH 05/19] Adding an anchor on each helper --- doc/helper_doc_template.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/helper_doc_template.md b/doc/helper_doc_template.md index cf88e10ac..d41c0b6e9 100644 --- a/doc/helper_doc_template.md +++ b/doc/helper_doc_template.md @@ -10,11 +10,10 @@ routes: Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{{ current_commit }}/doc/generate_helper_doc.py) on {{data.date}} (YunoHost version {{data.version}}) {% for category, helpers in data.helpers %} -### {{ category.upper() }} +## {{ 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 %} From c53a6006ce8017c39ea9f2b0f410acf64ef98f7c Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 14:47:12 +0200 Subject: [PATCH 06/19] Remove unused import --- src/yunohost/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 70e55ceb0..e7fae9e76 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -56,7 +56,6 @@ from yunohost.utils import packages from yunohost.utils.config import ( ConfigPanel, parse_args_in_yunohost_format, - Question, ) from yunohost.utils.i18n import _value_for_locale from yunohost.utils.error import YunohostError, YunohostValidationError From 4db4338812216a0787c9b5389bdc71756e660af2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 17 Sep 2021 16:57:51 +0200 Subject: [PATCH 07/19] mypy: read_yaml argument should always be a string --- src/yunohost/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 447540e13..e3bbc5299 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -126,7 +126,7 @@ class ConfigPanel: if args_file: # Import YAML / JSON file but keep --args values - self.args = {**read_yaml(args_file), **self.args} + self.args = {**read_yaml(args_file.name), **self.args} if value is not None: self.args = {self.filter_key.split(".")[-1]: value} From d135b97784cb06fc9a4de51ca4324f92c452d245 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 17 Sep 2021 17:10:07 +0200 Subject: [PATCH 08/19] Revert "mypy: read_yaml argument should always be a string" This reverts commit 4db4338812216a0787c9b5389bdc71756e660af2. --- src/yunohost/utils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index e3bbc5299..447540e13 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -126,7 +126,7 @@ class ConfigPanel: if args_file: # Import YAML / JSON file but keep --args values - self.args = {**read_yaml(args_file.name), **self.args} + self.args = {**read_yaml(args_file), **self.args} if value is not None: self.args = {self.filter_key.split(".")[-1]: value} From 29bb26f24687989334289d7d17e8c4a5413af968 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 17:51:50 +0200 Subject: [PATCH 09/19] remove created permission if error --- src/yunohost/permission.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 01330ad7f..5161430de 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -457,22 +457,26 @@ def permission_create( "permission_creation_failed", permission=permission, error=e ) - permission_url( - permission, - url=url, - add_url=additional_urls, - auth_header=auth_header, - sync_perm=False, - ) + try: + permission_url( + permission, + url=url, + add_url=additional_urls, + auth_header=auth_header, + sync_perm=False, + ) - new_permission = _update_ldap_group_permission( - permission=permission, - allowed=allowed, - label=label, - show_tile=show_tile, - protected=protected, - sync_perm=sync_perm, - ) + new_permission = _update_ldap_group_permission( + permission=permission, + allowed=allowed, + label=label, + show_tile=show_tile, + protected=protected, + sync_perm=sync_perm, + ) + except: + permission_delete(permission, force=True) + raise logger.debug(m18n.n("permission_created", permission=permission)) return new_permission From ddd522ac54e580d75728c349aaeb766231de9e72 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 18:24:50 +0200 Subject: [PATCH 10/19] add YNH_APP_BASEDIR in the env var --- data/helpers.d/utils | 2 -- src/yunohost/app.py | 10 ++++++++-- src/yunohost/backup.py | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 34a089eb1..085404f1b 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -1,7 +1,5 @@ #!/bin/bash -YNH_APP_BASEDIR=$(realpath $([[ "$(basename $0)" =~ ^backup|restore$ ]] && echo '../settings' || [[ -n "${YNH_ACTION:-}" ]] && echo '.' || echo '..' )) - # Handle script crashes / failures # # [internal] diff --git a/src/yunohost/app.py b/src/yunohost/app.py index e7fae9e76..a5291ed88 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -456,19 +456,21 @@ def app_change_url(operation_logger, app, domain, path): # TODO: Allow to specify arguments args_odict = _parse_args_from_manifest(manifest, "change_url") + tmp_workdir_for_app = _make_tmp_workdir_for_app(app=app) + # Prepare env. var. to pass to script env_dict = _make_environment_for_app_script(app, args=args_odict) env_dict["YNH_APP_OLD_DOMAIN"] = old_domain env_dict["YNH_APP_OLD_PATH"] = old_path env_dict["YNH_APP_NEW_DOMAIN"] = domain env_dict["YNH_APP_NEW_PATH"] = path + env_dict["YNH_APP_BASEDIR"] = tmp_workdir_for_app if domain != old_domain: operation_logger.related_to.append(("domain", old_domain)) operation_logger.extra.update({"env": env_dict}) operation_logger.start() - tmp_workdir_for_app = _make_tmp_workdir_for_app(app=app) change_url_script = os.path.join(tmp_workdir_for_app, "scripts/change_url") # Execute App change_url script @@ -619,6 +621,7 @@ def app_upgrade(app=[], url=None, file=None, force=False, no_safety_backup=False env_dict["YNH_APP_MANIFEST_VERSION"] = str(app_new_version) env_dict["YNH_APP_CURRENT_VERSION"] = str(app_current_version) env_dict["NO_BACKUP_UPGRADE"] = "1" if no_safety_backup else "0" + env_dict["YNH_APP_BASEDIR"] = extracted_app_folder # We'll check that the app didn't brutally edit some system configuration manually_modified_files_before_install = manually_modified_files() @@ -980,6 +983,7 @@ def app_install( # Prepare env. var. to pass to script env_dict = _make_environment_for_app_script(app_instance_name, args=args_odict) + env_dict["YNH_APP_BASEDIR"] = extracted_app_folder env_dict_for_logging = env_dict.copy() for arg_name, arg_value_and_type in args_odict.items(): @@ -1645,12 +1649,14 @@ def app_action_run(operation_logger, app, action, args=None): ) args_odict = _parse_args_for_action(actions[action], args=args_dict) + tmp_workdir_for_app = _make_tmp_workdir_for_app(app=app) + env_dict = _make_environment_for_app_script( app, args=args_odict, args_prefix="ACTION_" ) env_dict["YNH_ACTION"] = action + env_dict["YNH_APP_BASEDIR"] = tmp_workdir_for_app - tmp_workdir_for_app = _make_tmp_workdir_for_app(app=app) _, action_script = tempfile.mkstemp(dir=tmp_workdir_for_app) with open(action_script, "w") as script: diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 15abc08ef..80f01fd35 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -707,6 +707,7 @@ class BackupManager: # Prepare environment env_dict = self._get_env_var(app) + env_dict["YNH_APP_BASEDIR"] = os.path.join(self.work_dir, "apps", app, "settings") tmp_app_bkp_dir = env_dict["YNH_APP_BACKUP_DIR"] settings_dir = os.path.join(self.work_dir, "apps", app, "settings") @@ -1487,6 +1488,7 @@ class RestoreManager: "YNH_APP_BACKUP_DIR": os.path.join( self.work_dir, "apps", app_instance_name, "backup" ), + "YNH_APP_BASEDIR": os.path.join(self.work_dir, "apps", app_instance_name, "settings"), } ) @@ -1524,6 +1526,7 @@ class RestoreManager: # Setup environment for remove script env_dict_remove = _make_environment_for_app_script(app_instance_name) + env_dict_remove["YNH_APP_BASEDIR"] = os.path.join(self.work_dir, "apps", app_instance_name, "settings") remove_operation_logger = OperationLogger( "remove_on_failed_restore", From aeed9f897b005857216813fd96dfa171934f7b5b Mon Sep 17 00:00:00 2001 From: ljf Date: Fri, 17 Sep 2021 18:32:06 +0200 Subject: [PATCH 11/19] [fix] Redact password in app install --- src/yunohost/app.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 3ba7fd5e4..569fbdb23 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -895,6 +895,9 @@ def app_install( else: app_instance_name = app_id + # Neede to redact password question + Question.operation_logger = operation_logger + # Retrieve arguments list for install script args_dict = ( {} if not args else dict(urllib.parse.parse_qsl(args, keep_blank_values=True)) @@ -913,19 +916,6 @@ def app_install( # We'll check that the app didn't brutally edit some system configuration manually_modified_files_before_install = manually_modified_files() - # Tell the operation_logger to redact all password-type args - # Also redact the % escaped version of the password that might appear in - # the 'args' section of metadata (relevant for password with non-alphanumeric char) - data_to_redact = [ - value[0] for value in args_odict.values() if value[1] == "password" - ] - data_to_redact += [ - urllib.parse.quote(data) - for data in data_to_redact - if urllib.parse.quote(data) != data - ] - operation_logger.data_to_redact.extend(data_to_redact) - operation_logger.related_to = [ s for s in operation_logger.related_to if s[0] != "app" ] From c1eecd5eb30c299919d13a29e4d50399663b68d0 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 18:38:00 +0200 Subject: [PATCH 12/19] moar YNH_APP_BASEDIR --- src/yunohost/app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index a5291ed88..de4f1efc6 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1048,6 +1048,7 @@ def app_install( env_dict_remove["YNH_APP_INSTANCE_NAME"] = app_instance_name env_dict_remove["YNH_APP_INSTANCE_NUMBER"] = str(instance_number) env_dict_remove["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?") + env_dict_remove["YNH_APP_BASEDIR"] = extracted_app_folder # Execute remove script operation_logger_remove = OperationLogger( @@ -1165,6 +1166,8 @@ def app_remove(operation_logger, app, purge=False): env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb) env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?") env_dict["YNH_APP_PURGE"] = str(purge) + env_dict["YNH_APP_BASEDIR"] = tmp_workdir_for_app + operation_logger.extra.update({"env": env_dict}) operation_logger.flush() @@ -1783,6 +1786,7 @@ ynh_app_config_run $1 "app": self.app, "app_instance_nb": str(app_instance_nb), "final_path": settings.get("final_path", ""), + "YNH_APP_BASEDIR": os.path.join(APPS_SETTING_PATH, self.app), } ) From efdd287bff82c8e250b8406f890768c990b7a94d Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 18:47:47 +0200 Subject: [PATCH 13/19] define a default YNH_APP_BASEDIR --- data/helpers.d/utils | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 085404f1b..396374174 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -1,5 +1,11 @@ #!/bin/bash +if [ -z "$YNH_APP_BASEDIR" ]; +then + ynh_print_warn --message="YNH_APP_BASEDIR is not defined, many helpers use it, please define it!" + YNH_APP_BASEDIR=$(realpath ..) +fi + # Handle script crashes / failures # # [internal] From c20ac160ccc468dbf5909c4499b75e4b879d906f Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 17 Sep 2021 18:49:33 +0200 Subject: [PATCH 14/19] do not use ynh_print_warn here --- 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 396374174..fd989c682 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -2,7 +2,7 @@ if [ -z "$YNH_APP_BASEDIR" ]; then - ynh_print_warn --message="YNH_APP_BASEDIR is not defined, many helpers use it, please define it!" + echo -e "YNH_APP_BASEDIR is not defined, many helpers use it, please define it!" >&2 YNH_APP_BASEDIR=$(realpath ..) fi From 0d881fe008fbfb62e8c173fa6b306f94f3fbb569 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 17 Sep 2021 19:56:24 +0200 Subject: [PATCH 15/19] app.py: No need to define Question.operation_logger anymoar --- src/yunohost/app.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 14ef6e3e7..06185761a 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -894,9 +894,6 @@ def app_install( else: app_instance_name = app_id - # Neede to redact password question - Question.operation_logger = operation_logger - # Retrieve arguments list for install script args_dict = ( {} if not args else dict(urllib.parse.parse_qsl(args, keep_blank_values=True)) From 991eea447c9685142d3c59c38efcb691281552a6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 17 Sep 2021 22:23:08 +0200 Subject: [PATCH 16/19] [fix] YNH_APP_BASEDIR may not exist, set -eu etc --- 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 fd989c682..732c1bc47 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -1,6 +1,6 @@ #!/bin/bash -if [ -z "$YNH_APP_BASEDIR" ]; +if [ -z "${YNH_APP_BASEDIR:-}" ]; then echo -e "YNH_APP_BASEDIR is not defined, many helpers use it, please define it!" >&2 YNH_APP_BASEDIR=$(realpath ..) From ef91b67d670638c4c60edb398b665956375806af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Fri, 17 Sep 2021 23:31:40 +0200 Subject: [PATCH 17/19] Fix time format Set more meaningful time format --- locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.json b/locales/en.json index 5bb408f1d..49c7eb09c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -150,7 +150,7 @@ "config_validate_color": "Should be a valid RGB hexadecimal color", "config_validate_date": "Should be a valid date like in the format YYYY-MM-DD", "config_validate_email": "Should be a valid email", - "config_validate_time": "Should be a valid time like XX:YY", + "config_validate_time": "Should be a valid time like HH:MM", "config_validate_url": "Should be a valid web URL", "config_version_not_supported": "Config panel versions '{version}' are not supported.", "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system... If you are willing to take that risk anyway, type '{answers}'", From e7844ef09ef9b88a236ce0d4e7e93365d7e4ccf3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 19 Sep 2021 20:46:32 +0200 Subject: [PATCH 18/19] Simplify YNH_APP_BASEDIR definition Co-authored-by: Kayou --- data/helpers.d/utils | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 732c1bc47..061ff324d 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -1,10 +1,6 @@ #!/bin/bash -if [ -z "${YNH_APP_BASEDIR:-}" ]; -then - echo -e "YNH_APP_BASEDIR is not defined, many helpers use it, please define it!" >&2 - YNH_APP_BASEDIR=$(realpath ..) -fi +YNH_APP_BASEDIR=${YNH_APP_BASEDIR:-$(realpath ..)} # Handle script crashes / failures # From b6981c80b8e046af13ab0b5f9fa8b213e65984b1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 19 Sep 2021 20:40:13 +0200 Subject: [PATCH 19/19] backup: Manually modified files may not exists... --- data/hooks/backup/50-conf_manually_modified_files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/hooks/backup/50-conf_manually_modified_files b/data/hooks/backup/50-conf_manually_modified_files index 685fb56a8..2cca11afb 100644 --- a/data/hooks/backup/50-conf_manually_modified_files +++ b/data/hooks/backup/50-conf_manually_modified_files @@ -12,7 +12,7 @@ ynh_backup --src_path="./manually_modified_files_list" for file in $(cat ./manually_modified_files_list) do - ynh_backup --src_path="$file" + [[ -e $file ]] && ynh_backup --src_path="$file" done ynh_backup --src_path="/etc/ssowat/conf.json.persistent"