mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
App system hooks
This commit is contained in:
parent
b0f1bea9a1
commit
81dccca288
4 changed files with 65 additions and 77 deletions
|
@ -332,6 +332,18 @@ app:
|
||||||
help: Return the full app_dict
|
help: Return the full app_dict
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
||||||
|
### app_setting()
|
||||||
|
addaccess:
|
||||||
|
action_help: Set ou get an app setting value
|
||||||
|
api: GET /app/{app}/setting
|
||||||
|
arguments:
|
||||||
|
app:
|
||||||
|
help: App ID
|
||||||
|
key:
|
||||||
|
help: Key to get/set
|
||||||
|
-v:
|
||||||
|
full: --value
|
||||||
|
help: Value to set
|
||||||
|
|
||||||
### app_addaccess() TODO: Write help
|
### app_addaccess() TODO: Write help
|
||||||
addaccess:
|
addaccess:
|
||||||
|
|
|
@ -24,8 +24,8 @@ gettext.install('YunoHost')
|
||||||
|
|
||||||
dev = False
|
dev = False
|
||||||
installed = True
|
installed = True
|
||||||
ssl_key = '/usr/share/yunohost/yunohost-config/ssl/yunoCA/certs/yunohost_key.pem'
|
ssl_key = '/etc/ssl/private/yunohost_key.pem'
|
||||||
ssl_crt = '/usr/share/yunohost/yunohost-config/ssl/yunoCA/newcerts/02.pem'
|
ssl_crt = '/etc/ssl/certs/yunohost_crt.pem'
|
||||||
action_dict = {}
|
action_dict = {}
|
||||||
api = APIResource()
|
api = APIResource()
|
||||||
|
|
||||||
|
|
115
yunohost_app.py
115
yunohost_app.py
|
@ -33,6 +33,7 @@ import time
|
||||||
from yunohost import YunoHostError, YunoHostLDAP, win_msg, random_password, is_true
|
from yunohost import YunoHostError, YunoHostLDAP, win_msg, random_password, is_true
|
||||||
from yunohost_domain import domain_list, domain_add
|
from yunohost_domain import domain_list, domain_add
|
||||||
from yunohost_user import user_info
|
from yunohost_user import user_info
|
||||||
|
from yunohost_hook import hook_exec
|
||||||
|
|
||||||
repo_path = '/var/cache/yunohost/repo'
|
repo_path = '/var/cache/yunohost/repo'
|
||||||
apps_path = '/usr/share/yunohost/apps'
|
apps_path = '/usr/share/yunohost/apps'
|
||||||
|
@ -249,7 +250,7 @@ def app_upgrade(app, url=None, file=None):
|
||||||
raise YunoHostError(1, app_id + _(" is not installed"))
|
raise YunoHostError(1, app_id + _(" is not installed"))
|
||||||
|
|
||||||
if app_id in upgraded_apps:
|
if app_id in upgraded_apps:
|
||||||
raise YunoHostError(1, _("Conflict, multiple upgrades of the same app: ")+ app_id +' (instance n°'+ number +')')
|
continue
|
||||||
|
|
||||||
#TODO: fix that (and check for instance number)
|
#TODO: fix that (and check for instance number)
|
||||||
current_app_dict = app_info(app_id, instance=number, raw=True)
|
current_app_dict = app_info(app_id, instance=number, raw=True)
|
||||||
|
@ -264,22 +265,17 @@ def app_upgrade(app, url=None, file=None):
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
# Execute App upgrade script
|
|
||||||
#TODO: display fail messages from script
|
|
||||||
_exec_app_script(step='upgrade', path=app_tmp_folder +'/scripts', var_dict={}, parameters=manifest['parameters'])
|
|
||||||
|
|
||||||
|
|
||||||
# Write App settings
|
|
||||||
app_setting_path = apps_setting_path +'/'+ app_id
|
app_setting_path = apps_setting_path +'/'+ app_id
|
||||||
|
|
||||||
current_app_dict['settings']['update_time'] = int(time.time())
|
# Execute App upgrade script
|
||||||
|
if hook_exec(app_setting_path+ '/scripts/upgrade') != 0:
|
||||||
|
#TODO: display fail messages from script
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
app_setting(app_id, 'update_time', int(time.time())
|
||||||
|
|
||||||
with open(app_setting_path +'/settings.yml', 'w') as f:
|
# Move scripts and manifest to the right place
|
||||||
yaml.safe_dump(current_app_dict['settings'], f, default_flow_style=False)
|
os.system('mv "'+ app_tmp_folder +'/manifest.json" "'+ app_tmp_folder +'/scripts" '+ app_setting_path)
|
||||||
win_msg(_("App setting file updated"))
|
|
||||||
|
|
||||||
os.system('mv "'+ app_tmp_folder +'/*" '+ app_setting_path)
|
|
||||||
|
|
||||||
# So much win
|
# So much win
|
||||||
upgraded_apps.append(app_id)
|
upgraded_apps.append(app_id)
|
||||||
|
@ -302,11 +298,9 @@ def app_install(app, label=None):
|
||||||
"""
|
"""
|
||||||
#TODO: Create tool for ssowat
|
#TODO: Create tool for ssowat
|
||||||
#TODO: Create tool for nginx (check path availability & stuff)
|
#TODO: Create tool for nginx (check path availability & stuff)
|
||||||
#TODO: Create tool for MySQL DB ?
|
|
||||||
|
|
||||||
with YunoHostLDAP() as yldap:
|
with YunoHostLDAP() as yldap:
|
||||||
|
|
||||||
|
|
||||||
# Fetch or extract sources
|
# Fetch or extract sources
|
||||||
try: os.listdir(install_tmp)
|
try: os.listdir(install_tmp)
|
||||||
except OSError: os.makedirs(install_tmp)
|
except OSError: os.makedirs(install_tmp)
|
||||||
|
@ -350,23 +344,20 @@ def app_install(app, label=None):
|
||||||
if os.path.exists(app_setting_path): shutil.rmtree(app_setting_path)
|
if os.path.exists(app_setting_path): shutil.rmtree(app_setting_path)
|
||||||
os.makedirs(app_setting_path)
|
os.makedirs(app_setting_path)
|
||||||
|
|
||||||
yaml_dict = {
|
os.system('touch '+ app_setting_path +'/settings.yml')
|
||||||
'id': app_id,
|
app_setting(app_id, 'id', app_id)
|
||||||
'install_time': int(time.time())
|
app_setting(app_id, 'install_time', int(time.time()))
|
||||||
}
|
|
||||||
|
|
||||||
if label: yaml_dict['label'] = label
|
if label:
|
||||||
else: yaml_dict['label'] = manifest['name']
|
app_setting(app_id, 'label', label)
|
||||||
|
else:
|
||||||
|
app_setting(app_id, 'label', manifest['name'])
|
||||||
|
|
||||||
# Write App settings
|
# Move scripts and manifest to the right place
|
||||||
with open(app_setting_path +'/settings.yml', 'w') as f:
|
os.system('mv "'+ app_tmp_folder +'/manifest.json" "'+ app_tmp_folder +'/scripts" '+ app_setting_path)
|
||||||
yaml.safe_dump(yaml_dict, f, default_flow_style=False)
|
|
||||||
win_msg(_("App setting file created"))
|
|
||||||
|
|
||||||
os.system('mv "'+ app_final_path +'/manifest.json" "'+ app_final_path +'/scripts" '+ app_setting_path)
|
|
||||||
|
|
||||||
# Execute App install script
|
# Execute App install script
|
||||||
if _exec_app_script(step='install', path=app_tmp_folder +'/scripts', var_dict={}, parameters=manifest['parameters']) != 0:
|
if hook_exec(app_setting_path+ '/scripts/install') != 0:
|
||||||
#TODO: display script fail messages
|
#TODO: display script fail messages
|
||||||
shutil.rmtree(app_setting_path)
|
shutil.rmtree(app_setting_path)
|
||||||
|
|
||||||
|
@ -385,13 +376,9 @@ def app_remove(app):
|
||||||
if not _is_installed(app):
|
if not _is_installed(app):
|
||||||
raise YunoHostError(22, _("App is not installed"))
|
raise YunoHostError(22, _("App is not installed"))
|
||||||
|
|
||||||
app_final_path = apps_path +'/'+ app
|
|
||||||
app_dict = app_info(app, raw=True)
|
|
||||||
app_settings = app_dict['settings']
|
|
||||||
manifest = app_dict['manifest']
|
|
||||||
|
|
||||||
#TODO: display fail messages from script
|
#TODO: display fail messages from script
|
||||||
_exec_app_script(step='remove', path=app_tmp_folder +'/scripts', var_dict=script_var_dict, parameters=manifest['parameters'])
|
if hook_exec(apps_setting_path +'/'+ app + '/scripts/remove') != 0:
|
||||||
|
pass
|
||||||
|
|
||||||
win_msg(_("App removed: ")+ app)
|
win_msg(_("App removed: ")+ app)
|
||||||
|
|
||||||
|
@ -474,6 +461,29 @@ def app_removeaccess(apps, users):
|
||||||
#TODO: Regenerate SSOwat conf
|
#TODO: Regenerate SSOwat conf
|
||||||
|
|
||||||
|
|
||||||
|
def app_setting(app, key, value=None):
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
settings_file = apps_setting_path + app +'/settings.yml'
|
||||||
|
|
||||||
|
with open(settings_file) as f:
|
||||||
|
app_settings = yaml.load(f)
|
||||||
|
|
||||||
|
if value is not None:
|
||||||
|
if value == '' and key in app_settings:
|
||||||
|
del app_settings[key]
|
||||||
|
else:
|
||||||
|
app_settings[key] = value
|
||||||
|
elif key in app_settings:
|
||||||
|
return app_settings[key]
|
||||||
|
|
||||||
|
with open(settings_file, 'w') as f:
|
||||||
|
yaml.safe_dump(app_settings, f, default_flow_style=False)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _extract_app_from_file(path):
|
def _extract_app_from_file(path):
|
||||||
"""
|
"""
|
||||||
Unzip or untar application tarball in app_tmp_folder, or copy it from a directory
|
Unzip or untar application tarball in app_tmp_folder, or copy it from a directory
|
||||||
|
@ -562,41 +572,6 @@ def _fetch_app_from_git(app):
|
||||||
return manifest
|
return manifest
|
||||||
|
|
||||||
|
|
||||||
def _exec_app_script(step, path, var_dict, parameters):
|
|
||||||
"""
|
|
||||||
Execute step user script
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
step -- Name of the script to call regarding the current step (e.g. install|upgrade|remove|etc.)
|
|
||||||
path -- Absolute path of the script's directory
|
|
||||||
var_dict -- Dictionnary of environnement variable to pass to the script
|
|
||||||
parameters -- Parameters to pass to the script
|
|
||||||
|
|
||||||
"""
|
|
||||||
scripts = [ step, step +'.sh', step +'.py' ]
|
|
||||||
|
|
||||||
for script in scripts:
|
|
||||||
script_path = path +'/'+ script
|
|
||||||
if os.path.exists(script_path):
|
|
||||||
st = os.stat(script_path)
|
|
||||||
os.chmod(script_path, st.st_mode | stat.S_IEXEC)
|
|
||||||
|
|
||||||
user = 'yunohost'
|
|
||||||
os.system('chown -R '+ user +': '+ app_tmp_folder)
|
|
||||||
|
|
||||||
env_vars = ''
|
|
||||||
for key, value in var_dict.items():
|
|
||||||
env_vars = env_vars + key + "='"+ value +"' "
|
|
||||||
|
|
||||||
command = 'su - '+ user +' -c "'+ env_vars +' sh '+ path +'/'+ script +'"'
|
|
||||||
if os.system(command) == 0:
|
|
||||||
win_msg(_("Script executed: ") + script)
|
|
||||||
else:
|
|
||||||
raise YunoHostError(1, _("Script execution failed: ") + script)
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
def _installed_instance_number(app, last=False):
|
def _installed_instance_number(app, last=False):
|
||||||
"""
|
"""
|
||||||
Check if application is installed and return instance number
|
Check if application is installed and return instance number
|
||||||
|
|
|
@ -54,11 +54,12 @@ def hook_callback(action):
|
||||||
action -- Action name
|
action -- Action name
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try: os.listdir(hook_folder + action)
|
with YunoHostLDAP() as yldap:
|
||||||
except OSError: os.makedirs(hook_folder + action)
|
try: os.listdir(hook_folder + action)
|
||||||
|
except OSError: os.makedirs(hook_folder + action)
|
||||||
|
|
||||||
for hook in os.listdir(hook_folder + action):
|
for hook in os.listdir(hook_folder + action):
|
||||||
hook_exec(file=hook_folder + action +'/'+ hook)
|
hook_exec(file=hook_folder + action +'/'+ hook)
|
||||||
|
|
||||||
|
|
||||||
def hook_check(file):
|
def hook_check(file):
|
||||||
|
@ -116,4 +117,4 @@ def hook_exec(file, args=None):
|
||||||
else:
|
else:
|
||||||
raise YunoHostError(22, _("Missing arguments") + ': ' + arg_name)
|
raise YunoHostError(22, _("Missing arguments") + ': ' + arg_name)
|
||||||
|
|
||||||
os.system('su - admin -c "bash \\"'+ file +'\\" '+ ' '.join(arg_list) +'"')
|
return os.system('su - admin -c "bash \\"'+ file +'\\" '+ ' '.join(arg_list) +'"') #TODO: Allow python script
|
||||||
|
|
Loading…
Reference in a new issue