Merge pull request #739 from YunoHost/proper-return-interface-for-app-config

[mod] Proper return interface for app config
This commit is contained in:
Alexandre Aubin 2019-07-02 22:01:18 +02:00 committed by GitHub
commit 8917238159
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 35 deletions

View file

@ -285,6 +285,16 @@ ynh_script_progression () {
set -x
}
# Return data to the Yunohost core for later processing
# (to be used by special hooks like app config panel and core diagnosis)
#
# usage: ynh_return somedata
#
# Requires YunoHost version 3.6.0 or higher.
ynh_return () {
echo "$1" >> "$YNH_STDRETURN"
}
# Debugger for app packagers
#
# usage: ynh_debug [--message=message] [--trace=1/0]

View file

@ -1603,31 +1603,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)

View file

@ -297,8 +297,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):
chdir=None, env=None, user="root", return_format="json"):
"""
Execute hook from a file with arguments
@ -372,8 +371,8 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
# Define output callbacks and call command
callbacks = (
stdout_callback if stdout_callback else lambda l: logger.debug(l.rstrip()+"\r"),
stderr_callback if stderr_callback else lambda l: logger.warning(l.rstrip()),
lambda l: logger.debug(l.rstrip()+"\r"),
lambda l: logger.warning(l.rstrip()),
)
if stdinfo:
@ -401,19 +400,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):