[wip] Reduce config panel var

This commit is contained in:
ljf 2021-08-17 17:07:26 +02:00
parent 65fc06e3e7
commit fddb79e841
2 changed files with 60 additions and 74 deletions

View file

@ -115,19 +115,16 @@ for panel_name,panel in loaded_toml.items():
if isinstance(section, dict): if isinstance(section, dict):
for name, param in section.items(): for name, param in section.items():
if isinstance(param, dict) and param.get('type', 'string') not in ['info', 'warning', 'error']: if isinstance(param, dict) and param.get('type', 'string') not in ['info', 'warning', 'error']:
print("%s.%s.%s=%s" %(panel_name, section_name, name, param.get('source', 'settings'))) print("%s=%s" % (name, param.get('source', 'settings')))
EOL EOL
` `
for param_source in $params_sources for param_source in $params_sources
do do
local _dot_setting=$(echo "$param_source" | cut -d= -f1) local short_setting="$(echo $param_source | cut -d= -f1)"
local _snake_setting="YNH_CONFIG_$(ynh_lowerdot_to_uppersnake $_dot_setting)"
local short_setting=$(echo "$_dot_setting" | cut -d. -f3)
local getter="get__${short_setting}" local getter="get__${short_setting}"
local source="$(echo $param_source | cut -d= -f2)" local source="$(echo $param_source | cut -d= -f2)"
sources[${short_setting}]="$source" sources[${short_setting}]="$source"
file_hash[${short_setting}]="" file_hash[${short_setting}]=""
dot_settings[${short_setting}]="${_dot_setting}"
# Get value from getter if exists # Get value from getter if exists
if type -t $getter 2>/dev/null | grep -q '^function$' 2>/dev/null; then if type -t $getter 2>/dev/null | grep -q '^function$' 2>/dev/null; then
@ -149,9 +146,6 @@ EOL
old[$short_setting]="$source" old[$short_setting]="$source"
file_hash[$short_setting]="true" file_hash[$short_setting]="true"
fi fi
set +u
new[$short_setting]="${!_snake_setting}"
set -u
done done
set -x set -x
@ -191,8 +185,7 @@ _ynh_panel_apply() {
_ynh_panel_show() { _ynh_panel_show() {
for short_setting in "${!old[@]}" for short_setting in "${!old[@]}"
do do
local key="YNH_CONFIG_$(ynh_lowerdot_to_uppersnake $dot_settings[$short_setting])" ynh_return "${short_setting}=${old[$short_setting]}"
ynh_return "$key=${old[$short_setting]}"
done done
} }
@ -238,7 +231,7 @@ _ynh_panel_validate() {
fi fi
if [ -n "$result" ] if [ -n "$result" ]
then then
local key="YNH_ERROR_$(ynh_lowerdot_to_uppersnake $dot_settings[$short_setting])" local key="YNH_ERROR_${$short_setting}"
ynh_return "$key=$result" ynh_return "$key=$result"
is_error=true is_error=true
fi fi
@ -247,7 +240,7 @@ _ynh_panel_validate() {
if [[ "$is_error" == "true" ]] if [[ "$is_error" == "true" ]]
then then
ynh_die ynh_die ""
fi fi
set -x set -x
@ -275,7 +268,6 @@ ynh_panel_run() {
declare -Ag changed=() declare -Ag changed=()
declare -Ag file_hash=() declare -Ag file_hash=()
declare -Ag sources=() declare -Ag sources=()
declare -Ag dot_settings=()
ynh_panel_get ynh_panel_get
case $1 in case $1 in

View file

@ -1782,59 +1782,49 @@ def app_config_show_panel(operation_logger, app):
} }
env = { env = {
"YNH_APP_ID": app_id, "app_id": app_id,
"YNH_APP_INSTANCE_NAME": app, "app": app,
"YNH_APP_INSTANCE_NUMBER": str(app_instance_nb), "app_instance_nb": str(app_instance_nb),
} }
# FIXME: this should probably be ran in a tmp workdir... try:
return_code, parsed_values = hook_exec( ret, parsed_values = hook_exec(
config_script, args=["show"], env=env, return_format="plain_dict" 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,
) )
# Here again, calling hook_exec could fail miserably, or get
# manually interrupted (by mistake or because script was stuck)
except (KeyboardInterrupt, EOFError, Exception):
raise YunohostError("unexpected_error")
logger.debug("Generating global variables:") logger.debug("Generating global variables:")
for tab in config_panel.get("panel", []): for tab in config_panel.get("panel", []):
tab_id = tab["id"] # this makes things easier to debug on crash
for section in tab.get("sections", []): for section in tab.get("sections", []):
section_id = section["id"]
for option in section.get("options", []): for option in section.get("options", []):
option_name = option["name"]
generated_name = (
"YNH_CONFIG_%s_%s_%s" % (tab_id, section_id, option_name)
).upper()
option["name"] = generated_name
logger.debug( logger.debug(
" * '%s'.'%s'.'%s' -> %s", " * '%s'.'%s'.'%s'",
tab.get("name"), tab.get("name"),
section.get("name"), section.get("name"),
option.get("name"), option.get("name"),
generated_name,
) )
if generated_name in parsed_values: if option['name'] in parsed_values:
# code is not adapted for that so we have to mock expected format :/ # code is not adapted for that so we have to mock expected format :/
if option.get("type") == "boolean": if option.get("type") == "boolean":
if parsed_values[generated_name].lower() in ("true", "1", "y"): if parsed_values[option['name']].lower() in ("true", "1", "y"):
option["default"] = parsed_values[generated_name] option["default"] = parsed_values[option['name']]
else: else:
del option["default"] del option["default"]
else: else:
option["default"] = parsed_values[generated_name] option["default"] = parsed_values[option['name']]
args_dict = _parse_args_in_yunohost_format( args_dict = _parse_args_in_yunohost_format(
{option["name"]: parsed_values[generated_name]}, [option] parsed_values, [option]
) )
option["default"] = args_dict[option["name"]][0] option["default"] = args_dict[option["name"]][0]
else: else:
logger.debug( logger.debug(
"Variable '%s' is not declared by config script, using default", "Variable '%s' is not declared by config script, using default",
generated_name, option['name'],
) )
# do nothing, we'll use the default if present # do nothing, we'll use the default if present
@ -1869,32 +1859,26 @@ def app_config_apply(operation_logger, app, args):
operation_logger.start() operation_logger.start()
app_id, app_instance_nb = _parse_app_instance_name(app) app_id, app_instance_nb = _parse_app_instance_name(app)
env = { env = {
"YNH_APP_ID": app_id, "app_id": app_id,
"YNH_APP_INSTANCE_NAME": app, "app": app,
"YNH_APP_INSTANCE_NUMBER": str(app_instance_nb), "app_instance_nb": str(app_instance_nb),
} }
args = dict(urllib.parse.parse_qsl(args, keep_blank_values=True)) if args else {} args = dict(urllib.parse.parse_qsl(args, keep_blank_values=True)) if args else {}
upload_dir = None upload_dir = None
for tab in config_panel.get("panel", []): for tab in config_panel.get("panel", []):
tab_id = tab["id"] # this makes things easier to debug on crash
for section in tab.get("sections", []): for section in tab.get("sections", []):
section_id = section["id"]
for option in section.get("options", []): for option in section.get("options", []):
option_name = option["name"]
generated_name = (
"YNH_CONFIG_%s_%s_%s" % (tab_id, section_id, option_name)
).upper()
if generated_name in args: if option['name'] in args:
# Upload files from API # Upload files from API
# A file arg contains a string with "FILENAME:BASE64_CONTENT" # A file arg contains a string with "FILENAME:BASE64_CONTENT"
if 'type' in option and option["type"] == "file" \ if 'type' in option and option["type"] == "file" \
and msettings.get('interface') == 'api': and msettings.get('interface') == 'api':
if upload_dir is None: if upload_dir is None:
upload_dir = tempfile.mkdtemp(prefix='tmp_configpanel_') upload_dir = tempfile.mkdtemp(prefix='tmp_configpanel_')
filename = args[generated_name + '[name]'] filename = args[option['name'] + '[name]']
content = args[generated_name] content = args[option['name']]
logger.debug("Save uploaded file %s from API into %s", filename, upload_dir) logger.debug("Save uploaded file %s from API into %s", filename, upload_dir)
# Filename is given by user of the API. For security reason, we have replaced # Filename is given by user of the API. For security reason, we have replaced
@ -1912,14 +1896,14 @@ def app_config_apply(operation_logger, app, args):
raise YunohostError("cannot_write_file", file=file_path, error=str(e)) raise YunohostError("cannot_write_file", file=file_path, error=str(e))
except Exception as e: except Exception as e:
raise YunohostError("error_writing_file", file=file_path, error=str(e)) raise YunohostError("error_writing_file", file=file_path, error=str(e))
args[generated_name] = file_path args[option['name']] = file_path
logger.debug( logger.debug(
"include into env %s=%s", generated_name, args[generated_name] "include into env %s=%s", option['name'], args[option['name']]
) )
env[generated_name] = args[generated_name] env[option['name']] = args[option['name']]
else: else:
logger.debug("no value for key id %s", generated_name) logger.debug("no value for key id %s", option['name'])
# for debug purpose # for debug purpose
for key in args: for key in args:
@ -1928,25 +1912,21 @@ def app_config_apply(operation_logger, app, args):
"Ignore key '%s' from arguments because it is not in the config", key "Ignore key '%s' from arguments because it is not in the config", key
) )
# FIXME: this should probably be ran in a tmp workdir... try:
return_code = hook_exec( hook_exec(
config_script, config_script,
args=["apply"], args=["apply"],
env=env, env=env
)[0]
# Delete files uploaded from API
if msettings.get('interface') == 'api':
if upload_dir is not None:
shutil.rmtree(upload_dir)
if return_code != 0:
msg = (
"'script/config apply' return value code: %s (considered as an error)"
% return_code
) )
operation_logger.error(msg) # Here again, calling hook_exec could fail miserably, or get
raise Exception(msg) # manually interrupted (by mistake or because script was stuck)
except (KeyboardInterrupt, EOFError, Exception):
raise YunohostError("unexpected_error")
finally:
# Delete files uploaded from API
if msettings.get('interface') == 'api':
if upload_dir is not None:
shutil.rmtree(upload_dir)
logger.success("Config updated as expected") logger.success("Config updated as expected")
return { return {
@ -2991,16 +2971,30 @@ class DisplayTextArgumentParser(YunoHostArgumentFormatParser):
def parse(self, question, user_answers): def parse(self, question, user_answers):
print(question["ask"]) print(question["ask"])
class FileArgumentParser(YunoHostArgumentFormatParser):
argument_type = "file"
ARGUMENTS_TYPE_PARSERS = { ARGUMENTS_TYPE_PARSERS = {
"string": StringArgumentParser, "string": StringArgumentParser,
"text": StringArgumentParser,
"select": StringArgumentParser,
"tags": StringArgumentParser,
"email": StringArgumentParser,
"url": StringArgumentParser,
"date": StringArgumentParser,
"time": StringArgumentParser,
"color": StringArgumentParser,
"password": PasswordArgumentParser, "password": PasswordArgumentParser,
"path": PathArgumentParser, "path": PathArgumentParser,
"boolean": BooleanArgumentParser, "boolean": BooleanArgumentParser,
"domain": DomainArgumentParser, "domain": DomainArgumentParser,
"user": UserArgumentParser, "user": UserArgumentParser,
"number": NumberArgumentParser, "number": NumberArgumentParser,
"range": NumberArgumentParser,
"display_text": DisplayTextArgumentParser, "display_text": DisplayTextArgumentParser,
"file": FileArgumentParser,
} }