mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Clean app system (le retour)
This commit is contained in:
parent
b5f8a8c0fd
commit
b84b7dc8f9
2 changed files with 116 additions and 126 deletions
|
@ -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:
|
||||||
|
|
182
yunohost_app.py
182
yunohost_app.py
|
@ -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'])
|
#TMP: Remove old settings
|
||||||
|
|
||||||
|
|
||||||
#########################################
|
|
||||||
# Write App settings #
|
|
||||||
#########################################
|
|
||||||
|
|
||||||
app_setting_path = apps_setting_path +'/'+ unique_app_id
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue