Clean app system (le retour)

This commit is contained in:
Kload 2013-10-09 11:05:04 +02:00
parent b5f8a8c0fd
commit b84b7dc8f9
2 changed files with 116 additions and 126 deletions

View file

@ -300,10 +300,6 @@ app:
arguments: arguments:
app: app:
help: App(s) to delete help: App(s) to delete
-i:
full: --instance
help: App instance number to delete
nargs: '*'
### app_upgrade() ### app_upgrade()
upgrade: upgrade:

View file

@ -142,6 +142,7 @@ def app_list(offset=None, limit=None, filter=None, raw=False):
for app_id, app_info in sorted_app_dict.items(): for app_id, app_info in sorted_app_dict.items():
if i < limit: if i < limit:
if (filter and ((filter in app_id) or (filter in app_info['manifest']['name']))) or not filter: if (filter and ((filter in app_id) or (filter in app_info['manifest']['name']))) or not filter:
#TODO: make _is_installed
installed = _is_installed(app_id) installed = _is_installed(app_id)
if raw: if raw:
@ -267,17 +268,12 @@ def app_upgrade(app, url=None, file=None):
continue continue
######################################### # Execute App upgrade script
# 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']) _exec_app_script(step='upgrade', path=app_tmp_folder +'/scripts', var_dict={}, parameters=manifest['parameters'])
######################################### # Write App settings
# 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()) current_app_dict['settings']['update_time'] = int(time.time())
@ -288,11 +284,8 @@ def app_upgrade(app, url=None, file=None):
os.system('mv "'+ app_tmp_folder +'/*" '+ app_setting_path) os.system('mv "'+ app_tmp_folder +'/*" '+ app_setting_path)
######################################### # So much win
# So much win # upgraded_apps.append(app_id)
#########################################
upgraded_apps.append(unique_app_id)
win_msg(app_id + _(" upgraded successfully")) win_msg(app_id + _(" upgraded successfully"))
if not upgraded_apps: if not upgraded_apps:
@ -317,10 +310,7 @@ def app_install(app, label=None):
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)
@ -329,99 +319,84 @@ def app_install(app, label=None):
else: else:
manifest = _extract_app_from_file(app) manifest = _extract_app_from_file(app)
# Check ID
######################################### if 'id' not in manifest or '__' in manifest['id']:
# Define App ID & path #
#########################################
if not lvl(manifest, 'id') or '__' in manifest['uid']:
raise YunoHostError(22, _("App id is invalid")) raise YunoHostError(22, _("App id is invalid"))
instance_number = _installed_instance_number(manifest['yunohost']['id'], last=True) + 1 app_id = manifest['id']
if instance_number > 1:
if not lvl(manifest, 'multi_instance') or not is_true(manifest['multi_instance']): # Check if app can be forked
instance_number = _installed_instance_number(app_id, last=True) + 1
if fork and instance_number > 1 :
if 'multi_instance' not in manifest or not is_true(manifest['multi_instance']):
raise YunoHostError(1, _("App is already installed")) raise YunoHostError(1, _("App is already installed"))
forked_app_id = app_id + '__' + instance_number
unique_app_id = manifest['id'] +'__'+ str(instance_number) # Replace app_id with the new one in scripts
app_final_path = apps_path +'/'+ unique_app_id for file in os.listdir(app_tmp_folder +'/scripts'):
script_var_dict = { #TODO: add hooks directory to the list
'SCRIPT_DIR': app_tmp_folder, #TODO: do it with sed ?
'APP_DIR': app_final_path, with open(file, "r") as sources:
'APP_ID': unique_app_id lines = sources.readlines()
} with open(file, "w") as sources:
for line in lines:
sources.write(re.sub(r''+ app_id +'', app_id_forked, line))
# Change app_id for the rest of the process
app_id = app_id_forked
######################################### # Prepare App settings
# Execute App install script # app_setting_path = apps_setting_path +'/'+ app_id
#########################################
_exec_app_script(step='install', path=app_tmp_folder +'/scripts', var_dict=script_var_dict, parameters=manifest['parameters'])
#########################################
# Write App settings #
#########################################
app_setting_path = apps_setting_path +'/'+ unique_app_id
#TMP: Remove old settings #TMP: Remove old settings
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 = { yaml_dict = {
'id': manifest['yunohost']['uid'], 'id': app_id,
'instance' : instance_number,
'install_time': int(time.time()) 'install_time': int(time.time())
} }
if label: yaml_dict['label'] = label if label: yaml_dict['label'] = label
else: yaml_dict['label'] = manifest['name'] else: yaml_dict['label'] = manifest['name']
# Write App settings
with open(app_setting_path +'/settings.yml', 'w') as f: with open(app_setting_path +'/settings.yml', 'w') as f:
yaml.safe_dump(yaml_dict, f, default_flow_style=False) yaml.safe_dump(yaml_dict, f, default_flow_style=False)
win_msg(_("App setting file created")) win_msg(_("App setting file created"))
os.system('mv "'+ app_final_path +'/manifest.json" "'+ app_final_path +'/scripts" '+ app_setting_path) os.system('mv "'+ app_final_path +'/manifest.json" "'+ app_final_path +'/scripts" '+ app_setting_path)
# Execute App install script
######################################### if _exec_app_script(step='install', path=app_tmp_folder +'/scripts', var_dict={}, parameters=manifest['parameters']) != 0:
# So much win # #TODO: display script fail messages
######################################### shutil.rmtree(app_setting_path)
win_msg(_("Installation complete")) win_msg(_("Installation complete"))
def app_remove(app, instance=[]): def app_remove(app):
""" """
Remove app Remove app
Keyword argument: Keyword argument:
app -- App(s) to delete app -- App(s) to delete
instance -- App instance number to delete
""" """
lemon_conf_lines = {}
if not instance: if not _is_installed(app):
instance = _installed_instance_number(app) raise YunoHostError(22, _("App is not installed"))
for number in instance: app_final_path = apps_path +'/'+ app
number = str(number) app_dict = app_info(app, raw=True)
unique_app_id = app +'__'+ number
app_final_path = apps_path +'/'+ unique_app_id
app_dict = app_info(app, instance=number, raw=True)
app_settings = app_dict['settings'] app_settings = app_dict['settings']
manifest = app_dict['manifest'] manifest = app_dict['manifest']
script_var_dict = { #TODO: display fail messages from script
'APP_DIR': apps_path +'/'+ unique_app_id,
'APP_ID': unique_app_id
}
_exec_app_script(step='remove', path=app_tmp_folder +'/scripts', var_dict=script_var_dict, parameters=manifest['parameters']) _exec_app_script(step='remove', path=app_tmp_folder +'/scripts', var_dict=script_var_dict, parameters=manifest['parameters'])
win_msg(_("App removed: ")+ unique_app_id) win_msg(_("App removed: ")+ app)
def app_addaccess(apps, users): def app_addaccess(apps, users):
@ -437,20 +412,14 @@ def app_addaccess(apps, users):
if not isinstance(users, list): users = [users] if not isinstance(users, list): users = [users]
if not isinstance(apps, list): apps = [apps] if not isinstance(apps, list): apps = [apps]
installed_apps = os.listdir(apps_setting_path)
lemon_conf_lines = {}
for installed_app in installed_apps:
for app in apps: for app in apps:
if '__' not in app: if not _is_installed(app):
app = app + '__1' raise YunoHostError(22, _("App is not installed"))
if app == installed_app: with open(apps_setting_path + app +'/settings.yml') as f:
with open(apps_setting_path + installed_app +'/settings.yml') as f:
app_settings = yaml.load(f) app_settings = yaml.load(f)
if app_settings['mode'] == 'private': if 'mode' in app_settings and app_settings['mode'] == 'private':
if 'allowed_users' in app_settings: if 'allowed_users' in app_settings:
new_users = app_settings['allowed_users'] new_users = app_settings['allowed_users']
else: else:
@ -465,13 +434,14 @@ def app_addaccess(apps, users):
new_users = new_users +' '+ allowed_user new_users = new_users +' '+ allowed_user
app_settings['allowed_users'] = new_users.strip() app_settings['allowed_users'] = new_users.strip()
with open(apps_setting_path + installed_app +'/settings.yml', 'w') as f: with open(apps_setting_path + app +'/settings.yml', 'w') as f:
yaml.safe_dump(app_settings, f, default_flow_style=False) yaml.safe_dump(app_settings, f, default_flow_style=False)
win_msg(_("App setting file updated")) win_msg(_("App setting file updated"))
lemon_conf_lines[('locationRules', app_settings['domain'], '(?#'+ installed_app +'Z)^'+ app_settings['path'] )] = 'grep( /^$uid$/, qw('+ new_users.strip() +'))' #TODO: create lemon tool
tools_lemon(id=app, access='grant', url=app_settings['domain']+app_settings['path'], value='grep( /^$uid$/, qw('+ new_users.strip() +'))')
lemon_configuration(lemon_conf_lines) tools_lemon(apply=True)
def app_removeaccess(apps, users): def app_removeaccess(apps, users):
@ -487,34 +457,29 @@ def app_removeaccess(apps, users):
if not isinstance(users, list): users = [users] if not isinstance(users, list): users = [users]
if not isinstance(apps, list): apps = [apps] if not isinstance(apps, list): apps = [apps]
installed_apps = os.listdir(apps_setting_path)
lemon_conf_lines = {}
for installed_app in installed_apps:
for app in apps: for app in apps:
new_users = '' new_users = ''
if '__' not in app:
app = app + '__1'
if app == installed_app: if not _is_installed(app):
with open(apps_setting_path + installed_app +'/settings.yml') as f: raise YunoHostError(22, _("App is not installed"))
with open(apps_setting_path + app +'/settings.yml') as f:
app_settings = yaml.load(f) app_settings = yaml.load(f)
if app_settings['mode'] == 'private': if 'mode' in app_settings and app_settings['mode'] == 'private':
if 'allowed_users' in app_settings: if 'allowed_users' in app_settings:
for allowed_user in app_settings['allowed_users'].split(' '): for allowed_user in app_settings['allowed_users'].split(' '):
if allowed_user not in users: if allowed_user not in users:
new_users = new_users +' '+ allowed_user new_users = new_users +' '+ allowed_user
app_settings['allowed_users'] = new_users.strip() app_settings['allowed_users'] = new_users.strip()
with open(apps_setting_path + installed_app +'/settings.yml', 'w') as f: with open(apps_setting_path + app +'/settings.yml', 'w') as f:
yaml.safe_dump(app_settings, f, default_flow_style=False) yaml.safe_dump(app_settings, f, default_flow_style=False)
win_msg(_("App setting file updated")) win_msg(_("App setting file updated"))
lemon_conf_lines[('locationRules', app_settings['domain'], '(?#'+ installed_app +'Z)^'+ app_settings['path'] )] = 'grep( /^$uid$/, qw('+ new_users.strip() +'))' tools_lemon(id=app, access='grant', url=app_settings['domain']+app_settings['path'], value='grep( /^$uid$/, qw('+ new_users.strip() +'))')
lemon_configuration(lemon_conf_lines) tools_lemon(apply=True)
def _extract_app_from_file(path): def _extract_app_from_file(path):
@ -665,6 +630,9 @@ def _installed_instance_number(app, last=False):
if app == installed_app[:installed_app.index('__')]: if app == installed_app[:installed_app.index('__')]:
if int(installed_app[installed_app.index('__') + 2:]) > number: if int(installed_app[installed_app.index('__') + 2:]) > number:
number = int(installed_app[installed_app.index('__') + 2:]) number = int(installed_app[installed_app.index('__') + 2:])
else:
if _is_installed(app):
number = 1
return number return number
@ -677,3 +645,29 @@ def _installed_instance_number(app, last=False):
return sorted(instance_number_list) return sorted(instance_number_list)
def _is_installed(app):
"""
Check if application is installed
Keyword arguments:
app -- id of App to check
Returns:
Boolean
"""
try:
installed_apps = os.listdir(apps_setting_path)
except OSError:
os.makedirs(apps_setting_path)
return False
for installed_app in installed_apps:
if app == installed_app:
return True
else:
continue
return False