mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #1096 from YunoHost/less-madness-for-hook-exec
Less madness for hook exec
This commit is contained in:
commit
47181a4598
5 changed files with 94 additions and 59 deletions
|
@ -371,8 +371,6 @@ def app_change_url(operation_logger, app, domain, path):
|
||||||
# Retrieve arguments list for change_url script
|
# Retrieve arguments list for change_url script
|
||||||
# TODO: Allow to specify arguments
|
# TODO: Allow to specify arguments
|
||||||
args_odict = _parse_args_from_manifest(manifest, 'change_url')
|
args_odict = _parse_args_from_manifest(manifest, 'change_url')
|
||||||
args_list = [value[0] for value in args_odict.values()]
|
|
||||||
args_list.append(app)
|
|
||||||
|
|
||||||
# Prepare env. var. to pass to script
|
# Prepare env. var. to pass to script
|
||||||
env_dict = _make_environment_for_app_script(app, args=args_odict)
|
env_dict = _make_environment_for_app_script(app, args=args_odict)
|
||||||
|
@ -404,7 +402,7 @@ def app_change_url(operation_logger, app, domain, path):
|
||||||
os.system('chmod +x %s' % os.path.join(os.path.join(APP_TMP_FOLDER, "scripts", "change_url")))
|
os.system('chmod +x %s' % os.path.join(os.path.join(APP_TMP_FOLDER, "scripts", "change_url")))
|
||||||
|
|
||||||
if hook_exec(os.path.join(APP_TMP_FOLDER, 'scripts/change_url'),
|
if hook_exec(os.path.join(APP_TMP_FOLDER, 'scripts/change_url'),
|
||||||
args=args_list, env=env_dict)[0] != 0:
|
env=env_dict)[0] != 0:
|
||||||
msg = "Failed to change '%s' url." % app
|
msg = "Failed to change '%s' url." % app
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
operation_logger.error(msg)
|
operation_logger.error(msg)
|
||||||
|
@ -432,7 +430,7 @@ def app_change_url(operation_logger, app, domain, path):
|
||||||
logger.success(m18n.n("app_change_url_success",
|
logger.success(m18n.n("app_change_url_success",
|
||||||
app=app, domain=domain, path=path))
|
app=app, domain=domain, path=path))
|
||||||
|
|
||||||
hook_callback('post_app_change_url', args=args_list, env=env_dict)
|
hook_callback('post_app_change_url', env=env_dict)
|
||||||
|
|
||||||
|
|
||||||
def app_upgrade(app=[], url=None, file=None, force=False):
|
def app_upgrade(app=[], url=None, file=None, force=False):
|
||||||
|
@ -530,8 +528,6 @@ def app_upgrade(app=[], url=None, file=None, force=False):
|
||||||
# Retrieve arguments list for upgrade script
|
# Retrieve arguments list for upgrade script
|
||||||
# TODO: Allow to specify arguments
|
# TODO: Allow to specify arguments
|
||||||
args_odict = _parse_args_from_manifest(manifest, 'upgrade')
|
args_odict = _parse_args_from_manifest(manifest, 'upgrade')
|
||||||
args_list = [value[0] for value in args_odict.values()]
|
|
||||||
args_list.append(app_instance_name)
|
|
||||||
|
|
||||||
# Prepare env. var. to pass to script
|
# Prepare env. var. to pass to script
|
||||||
env_dict = _make_environment_for_app_script(app_instance_name, args=args_odict)
|
env_dict = _make_environment_for_app_script(app_instance_name, args=args_odict)
|
||||||
|
@ -560,7 +556,7 @@ def app_upgrade(app=[], url=None, file=None, force=False):
|
||||||
upgrade_failed = True
|
upgrade_failed = True
|
||||||
try:
|
try:
|
||||||
upgrade_retcode = hook_exec(extracted_app_folder + '/scripts/upgrade',
|
upgrade_retcode = hook_exec(extracted_app_folder + '/scripts/upgrade',
|
||||||
args=args_list, env=env_dict)[0]
|
env=env_dict)[0]
|
||||||
|
|
||||||
upgrade_failed = True if upgrade_retcode != 0 else False
|
upgrade_failed = True if upgrade_retcode != 0 else False
|
||||||
if upgrade_failed:
|
if upgrade_failed:
|
||||||
|
@ -637,7 +633,7 @@ def app_upgrade(app=[], url=None, file=None, force=False):
|
||||||
# So much win
|
# So much win
|
||||||
logger.success(m18n.n('app_upgraded', app=app_instance_name))
|
logger.success(m18n.n('app_upgraded', app=app_instance_name))
|
||||||
|
|
||||||
hook_callback('post_app_upgrade', args=args_list, env=env_dict)
|
hook_callback('post_app_upgrade', env=env_dict)
|
||||||
operation_logger.success()
|
operation_logger.success()
|
||||||
|
|
||||||
permission_sync_to_user()
|
permission_sync_to_user()
|
||||||
|
@ -754,10 +750,6 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
# Validate domain / path availability for webapps
|
# Validate domain / path availability for webapps
|
||||||
_validate_and_normalize_webpath(manifest, args_odict, extracted_app_folder)
|
_validate_and_normalize_webpath(manifest, args_odict, extracted_app_folder)
|
||||||
|
|
||||||
# build arg list tq
|
|
||||||
args_list = [value[0] for value in args_odict.values()]
|
|
||||||
args_list.append(app_instance_name)
|
|
||||||
|
|
||||||
# Attempt to patch legacy helpers ...
|
# Attempt to patch legacy helpers ...
|
||||||
_patch_legacy_helpers(extracted_app_folder)
|
_patch_legacy_helpers(extracted_app_folder)
|
||||||
|
|
||||||
|
@ -830,7 +822,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
try:
|
try:
|
||||||
install_retcode = hook_exec(
|
install_retcode = hook_exec(
|
||||||
os.path.join(extracted_app_folder, 'scripts/install'),
|
os.path.join(extracted_app_folder, 'scripts/install'),
|
||||||
args=args_list, env=env_dict
|
env=env_dict
|
||||||
)[0]
|
)[0]
|
||||||
# "Common" app install failure : the script failed and returned exit code != 0
|
# "Common" app install failure : the script failed and returned exit code != 0
|
||||||
install_failed = True if install_retcode != 0 else False
|
install_failed = True if install_retcode != 0 else False
|
||||||
|
@ -946,7 +938,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
|
|
||||||
logger.success(m18n.n('installation_complete'))
|
logger.success(m18n.n('installation_complete'))
|
||||||
|
|
||||||
hook_callback('post_app_install', args=args_list, env=env_dict)
|
hook_callback('post_app_install', env=env_dict)
|
||||||
|
|
||||||
|
|
||||||
def dump_app_log_extract_for_debugging(operation_logger):
|
def dump_app_log_extract_for_debugging(operation_logger):
|
||||||
|
@ -1033,8 +1025,6 @@ def app_remove(operation_logger, app):
|
||||||
os.system('chown -R admin: /tmp/yunohost_remove')
|
os.system('chown -R admin: /tmp/yunohost_remove')
|
||||||
os.system('chmod -R u+rX /tmp/yunohost_remove')
|
os.system('chmod -R u+rX /tmp/yunohost_remove')
|
||||||
|
|
||||||
args_list = [app]
|
|
||||||
|
|
||||||
env_dict = {}
|
env_dict = {}
|
||||||
app_id, app_instance_nb = _parse_app_instance_name(app)
|
app_id, app_instance_nb = _parse_app_instance_name(app)
|
||||||
env_dict["YNH_APP_ID"] = app_id
|
env_dict["YNH_APP_ID"] = app_id
|
||||||
|
@ -1046,7 +1036,6 @@ def app_remove(operation_logger, app):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = hook_exec('/tmp/yunohost_remove/scripts/remove',
|
ret = hook_exec('/tmp/yunohost_remove/scripts/remove',
|
||||||
args=args_list,
|
|
||||||
env=env_dict)[0]
|
env=env_dict)[0]
|
||||||
# Here again, calling hook_exec could fail miserably, or get
|
# Here again, calling hook_exec could fail miserably, or get
|
||||||
# manually interrupted (by mistake or because script was stuck)
|
# manually interrupted (by mistake or because script was stuck)
|
||||||
|
@ -1059,7 +1048,7 @@ def app_remove(operation_logger, app):
|
||||||
|
|
||||||
if ret == 0:
|
if ret == 0:
|
||||||
logger.success(m18n.n('app_removed', app=app))
|
logger.success(m18n.n('app_removed', app=app))
|
||||||
hook_callback('post_app_remove', args=args_list, env=env_dict)
|
hook_callback('post_app_remove', env=env_dict)
|
||||||
else:
|
else:
|
||||||
logger.warning(m18n.n('app_not_properly_removed', app=app))
|
logger.warning(m18n.n('app_not_properly_removed', app=app))
|
||||||
|
|
||||||
|
@ -1470,7 +1459,6 @@ def app_action_run(operation_logger, app, action, args=None):
|
||||||
# Retrieve arguments list for install script
|
# Retrieve arguments list for install script
|
||||||
args_dict = dict(urllib.parse.parse_qsl(args, keep_blank_values=True)) if args else {}
|
args_dict = dict(urllib.parse.parse_qsl(args, keep_blank_values=True)) if args else {}
|
||||||
args_odict = _parse_args_for_action(actions[action], args=args_dict)
|
args_odict = _parse_args_for_action(actions[action], args=args_dict)
|
||||||
args_list = [value[0] for value in args_odict.values()]
|
|
||||||
|
|
||||||
env_dict = _make_environment_for_app_script(app, args=args_odict, args_prefix="ACTION_")
|
env_dict = _make_environment_for_app_script(app, args=args_odict, args_prefix="ACTION_")
|
||||||
env_dict["YNH_ACTION"] = action
|
env_dict["YNH_ACTION"] = action
|
||||||
|
@ -1489,7 +1477,6 @@ def app_action_run(operation_logger, app, action, args=None):
|
||||||
|
|
||||||
retcode = hook_exec(
|
retcode = hook_exec(
|
||||||
path,
|
path,
|
||||||
args=args_list,
|
|
||||||
env=env_dict,
|
env=env_dict,
|
||||||
chdir=cwd,
|
chdir=cwd,
|
||||||
user=action_declaration.get("user", "root"),
|
user=action_declaration.get("user", "root"),
|
||||||
|
@ -2775,7 +2762,7 @@ def _make_environment_for_app_script(app, args={}, args_prefix="APP_ARG_"):
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg_name, arg_value_and_type in args.items():
|
for arg_name, arg_value_and_type in args.items():
|
||||||
env_dict["YNH_%s%s" % (args_prefix, arg_name.upper())] = arg_value_and_type[0]
|
env_dict["YNH_%s%s" % (args_prefix, arg_name.upper())] = str(arg_value_and_type[0])
|
||||||
|
|
||||||
return env_dict
|
return env_dict
|
||||||
|
|
||||||
|
@ -3139,6 +3126,33 @@ def _patch_legacy_helpers(app_folder):
|
||||||
"pattern": r"(Automatic diagnosis data from YunoHost( *\n)*)? *(__\w+__)? *\$\(yunohost tools diagnosis.*\)(__\w+__)?",
|
"pattern": r"(Automatic diagnosis data from YunoHost( *\n)*)? *(__\w+__)? *\$\(yunohost tools diagnosis.*\)(__\w+__)?",
|
||||||
"replace": r"",
|
"replace": r"",
|
||||||
"important": False
|
"important": False
|
||||||
|
},
|
||||||
|
# Old $1, $2 in backup/restore scripts...
|
||||||
|
"app=$2": {
|
||||||
|
"only_for": ["scripts/backup", "scripts/restore"],
|
||||||
|
"pattern": r"app=\$2",
|
||||||
|
"replace": r"app=$YNH_APP_INSTANCE_NAME",
|
||||||
|
"important": True
|
||||||
|
},
|
||||||
|
# Old $1, $2 in backup/restore scripts...
|
||||||
|
"backup_dir=$1": {
|
||||||
|
"only_for": ["scripts/backup", "scripts/restore"],
|
||||||
|
"pattern": r"backup_dir=\$1",
|
||||||
|
"replace": r"backup_dir=.",
|
||||||
|
"important": True
|
||||||
|
},
|
||||||
|
# Old $1, $2 in backup/restore scripts...
|
||||||
|
"restore_dir=$1": {
|
||||||
|
"only_for": ["scripts/restore"],
|
||||||
|
"pattern": r"restore_dir=\$1",
|
||||||
|
"replace": r"restore_dir=.",
|
||||||
|
"important": True
|
||||||
|
},
|
||||||
|
# Old $1, $2 in install scripts...
|
||||||
|
# We ain't patching that shit because it ain't trivial to patch all args...
|
||||||
|
"domain=$1": {
|
||||||
|
"only_for": ["scripts/install"],
|
||||||
|
"important": True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3157,6 +3171,11 @@ def _patch_legacy_helpers(app_folder):
|
||||||
show_warning = False
|
show_warning = False
|
||||||
|
|
||||||
for helper, infos in stuff_to_replace.items():
|
for helper, infos in stuff_to_replace.items():
|
||||||
|
|
||||||
|
# Ignore if not relevant for this file
|
||||||
|
if infos.get("only_for") and not any(filename.endswith(f) for f in infos["only_for"]):
|
||||||
|
continue
|
||||||
|
|
||||||
# If helper is used, attempt to patch the file
|
# If helper is used, attempt to patch the file
|
||||||
if helper in content and infos["pattern"]:
|
if helper in content and infos["pattern"]:
|
||||||
content = infos["pattern"].sub(infos["replace"], content)
|
content = infos["pattern"].sub(infos["replace"], content)
|
||||||
|
@ -3164,11 +3183,11 @@ def _patch_legacy_helpers(app_folder):
|
||||||
if infos["important"]:
|
if infos["important"]:
|
||||||
show_warning = True
|
show_warning = True
|
||||||
|
|
||||||
# If the helpert is *still* in the content, it means that we
|
# If the helper is *still* in the content, it means that we
|
||||||
# couldn't patch the deprecated helper in the previous lines. In
|
# couldn't patch the deprecated helper in the previous lines. In
|
||||||
# that case, abort the install or whichever step is performed
|
# that case, abort the install or whichever step is performed
|
||||||
if helper in content and infos["important"]:
|
if helper in content and infos["important"]:
|
||||||
raise YunohostError("This app is likely pretty old and uses deprecated / outdated helpers that can't be migrated easily. It can't be installed anymore.")
|
raise YunohostError("This app is likely pretty old and uses deprecated / outdated helpers that can't be migrated easily. It can't be installed anymore.", raw_msg=True)
|
||||||
|
|
||||||
if replaced_stuff:
|
if replaced_stuff:
|
||||||
|
|
||||||
|
|
|
@ -686,8 +686,10 @@ class BackupManager():
|
||||||
app_script = os.path.join(app_setting_path, 'scripts/backup')
|
app_script = os.path.join(app_setting_path, 'scripts/backup')
|
||||||
subprocess.call(['install', '-Dm555', app_script, tmp_script])
|
subprocess.call(['install', '-Dm555', app_script, tmp_script])
|
||||||
|
|
||||||
hook_exec(tmp_script, args=[tmp_app_bkp_dir, app],
|
hook_exec(tmp_script,
|
||||||
raise_on_error=True, chdir=tmp_app_bkp_dir, env=env_dict)[0]
|
raise_on_error=True,
|
||||||
|
chdir=tmp_app_bkp_dir,
|
||||||
|
env=env_dict)[0]
|
||||||
|
|
||||||
self._import_to_list_to_backup(env_dict["YNH_BACKUP_CSV"])
|
self._import_to_list_to_backup(env_dict["YNH_BACKUP_CSV"])
|
||||||
|
|
||||||
|
@ -1383,7 +1385,6 @@ class RestoreManager():
|
||||||
|
|
||||||
# Execute app restore script
|
# Execute app restore script
|
||||||
hook_exec(restore_script,
|
hook_exec(restore_script,
|
||||||
args=[app_backup_in_archive, app_instance_name],
|
|
||||||
chdir=app_backup_in_archive,
|
chdir=app_backup_in_archive,
|
||||||
raise_on_error=True,
|
raise_on_error=True,
|
||||||
env=env_dict)[0]
|
env=env_dict)[0]
|
||||||
|
@ -1408,7 +1409,7 @@ class RestoreManager():
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
# Execute remove script
|
# Execute remove script
|
||||||
if hook_exec(remove_script, args=[app_instance_name],
|
if hook_exec(remove_script,
|
||||||
env=env_dict_remove)[0] != 0:
|
env=env_dict_remove)[0] != 0:
|
||||||
msg = m18n.n('app_not_properly_removed', app=app_instance_name)
|
msg = m18n.n('app_not_properly_removed', app=app_instance_name)
|
||||||
logger.warning(msg)
|
logger.warning(msg)
|
||||||
|
|
|
@ -212,7 +212,7 @@ def hook_list(action, list_by='name', show_info=False):
|
||||||
return {'hooks': result}
|
return {'hooks': result}
|
||||||
|
|
||||||
|
|
||||||
def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
def hook_callback(action, hooks=[], args=None, chdir=None,
|
||||||
env=None, pre_callback=None, post_callback=None):
|
env=None, pre_callback=None, post_callback=None):
|
||||||
"""
|
"""
|
||||||
Execute all scripts binded to an action
|
Execute all scripts binded to an action
|
||||||
|
@ -221,7 +221,6 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
action -- Action name
|
action -- Action name
|
||||||
hooks -- List of hooks names to execute
|
hooks -- List of hooks names to execute
|
||||||
args -- Ordered list of arguments to pass to the scripts
|
args -- Ordered list of arguments to pass to the scripts
|
||||||
no_trace -- Do not print each command that will be executed
|
|
||||||
chdir -- The directory from where the scripts will be executed
|
chdir -- The directory from where the scripts will be executed
|
||||||
env -- Dictionnary of environment variables to export
|
env -- Dictionnary of environment variables to export
|
||||||
pre_callback -- An object to call before each script execution with
|
pre_callback -- An object to call before each script execution with
|
||||||
|
@ -282,7 +281,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
hook_args = pre_callback(name=name, priority=priority,
|
hook_args = pre_callback(name=name, priority=priority,
|
||||||
path=path, args=args)
|
path=path, args=args)
|
||||||
hook_return = hook_exec(path, args=hook_args, chdir=chdir, env=env,
|
hook_return = hook_exec(path, args=hook_args, chdir=chdir, env=env,
|
||||||
no_trace=no_trace, raise_on_error=True)[1]
|
raise_on_error=True)[1]
|
||||||
except YunohostError as e:
|
except YunohostError as e:
|
||||||
state = 'failed'
|
state = 'failed'
|
||||||
hook_return = {}
|
hook_return = {}
|
||||||
|
@ -298,8 +297,8 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
def hook_exec(path, args=None, raise_on_error=False,
|
||||||
chdir=None, env=None, user="root", return_format="json"):
|
chdir=None, env=None, return_format="json"):
|
||||||
"""
|
"""
|
||||||
Execute hook from a file with arguments
|
Execute hook from a file with arguments
|
||||||
|
|
||||||
|
@ -307,11 +306,8 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
||||||
path -- Path of the script to execute
|
path -- Path of the script to execute
|
||||||
args -- Ordered list of arguments to pass to the script
|
args -- Ordered list of arguments to pass to the script
|
||||||
raise_on_error -- Raise if the script returns a non-zero exit code
|
raise_on_error -- Raise if the script returns a non-zero exit code
|
||||||
no_trace -- Do not print each command that will be executed
|
|
||||||
chdir -- The directory from where the script will be executed
|
chdir -- The directory from where the script will be executed
|
||||||
env -- Dictionnary of environment variables to export
|
env -- Dictionnary of environment variables to export
|
||||||
user -- User with which to run the command
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Validate hook path
|
# Validate hook path
|
||||||
|
@ -350,7 +346,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
||||||
if hook_type == 'text/x-python':
|
if hook_type == 'text/x-python':
|
||||||
returncode, returndata = _hook_exec_python(path, args, env, loggers)
|
returncode, returndata = _hook_exec_python(path, args, env, loggers)
|
||||||
else:
|
else:
|
||||||
returncode, returndata = _hook_exec_bash(path, args, no_trace, chdir, env, user, return_format, loggers)
|
returncode, returndata = _hook_exec_bash(path, args, chdir, env, return_format, loggers)
|
||||||
|
|
||||||
# Check and return process' return code
|
# Check and return process' return code
|
||||||
if returncode is None:
|
if returncode is None:
|
||||||
|
@ -365,7 +361,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
||||||
return returncode, returndata
|
return returncode, returndata
|
||||||
|
|
||||||
|
|
||||||
def _hook_exec_bash(path, args, no_trace, chdir, env, user, return_format, loggers):
|
def _hook_exec_bash(path, args, chdir, env, return_format, loggers):
|
||||||
|
|
||||||
from moulinette.utils.process import call_async_output
|
from moulinette.utils.process import call_async_output
|
||||||
|
|
||||||
|
@ -393,27 +389,20 @@ def _hook_exec_bash(path, args, no_trace, chdir, env, user, return_format, logge
|
||||||
f.write('')
|
f.write('')
|
||||||
env['YNH_STDRETURN'] = stdreturn
|
env['YNH_STDRETURN'] = stdreturn
|
||||||
|
|
||||||
# Construct command to execute
|
# use xtrace on fd 7 which is redirected to stdout
|
||||||
if user == "root":
|
env['BASH_XTRACEFD'] = "7"
|
||||||
command = ['sh', '-c']
|
cmd = '/bin/bash -x "{script}" {args} 7>&1'
|
||||||
else:
|
cmd = cmd.format(script=cmd_script, args=cmd_args)
|
||||||
command = ['sudo', '-n', '-u', user, '-H', 'sh', '-c']
|
|
||||||
|
|
||||||
if no_trace:
|
logger.debug("Executing command '%s'" % cmd)
|
||||||
cmd = '/bin/bash "{script}" {args}'
|
|
||||||
else:
|
|
||||||
# use xtrace on fd 7 which is redirected to stdout
|
|
||||||
cmd = 'BASH_XTRACEFD=7 /bin/bash -x "{script}" {args} 7>&1'
|
|
||||||
|
|
||||||
# prepend environment variables
|
_env = os.environ.copy()
|
||||||
cmd = '{0} {1}'.format(
|
_env.update(env)
|
||||||
' '.join(['{0}={1}'.format(k, shell_quote(v))
|
|
||||||
for k, v in env.items()]), cmd)
|
|
||||||
command.append(cmd.format(script=cmd_script, args=cmd_args))
|
|
||||||
|
|
||||||
logger.debug("Executing command '%s'" % ' '.join(command))
|
returncode = call_async_output(
|
||||||
|
cmd, loggers, shell=False, cwd=chdir,
|
||||||
returncode = call_async_output(command, loggers, shell=False, cwd=chdir)
|
env=_env
|
||||||
|
)
|
||||||
|
|
||||||
raw_content = None
|
raw_content = None
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -3,7 +3,7 @@ import pytest
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import moulinette
|
import moulinette
|
||||||
from moulinette import m18n
|
from moulinette import m18n, msettings
|
||||||
from yunohost.utils.error import YunohostError
|
from yunohost.utils.error import YunohostError
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
sys.path.append("..")
|
sys.path.append("..")
|
||||||
|
@ -78,3 +78,4 @@ def pytest_cmdline_main(config):
|
||||||
sys.path.insert(0, "/usr/lib/moulinette/")
|
sys.path.insert(0, "/usr/lib/moulinette/")
|
||||||
import yunohost
|
import yunohost
|
||||||
yunohost.init(debug=config.option.yunodebug)
|
yunohost.init(debug=config.option.yunodebug)
|
||||||
|
msettings["interface"] = "test"
|
||||||
|
|
|
@ -219,12 +219,20 @@ def user_create(operation_logger, username, firstname, lastname, domain, passwor
|
||||||
user_group_create(groupname=username, gid=uid, primary_group=True, sync_perm=False)
|
user_group_create(groupname=username, gid=uid, primary_group=True, sync_perm=False)
|
||||||
user_group_update(groupname='all_users', add=username, force=True, sync_perm=True)
|
user_group_update(groupname='all_users', add=username, force=True, sync_perm=True)
|
||||||
|
|
||||||
|
# Trigger post_user_create hooks
|
||||||
|
env_dict = {
|
||||||
|
"YNH_USER_USERNAME": username,
|
||||||
|
"YNH_USER_MAIL": mail,
|
||||||
|
"YNH_USER_PASSWORD": password,
|
||||||
|
"YNH_USER_FIRSTNAME": firstname,
|
||||||
|
"YNH_USER_LASTNAME": lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
hook_callback('post_user_create', args=[username, mail], env=env_dict)
|
||||||
|
|
||||||
# TODO: Send a welcome mail to user
|
# TODO: Send a welcome mail to user
|
||||||
logger.success(m18n.n('user_created'))
|
logger.success(m18n.n('user_created'))
|
||||||
|
|
||||||
hook_callback('post_user_create',
|
|
||||||
args=[username, mail, password, firstname, lastname])
|
|
||||||
|
|
||||||
return {'fullname': fullname, 'username': username, 'mail': mail}
|
return {'fullname': fullname, 'username': username, 'mail': mail}
|
||||||
|
|
||||||
|
|
||||||
|
@ -302,6 +310,7 @@ def user_update(operation_logger, username, firstname=None, lastname=None, mail=
|
||||||
from yunohost.app import app_ssowatconf
|
from yunohost.app import app_ssowatconf
|
||||||
from yunohost.utils.password import assert_password_is_strong_enough
|
from yunohost.utils.password import assert_password_is_strong_enough
|
||||||
from yunohost.utils.ldap import _get_ldap_interface
|
from yunohost.utils.ldap import _get_ldap_interface
|
||||||
|
from yunohost.hook import hook_callback
|
||||||
|
|
||||||
domains = domain_list()['domains']
|
domains = domain_list()['domains']
|
||||||
|
|
||||||
|
@ -312,16 +321,21 @@ def user_update(operation_logger, username, firstname=None, lastname=None, mail=
|
||||||
if not result:
|
if not result:
|
||||||
raise YunohostError('user_unknown', user=username)
|
raise YunohostError('user_unknown', user=username)
|
||||||
user = result[0]
|
user = result[0]
|
||||||
|
env_dict = {
|
||||||
|
"YNH_USER_USERNAME": username
|
||||||
|
}
|
||||||
|
|
||||||
# Get modifications from arguments
|
# Get modifications from arguments
|
||||||
new_attr_dict = {}
|
new_attr_dict = {}
|
||||||
if firstname:
|
if firstname:
|
||||||
new_attr_dict['givenName'] = [firstname] # TODO: Validate
|
new_attr_dict['givenName'] = [firstname] # TODO: Validate
|
||||||
new_attr_dict['cn'] = new_attr_dict['displayName'] = [firstname + ' ' + user['sn'][0]]
|
new_attr_dict['cn'] = new_attr_dict['displayName'] = [firstname + ' ' + user['sn'][0]]
|
||||||
|
env_dict["YNH_USER_FIRSTNAME"] = firstname
|
||||||
|
|
||||||
if lastname:
|
if lastname:
|
||||||
new_attr_dict['sn'] = [lastname] # TODO: Validate
|
new_attr_dict['sn'] = [lastname] # TODO: Validate
|
||||||
new_attr_dict['cn'] = new_attr_dict['displayName'] = [user['givenName'][0] + ' ' + lastname]
|
new_attr_dict['cn'] = new_attr_dict['displayName'] = [user['givenName'][0] + ' ' + lastname]
|
||||||
|
env_dict["YNH_USER_LASTNAME"] = lastname
|
||||||
|
|
||||||
if lastname and firstname:
|
if lastname and firstname:
|
||||||
new_attr_dict['cn'] = new_attr_dict['displayName'] = [firstname + ' ' + lastname]
|
new_attr_dict['cn'] = new_attr_dict['displayName'] = [firstname + ' ' + lastname]
|
||||||
|
@ -337,6 +351,7 @@ def user_update(operation_logger, username, firstname=None, lastname=None, mail=
|
||||||
assert_password_is_strong_enough("user", change_password)
|
assert_password_is_strong_enough("user", change_password)
|
||||||
|
|
||||||
new_attr_dict['userPassword'] = [_hash_user_password(change_password)]
|
new_attr_dict['userPassword'] = [_hash_user_password(change_password)]
|
||||||
|
env_dict["YNH_USER_PASSWORD"] = change_password
|
||||||
|
|
||||||
if mail:
|
if mail:
|
||||||
main_domain = _get_maindomain()
|
main_domain = _get_maindomain()
|
||||||
|
@ -381,6 +396,9 @@ def user_update(operation_logger, username, firstname=None, lastname=None, mail=
|
||||||
raise YunohostError('mail_alias_remove_failed', mail=mail)
|
raise YunohostError('mail_alias_remove_failed', mail=mail)
|
||||||
new_attr_dict['mail'] = user['mail']
|
new_attr_dict['mail'] = user['mail']
|
||||||
|
|
||||||
|
if 'mail' in new_attr_dict:
|
||||||
|
env_dict["YNH_USER_MAILS"] = ','.join(new_attr_dict['mail'])
|
||||||
|
|
||||||
if add_mailforward:
|
if add_mailforward:
|
||||||
if not isinstance(add_mailforward, list):
|
if not isinstance(add_mailforward, list):
|
||||||
add_mailforward = [add_mailforward]
|
add_mailforward = [add_mailforward]
|
||||||
|
@ -400,8 +418,12 @@ def user_update(operation_logger, username, firstname=None, lastname=None, mail=
|
||||||
raise YunohostError('mail_forward_remove_failed', mail=mail)
|
raise YunohostError('mail_forward_remove_failed', mail=mail)
|
||||||
new_attr_dict['maildrop'] = user['maildrop']
|
new_attr_dict['maildrop'] = user['maildrop']
|
||||||
|
|
||||||
|
if 'maildrop' in new_attr_dict:
|
||||||
|
env_dict["YNH_USER_MAILFORWARDS"] = ','.join(new_attr_dict['maildrop'])
|
||||||
|
|
||||||
if mailbox_quota is not None:
|
if mailbox_quota is not None:
|
||||||
new_attr_dict['mailuserquota'] = [mailbox_quota]
|
new_attr_dict['mailuserquota'] = [mailbox_quota]
|
||||||
|
env_dict["YNH_USER_MAILQUOTA"] = mailbox_quota
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -410,6 +432,9 @@ def user_update(operation_logger, username, firstname=None, lastname=None, mail=
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise YunohostError('user_update_failed', user=username, error=e)
|
raise YunohostError('user_update_failed', user=username, error=e)
|
||||||
|
|
||||||
|
# Trigger post_user_update hooks
|
||||||
|
hook_callback('post_user_update', env=env_dict)
|
||||||
|
|
||||||
logger.success(m18n.n('user_updated'))
|
logger.success(m18n.n('user_updated'))
|
||||||
app_ssowatconf()
|
app_ssowatconf()
|
||||||
return user_info(username)
|
return user_info(username)
|
||||||
|
|
Loading…
Add table
Reference in a new issue