From b1634785fb510d3a0def3931845420b3b38a870f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 17 Jun 2019 17:32:47 +0200 Subject: [PATCH] Add a new 'plain_dict' return type for hook_exec, and use it for app config --- src/yunohost/app.py | 33 +++++++-------------------------- src/yunohost/hook.py | 28 ++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 1f172a267..c6187a52b 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -362,10 +362,10 @@ def app_info(app, show_status=False, raw=False): ret['upgradable'] = upgradable ret['change_url'] = os.path.exists(os.path.join(app_setting_path, "scripts", "change_url")) - + with open(os.path.join(APPS_SETTING_PATH, app, 'manifest.json')) as json_manifest: manifest = json.load(json_manifest) - + ret['version'] = manifest.get('version', '-') return ret @@ -1606,31 +1606,12 @@ def app_config_show_panel(app): "YNH_APP_INSTANCE_NAME": app, "YNH_APP_INSTANCE_NUMBER": str(app_instance_nb), } - parsed_values = {} - # I need to parse stdout to communicate between scripts because I can't - # read the child environment :( (that would simplify things so much) - # after hours of research this is apparently quite a standard way, another - # option would be to add an explicite pipe or a named pipe for that - # a third option would be to write in a temporary file but I don't like - # that because that could expose sensitive data - def parse_stdout(line): - line = line.rstrip() - logger.info(line) - - if line.strip().startswith("YNH_CONFIG_") and "=" in line: - # XXX error handling? - # XXX this might not work for multilines stuff :( (but echo without - # formatting should do it no?) - key, value = line.strip().split("=", 1) - logger.debug("config script declared: %s -> %s", key, value) - parsed_values[key] = value - - return_code = hook_exec(config_script, - args=["show"], - env=env, - stdout_callback=parse_stdout, - )[0] + return_code, parsed_values = hook_exec(config_script, + args=["show"], + env=env, + return_format="plain_dict" + ) if return_code != 0: raise Exception("script/config show return value code: %s (considered as an error)", return_code) diff --git a/src/yunohost/hook.py b/src/yunohost/hook.py index 42807fdf7..f1b7515bc 100644 --- a/src/yunohost/hook.py +++ b/src/yunohost/hook.py @@ -298,7 +298,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None, def hook_exec(path, args=None, raise_on_error=False, no_trace=False, chdir=None, env=None, user="root", stdout_callback=None, - stderr_callback=None): + stderr_callback=None, return_format="json"): """ Execute hook from a file with arguments @@ -401,19 +401,31 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False, try: with open(stdreturn, 'r') as f: raw_content = f.read() - if raw_content != '': - returnjson = read_json(stdreturn) + returncontent = {} + + if return_format == "json": + if raw_content != '': + try: + returncontent = read_json(stdreturn) + except Exception as e: + raise YunohostError('hook_json_return_error', + path=path, msg=str(e), + raw_content=raw_content) + + elif return_format == "plain_dict": + for line in raw_content.split("\n"): + if "=" in line: + key, value = line.strip().split("=", 1) + returncontent[key] = value + else: - returnjson = {} - except Exception as e: - raise YunohostError('hook_json_return_error', path=path, msg=str(e), - raw_content=raw_content) + raise YunohostError("Excepted value for return_format is either 'json' or 'plain_dict', got '%s'" % return_format) finally: stdreturndir = os.path.split(stdreturn)[0] os.remove(stdreturn) os.rmdir(stdreturndir) - return returncode, returnjson + return returncode, returncontent def _extract_filename_parts(filename):