mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge remote-tracking branch 'origin/unstable' into unstable
This commit is contained in:
commit
c4ada6eb3b
3 changed files with 69 additions and 78 deletions
|
@ -1345,14 +1345,6 @@ hook:
|
||||||
help: Ordered list of arguments to pass to the script
|
help: Ordered list of arguments to pass to the script
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
|
|
||||||
### hook_check()
|
|
||||||
check:
|
|
||||||
action_help: Parse the script file and get arguments
|
|
||||||
api: GET /hook/check
|
|
||||||
arguments:
|
|
||||||
file:
|
|
||||||
help: File to check
|
|
||||||
|
|
||||||
### hook_exec()
|
### hook_exec()
|
||||||
exec:
|
exec:
|
||||||
action_help: Execute hook from a file with arguments
|
action_help: Execute hook from a file with arguments
|
||||||
|
|
|
@ -383,9 +383,14 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
for hook in os.listdir(app_tmp_folder +'/hooks'):
|
for hook in os.listdir(app_tmp_folder +'/hooks'):
|
||||||
hook_add(app_id, app_tmp_folder +'/hooks/'+ hook)
|
hook_add(app_id, app_tmp_folder +'/hooks/'+ hook)
|
||||||
|
|
||||||
|
# Retrieve arguments list for upgrade script
|
||||||
|
# TODO: Allow to specify arguments
|
||||||
|
args_list = _parse_args_from_manifest(manifest, 'upgrade')
|
||||||
|
args_list.append(app_id)
|
||||||
|
|
||||||
# Execute App upgrade script
|
# Execute App upgrade script
|
||||||
os.system('chown -hR admin: %s' % install_tmp)
|
os.system('chown -hR admin: %s' % install_tmp)
|
||||||
if hook_exec(app_tmp_folder +'/scripts/upgrade') != 0:
|
if hook_exec(app_tmp_folder +'/scripts/upgrade', args_list) != 0:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('installation_failed'))
|
raise MoulinetteError(errno.EIO, m18n.n('installation_failed'))
|
||||||
else:
|
else:
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
|
@ -514,12 +519,11 @@ def app_install(auth, app, label=None, args=None):
|
||||||
|
|
||||||
os.system('chown -R admin: '+ app_tmp_folder)
|
os.system('chown -R admin: '+ app_tmp_folder)
|
||||||
|
|
||||||
try:
|
# Retrieve arguments list for install script
|
||||||
if args is None:
|
args_dict = {} if not args else \
|
||||||
args = ''
|
dict(urlparse.parse_qsl(args, keep_blank_values=True))
|
||||||
args_dict = dict(urlparse.parse_qsl(args, keep_blank_values=True))
|
args_list = _parse_args_from_manifest(manifest, 'install', args_dict)
|
||||||
except:
|
args_list.append(app_id)
|
||||||
args_dict = {}
|
|
||||||
|
|
||||||
# Execute App install script
|
# Execute App install script
|
||||||
os.system('chown -hR admin: %s' % install_tmp)
|
os.system('chown -hR admin: %s' % install_tmp)
|
||||||
|
@ -527,7 +531,7 @@ def app_install(auth, app, label=None, args=None):
|
||||||
os.system('cp %s/manifest.json %s' % (app_tmp_folder, app_setting_path))
|
os.system('cp %s/manifest.json %s' % (app_tmp_folder, app_setting_path))
|
||||||
os.system('cp -R %s/scripts %s' % (app_tmp_folder, app_setting_path))
|
os.system('cp -R %s/scripts %s' % (app_tmp_folder, app_setting_path))
|
||||||
try:
|
try:
|
||||||
if hook_exec(app_tmp_folder + '/scripts/install', args_dict) == 0:
|
if hook_exec(app_tmp_folder + '/scripts/install', args_list) == 0:
|
||||||
# Store app status
|
# Store app status
|
||||||
with open(app_setting_path + '/status.json', 'w+') as f:
|
with open(app_setting_path + '/status.json', 'w+') as f:
|
||||||
json.dump(status, f)
|
json.dump(status, f)
|
||||||
|
@ -584,7 +588,9 @@ def app_remove(auth, 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')
|
||||||
|
|
||||||
if hook_exec('/tmp/yunohost_remove/scripts/remove') == 0:
|
args_list = [app]
|
||||||
|
|
||||||
|
if hook_exec('/tmp/yunohost_remove/scripts/remove', args_list) == 0:
|
||||||
msignals.display(m18n.n('app_removed', app), 'success')
|
msignals.display(m18n.n('app_removed', app), 'success')
|
||||||
|
|
||||||
if os.path.exists(app_setting_path): shutil.rmtree(app_setting_path)
|
if os.path.exists(app_setting_path): shutil.rmtree(app_setting_path)
|
||||||
|
@ -1337,6 +1343,57 @@ def _encode_string(value):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_args_from_manifest(manifest, action, args={}):
|
||||||
|
"""Parse arguments needed for an action from the manifest
|
||||||
|
|
||||||
|
Retrieve specified arguments for the action from the manifest, and parse
|
||||||
|
given args according to that. If some required arguments are not provided,
|
||||||
|
its values will be asked if interaction is possible.
|
||||||
|
Parsed arguments will be returned as a list of strings to pass directly
|
||||||
|
to the proper script.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
manifest -- The app manifest to use
|
||||||
|
action -- The action to retrieve arguments for
|
||||||
|
args -- A dictionnary of arguments to parse
|
||||||
|
|
||||||
|
"""
|
||||||
|
args_list = []
|
||||||
|
try:
|
||||||
|
action_args = manifest['arguments'][action]
|
||||||
|
except KeyError:
|
||||||
|
logger.debug("no arguments found for '%s' in '%s'", action, path)
|
||||||
|
else:
|
||||||
|
for arg in action_args:
|
||||||
|
if arg['name'] in args:
|
||||||
|
if 'choices' in arg and args[arg['name']] not in arg['choices']:
|
||||||
|
raise MoulinetteError(errno.EINVAL,
|
||||||
|
m18n.n('hook_choice_invalid', args[arg['name']]))
|
||||||
|
args_list.append(args[arg['name']])
|
||||||
|
else:
|
||||||
|
if os.isatty(1) and 'ask' in arg:
|
||||||
|
# Retrieve proper ask string
|
||||||
|
ask_string = _value_for_locale(arg['ask'])
|
||||||
|
|
||||||
|
# Append extra strings
|
||||||
|
if 'choices' in arg:
|
||||||
|
ask_string += ' ({:s})'.format('|'.join(arg['choices']))
|
||||||
|
if 'default' in arg:
|
||||||
|
ask_string += ' (default: {:s})'.format(arg['default'])
|
||||||
|
|
||||||
|
input_string = msignals.prompt(ask_string)
|
||||||
|
if not input_string and 'default' in arg:
|
||||||
|
input_string = arg['default']
|
||||||
|
|
||||||
|
args_list.append(input_string)
|
||||||
|
elif 'default' in arg:
|
||||||
|
args_list.append(arg['default'])
|
||||||
|
else:
|
||||||
|
raise MoulinetteError(errno.EINVAL,
|
||||||
|
m18n.n('hook_argument_missing', arg['name']))
|
||||||
|
return args_list
|
||||||
|
|
||||||
|
|
||||||
def is_true(arg):
|
def is_true(arg):
|
||||||
"""
|
"""
|
||||||
Convert a string into a boolean
|
Convert a string into a boolean
|
||||||
|
|
|
@ -275,34 +275,13 @@ def hook_callback(action, hooks=[], args=None):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def hook_check(file):
|
|
||||||
"""
|
|
||||||
Parse the script file and get arguments
|
|
||||||
|
|
||||||
Keyword argument:
|
|
||||||
file -- File to check
|
|
||||||
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
with open(file[:file.index('scripts/')] + 'manifest.json') as f:
|
|
||||||
manifest = json.loads(str(f.read()))
|
|
||||||
except:
|
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('app_manifest_invalid'))
|
|
||||||
|
|
||||||
action = file[file.index('scripts/') + 8:]
|
|
||||||
if 'arguments' in manifest and action in manifest['arguments']:
|
|
||||||
return manifest['arguments'][action]
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
def hook_exec(path, args=None, raise_on_error=False, no_trace=False):
|
def hook_exec(path, args=None, raise_on_error=False, no_trace=False):
|
||||||
"""
|
"""
|
||||||
Execute hook from a file with arguments
|
Execute hook from a file with arguments
|
||||||
|
|
||||||
Keyword argument:
|
Keyword argument:
|
||||||
path -- Path of the script to execute
|
path -- Path of the script to execute
|
||||||
args -- Arguments to pass to the script
|
args -- A 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
|
no_trace -- Do not print each command that will be executed
|
||||||
|
|
||||||
|
@ -316,52 +295,15 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False):
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
raise MoulinetteError(errno.EIO, m18n.g('file_not_exist'))
|
raise MoulinetteError(errno.EIO, m18n.g('file_not_exist'))
|
||||||
|
|
||||||
if isinstance(args, list):
|
|
||||||
arg_list = args
|
|
||||||
else:
|
|
||||||
required_args = hook_check(path)
|
|
||||||
if args is None:
|
|
||||||
args = {}
|
|
||||||
|
|
||||||
arg_list = []
|
|
||||||
for arg in required_args:
|
|
||||||
if arg['name'] in args:
|
|
||||||
if 'choices' in arg and args[arg['name']] not in arg['choices']:
|
|
||||||
raise MoulinetteError(errno.EINVAL,
|
|
||||||
m18n.n('hook_choice_invalid', args[arg['name']]))
|
|
||||||
arg_list.append(args[arg['name']])
|
|
||||||
else:
|
|
||||||
if os.isatty(1) and 'ask' in arg:
|
|
||||||
# Retrieve proper ask string
|
|
||||||
ask_string = _value_for_locale(arg['ask'])
|
|
||||||
|
|
||||||
# Append extra strings
|
|
||||||
if 'choices' in arg:
|
|
||||||
ask_string += ' ({:s})'.format('|'.join(arg['choices']))
|
|
||||||
if 'default' in arg:
|
|
||||||
ask_string += ' (default: {:s})'.format(arg['default'])
|
|
||||||
|
|
||||||
input_string = msignals.prompt(ask_string)
|
|
||||||
|
|
||||||
if input_string == '' and 'default' in arg:
|
|
||||||
input_string = arg['default']
|
|
||||||
|
|
||||||
arg_list.append(input_string)
|
|
||||||
elif 'default' in arg:
|
|
||||||
arg_list.append(arg['default'])
|
|
||||||
else:
|
|
||||||
raise MoulinetteError(errno.EINVAL,
|
|
||||||
m18n.n('hook_argument_missing', arg['name']))
|
|
||||||
|
|
||||||
# Construct command variables
|
# Construct command variables
|
||||||
cmd_fdir, cmd_fname = os.path.split(path)
|
cmd_fdir, cmd_fname = os.path.split(path)
|
||||||
cmd_fname = './{0}'.format(cmd_fname)
|
cmd_fname = './{0}'.format(cmd_fname)
|
||||||
|
|
||||||
cmd_args = ''
|
cmd_args = ''
|
||||||
if arg_list:
|
if args and isinstance(args, list):
|
||||||
# Concatenate arguments and escape them with double quotes to prevent
|
# Concatenate arguments and escape them with double quotes to prevent
|
||||||
# bash related issue if an argument is empty and is not the last
|
# bash related issue if an argument is empty and is not the last
|
||||||
cmd_args = '"{:s}"'.format('" "'.join(str(s) for s in arg_list))
|
cmd_args = '"{:s}"'.format('" "'.join(str(s) for s in args))
|
||||||
|
|
||||||
# Construct command to execute
|
# Construct command to execute
|
||||||
command = ['sudo', '-u', 'admin', '-H', 'sh', '-c']
|
command = ['sudo', '-u', 'admin', '-H', 'sh', '-c']
|
||||||
|
|
Loading…
Add table
Reference in a new issue