App system hooks

This commit is contained in:
kload 2013-10-18 13:48:01 +00:00
parent b0f1bea9a1
commit 81dccca288
4 changed files with 65 additions and 77 deletions

View file

@ -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:

View file

@ -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()

View file

@ -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

View file

@ -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