mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #574 from irina11y/enh-moulinette-error
[enh] Simplify error management
This commit is contained in:
commit
9106ee29ee
28 changed files with 363 additions and 511 deletions
|
@ -30,7 +30,6 @@ import yaml
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
import urlparse
|
import urlparse
|
||||||
import errno
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import glob
|
import glob
|
||||||
import pwd
|
import pwd
|
||||||
|
@ -39,7 +38,7 @@ from collections import OrderedDict
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from moulinette import msignals, m18n, msettings
|
from moulinette import msignals, m18n, msettings
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_json
|
from moulinette.utils.filesystem import read_json
|
||||||
|
|
||||||
|
@ -125,14 +124,12 @@ def app_fetchlist(url=None, name=None):
|
||||||
appslists_to_be_fetched = [name]
|
appslists_to_be_fetched = [name]
|
||||||
operation_logger.success()
|
operation_logger.success()
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('custom_appslist_name_required')
|
||||||
m18n.n('custom_appslist_name_required'))
|
|
||||||
|
|
||||||
# If a name is given, look for an appslist with that name and fetch it
|
# If a name is given, look for an appslist with that name and fetch it
|
||||||
elif name is not None:
|
elif name is not None:
|
||||||
if name not in appslists.keys():
|
if name not in appslists.keys():
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('appslist_unknown', appslist=name)
|
||||||
m18n.n('appslist_unknown', appslist=name))
|
|
||||||
else:
|
else:
|
||||||
appslists_to_be_fetched = [name]
|
appslists_to_be_fetched = [name]
|
||||||
|
|
||||||
|
@ -186,9 +183,7 @@ def app_fetchlist(url=None, name=None):
|
||||||
with open(list_file, "w") as f:
|
with open(list_file, "w") as f:
|
||||||
f.write(appslist)
|
f.write(appslist)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError("Error while writing appslist %s: %s" % (name, str(e)), raw_msg=True)
|
||||||
"Error while writing appslist %s: %s" %
|
|
||||||
(name, str(e)))
|
|
||||||
|
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
appslists[name]["lastUpdate"] = now
|
appslists[name]["lastUpdate"] = now
|
||||||
|
@ -212,7 +207,7 @@ def app_removelist(operation_logger, name):
|
||||||
|
|
||||||
# Make sure we know this appslist
|
# Make sure we know this appslist
|
||||||
if name not in appslists.keys():
|
if name not in appslists.keys():
|
||||||
raise MoulinetteError(errno.ENOENT, m18n.n('appslist_unknown', appslist=name))
|
raise YunohostError('appslist_unknown', appslist=name)
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -343,8 +338,7 @@ def app_info(app, show_status=False, raw=False):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not _is_installed(app):
|
if not _is_installed(app):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_not_installed', app=app)
|
||||||
m18n.n('app_not_installed', app=app))
|
|
||||||
|
|
||||||
app_setting_path = APPS_SETTING_PATH + app
|
app_setting_path = APPS_SETTING_PATH + app
|
||||||
|
|
||||||
|
@ -402,8 +396,7 @@ def app_map(app=None, raw=False, user=None):
|
||||||
|
|
||||||
if app is not None:
|
if app is not None:
|
||||||
if not _is_installed(app):
|
if not _is_installed(app):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_not_installed', app=app)
|
||||||
m18n.n('app_not_installed', app=app))
|
|
||||||
apps = [app, ]
|
apps = [app, ]
|
||||||
else:
|
else:
|
||||||
apps = os.listdir(APPS_SETTING_PATH)
|
apps = os.listdir(APPS_SETTING_PATH)
|
||||||
|
@ -455,11 +448,10 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
||||||
|
|
||||||
installed = _is_installed(app)
|
installed = _is_installed(app)
|
||||||
if not installed:
|
if not installed:
|
||||||
raise MoulinetteError(errno.ENOPKG,
|
raise YunohostError('app_not_installed', app=app)
|
||||||
m18n.n('app_not_installed', app=app))
|
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "change_url")):
|
if not os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "change_url")):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n("app_change_no_change_url_script", app_name=app))
|
raise YunohostError("app_change_no_change_url_script", app_name=app)
|
||||||
|
|
||||||
old_domain = app_setting(app, "domain")
|
old_domain = app_setting(app, "domain")
|
||||||
old_path = app_setting(app, "path")
|
old_path = app_setting(app, "path")
|
||||||
|
@ -471,7 +463,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
||||||
path = normalize_url_path(path)
|
path = normalize_url_path(path)
|
||||||
|
|
||||||
if (domain, path) == (old_domain, old_path):
|
if (domain, path) == (old_domain, old_path):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n("app_change_url_identical_domains", domain=domain, path=path))
|
raise YunohostError("app_change_url_identical_domains", domain=domain, path=path)
|
||||||
|
|
||||||
# WARNING / FIXME : checkurl will modify the settings
|
# WARNING / FIXME : checkurl will modify the settings
|
||||||
# (this is a non intuitive behavior that should be changed)
|
# (this is a non intuitive behavior that should be changed)
|
||||||
|
@ -547,7 +539,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
shell=True).rstrip()
|
shell=True).rstrip()
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n("app_change_url_failed_nginx_reload", nginx_errors=nginx_errors))
|
raise YunohostError("app_change_url_failed_nginx_reload", nginx_errors=nginx_errors)
|
||||||
|
|
||||||
logger.success(m18n.n("app_change_url_success",
|
logger.success(m18n.n("app_change_url_success",
|
||||||
app=app, domain=domain, path=path))
|
app=app, domain=domain, path=path))
|
||||||
|
@ -572,8 +564,8 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
app_list()
|
app_list()
|
||||||
except MoulinetteError:
|
except YunohostError:
|
||||||
raise MoulinetteError(errno.ENODATA, m18n.n('app_no_upgrade'))
|
raise YunohostError('app_no_upgrade')
|
||||||
|
|
||||||
upgraded_apps = []
|
upgraded_apps = []
|
||||||
|
|
||||||
|
@ -593,8 +585,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
logger.info(m18n.n('app_upgrade_app_name', app=app_instance_name))
|
logger.info(m18n.n('app_upgrade_app_name', app=app_instance_name))
|
||||||
installed = _is_installed(app_instance_name)
|
installed = _is_installed(app_instance_name)
|
||||||
if not installed:
|
if not installed:
|
||||||
raise MoulinetteError(errno.ENOPKG,
|
raise YunohostError('app_not_installed', app=app_instance_name)
|
||||||
m18n.n('app_not_installed', app=app_instance_name))
|
|
||||||
|
|
||||||
if app_instance_name in upgraded_apps:
|
if app_instance_name in upgraded_apps:
|
||||||
continue
|
continue
|
||||||
|
@ -684,7 +675,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
operation_logger.success()
|
operation_logger.success()
|
||||||
|
|
||||||
if not upgraded_apps:
|
if not upgraded_apps:
|
||||||
raise MoulinetteError(errno.ENODATA, m18n.n('app_no_upgrade'))
|
raise YunohostError('app_no_upgrade')
|
||||||
|
|
||||||
app_ssowatconf(auth)
|
app_ssowatconf(auth)
|
||||||
|
|
||||||
|
@ -730,12 +721,12 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
||||||
elif os.path.exists(app):
|
elif os.path.exists(app):
|
||||||
manifest, extracted_app_folder = _extract_app_from_file(app)
|
manifest, extracted_app_folder = _extract_app_from_file(app)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_unknown'))
|
raise YunohostError('app_unknown')
|
||||||
status['remote'] = manifest.get('remote', {})
|
status['remote'] = manifest.get('remote', {})
|
||||||
|
|
||||||
# Check ID
|
# Check ID
|
||||||
if 'id' not in manifest or '__' in manifest['id']:
|
if 'id' not in manifest or '__' in manifest['id']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_id_invalid'))
|
raise YunohostError('app_id_invalid')
|
||||||
|
|
||||||
app_id = manifest['id']
|
app_id = manifest['id']
|
||||||
|
|
||||||
|
@ -746,8 +737,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
||||||
instance_number = _installed_instance_number(app_id, last=True) + 1
|
instance_number = _installed_instance_number(app_id, last=True) + 1
|
||||||
if instance_number > 1:
|
if instance_number > 1:
|
||||||
if 'multi_instance' not in manifest or not is_true(manifest['multi_instance']):
|
if 'multi_instance' not in manifest or not is_true(manifest['multi_instance']):
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise YunohostError('app_already_installed', app=app_id)
|
||||||
m18n.n('app_already_installed', app=app_id))
|
|
||||||
|
|
||||||
# Change app_id to the forked app id
|
# Change app_id to the forked app id
|
||||||
app_instance_name = app_id + '__' + str(instance_number)
|
app_instance_name = app_id + '__' + str(instance_number)
|
||||||
|
@ -850,9 +840,9 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
||||||
|
|
||||||
if install_retcode == -1:
|
if install_retcode == -1:
|
||||||
msg = m18n.n('operation_interrupted') + " " + error_msg
|
msg = m18n.n('operation_interrupted') + " " + error_msg
|
||||||
raise MoulinetteError(errno.EINTR, msg)
|
raise YunohostError(msg, raw_msg=True)
|
||||||
msg = error_msg
|
msg = error_msg
|
||||||
raise MoulinetteError(errno.EIO, msg)
|
raise YunohostError(msg, raw_msg=True)
|
||||||
|
|
||||||
# Clean hooks and add new ones
|
# Clean hooks and add new ones
|
||||||
hook_remove(app_instance_name)
|
hook_remove(app_instance_name)
|
||||||
|
@ -888,8 +878,7 @@ def app_remove(operation_logger, auth, app):
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_exec, hook_remove, hook_callback
|
from yunohost.hook import hook_exec, hook_remove, hook_callback
|
||||||
if not _is_installed(app):
|
if not _is_installed(app):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_not_installed', app=app)
|
||||||
m18n.n('app_not_installed', app=app))
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -979,7 +968,7 @@ def app_addaccess(auth, apps, users=[]):
|
||||||
if allowed_user not in allowed_users:
|
if allowed_user not in allowed_users:
|
||||||
try:
|
try:
|
||||||
user_info(auth, allowed_user)
|
user_info(auth, allowed_user)
|
||||||
except MoulinetteError:
|
except YunohostError:
|
||||||
logger.warning(m18n.n('user_unknown', user=allowed_user))
|
logger.warning(m18n.n('user_unknown', user=allowed_user))
|
||||||
continue
|
continue
|
||||||
allowed_users.add(allowed_user)
|
allowed_users.add(allowed_user)
|
||||||
|
@ -1139,21 +1128,17 @@ def app_makedefault(operation_logger, auth, app, domain=None):
|
||||||
domain = app_domain
|
domain = app_domain
|
||||||
operation_logger.related_to.append(('domain',domain))
|
operation_logger.related_to.append(('domain',domain))
|
||||||
elif domain not in domain_list(auth)['domains']:
|
elif domain not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
raise YunohostError('domain_unknown')
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
if '/' in app_map(raw=True)[domain]:
|
if '/' in app_map(raw=True)[domain]:
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise YunohostError('app_make_default_location_already_used', app=app, domain=app_domain, other_app=app_map(raw=True)[domain]["/"]["id"])
|
||||||
m18n.n('app_make_default_location_already_used',
|
|
||||||
app=app, domain=app_domain,
|
|
||||||
other_app=app_map(raw=True)[domain]["/"]["id"]))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
||||||
ssowat_conf = json.loads(str(json_conf.read()))
|
ssowat_conf = json.loads(str(json_conf.read()))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('ssowat_persistent_conf_read_error', error=e.strerror)
|
||||||
m18n.n('ssowat_persistent_conf_read_error', error=e.strerror))
|
|
||||||
except IOError:
|
except IOError:
|
||||||
ssowat_conf = {}
|
ssowat_conf = {}
|
||||||
|
|
||||||
|
@ -1166,8 +1151,7 @@ def app_makedefault(operation_logger, auth, app, domain=None):
|
||||||
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
||||||
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('ssowat_persistent_conf_write_error', error=e.strerror)
|
||||||
m18n.n('ssowat_persistent_conf_write_error', error=e.strerror))
|
|
||||||
|
|
||||||
os.system('chmod 644 /etc/ssowat/conf.json.persistent')
|
os.system('chmod 644 /etc/ssowat/conf.json.persistent')
|
||||||
|
|
||||||
|
@ -1219,8 +1203,7 @@ def app_checkport(port):
|
||||||
if tools_port_available(port):
|
if tools_port_available(port):
|
||||||
logger.success(m18n.n('port_available', port=int(port)))
|
logger.success(m18n.n('port_available', port=int(port)))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('port_unavailable', port=int(port))
|
||||||
m18n.n('port_unavailable', port=int(port)))
|
|
||||||
|
|
||||||
|
|
||||||
def app_register_url(auth, app, domain, path):
|
def app_register_url(auth, app, domain, path):
|
||||||
|
@ -1247,8 +1230,7 @@ def app_register_url(auth, app, domain, path):
|
||||||
if installed:
|
if installed:
|
||||||
settings = _get_app_settings(app)
|
settings = _get_app_settings(app)
|
||||||
if "path" in settings.keys() and "domain" in settings.keys():
|
if "path" in settings.keys() and "domain" in settings.keys():
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_already_installed_cant_change_url')
|
||||||
m18n.n('app_already_installed_cant_change_url'))
|
|
||||||
|
|
||||||
# Check the url is available
|
# Check the url is available
|
||||||
conflicts = _get_conflicting_apps(auth, domain, path)
|
conflicts = _get_conflicting_apps(auth, domain, path)
|
||||||
|
@ -1262,7 +1244,7 @@ def app_register_url(auth, app, domain, path):
|
||||||
app_label=app_label,
|
app_label=app_label,
|
||||||
))
|
))
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_location_unavailable', apps="\n".join(apps)))
|
raise YunohostError('app_location_unavailable', apps="\n".join(apps))
|
||||||
|
|
||||||
app_setting(app, 'domain', value=domain)
|
app_setting(app, 'domain', value=domain)
|
||||||
app_setting(app, 'path', value=path)
|
app_setting(app, 'path', value=path)
|
||||||
|
@ -1300,7 +1282,7 @@ def app_checkurl(auth, url, app=None):
|
||||||
apps_map = app_map(raw=True)
|
apps_map = app_map(raw=True)
|
||||||
|
|
||||||
if domain not in domain_list(auth)['domains']:
|
if domain not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
raise YunohostError('domain_unknown')
|
||||||
|
|
||||||
if domain in apps_map:
|
if domain in apps_map:
|
||||||
# Loop through apps
|
# Loop through apps
|
||||||
|
@ -1310,14 +1292,10 @@ def app_checkurl(auth, url, app=None):
|
||||||
installed = True
|
installed = True
|
||||||
continue
|
continue
|
||||||
if path == p:
|
if path == p:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_location_already_used', app=a["id"], path=path)
|
||||||
m18n.n('app_location_already_used',
|
|
||||||
app=a["id"], path=path))
|
|
||||||
# can't install "/a/b/" if "/a/" exists
|
# can't install "/a/b/" if "/a/" exists
|
||||||
elif path.startswith(p) or p.startswith(path):
|
elif path.startswith(p) or p.startswith(path):
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('app_location_install_failed', other_path=p, other_app=a['id'])
|
||||||
m18n.n('app_location_install_failed',
|
|
||||||
other_path=p, other_app=a['id']))
|
|
||||||
|
|
||||||
if app is not None and not installed:
|
if app is not None and not installed:
|
||||||
app_setting(app, 'domain', value=domain)
|
app_setting(app, 'domain', value=domain)
|
||||||
|
@ -1349,10 +1327,10 @@ def app_initdb(user, password=None, db=None, sql=None):
|
||||||
mysql_root_pwd = open('/etc/yunohost/mysql').read().rstrip()
|
mysql_root_pwd = open('/etc/yunohost/mysql').read().rstrip()
|
||||||
mysql_command = 'mysql -u root -p%s -e "CREATE DATABASE %s ; GRANT ALL PRIVILEGES ON %s.* TO \'%s\'@localhost IDENTIFIED BY \'%s\';"' % (mysql_root_pwd, db, db, user, password)
|
mysql_command = 'mysql -u root -p%s -e "CREATE DATABASE %s ; GRANT ALL PRIVILEGES ON %s.* TO \'%s\'@localhost IDENTIFIED BY \'%s\';"' % (mysql_root_pwd, db, db, user, password)
|
||||||
if os.system(mysql_command) != 0:
|
if os.system(mysql_command) != 0:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('mysql_db_creation_failed'))
|
raise YunohostError('mysql_db_creation_failed')
|
||||||
if sql is not None:
|
if sql is not None:
|
||||||
if os.system('mysql -u %s -p%s %s < %s' % (user, password, db, sql)) != 0:
|
if os.system('mysql -u %s -p%s %s < %s' % (user, password, db, sql)) != 0:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('mysql_db_init_failed'))
|
raise YunohostError('mysql_db_init_failed')
|
||||||
|
|
||||||
if return_pwd:
|
if return_pwd:
|
||||||
return password
|
return password
|
||||||
|
@ -1458,8 +1436,7 @@ def app_ssowatconf(auth):
|
||||||
def app_change_label(auth, app, new_label):
|
def app_change_label(auth, app, new_label):
|
||||||
installed = _is_installed(app)
|
installed = _is_installed(app)
|
||||||
if not installed:
|
if not installed:
|
||||||
raise MoulinetteError(errno.ENOPKG,
|
raise YunohostError('app_not_installed', app=app)
|
||||||
m18n.n('app_not_installed', app=app))
|
|
||||||
|
|
||||||
app_setting(app, "label", value=new_label)
|
app_setting(app, "label", value=new_label)
|
||||||
|
|
||||||
|
@ -1495,7 +1472,7 @@ def app_action_run(app, action, args=None):
|
||||||
actions = {x["id"]: x for x in actions}
|
actions = {x["id"]: x for x in actions}
|
||||||
|
|
||||||
if action not in actions:
|
if action not in actions:
|
||||||
raise MoulinetteError(errno.EINVAL, "action '%s' not available for app '%s', available actions are: %s" % (action, app, ", ".join(actions.keys())))
|
raise YunohostError("action '%s' not available for app '%s', available actions are: %s" % (action, app, ", ".join(actions.keys())), raw_msg=True)
|
||||||
|
|
||||||
action_declaration = actions[action]
|
action_declaration = actions[action]
|
||||||
|
|
||||||
|
@ -1533,7 +1510,7 @@ def app_action_run(app, action, args=None):
|
||||||
)
|
)
|
||||||
|
|
||||||
if retcode not in action_declaration.get("accepted_return_codes", [0]):
|
if retcode not in action_declaration.get("accepted_return_codes", [0]):
|
||||||
raise MoulinetteError(retcode, "Error while executing action '%s' of app '%s': return code %s" % (action, app, retcode))
|
raise YunohostError("Error while executing action '%s' of app '%s': return code %s" % (action, app, retcode), raw_msg=True)
|
||||||
|
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
|
@ -1640,8 +1617,7 @@ def app_config_apply(app, args):
|
||||||
|
|
||||||
installed = _is_installed(app)
|
installed = _is_installed(app)
|
||||||
if not installed:
|
if not installed:
|
||||||
raise MoulinetteError(errno.ENOPKG,
|
raise YunohostError('app_not_installed', app=app)
|
||||||
m18n.n('app_not_installed', app=app))
|
|
||||||
|
|
||||||
config_panel = os.path.join(APPS_SETTING_PATH, app, 'config_panel.json')
|
config_panel = os.path.join(APPS_SETTING_PATH, app, 'config_panel.json')
|
||||||
config_script = os.path.join(APPS_SETTING_PATH, app, 'scripts', 'config')
|
config_script = os.path.join(APPS_SETTING_PATH, app, 'scripts', 'config')
|
||||||
|
@ -1699,8 +1675,7 @@ def _get_app_settings(app_id):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not _is_installed(app_id):
|
if not _is_installed(app_id):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_not_installed', app=app_id)
|
||||||
m18n.n('app_not_installed', app=app_id))
|
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(
|
with open(os.path.join(
|
||||||
APPS_SETTING_PATH, app_id, 'settings.yml')) as f:
|
APPS_SETTING_PATH, app_id, 'settings.yml')) as f:
|
||||||
|
@ -1738,7 +1713,7 @@ def _get_app_status(app_id, format_date=False):
|
||||||
"""
|
"""
|
||||||
app_setting_path = APPS_SETTING_PATH + app_id
|
app_setting_path = APPS_SETTING_PATH + app_id
|
||||||
if not os.path.isdir(app_setting_path):
|
if not os.path.isdir(app_setting_path):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_unknown'))
|
raise YunohostError('app_unknown')
|
||||||
status = {}
|
status = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1803,7 +1778,7 @@ def _extract_app_from_file(path, remove=False):
|
||||||
extract_result = 1
|
extract_result = 1
|
||||||
|
|
||||||
if extract_result != 0:
|
if extract_result != 0:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_extraction_failed'))
|
raise YunohostError('app_extraction_failed')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
extracted_app_folder = APP_TMP_FOLDER
|
extracted_app_folder = APP_TMP_FOLDER
|
||||||
|
@ -1814,10 +1789,9 @@ def _extract_app_from_file(path, remove=False):
|
||||||
manifest = json.loads(str(json_manifest.read()))
|
manifest = json.loads(str(json_manifest.read()))
|
||||||
manifest['lastUpdate'] = int(time.time())
|
manifest['lastUpdate'] = int(time.time())
|
||||||
except IOError:
|
except IOError:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('app_install_files_invalid'))
|
raise YunohostError('app_install_files_invalid')
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_manifest_invalid', error=e.strerror)
|
||||||
m18n.n('app_manifest_invalid', error=e.strerror))
|
|
||||||
|
|
||||||
logger.debug(m18n.n('done'))
|
logger.debug(m18n.n('done'))
|
||||||
|
|
||||||
|
@ -1885,8 +1859,7 @@ def _fetch_app_from_git(app):
|
||||||
'wget', '-qO', app_tmp_archive, tarball_url])
|
'wget', '-qO', app_tmp_archive, tarball_url])
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
logger.exception('unable to download %s', tarball_url)
|
logger.exception('unable to download %s', tarball_url)
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('app_sources_fetch_failed')
|
||||||
m18n.n('app_sources_fetch_failed'))
|
|
||||||
else:
|
else:
|
||||||
manifest, extracted_app_folder = _extract_app_from_file(
|
manifest, extracted_app_folder = _extract_app_from_file(
|
||||||
app_tmp_archive, remove=True)
|
app_tmp_archive, remove=True)
|
||||||
|
@ -1909,11 +1882,9 @@ def _fetch_app_from_git(app):
|
||||||
with open(extracted_app_folder + '/manifest.json') as f:
|
with open(extracted_app_folder + '/manifest.json') as f:
|
||||||
manifest = json.loads(str(f.read()))
|
manifest = json.loads(str(f.read()))
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('app_sources_fetch_failed')
|
||||||
m18n.n('app_sources_fetch_failed'))
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('app_manifest_invalid', error=e.strerror)
|
||||||
m18n.n('app_manifest_invalid', error=e.strerror))
|
|
||||||
else:
|
else:
|
||||||
logger.debug(m18n.n('done'))
|
logger.debug(m18n.n('done'))
|
||||||
|
|
||||||
|
@ -1933,11 +1904,10 @@ def _fetch_app_from_git(app):
|
||||||
app_info['manifest']['lastUpdate'] = app_info['lastUpdate']
|
app_info['manifest']['lastUpdate'] = app_info['lastUpdate']
|
||||||
manifest = app_info['manifest']
|
manifest = app_info['manifest']
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_unknown'))
|
raise YunohostError('app_unknown')
|
||||||
|
|
||||||
if 'git' not in app_info:
|
if 'git' not in app_info:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_unsupported_remote_type')
|
||||||
m18n.n('app_unsupported_remote_type'))
|
|
||||||
url = app_info['git']['url']
|
url = app_info['git']['url']
|
||||||
|
|
||||||
if 'github.com' in url:
|
if 'github.com' in url:
|
||||||
|
@ -1949,8 +1919,7 @@ def _fetch_app_from_git(app):
|
||||||
'wget', '-qO', app_tmp_archive, tarball_url])
|
'wget', '-qO', app_tmp_archive, tarball_url])
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
logger.exception('unable to download %s', tarball_url)
|
logger.exception('unable to download %s', tarball_url)
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('app_sources_fetch_failed')
|
||||||
m18n.n('app_sources_fetch_failed'))
|
|
||||||
else:
|
else:
|
||||||
manifest, extracted_app_folder = _extract_app_from_file(
|
manifest, extracted_app_folder = _extract_app_from_file(
|
||||||
app_tmp_archive, remove=True)
|
app_tmp_archive, remove=True)
|
||||||
|
@ -1966,11 +1935,9 @@ def _fetch_app_from_git(app):
|
||||||
with open(extracted_app_folder + '/manifest.json') as f:
|
with open(extracted_app_folder + '/manifest.json') as f:
|
||||||
manifest = json.loads(str(f.read()))
|
manifest = json.loads(str(f.read()))
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('app_sources_fetch_failed')
|
||||||
m18n.n('app_sources_fetch_failed'))
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('app_manifest_invalid', error=e.strerror)
|
||||||
m18n.n('app_manifest_invalid', error=e.strerror))
|
|
||||||
else:
|
else:
|
||||||
logger.debug(m18n.n('done'))
|
logger.debug(m18n.n('done'))
|
||||||
|
|
||||||
|
@ -2089,7 +2056,7 @@ def _check_manifest_requirements(manifest, app_instance_name):
|
||||||
yunohost_req = requirements.get('yunohost', None)
|
yunohost_req = requirements.get('yunohost', None)
|
||||||
if (not yunohost_req or
|
if (not yunohost_req or
|
||||||
not packages.SpecifierSet(yunohost_req) & '>= 2.3.6'):
|
not packages.SpecifierSet(yunohost_req) & '>= 2.3.6'):
|
||||||
raise MoulinetteError(errno.EINVAL, '{0}{1}'.format(
|
raise YunohostError('{0}{1}'.format(
|
||||||
m18n.g('colon', m18n.n('app_incompatible'), app=app_instance_name),
|
m18n.g('colon', m18n.n('app_incompatible'), app=app_instance_name),
|
||||||
m18n.n('app_package_need_update', app=app_instance_name)))
|
m18n.n('app_package_need_update', app=app_instance_name)))
|
||||||
elif not requirements:
|
elif not requirements:
|
||||||
|
@ -2102,18 +2069,15 @@ def _check_manifest_requirements(manifest, app_instance_name):
|
||||||
versions = packages.get_installed_version(
|
versions = packages.get_installed_version(
|
||||||
*requirements.keys(), strict=True, as_dict=True)
|
*requirements.keys(), strict=True, as_dict=True)
|
||||||
except packages.PackageException as e:
|
except packages.PackageException as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_requirements_failed', error=str(e), app=app_instance_name)
|
||||||
m18n.n('app_requirements_failed',
|
|
||||||
error=str(e), app=app_instance_name))
|
|
||||||
|
|
||||||
# Iterate over requirements
|
# Iterate over requirements
|
||||||
for pkgname, spec in requirements.items():
|
for pkgname, spec in requirements.items():
|
||||||
version = versions[pkgname]
|
version = versions[pkgname]
|
||||||
if version not in packages.SpecifierSet(spec):
|
if version not in packages.SpecifierSet(spec):
|
||||||
raise MoulinetteError(
|
raise YunohostError('app_requirements_unmeet',
|
||||||
errno.EINVAL, m18n.n('app_requirements_unmeet',
|
|
||||||
pkgname=pkgname, version=version,
|
pkgname=pkgname, version=version,
|
||||||
spec=spec, app=app_instance_name))
|
spec=spec, app=app_instance_name)
|
||||||
|
|
||||||
|
|
||||||
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||||
|
@ -2237,36 +2201,27 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
||||||
# Validate argument value
|
# Validate argument value
|
||||||
if (arg_value is None or arg_value == '') \
|
if (arg_value is None or arg_value == '') \
|
||||||
and not arg.get('optional', False):
|
and not arg.get('optional', False):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_argument_required', name=arg_name)
|
||||||
m18n.n('app_argument_required', name=arg_name))
|
|
||||||
elif arg_value is None:
|
elif arg_value is None:
|
||||||
args_dict[arg_name] = ''
|
args_dict[arg_name] = ''
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Validate argument choice
|
# Validate argument choice
|
||||||
if arg_choices and arg_value not in arg_choices:
|
if arg_choices and arg_value not in arg_choices:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_argument_choice_invalid', name=arg_name, choices=', '.join(arg_choices))
|
||||||
m18n.n('app_argument_choice_invalid',
|
|
||||||
name=arg_name, choices=', '.join(arg_choices)))
|
|
||||||
|
|
||||||
# Validate argument type
|
# Validate argument type
|
||||||
if arg_type == 'domain':
|
if arg_type == 'domain':
|
||||||
if arg_value not in domain_list(auth)['domains']:
|
if arg_value not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_argument_invalid', name=arg_name, error=m18n.n('domain_unknown'))
|
||||||
m18n.n('app_argument_invalid',
|
|
||||||
name=arg_name, error=m18n.n('domain_unknown')))
|
|
||||||
elif arg_type == 'user':
|
elif arg_type == 'user':
|
||||||
try:
|
try:
|
||||||
user_info(auth, arg_value)
|
user_info(auth, arg_value)
|
||||||
except MoulinetteError as e:
|
except YunohostError as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_argument_invalid', name=arg_name, error=e.strerror)
|
||||||
m18n.n('app_argument_invalid',
|
|
||||||
name=arg_name, error=e.strerror))
|
|
||||||
elif arg_type == 'app':
|
elif arg_type == 'app':
|
||||||
if not _is_installed(arg_value):
|
if not _is_installed(arg_value):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_argument_invalid', name=arg_name, error=m18n.n('app_unknown'))
|
||||||
m18n.n('app_argument_invalid',
|
|
||||||
name=arg_name, error=m18n.n('app_unknown')))
|
|
||||||
elif arg_type == 'boolean':
|
elif arg_type == 'boolean':
|
||||||
if isinstance(arg_value, bool):
|
if isinstance(arg_value, bool):
|
||||||
arg_value = 1 if arg_value else 0
|
arg_value = 1 if arg_value else 0
|
||||||
|
@ -2276,9 +2231,7 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
||||||
elif str(arg_value).lower() in ["0", "no", "n"]:
|
elif str(arg_value).lower() in ["0", "no", "n"]:
|
||||||
arg_value = 0
|
arg_value = 0
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('app_argument_choice_invalid', name=arg_name, choices='yes, no, y, n, 1, 0')
|
||||||
m18n.n('app_argument_choice_invalid',
|
|
||||||
name=arg_name, choices='yes, no, y, n, 1, 0'))
|
|
||||||
elif arg_type == 'password':
|
elif arg_type == 'password':
|
||||||
from yunohost.utils.password import assert_password_is_strong_enough
|
from yunohost.utils.password import assert_password_is_strong_enough
|
||||||
assert_password_is_strong_enough('user', arg_value)
|
assert_password_is_strong_enough('user', arg_value)
|
||||||
|
@ -2312,7 +2265,7 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
||||||
app_label=app_label,
|
app_label=app_label,
|
||||||
))
|
))
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('app_location_unavailable', apps="\n".join(apps)))
|
raise YunohostError('app_location_unavailable', apps="\n".join(apps))
|
||||||
|
|
||||||
# (We save this normalized path so that the install script have a
|
# (We save this normalized path so that the install script have a
|
||||||
# standard path format to deal with no matter what the user inputted)
|
# standard path format to deal with no matter what the user inputted)
|
||||||
|
@ -2462,8 +2415,7 @@ def _read_appslist_list():
|
||||||
try:
|
try:
|
||||||
appslists = json.loads(appslists_json)
|
appslists = json.loads(appslists_json)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise MoulinetteError(errno.EBADR,
|
raise YunohostError('appslist_corrupted_json', filename=APPSLISTS_JSON)
|
||||||
m18n.n('appslist_corrupted_json', filename=APPSLISTS_JSON))
|
|
||||||
|
|
||||||
return appslists
|
return appslists
|
||||||
|
|
||||||
|
@ -2478,9 +2430,8 @@ def _write_appslist_list(appslist_lists):
|
||||||
with open(APPSLISTS_JSON, "w") as f:
|
with open(APPSLISTS_JSON, "w") as f:
|
||||||
json.dump(appslist_lists, f)
|
json.dump(appslist_lists, f)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError("Error while writing list of appslist %s: %s" %
|
||||||
"Error while writing list of appslist %s: %s" %
|
(APPSLISTS_JSON, str(e)), raw_msg=True)
|
||||||
(APPSLISTS_JSON, str(e)))
|
|
||||||
|
|
||||||
|
|
||||||
def _register_new_appslist(url, name):
|
def _register_new_appslist(url, name):
|
||||||
|
@ -2493,15 +2444,13 @@ def _register_new_appslist(url, name):
|
||||||
|
|
||||||
# Check if name conflicts with an existing list
|
# Check if name conflicts with an existing list
|
||||||
if name in appslist_list:
|
if name in appslist_list:
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise YunohostError('appslist_name_already_tracked', name=name)
|
||||||
m18n.n('appslist_name_already_tracked', name=name))
|
|
||||||
|
|
||||||
# Check if url conflicts with an existing list
|
# Check if url conflicts with an existing list
|
||||||
known_appslist_urls = [appslist["url"] for _, appslist in appslist_list.items()]
|
known_appslist_urls = [appslist["url"] for _, appslist in appslist_list.items()]
|
||||||
|
|
||||||
if url in known_appslist_urls:
|
if url in known_appslist_urls:
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise YunohostError('appslist_url_already_tracked', url=url)
|
||||||
m18n.n('appslist_url_already_tracked', url=url))
|
|
||||||
|
|
||||||
logger.debug("Registering new appslist %s at %s" % (name, url))
|
logger.debug("Registering new appslist %s at %s" % (name, url))
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
import time
|
import time
|
||||||
import tarfile
|
import tarfile
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -38,7 +37,7 @@ from glob import glob
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from moulinette import msignals, m18n
|
from moulinette import msignals, m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils import filesystem
|
from moulinette.utils import filesystem
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_file
|
from moulinette.utils.filesystem import read_file
|
||||||
|
@ -308,14 +307,14 @@ class BackupManager():
|
||||||
Ensure the working directory exists and is empty
|
Ensure the working directory exists and is empty
|
||||||
|
|
||||||
exception:
|
exception:
|
||||||
backup_output_directory_not_empty -- (MoulinetteError) Raised if the
|
backup_output_directory_not_empty -- (YunohostError) Raised if the
|
||||||
directory was given by the user and isn't empty
|
directory was given by the user and isn't empty
|
||||||
|
|
||||||
(TODO) backup_cant_clean_tmp_working_directory -- (MoulinetteError)
|
(TODO) backup_cant_clean_tmp_working_directory -- (YunohostError)
|
||||||
Raised if the working directory isn't empty, is temporary and can't
|
Raised if the working directory isn't empty, is temporary and can't
|
||||||
be automaticcaly cleaned
|
be automaticcaly cleaned
|
||||||
|
|
||||||
(TODO) backup_cant_create_working_directory -- (MoulinetteError) Raised
|
(TODO) backup_cant_create_working_directory -- (YunohostError) Raised
|
||||||
if iyunohost can't create the working directory
|
if iyunohost can't create the working directory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -327,8 +326,7 @@ class BackupManager():
|
||||||
logger.debug("temporary directory for backup '%s' already exists",
|
logger.debug("temporary directory for backup '%s' already exists",
|
||||||
self.work_dir)
|
self.work_dir)
|
||||||
# FIXME May be we should clean the workdir here
|
# FIXME May be we should clean the workdir here
|
||||||
raise MoulinetteError(
|
raise YunohostError('backup_output_directory_not_empty')
|
||||||
errno.EIO, m18n.n('backup_output_directory_not_empty'))
|
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
# Backup target management #
|
# Backup target management #
|
||||||
|
@ -494,7 +492,7 @@ class BackupManager():
|
||||||
copied here
|
copied here
|
||||||
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
"backup_nothings_done" -- (MoulinetteError) This exception is raised if
|
"backup_nothings_done" -- (YunohostError) This exception is raised if
|
||||||
nothing has been listed.
|
nothing has been listed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -507,7 +505,7 @@ class BackupManager():
|
||||||
|
|
||||||
if not successfull_apps and not successfull_system:
|
if not successfull_apps and not successfull_system:
|
||||||
filesystem.rm(self.work_dir, True, True)
|
filesystem.rm(self.work_dir, True, True)
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('backup_nothings_done'))
|
raise YunohostError('backup_nothings_done')
|
||||||
|
|
||||||
# Add unlisted files from backup tmp dir
|
# Add unlisted files from backup tmp dir
|
||||||
self._add_to_list_to_backup('backup.csv')
|
self._add_to_list_to_backup('backup.csv')
|
||||||
|
@ -857,7 +855,7 @@ class RestoreManager():
|
||||||
self.info["system"] = self.info["hooks"]
|
self.info["system"] = self.info["hooks"]
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.debug("unable to load '%s'", info_file, exc_info=1)
|
logger.debug("unable to load '%s'", info_file, exc_info=1)
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('backup_invalid_archive'))
|
raise YunohostError('backup_invalid_archive')
|
||||||
else:
|
else:
|
||||||
logger.debug("restoring from backup '%s' created on %s", self.name,
|
logger.debug("restoring from backup '%s' created on %s", self.name,
|
||||||
datetime.utcfromtimestamp(self.info['created_at']))
|
datetime.utcfromtimestamp(self.info['created_at']))
|
||||||
|
@ -880,8 +878,7 @@ class RestoreManager():
|
||||||
logger.debug("unable to retrieve current_host from the backup",
|
logger.debug("unable to retrieve current_host from the backup",
|
||||||
exc_info=1)
|
exc_info=1)
|
||||||
# FIXME include the current_host by default ?
|
# FIXME include the current_host by default ?
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_invalid_archive')
|
||||||
m18n.n('backup_invalid_archive'))
|
|
||||||
|
|
||||||
logger.debug("executing the post-install...")
|
logger.debug("executing the post-install...")
|
||||||
tools_postinstall(domain, 'yunohost', True)
|
tools_postinstall(domain, 'yunohost', True)
|
||||||
|
@ -1010,8 +1007,7 @@ class RestoreManager():
|
||||||
subprocess.call(['rmdir', self.work_dir])
|
subprocess.call(['rmdir', self.work_dir])
|
||||||
logger.debug("Unmount dir: {}".format(self.work_dir))
|
logger.debug("Unmount dir: {}".format(self.work_dir))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('restore_removing_tmp_dir_failed')
|
||||||
m18n.n('restore_removing_tmp_dir_failed'))
|
|
||||||
elif os.path.isdir(self.work_dir):
|
elif os.path.isdir(self.work_dir):
|
||||||
logger.debug("temporary restore directory '%s' already exists",
|
logger.debug("temporary restore directory '%s' already exists",
|
||||||
self.work_dir)
|
self.work_dir)
|
||||||
|
@ -1019,8 +1015,7 @@ class RestoreManager():
|
||||||
if ret == 0:
|
if ret == 0:
|
||||||
logger.debug("Delete dir: {}".format(self.work_dir))
|
logger.debug("Delete dir: {}".format(self.work_dir))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('restore_removing_tmp_dir_failed')
|
||||||
m18n.n('restore_removing_tmp_dir_failed'))
|
|
||||||
|
|
||||||
filesystem.mkdir(self.work_dir, parents=True)
|
filesystem.mkdir(self.work_dir, parents=True)
|
||||||
|
|
||||||
|
@ -1087,17 +1082,9 @@ class RestoreManager():
|
||||||
return True
|
return True
|
||||||
elif free_space > needed_space:
|
elif free_space > needed_space:
|
||||||
# TODO Add --force options to avoid the error raising
|
# TODO Add --force options to avoid the error raising
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('restore_may_be_not_enough_disk_space', free_space=free_space, needed_space=needed_space, margin=margin)
|
||||||
m18n.n('restore_may_be_not_enough_disk_space',
|
|
||||||
free_space=free_space,
|
|
||||||
needed_space=needed_space,
|
|
||||||
margin=margin))
|
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('restore_not_enough_disk_space', free_space=free_space, needed_space=needed_space, margin=margin)
|
||||||
m18n.n('restore_not_enough_disk_space',
|
|
||||||
free_space=free_space,
|
|
||||||
needed_space=needed_space,
|
|
||||||
margin=margin))
|
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
# "Actual restore" (reverse step of the backup collect part) #
|
# "Actual restore" (reverse step of the backup collect part) #
|
||||||
|
@ -1147,9 +1134,7 @@ class RestoreManager():
|
||||||
|
|
||||||
newlines.append(row)
|
newlines.append(row)
|
||||||
except (IOError, OSError, csv.Error) as e:
|
except (IOError, OSError, csv.Error) as e:
|
||||||
raise MoulinetteError(errno.EIO,m18n.n('error_reading_file',
|
raise YunohostError('error_reading_file', file=backup_csv, error=str(e))
|
||||||
file=backup_csv,
|
|
||||||
error=str(e)))
|
|
||||||
|
|
||||||
if not contains_php5:
|
if not contains_php5:
|
||||||
return
|
return
|
||||||
|
@ -1442,7 +1427,7 @@ class BackupMethod(object):
|
||||||
@property
|
@property
|
||||||
def method_name(self):
|
def method_name(self):
|
||||||
"""Return the string name of a BackupMethod (eg "tar" or "copy")"""
|
"""Return the string name of a BackupMethod (eg "tar" or "copy")"""
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('backup_abstract_method'))
|
raise YunohostError('backup_abstract_method')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -1524,8 +1509,7 @@ class BackupMethod(object):
|
||||||
"""
|
"""
|
||||||
if self.need_mount():
|
if self.need_mount():
|
||||||
if self._recursive_umount(self.work_dir) > 0:
|
if self._recursive_umount(self.work_dir) > 0:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('backup_cleaning_failed')
|
||||||
m18n.n('backup_cleaning_failed'))
|
|
||||||
|
|
||||||
if self.manager.is_tmp_work_dir:
|
if self.manager.is_tmp_work_dir:
|
||||||
filesystem.rm(self.work_dir, True, True)
|
filesystem.rm(self.work_dir, True, True)
|
||||||
|
@ -1567,8 +1551,7 @@ class BackupMethod(object):
|
||||||
if free_space < backup_size:
|
if free_space < backup_size:
|
||||||
logger.debug('Not enough space at %s (free: %s / needed: %d)',
|
logger.debug('Not enough space at %s (free: %s / needed: %d)',
|
||||||
self.repo, free_space, backup_size)
|
self.repo, free_space, backup_size)
|
||||||
raise MoulinetteError(errno.EIO, m18n.n(
|
raise YunohostError('not_enough_disk_space', path=self.repo)
|
||||||
'not_enough_disk_space', path=self.repo))
|
|
||||||
|
|
||||||
def _organize_files(self):
|
def _organize_files(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1656,12 +1639,10 @@ class BackupMethod(object):
|
||||||
i = msignals.prompt(m18n.n('backup_ask_for_copying_if_needed',
|
i = msignals.prompt(m18n.n('backup_ask_for_copying_if_needed',
|
||||||
answers='y/N', size=str(size)))
|
answers='y/N', size=str(size)))
|
||||||
except NotImplemented:
|
except NotImplemented:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_unable_to_organize_files')
|
||||||
m18n.n('backup_unable_to_organize_files'))
|
|
||||||
else:
|
else:
|
||||||
if i != 'y' and i != 'Y':
|
if i != 'y' and i != 'Y':
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_unable_to_organize_files')
|
||||||
m18n.n('backup_unable_to_organize_files'))
|
|
||||||
|
|
||||||
# Copy unbinded path
|
# Copy unbinded path
|
||||||
logger.debug(m18n.n('backup_copying_to_organize_the_archive',
|
logger.debug(m18n.n('backup_copying_to_organize_the_archive',
|
||||||
|
@ -1751,8 +1732,7 @@ class CopyBackupMethod(BackupMethod):
|
||||||
super(CopyBackupMethod, self).mount()
|
super(CopyBackupMethod, self).mount()
|
||||||
|
|
||||||
if not os.path.isdir(self.repo):
|
if not os.path.isdir(self.repo):
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_no_uncompress_archive_dir')
|
||||||
m18n.n('backup_no_uncompress_archive_dir'))
|
|
||||||
|
|
||||||
filesystem.mkdir(self.work_dir, parent=True)
|
filesystem.mkdir(self.work_dir, parent=True)
|
||||||
ret = subprocess.call(["mount", "-r", "--rbind", self.repo,
|
ret = subprocess.call(["mount", "-r", "--rbind", self.repo,
|
||||||
|
@ -1763,8 +1743,7 @@ class CopyBackupMethod(BackupMethod):
|
||||||
logger.warning(m18n.n("bind_mouting_disable"))
|
logger.warning(m18n.n("bind_mouting_disable"))
|
||||||
subprocess.call(["mountpoint", "-q", dest,
|
subprocess.call(["mountpoint", "-q", dest,
|
||||||
"&&", "umount", "-R", dest])
|
"&&", "umount", "-R", dest])
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_cant_mount_uncompress_archive')
|
||||||
m18n.n('backup_cant_mount_uncompress_archive'))
|
|
||||||
|
|
||||||
|
|
||||||
class TarBackupMethod(BackupMethod):
|
class TarBackupMethod(BackupMethod):
|
||||||
|
@ -1809,8 +1788,7 @@ class TarBackupMethod(BackupMethod):
|
||||||
except:
|
except:
|
||||||
logger.debug("unable to open '%s' for writing",
|
logger.debug("unable to open '%s' for writing",
|
||||||
self._archive_file, exc_info=1)
|
self._archive_file, exc_info=1)
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_archive_open_failed')
|
||||||
m18n.n('backup_archive_open_failed'))
|
|
||||||
|
|
||||||
# Add files to the archive
|
# Add files to the archive
|
||||||
try:
|
try:
|
||||||
|
@ -1821,8 +1799,7 @@ class TarBackupMethod(BackupMethod):
|
||||||
tar.close()
|
tar.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.error(m18n.n('backup_archive_writing_error'), exc_info=1)
|
logger.error(m18n.n('backup_archive_writing_error'), exc_info=1)
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_creation_failed')
|
||||||
m18n.n('backup_creation_failed'))
|
|
||||||
|
|
||||||
# Move info file
|
# Move info file
|
||||||
shutil.copy(os.path.join(self.work_dir, 'info.json'),
|
shutil.copy(os.path.join(self.work_dir, 'info.json'),
|
||||||
|
@ -1850,8 +1827,7 @@ class TarBackupMethod(BackupMethod):
|
||||||
except:
|
except:
|
||||||
logger.debug("cannot open backup archive '%s'",
|
logger.debug("cannot open backup archive '%s'",
|
||||||
self._archive_file, exc_info=1)
|
self._archive_file, exc_info=1)
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_archive_open_failed')
|
||||||
m18n.n('backup_archive_open_failed'))
|
|
||||||
tar.close()
|
tar.close()
|
||||||
|
|
||||||
# Mount the tarball
|
# Mount the tarball
|
||||||
|
@ -1912,12 +1888,10 @@ class BorgBackupMethod(BackupMethod):
|
||||||
super(CopyBackupMethod, self).backup()
|
super(CopyBackupMethod, self).backup()
|
||||||
|
|
||||||
# TODO run borg create command
|
# TODO run borg create command
|
||||||
raise MoulinetteError(
|
raise YunohostError('backup_borg_not_implemented')
|
||||||
errno.EIO, m18n.n('backup_borg_not_implemented'))
|
|
||||||
|
|
||||||
def mount(self, mnt_path):
|
def mount(self, mnt_path):
|
||||||
raise MoulinetteError(
|
raise YunohostError('backup_borg_not_implemented')
|
||||||
errno.EIO, m18n.n('backup_borg_not_implemented'))
|
|
||||||
|
|
||||||
|
|
||||||
class CustomBackupMethod(BackupMethod):
|
class CustomBackupMethod(BackupMethod):
|
||||||
|
@ -1963,8 +1937,7 @@ class CustomBackupMethod(BackupMethod):
|
||||||
ret = hook_callback('backup_method', [self.method],
|
ret = hook_callback('backup_method', [self.method],
|
||||||
args=self._get_args('backup'))
|
args=self._get_args('backup'))
|
||||||
if ret['failed']:
|
if ret['failed']:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_custom_backup_error')
|
||||||
m18n.n('backup_custom_backup_error'))
|
|
||||||
|
|
||||||
def mount(self, restore_manager):
|
def mount(self, restore_manager):
|
||||||
"""
|
"""
|
||||||
|
@ -1977,8 +1950,7 @@ class CustomBackupMethod(BackupMethod):
|
||||||
ret = hook_callback('backup_method', [self.method],
|
ret = hook_callback('backup_method', [self.method],
|
||||||
args=self._get_args('mount'))
|
args=self._get_args('mount'))
|
||||||
if ret['failed']:
|
if ret['failed']:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_custom_mount_error')
|
||||||
m18n.n('backup_custom_mount_error'))
|
|
||||||
|
|
||||||
def _get_args(self, action):
|
def _get_args(self, action):
|
||||||
"""Return the arguments to give to the custom script"""
|
"""Return the arguments to give to the custom script"""
|
||||||
|
@ -2014,8 +1986,7 @@ def backup_create(name=None, description=None, methods=[],
|
||||||
|
|
||||||
# Validate there is no archive with the same name
|
# Validate there is no archive with the same name
|
||||||
if name and name in backup_list()['archives']:
|
if name and name in backup_list()['archives']:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('backup_archive_name_exists')
|
||||||
m18n.n('backup_archive_name_exists'))
|
|
||||||
|
|
||||||
# Validate output_directory option
|
# Validate output_directory option
|
||||||
if output_directory:
|
if output_directory:
|
||||||
|
@ -2025,17 +1996,14 @@ def backup_create(name=None, description=None, methods=[],
|
||||||
if output_directory.startswith(ARCHIVES_PATH) or \
|
if output_directory.startswith(ARCHIVES_PATH) or \
|
||||||
re.match(r'^/(|(bin|boot|dev|etc|lib|root|run|sbin|sys|usr|var)(|/.*))$',
|
re.match(r'^/(|(bin|boot|dev|etc|lib|root|run|sbin|sys|usr|var)(|/.*))$',
|
||||||
output_directory):
|
output_directory):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('backup_output_directory_forbidden')
|
||||||
m18n.n('backup_output_directory_forbidden'))
|
|
||||||
|
|
||||||
# Check that output directory is empty
|
# Check that output directory is empty
|
||||||
if os.path.isdir(output_directory) and no_compress and \
|
if os.path.isdir(output_directory) and no_compress and \
|
||||||
os.listdir(output_directory):
|
os.listdir(output_directory):
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_output_directory_not_empty')
|
||||||
m18n.n('backup_output_directory_not_empty'))
|
|
||||||
elif no_compress:
|
elif no_compress:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('backup_output_directory_required')
|
||||||
m18n.n('backup_output_directory_required'))
|
|
||||||
|
|
||||||
# Define methods (retro-compat)
|
# Define methods (retro-compat)
|
||||||
if not methods:
|
if not methods:
|
||||||
|
@ -2132,7 +2100,7 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
|
||||||
if i == 'y' or i == 'Y':
|
if i == 'y' or i == 'Y':
|
||||||
force = True
|
force = True
|
||||||
if not force:
|
if not force:
|
||||||
raise MoulinetteError(errno.EEXIST, m18n.n('restore_failed'))
|
raise YunohostError('restore_failed')
|
||||||
|
|
||||||
# TODO Partial app restore could not work if ldap is not restored before
|
# TODO Partial app restore could not work if ldap is not restored before
|
||||||
# TODO repair mysql if broken and it's a complete restore
|
# TODO repair mysql if broken and it's a complete restore
|
||||||
|
@ -2159,7 +2127,7 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
|
||||||
if restore_manager.success:
|
if restore_manager.success:
|
||||||
logger.success(m18n.n('restore_complete'))
|
logger.success(m18n.n('restore_complete'))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('restore_nothings_done'))
|
raise YunohostError('restore_nothings_done')
|
||||||
|
|
||||||
return restore_manager.targets.results
|
return restore_manager.targets.results
|
||||||
|
|
||||||
|
@ -2195,7 +2163,7 @@ def backup_list(with_info=False, human_readable=False):
|
||||||
for a in result:
|
for a in result:
|
||||||
try:
|
try:
|
||||||
d[a] = backup_info(a, human_readable=human_readable)
|
d[a] = backup_info(a, human_readable=human_readable)
|
||||||
except MoulinetteError, e:
|
except YunohostError as e:
|
||||||
logger.warning('%s: %s' % (a, e.strerror))
|
logger.warning('%s: %s' % (a, e.strerror))
|
||||||
|
|
||||||
result = d
|
result = d
|
||||||
|
@ -2217,8 +2185,7 @@ def backup_info(name, with_details=False, human_readable=False):
|
||||||
|
|
||||||
# Check file exist (even if it's a broken symlink)
|
# Check file exist (even if it's a broken symlink)
|
||||||
if not os.path.lexists(archive_file):
|
if not os.path.lexists(archive_file):
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_archive_name_unknown', name=name)
|
||||||
m18n.n('backup_archive_name_unknown', name=name))
|
|
||||||
|
|
||||||
# If symlink, retrieve the real path
|
# If symlink, retrieve the real path
|
||||||
if os.path.islink(archive_file):
|
if os.path.islink(archive_file):
|
||||||
|
@ -2226,9 +2193,8 @@ def backup_info(name, with_details=False, human_readable=False):
|
||||||
|
|
||||||
# Raise exception if link is broken (e.g. on unmounted external storage)
|
# Raise exception if link is broken (e.g. on unmounted external storage)
|
||||||
if not os.path.exists(archive_file):
|
if not os.path.exists(archive_file):
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('backup_archive_broken_link',
|
||||||
m18n.n('backup_archive_broken_link',
|
path=archive_file)
|
||||||
path=archive_file))
|
|
||||||
|
|
||||||
info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name)
|
info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name)
|
||||||
|
|
||||||
|
@ -2240,7 +2206,7 @@ def backup_info(name, with_details=False, human_readable=False):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.debug("unable to retrieve '%s' inside the archive",
|
logger.debug("unable to retrieve '%s' inside the archive",
|
||||||
info_file, exc_info=1)
|
info_file, exc_info=1)
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('backup_invalid_archive'))
|
raise YunohostError('backup_invalid_archive')
|
||||||
else:
|
else:
|
||||||
shutil.move(os.path.join(info_dir, 'info.json'), info_file)
|
shutil.move(os.path.join(info_dir, 'info.json'), info_file)
|
||||||
finally:
|
finally:
|
||||||
|
@ -2253,7 +2219,7 @@ def backup_info(name, with_details=False, human_readable=False):
|
||||||
info = json.load(f)
|
info = json.load(f)
|
||||||
except:
|
except:
|
||||||
logger.debug("unable to load '%s'", info_file, exc_info=1)
|
logger.debug("unable to load '%s'", info_file, exc_info=1)
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('backup_invalid_archive'))
|
raise YunohostError('backup_invalid_archive')
|
||||||
|
|
||||||
# Retrieve backup size
|
# Retrieve backup size
|
||||||
size = info.get('size', 0)
|
size = info.get('size', 0)
|
||||||
|
@ -2292,8 +2258,8 @@ def backup_delete(name):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if name not in backup_list()["archives"]:
|
if name not in backup_list()["archives"]:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('backup_archive_name_unknown',
|
raise YunohostError('backup_archive_name_unknown',
|
||||||
name=name))
|
name=name)
|
||||||
|
|
||||||
hook_callback('pre_backup_delete', args=[name])
|
hook_callback('pre_backup_delete', args=[name])
|
||||||
|
|
||||||
|
@ -2320,9 +2286,7 @@ def _create_archive_dir():
|
||||||
""" Create the YunoHost archives directory if doesn't exist """
|
""" Create the YunoHost archives directory if doesn't exist """
|
||||||
if not os.path.isdir(ARCHIVES_PATH):
|
if not os.path.isdir(ARCHIVES_PATH):
|
||||||
if os.path.lexists(ARCHIVES_PATH):
|
if os.path.lexists(ARCHIVES_PATH):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('backup_output_symlink_dir_broken', path=ARCHIVES_PATH)
|
||||||
m18n.n('backup_output_symlink_dir_broken',
|
|
||||||
path=ARCHIVES_PATH))
|
|
||||||
|
|
||||||
os.mkdir(ARCHIVES_PATH, 0750)
|
os.mkdir(ARCHIVES_PATH, 0750)
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import errno
|
|
||||||
import shutil
|
import shutil
|
||||||
import pwd
|
import pwd
|
||||||
import grp
|
import grp
|
||||||
|
@ -37,7 +36,7 @@ from datetime import datetime
|
||||||
|
|
||||||
from yunohost.vendor.acme_tiny.acme_tiny import get_crt as sign_certificate
|
from yunohost.vendor.acme_tiny.acme_tiny import get_crt as sign_certificate
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.utils.network import get_public_ip
|
from yunohost.utils.network import get_public_ip
|
||||||
|
@ -106,8 +105,7 @@ def certificate_status(auth, domain_list, full=False):
|
||||||
for domain in domain_list:
|
for domain in domain_list:
|
||||||
# Is it in Yunohost domain list?
|
# Is it in Yunohost domain list?
|
||||||
if domain not in yunohost_domains_list:
|
if domain not in yunohost_domains_list:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_domain_unknown', domain=domain)
|
||||||
'certmanager_domain_unknown', domain=domain))
|
|
||||||
|
|
||||||
certificates = {}
|
certificates = {}
|
||||||
|
|
||||||
|
@ -172,8 +170,7 @@ def _certificate_install_selfsigned(domain_list, force=False):
|
||||||
status = _get_status(domain)
|
status = _get_status(domain)
|
||||||
|
|
||||||
if status["summary"]["code"] in ('good', 'great'):
|
if status["summary"]["code"] in ('good', 'great'):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_attempt_to_replace_valid_cert', domain=domain)
|
||||||
'certmanager_attempt_to_replace_valid_cert', domain=domain))
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -203,8 +200,7 @@ def _certificate_install_selfsigned(domain_list, force=False):
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logger.warning(out)
|
logger.warning(out)
|
||||||
raise MoulinetteError(
|
raise YunohostError('domain_cert_gen_failed')
|
||||||
errno.EIO, m18n.n('domain_cert_gen_failed'))
|
|
||||||
else:
|
else:
|
||||||
logger.debug(out)
|
logger.debug(out)
|
||||||
|
|
||||||
|
@ -262,14 +258,12 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
|
||||||
for domain in domain_list:
|
for domain in domain_list:
|
||||||
yunohost_domains_list = yunohost.domain.domain_list(auth)['domains']
|
yunohost_domains_list = yunohost.domain.domain_list(auth)['domains']
|
||||||
if domain not in yunohost_domains_list:
|
if domain not in yunohost_domains_list:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_domain_unknown', domain=domain)
|
||||||
'certmanager_domain_unknown', domain=domain))
|
|
||||||
|
|
||||||
# Is it self-signed?
|
# Is it self-signed?
|
||||||
status = _get_status(domain)
|
status = _get_status(domain)
|
||||||
if not force and status["CA_type"]["code"] != "self-signed":
|
if not force and status["CA_type"]["code"] != "self-signed":
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_domain_cert_not_selfsigned', domain=domain)
|
||||||
'certmanager_domain_cert_not_selfsigned', domain=domain))
|
|
||||||
|
|
||||||
if staging:
|
if staging:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
@ -349,25 +343,21 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal
|
||||||
|
|
||||||
# Is it in Yunohost dmomain list?
|
# Is it in Yunohost dmomain list?
|
||||||
if domain not in yunohost.domain.domain_list(auth)['domains']:
|
if domain not in yunohost.domain.domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_domain_unknown', domain=domain)
|
||||||
'certmanager_domain_unknown', domain=domain))
|
|
||||||
|
|
||||||
status = _get_status(domain)
|
status = _get_status(domain)
|
||||||
|
|
||||||
# Does it expire soon?
|
# Does it expire soon?
|
||||||
if status["validity"] > VALIDITY_LIMIT and not force:
|
if status["validity"] > VALIDITY_LIMIT and not force:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_attempt_to_renew_valid_cert', domain=domain)
|
||||||
'certmanager_attempt_to_renew_valid_cert', domain=domain))
|
|
||||||
|
|
||||||
# Does it have a Let's Encrypt cert?
|
# Does it have a Let's Encrypt cert?
|
||||||
if status["CA_type"]["code"] != "lets-encrypt":
|
if status["CA_type"]["code"] != "lets-encrypt":
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_attempt_to_renew_nonLE_cert', domain=domain)
|
||||||
'certmanager_attempt_to_renew_nonLE_cert', domain=domain))
|
|
||||||
|
|
||||||
# Check ACME challenge configured for given domain
|
# Check ACME challenge configured for given domain
|
||||||
if not _check_acme_challenge_configuration(domain):
|
if not _check_acme_challenge_configuration(domain):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_acme_not_configured_for_domain', domain=domain)
|
||||||
'certmanager_acme_not_configured_for_domain', domain=domain))
|
|
||||||
|
|
||||||
if staging:
|
if staging:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
@ -484,8 +474,7 @@ location ^~ '/.well-known/acme-challenge/'
|
||||||
contents = f.read()
|
contents = f.read()
|
||||||
|
|
||||||
if '/.well-known/acme-challenge' in contents:
|
if '/.well-known/acme-challenge' in contents:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_conflicting_nginx_file', filepath=path)
|
||||||
'certmanager_conflicting_nginx_file', filepath=path))
|
|
||||||
|
|
||||||
# Write the conf
|
# Write the conf
|
||||||
if os.path.exists(nginx_conf_file):
|
if os.path.exists(nginx_conf_file):
|
||||||
|
@ -563,25 +552,22 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
|
||||||
CA=certification_authority)
|
CA=certification_authority)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
if "urn:acme:error:rateLimited" in str(e):
|
if "urn:acme:error:rateLimited" in str(e):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_hit_rate_limit', domain=domain)
|
||||||
'certmanager_hit_rate_limit', domain=domain))
|
|
||||||
else:
|
else:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
_display_debug_information(domain)
|
_display_debug_information(domain)
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_cert_signing_failed')
|
||||||
'certmanager_cert_signing_failed'))
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_cert_signing_failed')
|
||||||
'certmanager_cert_signing_failed'))
|
|
||||||
|
|
||||||
import requests # lazy loading this module for performance reasons
|
import requests # lazy loading this module for performance reasons
|
||||||
try:
|
try:
|
||||||
intermediate_certificate = requests.get(INTERMEDIATE_CERTIFICATE_URL, timeout=30).text
|
intermediate_certificate = requests.get(INTERMEDIATE_CERTIFICATE_URL, timeout=30).text
|
||||||
except requests.exceptions.Timeout as e:
|
except requests.exceptions.Timeout as e:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('certmanager_couldnt_fetch_intermediate_cert'))
|
raise YunohostError('certmanager_couldnt_fetch_intermediate_cert')
|
||||||
|
|
||||||
# Now save the key and signed certificate
|
# Now save the key and signed certificate
|
||||||
logger.debug("Saving the key and signed certificate...")
|
logger.debug("Saving the key and signed certificate...")
|
||||||
|
@ -624,8 +610,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
|
||||||
status_summary = _get_status(domain)["summary"]
|
status_summary = _get_status(domain)["summary"]
|
||||||
|
|
||||||
if status_summary["code"] != "great":
|
if status_summary["code"] != "great":
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_certificate_fetching_or_enabling_failed', domain=domain)
|
||||||
'certmanager_certificate_fetching_or_enabling_failed', domain=domain))
|
|
||||||
|
|
||||||
|
|
||||||
def _prepare_certificate_signing_request(domain, key_file, output_folder):
|
def _prepare_certificate_signing_request(domain, key_file, output_folder):
|
||||||
|
@ -658,8 +643,7 @@ def _get_status(domain):
|
||||||
cert_file = os.path.join(CERT_FOLDER, domain, "crt.pem")
|
cert_file = os.path.join(CERT_FOLDER, domain, "crt.pem")
|
||||||
|
|
||||||
if not os.path.isfile(cert_file):
|
if not os.path.isfile(cert_file):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_no_cert_file', domain=domain, file=cert_file)
|
||||||
'certmanager_no_cert_file', domain=domain, file=cert_file))
|
|
||||||
|
|
||||||
from OpenSSL import crypto # lazy loading this module for performance reasons
|
from OpenSSL import crypto # lazy loading this module for performance reasons
|
||||||
try:
|
try:
|
||||||
|
@ -668,8 +652,7 @@ def _get_status(domain):
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc(file=sys.stdout)
|
traceback.print_exc(file=sys.stdout)
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_cannot_read_cert', domain=domain, file=cert_file, reason=exception)
|
||||||
'certmanager_cannot_read_cert', domain=domain, file=cert_file, reason=exception))
|
|
||||||
|
|
||||||
cert_subject = cert.get_subject().CN
|
cert_subject = cert.get_subject().CN
|
||||||
cert_issuer = cert.get_issuer().CN
|
cert_issuer = cert.get_issuer().CN
|
||||||
|
@ -830,13 +813,11 @@ def _check_domain_is_ready_for_ACME(domain):
|
||||||
|
|
||||||
# Check if IP from DNS matches public IP
|
# Check if IP from DNS matches public IP
|
||||||
if not _dns_ip_match_public_ip(public_ip, domain):
|
if not _dns_ip_match_public_ip(public_ip, domain):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_domain_dns_ip_differs_from_public_ip', domain=domain)
|
||||||
'certmanager_domain_dns_ip_differs_from_public_ip', domain=domain))
|
|
||||||
|
|
||||||
# Check if domain seems to be accessible through HTTP?
|
# Check if domain seems to be accessible through HTTP?
|
||||||
if not _domain_is_accessible_through_HTTP(public_ip, domain):
|
if not _domain_is_accessible_through_HTTP(public_ip, domain):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_domain_http_not_working', domain=domain)
|
||||||
'certmanager_domain_http_not_working', domain=domain))
|
|
||||||
|
|
||||||
|
|
||||||
def _get_dns_ip(domain):
|
def _get_dns_ip(domain):
|
||||||
|
@ -845,8 +826,7 @@ def _get_dns_ip(domain):
|
||||||
resolver.nameservers = DNS_RESOLVERS
|
resolver.nameservers = DNS_RESOLVERS
|
||||||
answers = resolver.query(domain, "A")
|
answers = resolver.query(domain, "A")
|
||||||
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
|
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('certmanager_error_no_A_record', domain=domain)
|
||||||
'certmanager_error_no_A_record', domain=domain))
|
|
||||||
|
|
||||||
return str(answers[0])
|
return str(answers[0])
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,9 @@ import requests
|
||||||
import base64
|
import base64
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.tools import Migration
|
from yunohost.tools import Migration
|
||||||
|
@ -29,7 +28,7 @@ class MyMigration(Migration):
|
||||||
try:
|
try:
|
||||||
(domain, private_key_path) = _guess_current_dyndns_domain(dyn_host)
|
(domain, private_key_path) = _guess_current_dyndns_domain(dyn_host)
|
||||||
assert "+157" in private_key_path
|
assert "+157" in private_key_path
|
||||||
except (MoulinetteError, AssertionError):
|
except (YunohostError, AssertionError):
|
||||||
logger.info(m18n.n("migrate_tsig_not_needed"))
|
logger.info(m18n.n("migrate_tsig_not_needed"))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ class MyMigration(Migration):
|
||||||
'public_key_sha512': base64.b64encode(public_key_sha512),
|
'public_key_sha512': base64.b64encode(public_key_sha512),
|
||||||
}, timeout=30)
|
}, timeout=30)
|
||||||
except requests.ConnectionError:
|
except requests.ConnectionError:
|
||||||
raise MoulinetteError(errno.ENETUNREACH, m18n.n('no_internet_connection'))
|
raise YunohostError('no_internet_connection')
|
||||||
|
|
||||||
if r.status_code != 201:
|
if r.status_code != 201:
|
||||||
try:
|
try:
|
||||||
|
@ -70,8 +69,8 @@ class MyMigration(Migration):
|
||||||
# Migration didn't succeed, so we rollback and raise an exception
|
# Migration didn't succeed, so we rollback and raise an exception
|
||||||
os.system("mv /etc/yunohost/dyndns/*+165* /tmp")
|
os.system("mv /etc/yunohost/dyndns/*+165* /tmp")
|
||||||
|
|
||||||
raise MoulinetteError(m18n.n('migrate_tsig_failed', domain=domain,
|
raise YunohostError('migrate_tsig_failed', domain=domain,
|
||||||
error_code=str(r.status_code), error=error))
|
error_code=str(r.status_code), error=error)
|
||||||
|
|
||||||
# remove old certificates
|
# remove old certificates
|
||||||
os.system("mv /etc/yunohost/dyndns/*+157* /tmp")
|
os.system("mv /etc/yunohost/dyndns/*+157* /tmp")
|
||||||
|
|
|
@ -3,7 +3,7 @@ import os
|
||||||
from shutil import copy2
|
from shutil import copy2
|
||||||
|
|
||||||
from moulinette import m18n, msettings
|
from moulinette import m18n, msettings
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.process import check_output, call_async_output
|
from moulinette.utils.process import check_output, call_async_output
|
||||||
from moulinette.utils.filesystem import read_file
|
from moulinette.utils.filesystem import read_file
|
||||||
|
@ -30,7 +30,7 @@ class MyMigration(Migration):
|
||||||
|
|
||||||
def backward(self):
|
def backward(self):
|
||||||
|
|
||||||
raise MoulinetteError(m18n.n("migration_0003_backward_impossible"))
|
raise YunohostError("migration_0003_backward_impossible")
|
||||||
|
|
||||||
def migrate(self):
|
def migrate(self):
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class MyMigration(Migration):
|
||||||
self.apt_dist_upgrade(conf_flags=["old", "miss", "def"])
|
self.apt_dist_upgrade(conf_flags=["old", "miss", "def"])
|
||||||
_run_service_command("start", "mysql")
|
_run_service_command("start", "mysql")
|
||||||
if self.debian_major_version() == 8:
|
if self.debian_major_version() == 8:
|
||||||
raise MoulinetteError(m18n.n("migration_0003_still_on_jessie_after_main_upgrade", log=self.logfile))
|
raise YunohostError("migration_0003_still_on_jessie_after_main_upgrade", log=self.logfile)
|
||||||
|
|
||||||
# Specific upgrade for fail2ban...
|
# Specific upgrade for fail2ban...
|
||||||
logger.info(m18n.n("migration_0003_fail2ban_upgrade"))
|
logger.info(m18n.n("migration_0003_fail2ban_upgrade"))
|
||||||
|
@ -107,11 +107,11 @@ class MyMigration(Migration):
|
||||||
# would still be in 2.x...
|
# would still be in 2.x...
|
||||||
if not self.debian_major_version() == 8 \
|
if not self.debian_major_version() == 8 \
|
||||||
and not self.yunohost_major_version() == 2:
|
and not self.yunohost_major_version() == 2:
|
||||||
raise MoulinetteError(m18n.n("migration_0003_not_jessie"))
|
raise YunohostError("migration_0003_not_jessie")
|
||||||
|
|
||||||
# Have > 1 Go free space on /var/ ?
|
# Have > 1 Go free space on /var/ ?
|
||||||
if free_space_in_directory("/var/") / (1024**3) < 1.0:
|
if free_space_in_directory("/var/") / (1024**3) < 1.0:
|
||||||
raise MoulinetteError(m18n.n("migration_0003_not_enough_free_space"))
|
raise YunohostError("migration_0003_not_enough_free_space")
|
||||||
|
|
||||||
# Check system is up to date
|
# Check system is up to date
|
||||||
# (but we don't if 'stretch' is already in the sources.list ...
|
# (but we don't if 'stretch' is already in the sources.list ...
|
||||||
|
@ -120,7 +120,7 @@ class MyMigration(Migration):
|
||||||
self.apt_update()
|
self.apt_update()
|
||||||
apt_list_upgradable = check_output("apt list --upgradable -a")
|
apt_list_upgradable = check_output("apt list --upgradable -a")
|
||||||
if "upgradable" in apt_list_upgradable:
|
if "upgradable" in apt_list_upgradable:
|
||||||
raise MoulinetteError(m18n.n("migration_0003_system_not_fully_up_to_date"))
|
raise YunohostError("migration_0003_system_not_fully_up_to_date")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def disclaimer(self):
|
def disclaimer(self):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.tools import Migration
|
from yunohost.tools import Migration
|
||||||
|
@ -20,10 +20,10 @@ class MyMigration(Migration):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.package_is_installed("postgresql-9.6"):
|
if not self.package_is_installed("postgresql-9.6"):
|
||||||
raise MoulinetteError(m18n.n("migration_0005_postgresql_96_not_installed"))
|
raise YunohostError("migration_0005_postgresql_96_not_installed")
|
||||||
|
|
||||||
if not space_used_by_directory("/var/lib/postgresql/9.4") > free_space_in_directory("/var/lib/postgresql"):
|
if not space_used_by_directory("/var/lib/postgresql/9.4") > free_space_in_directory("/var/lib/postgresql"):
|
||||||
raise MoulinetteError(m18n.n("migration_0005_not_enough_space", path="/var/lib/postgresql/"))
|
raise YunohostError("migration_0005_not_enough_space", path="/var/lib/postgresql/")
|
||||||
|
|
||||||
subprocess.check_call("service postgresql stop", shell=True)
|
subprocess.check_call("service postgresql stop", shell=True)
|
||||||
subprocess.check_call("pg_dropcluster --stop 9.6 main", shell=True)
|
subprocess.check_call("pg_dropcluster --stop 9.6 main", shell=True)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import string
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.process import run_commands, check_output
|
from moulinette.utils.process import run_commands, check_output
|
||||||
from moulinette.utils.filesystem import append_to_file
|
from moulinette.utils.filesystem import append_to_file
|
||||||
|
|
|
@ -4,7 +4,6 @@ import re
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import mkdir, rm
|
from moulinette.utils.filesystem import mkdir, rm
|
||||||
|
|
||||||
|
@ -12,6 +11,7 @@ from yunohost.tools import Migration
|
||||||
from yunohost.service import service_regen_conf, _get_conf_hashes, \
|
from yunohost.service import service_regen_conf, _get_conf_hashes, \
|
||||||
_calculate_hash, _run_service_command
|
_calculate_hash, _run_service_command
|
||||||
from yunohost.settings import settings_set
|
from yunohost.settings import settings_set
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.migration')
|
logger = getActionLogger('yunohost.migration')
|
||||||
|
|
||||||
|
@ -67,11 +67,11 @@ class MyMigration(Migration):
|
||||||
# Restart ssh and backward if it fail
|
# Restart ssh and backward if it fail
|
||||||
if not _run_service_command('restart', 'ssh'):
|
if not _run_service_command('restart', 'ssh'):
|
||||||
self.backward()
|
self.backward()
|
||||||
raise MoulinetteError(m18n.n("migration_0007_cancel"))
|
raise YunohostError("migration_0007_cancel")
|
||||||
|
|
||||||
def backward(self):
|
def backward(self):
|
||||||
|
|
||||||
# We don't backward completely but it should be enough
|
# We don't backward completely but it should be enough
|
||||||
copyfile('/etc/ssh/sshd_config.bkp', SSHD_CONF)
|
copyfile('/etc/ssh/sshd_config.bkp', SSHD_CONF)
|
||||||
if not _run_service_command('restart', 'ssh'):
|
if not _run_service_command('restart', 'ssh'):
|
||||||
raise MoulinetteError(m18n.n("migration_0007_cannot_restart"))
|
raise YunohostError("migration_0007_cannot_restart")
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from moulinette import m18n
|
|
||||||
from moulinette.core import MoulinetteError
|
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.tools import Migration
|
from yunohost.tools import Migration
|
||||||
from yunohost.service import service_regen_conf, _get_conf_hashes, \
|
from yunohost.service import service_regen_conf, _get_conf_hashes, \
|
||||||
_calculate_hash
|
_calculate_hash
|
||||||
from yunohost.settings import settings_set, settings_get
|
from yunohost.settings import settings_set, settings_get
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.migration')
|
logger = getActionLogger('yunohost.migration')
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ class MyMigration(Migration):
|
||||||
|
|
||||||
def backward(self):
|
def backward(self):
|
||||||
|
|
||||||
raise MoulinetteError(m18n.n("migration_0008_backward_impossible"))
|
raise YunohostError("migration_0008_backward_impossible")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mode(self):
|
def mode(self):
|
||||||
|
|
|
@ -27,10 +27,10 @@ import os
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import yaml
|
import yaml
|
||||||
import errno
|
|
||||||
|
|
||||||
from moulinette import m18n, msettings
|
from moulinette import m18n, msettings
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
import yunohost.certificate
|
import yunohost.certificate
|
||||||
|
@ -78,7 +78,7 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
|
||||||
try:
|
try:
|
||||||
auth.validate_uniqueness({'virtualdomain': domain})
|
auth.validate_uniqueness({'virtualdomain': domain})
|
||||||
except MoulinetteError:
|
except MoulinetteError:
|
||||||
raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))
|
raise YunohostError('domain_exists')
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -87,16 +87,14 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
|
||||||
|
|
||||||
# Do not allow to subscribe to multiple dyndns domains...
|
# Do not allow to subscribe to multiple dyndns domains...
|
||||||
if os.path.exists('/etc/cron.d/yunohost-dyndns'):
|
if os.path.exists('/etc/cron.d/yunohost-dyndns'):
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('domain_dyndns_already_subscribed')
|
||||||
m18n.n('domain_dyndns_already_subscribed'))
|
|
||||||
|
|
||||||
from yunohost.dyndns import dyndns_subscribe, _dyndns_provides
|
from yunohost.dyndns import dyndns_subscribe, _dyndns_provides
|
||||||
|
|
||||||
# Check that this domain can effectively be provided by
|
# Check that this domain can effectively be provided by
|
||||||
# dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st)
|
# dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st)
|
||||||
if not _dyndns_provides("dyndns.yunohost.org", domain):
|
if not _dyndns_provides("dyndns.yunohost.org", domain):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('domain_dyndns_root_unknown')
|
||||||
m18n.n('domain_dyndns_root_unknown'))
|
|
||||||
|
|
||||||
# Actually subscribe
|
# Actually subscribe
|
||||||
dyndns_subscribe(domain=domain)
|
dyndns_subscribe(domain=domain)
|
||||||
|
@ -110,7 +108,7 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
|
||||||
}
|
}
|
||||||
|
|
||||||
if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
|
if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed'))
|
raise YunohostError('domain_creation_failed')
|
||||||
|
|
||||||
# Don't regen these conf if we're still in postinstall
|
# Don't regen these conf if we're still in postinstall
|
||||||
if os.path.exists('/etc/yunohost/installed'):
|
if os.path.exists('/etc/yunohost/installed'):
|
||||||
|
@ -147,11 +145,11 @@ def domain_remove(operation_logger, auth, domain, force=False):
|
||||||
from yunohost.app import app_ssowatconf
|
from yunohost.app import app_ssowatconf
|
||||||
|
|
||||||
if not force and domain not in domain_list(auth)['domains']:
|
if not force and domain not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
raise YunohostError('domain_unknown')
|
||||||
|
|
||||||
# Check domain is not the main domain
|
# Check domain is not the main domain
|
||||||
if domain == _get_maindomain():
|
if domain == _get_maindomain():
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_cannot_remove_main'))
|
raise YunohostError('domain_cannot_remove_main')
|
||||||
|
|
||||||
# Check if apps are installed on the domain
|
# Check if apps are installed on the domain
|
||||||
for app in os.listdir('/etc/yunohost/apps/'):
|
for app in os.listdir('/etc/yunohost/apps/'):
|
||||||
|
@ -162,14 +160,13 @@ def domain_remove(operation_logger, auth, domain, force=False):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if app_domain == domain:
|
if app_domain == domain:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('domain_uninstall_app_first')
|
||||||
m18n.n('domain_uninstall_app_first'))
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
if auth.remove('virtualdomain=' + domain + ',ou=domains') or force:
|
if auth.remove('virtualdomain=' + domain + ',ou=domains') or force:
|
||||||
os.system('rm -rf /etc/yunohost/certs/%s' % domain)
|
os.system('rm -rf /etc/yunohost/certs/%s' % domain)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('domain_deletion_failed'))
|
raise YunohostError('domain_deletion_failed')
|
||||||
|
|
||||||
service_regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix'])
|
service_regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix'])
|
||||||
app_ssowatconf(auth)
|
app_ssowatconf(auth)
|
||||||
|
@ -246,7 +243,7 @@ def _get_conflicting_apps(auth, domain, path):
|
||||||
|
|
||||||
# Abort if domain is unknown
|
# Abort if domain is unknown
|
||||||
if domain not in domain_list(auth)['domains']:
|
if domain not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
raise YunohostError('domain_unknown')
|
||||||
|
|
||||||
# This import cannot be put on top of file because it would create a
|
# This import cannot be put on top of file because it would create a
|
||||||
# recursive import...
|
# recursive import...
|
||||||
|
|
|
@ -29,7 +29,6 @@ import json
|
||||||
import glob
|
import glob
|
||||||
import time
|
import time
|
||||||
import base64
|
import base64
|
||||||
import errno
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
|
@ -39,7 +38,7 @@ from moulinette.utils.filesystem import read_file, write_to_file, rm
|
||||||
from moulinette.utils.network import download_json
|
from moulinette.utils.network import download_json
|
||||||
from moulinette.utils.process import check_output
|
from moulinette.utils.process import check_output
|
||||||
|
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
from yunohost.domain import _get_maindomain, _build_dns_conf
|
from yunohost.domain import _get_maindomain, _build_dns_conf
|
||||||
from yunohost.utils.network import get_public_ip
|
from yunohost.utils.network import get_public_ip
|
||||||
from yunohost.log import is_unit_operation
|
from yunohost.log import is_unit_operation
|
||||||
|
@ -77,9 +76,7 @@ def _dyndns_provides(provider, domain):
|
||||||
dyndomains = download_json('https://%s/domains' % provider, timeout=30)
|
dyndomains = download_json('https://%s/domains' % provider, timeout=30)
|
||||||
except MoulinetteError as e:
|
except MoulinetteError as e:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('dyndns_could_not_check_provide', domain=domain, provider=provider)
|
||||||
m18n.n('dyndns_could_not_check_provide',
|
|
||||||
domain=domain, provider=provider))
|
|
||||||
|
|
||||||
# Extract 'dyndomain' from 'domain', e.g. 'nohost.me' from 'foo.nohost.me'
|
# Extract 'dyndomain' from 'domain', e.g. 'nohost.me' from 'foo.nohost.me'
|
||||||
dyndomain = '.'.join(domain.split('.')[1:])
|
dyndomain = '.'.join(domain.split('.')[1:])
|
||||||
|
@ -106,9 +103,8 @@ def _dyndns_available(provider, domain):
|
||||||
expected_status_code=None)
|
expected_status_code=None)
|
||||||
except MoulinetteError as e:
|
except MoulinetteError as e:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('dyndns_could_not_check_available',
|
||||||
m18n.n('dyndns_could_not_check_available',
|
domain=domain, provider=provider)
|
||||||
domain=domain, provider=provider))
|
|
||||||
|
|
||||||
return r == u"Domain %s is available" % domain
|
return r == u"Domain %s is available" % domain
|
||||||
|
|
||||||
|
@ -130,14 +126,11 @@ def dyndns_subscribe(operation_logger, subscribe_host="dyndns.yunohost.org", dom
|
||||||
|
|
||||||
# Verify if domain is provided by subscribe_host
|
# Verify if domain is provided by subscribe_host
|
||||||
if not _dyndns_provides(subscribe_host, domain):
|
if not _dyndns_provides(subscribe_host, domain):
|
||||||
raise MoulinetteError(errno.ENOENT,
|
raise YunohostError('dyndns_domain_not_provided', domain=domain, provider=subscribe_host)
|
||||||
m18n.n('dyndns_domain_not_provided',
|
|
||||||
domain=domain, provider=subscribe_host))
|
|
||||||
|
|
||||||
# Verify if domain is available
|
# Verify if domain is available
|
||||||
if not _dyndns_available(subscribe_host, domain):
|
if not _dyndns_available(subscribe_host, domain):
|
||||||
raise MoulinetteError(errno.ENOENT,
|
raise YunohostError('dyndns_unavailable', domain=domain)
|
||||||
m18n.n('dyndns_unavailable', domain=domain))
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -161,14 +154,13 @@ def dyndns_subscribe(operation_logger, subscribe_host="dyndns.yunohost.org", dom
|
||||||
try:
|
try:
|
||||||
r = requests.post('https://%s/key/%s?key_algo=hmac-sha512' % (subscribe_host, base64.b64encode(key)), data={'subdomain': domain}, timeout=30)
|
r = requests.post('https://%s/key/%s?key_algo=hmac-sha512' % (subscribe_host, base64.b64encode(key)), data={'subdomain': domain}, timeout=30)
|
||||||
except requests.ConnectionError:
|
except requests.ConnectionError:
|
||||||
raise MoulinetteError(errno.ENETUNREACH, m18n.n('no_internet_connection'))
|
raise YunohostError('no_internet_connection')
|
||||||
if r.status_code != 201:
|
if r.status_code != 201:
|
||||||
try:
|
try:
|
||||||
error = json.loads(r.text)['error']
|
error = json.loads(r.text)['error']
|
||||||
except:
|
except:
|
||||||
error = "Server error, code: %s. (Message: \"%s\")" % (r.status_code, r.text)
|
error = "Server error, code: %s. (Message: \"%s\")" % (r.status_code, r.text)
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('dyndns_registration_failed', error=error)
|
||||||
m18n.n('dyndns_registration_failed', error=error))
|
|
||||||
|
|
||||||
logger.success(m18n.n('dyndns_registered'))
|
logger.success(m18n.n('dyndns_registered'))
|
||||||
|
|
||||||
|
@ -202,7 +194,7 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
|
||||||
keys = glob.glob('/etc/yunohost/dyndns/K{0}.+*.private'.format(domain))
|
keys = glob.glob('/etc/yunohost/dyndns/K{0}.+*.private'.format(domain))
|
||||||
|
|
||||||
if not keys:
|
if not keys:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('dyndns_key_not_found'))
|
raise YunohostError('dyndns_key_not_found')
|
||||||
|
|
||||||
key = keys[0]
|
key = keys[0]
|
||||||
|
|
||||||
|
@ -302,8 +294,7 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
|
||||||
command = ["/usr/bin/nsupdate", "-k", key, DYNDNS_ZONE]
|
command = ["/usr/bin/nsupdate", "-k", key, DYNDNS_ZONE]
|
||||||
subprocess.check_call(command)
|
subprocess.check_call(command)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('dyndns_ip_update_failed')
|
||||||
m18n.n('dyndns_ip_update_failed'))
|
|
||||||
|
|
||||||
logger.success(m18n.n('dyndns_ip_updated'))
|
logger.success(m18n.n('dyndns_ip_updated'))
|
||||||
|
|
||||||
|
@ -329,7 +320,7 @@ def dyndns_removecron():
|
||||||
try:
|
try:
|
||||||
os.remove("/etc/cron.d/yunohost-dyndns")
|
os.remove("/etc/cron.d/yunohost-dyndns")
|
||||||
except:
|
except:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('dyndns_cron_remove_failed'))
|
raise YunohostError('dyndns_cron_remove_failed')
|
||||||
|
|
||||||
logger.success(m18n.n('dyndns_cron_removed'))
|
logger.success(m18n.n('dyndns_cron_removed'))
|
||||||
|
|
||||||
|
@ -359,5 +350,4 @@ def _guess_current_dyndns_domain(dyn_host):
|
||||||
else:
|
else:
|
||||||
return (_domain, path)
|
return (_domain, path)
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('dyndns_no_domain_registered')
|
||||||
m18n.n('dyndns_no_domain_registered'))
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import yaml
|
import yaml
|
||||||
import errno
|
|
||||||
try:
|
try:
|
||||||
import miniupnpc
|
import miniupnpc
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -34,7 +33,7 @@ except ImportError:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils import process
|
from moulinette.utils import process
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.text import prependlines
|
from moulinette.utils.text import prependlines
|
||||||
|
@ -268,7 +267,7 @@ def firewall_reload(skip_upnp=False):
|
||||||
reloaded = True
|
reloaded = True
|
||||||
|
|
||||||
if not reloaded:
|
if not reloaded:
|
||||||
raise MoulinetteError(errno.ESRCH, m18n.n('firewall_reload_failed'))
|
raise YunohostError('firewall_reload_failed')
|
||||||
|
|
||||||
hook_callback('post_iptable_rules',
|
hook_callback('post_iptable_rules',
|
||||||
args=[upnp, os.path.exists("/proc/net/if_inet6")])
|
args=[upnp, os.path.exists("/proc/net/if_inet6")])
|
||||||
|
@ -338,7 +337,7 @@ def firewall_upnp(action='status', no_refresh=False):
|
||||||
if action == 'status':
|
if action == 'status':
|
||||||
no_refresh = True
|
no_refresh = True
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('action_invalid', action=action))
|
raise YunohostError('action_invalid', action=action)
|
||||||
|
|
||||||
# Refresh port mapping using UPnP
|
# Refresh port mapping using UPnP
|
||||||
if not no_refresh:
|
if not no_refresh:
|
||||||
|
@ -407,7 +406,7 @@ def firewall_upnp(action='status', no_refresh=False):
|
||||||
firewall_reload(skip_upnp=True)
|
firewall_reload(skip_upnp=True)
|
||||||
|
|
||||||
if action == 'enable' and not enabled:
|
if action == 'enable' and not enabled:
|
||||||
raise MoulinetteError(errno.ENXIO, m18n.n('upnp_port_open_failed'))
|
raise YunohostError('upnp_port_open_failed')
|
||||||
return {'enabled': enabled}
|
return {'enabled': enabled}
|
||||||
|
|
||||||
|
|
||||||
|
@ -419,7 +418,7 @@ def firewall_stop():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if os.system("iptables -w -P INPUT ACCEPT") != 0:
|
if os.system("iptables -w -P INPUT ACCEPT") != 0:
|
||||||
raise MoulinetteError(errno.ESRCH, m18n.n('iptables_unavailable'))
|
raise YunohostError('iptables_unavailable')
|
||||||
|
|
||||||
os.system("iptables -w -F")
|
os.system("iptables -w -F")
|
||||||
os.system("iptables -w -X")
|
os.system("iptables -w -X")
|
||||||
|
|
|
@ -25,12 +25,11 @@
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import errno
|
|
||||||
import tempfile
|
import tempfile
|
||||||
from glob import iglob
|
from glob import iglob
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils import log
|
from moulinette.utils import log
|
||||||
|
|
||||||
HOOK_FOLDER = '/usr/share/yunohost/hooks/'
|
HOOK_FOLDER = '/usr/share/yunohost/hooks/'
|
||||||
|
@ -112,7 +111,7 @@ def hook_info(action, name):
|
||||||
})
|
})
|
||||||
|
|
||||||
if not hooks:
|
if not hooks:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('hook_name_unknown', name=name))
|
raise YunohostError('hook_name_unknown', name=name)
|
||||||
return {
|
return {
|
||||||
'action': action,
|
'action': action,
|
||||||
'name': name,
|
'name': name,
|
||||||
|
@ -174,7 +173,7 @@ def hook_list(action, list_by='name', show_info=False):
|
||||||
# Add only the name
|
# Add only the name
|
||||||
d.add(name)
|
d.add(name)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('hook_list_by_invalid'))
|
raise YunohostError('hook_list_by_invalid')
|
||||||
|
|
||||||
def _append_folder(d, folder):
|
def _append_folder(d, folder):
|
||||||
# Iterate over and add hook from a folder
|
# Iterate over and add hook from a folder
|
||||||
|
@ -255,8 +254,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
try:
|
try:
|
||||||
hl = hooks_names[n]
|
hl = hooks_names[n]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('hook_name_unknown', n)
|
||||||
m18n.n('hook_name_unknown', n))
|
|
||||||
# Iterate over hooks with this name
|
# Iterate over hooks with this name
|
||||||
for h in hl:
|
for h in hl:
|
||||||
# Update hooks dict
|
# Update hooks dict
|
||||||
|
@ -282,7 +280,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
path=path, args=args)
|
path=path, args=args)
|
||||||
hook_exec(path, args=hook_args, chdir=chdir, env=env,
|
hook_exec(path, args=hook_args, chdir=chdir, env=env,
|
||||||
no_trace=no_trace, raise_on_error=True)
|
no_trace=no_trace, raise_on_error=True)
|
||||||
except MoulinetteError as e:
|
except YunohostError as e:
|
||||||
state = 'failed'
|
state = 'failed'
|
||||||
logger.error(e.strerror, exc_info=1)
|
logger.error(e.strerror, exc_info=1)
|
||||||
post_callback(name=name, priority=priority, path=path,
|
post_callback(name=name, priority=priority, path=path,
|
||||||
|
@ -319,7 +317,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
||||||
if path[0] != '/':
|
if path[0] != '/':
|
||||||
path = os.path.realpath(path)
|
path = os.path.realpath(path)
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
raise MoulinetteError(errno.EIO, m18n.g('file_not_exist', path=path))
|
raise YunohostError('file_not_exist', path=path)
|
||||||
|
|
||||||
# Construct command variables
|
# Construct command variables
|
||||||
cmd_args = ''
|
cmd_args = ''
|
||||||
|
@ -384,14 +382,12 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
||||||
# Check and return process' return code
|
# Check and return process' return code
|
||||||
if returncode is None:
|
if returncode is None:
|
||||||
if raise_on_error:
|
if raise_on_error:
|
||||||
raise MoulinetteError(
|
raise YunohostError('hook_exec_not_terminated', path=path)
|
||||||
errno.EIO, m18n.n('hook_exec_not_terminated', path=path))
|
|
||||||
else:
|
else:
|
||||||
logger.error(m18n.n('hook_exec_not_terminated', path=path))
|
logger.error(m18n.n('hook_exec_not_terminated', path=path))
|
||||||
return 1
|
return 1
|
||||||
elif raise_on_error and returncode != 0:
|
elif raise_on_error and returncode != 0:
|
||||||
raise MoulinetteError(
|
raise YunohostError('hook_exec_failed', path=path)
|
||||||
errno.EIO, m18n.n('hook_exec_failed', path=path))
|
|
||||||
return returncode
|
return returncode
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
import errno
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -34,7 +33,7 @@ from logging import FileHandler, getLogger, Formatter
|
||||||
from sys import exc_info
|
from sys import exc_info
|
||||||
|
|
||||||
from moulinette import m18n, msettings
|
from moulinette import m18n, msettings
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_file
|
from moulinette.utils.filesystem import read_file
|
||||||
|
|
||||||
|
@ -148,8 +147,7 @@ def log_display(path, number=50, share=False):
|
||||||
log_path = base_path + LOG_FILE_EXT
|
log_path = base_path + LOG_FILE_EXT
|
||||||
|
|
||||||
if not os.path.exists(md_path) and not os.path.exists(log_path):
|
if not os.path.exists(md_path) and not os.path.exists(log_path):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('log_does_exists', log=path)
|
||||||
m18n.n('log_does_exists', log=path))
|
|
||||||
|
|
||||||
infos = {}
|
infos = {}
|
||||||
|
|
||||||
|
@ -189,7 +187,7 @@ def log_display(path, number=50, share=False):
|
||||||
if os.path.exists(log_path):
|
if os.path.exists(log_path):
|
||||||
logger.warning(error)
|
logger.warning(error)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, error)
|
raise YunohostError(error)
|
||||||
|
|
||||||
# Display logs if exist
|
# Display logs if exist
|
||||||
if os.path.exists(log_path):
|
if os.path.exists(log_path):
|
||||||
|
|
|
@ -31,14 +31,13 @@ import calendar
|
||||||
import subprocess
|
import subprocess
|
||||||
import xmlrpclib
|
import xmlrpclib
|
||||||
import os.path
|
import os.path
|
||||||
import errno
|
|
||||||
import os
|
import os
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.utils.network import get_public_ip
|
from yunohost.utils.network import get_public_ip
|
||||||
|
@ -83,7 +82,7 @@ def monitor_disk(units=None, mountpoint=None, human_readable=False):
|
||||||
result_dname = dn
|
result_dname = dn
|
||||||
if len(devices) == 0:
|
if len(devices) == 0:
|
||||||
if mountpoint is not None:
|
if mountpoint is not None:
|
||||||
raise MoulinetteError(errno.ENODEV, m18n.n('mountpoint_unknown'))
|
raise YunohostError('mountpoint_unknown')
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# Retrieve monitoring for unit(s)
|
# Retrieve monitoring for unit(s)
|
||||||
|
@ -141,7 +140,7 @@ def monitor_disk(units=None, mountpoint=None, human_readable=False):
|
||||||
for dname in devices_names:
|
for dname in devices_names:
|
||||||
_set(dname, 'not-available')
|
_set(dname, 'not-available')
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('unit_unknown', unit=u))
|
raise YunohostError('unit_unknown', unit=u)
|
||||||
|
|
||||||
if result_dname is not None:
|
if result_dname is not None:
|
||||||
return result[result_dname]
|
return result[result_dname]
|
||||||
|
@ -237,7 +236,7 @@ def monitor_network(units=None, human_readable=False):
|
||||||
'gateway': gateway,
|
'gateway': gateway,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('unit_unknown', unit=u))
|
raise YunohostError('unit_unknown', unit=u)
|
||||||
|
|
||||||
if len(units) == 1:
|
if len(units) == 1:
|
||||||
return result[units[0]]
|
return result[units[0]]
|
||||||
|
@ -287,7 +286,7 @@ def monitor_system(units=None, human_readable=False):
|
||||||
elif u == 'infos':
|
elif u == 'infos':
|
||||||
result[u] = json.loads(glances.getSystem())
|
result[u] = json.loads(glances.getSystem())
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('unit_unknown', unit=u))
|
raise YunohostError('unit_unknown', unit=u)
|
||||||
|
|
||||||
if len(units) == 1 and type(result[units[0]]) is not str:
|
if len(units) == 1 and type(result[units[0]]) is not str:
|
||||||
return result[units[0]]
|
return result[units[0]]
|
||||||
|
@ -303,7 +302,7 @@ def monitor_update_stats(period):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if period not in ['day', 'week', 'month']:
|
if period not in ['day', 'week', 'month']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('monitor_period_invalid'))
|
raise YunohostError('monitor_period_invalid')
|
||||||
|
|
||||||
stats = _retrieve_stats(period)
|
stats = _retrieve_stats(period)
|
||||||
if not stats:
|
if not stats:
|
||||||
|
@ -321,7 +320,7 @@ def monitor_update_stats(period):
|
||||||
else:
|
else:
|
||||||
monitor = _monitor_all(p, 0)
|
monitor = _monitor_all(p, 0)
|
||||||
if not monitor:
|
if not monitor:
|
||||||
raise MoulinetteError(errno.ENODATA, m18n.n('monitor_stats_no_update'))
|
raise YunohostError('monitor_stats_no_update')
|
||||||
|
|
||||||
stats['timestamp'].append(time.time())
|
stats['timestamp'].append(time.time())
|
||||||
|
|
||||||
|
@ -386,15 +385,13 @@ def monitor_show_stats(period, date=None):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if period not in ['day', 'week', 'month']:
|
if period not in ['day', 'week', 'month']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('monitor_period_invalid'))
|
raise YunohostError('monitor_period_invalid')
|
||||||
|
|
||||||
result = _retrieve_stats(period, date)
|
result = _retrieve_stats(period, date)
|
||||||
if result is False:
|
if result is False:
|
||||||
raise MoulinetteError(errno.ENOENT,
|
raise YunohostError('monitor_stats_file_not_found')
|
||||||
m18n.n('monitor_stats_file_not_found'))
|
|
||||||
elif result is None:
|
elif result is None:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('monitor_stats_period_unavailable')
|
||||||
m18n.n('monitor_stats_period_unavailable'))
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -442,7 +439,7 @@ def monitor_disable():
|
||||||
if glances['loaded'] != 'disabled':
|
if glances['loaded'] != 'disabled':
|
||||||
try:
|
try:
|
||||||
service_disable('glances')
|
service_disable('glances')
|
||||||
except MoulinetteError as e:
|
except YunohostError as e:
|
||||||
logger.warning(e.strerror)
|
logger.warning(e.strerror)
|
||||||
|
|
||||||
# Remove crontab
|
# Remove crontab
|
||||||
|
@ -470,8 +467,8 @@ def _get_glances_api():
|
||||||
from yunohost.service import service_status
|
from yunohost.service import service_status
|
||||||
|
|
||||||
if service_status('glances')['status'] != 'running':
|
if service_status('glances')['status'] != 'running':
|
||||||
raise MoulinetteError(errno.EPERM, m18n.n('monitor_not_enabled'))
|
raise YunohostError('monitor_not_enabled')
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('monitor_glances_con_failed'))
|
raise YunohostError('monitor_glances_con_failed')
|
||||||
|
|
||||||
|
|
||||||
def _extract_inet(string, skip_netmask=False, skip_loopback=True):
|
def _extract_inet(string, skip_netmask=False, skip_loopback=True):
|
||||||
|
|
|
@ -28,7 +28,6 @@ import time
|
||||||
import yaml
|
import yaml
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
import errno
|
|
||||||
import shutil
|
import shutil
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ from difflib import unified_diff
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils import log, filesystem
|
from moulinette.utils import log, filesystem
|
||||||
|
|
||||||
from yunohost.log import is_unit_operation
|
from yunohost.log import is_unit_operation
|
||||||
|
@ -85,7 +84,7 @@ def service_add(name, status=None, log=None, runlevel=None, need_lock=False, des
|
||||||
_save_services(services)
|
_save_services(services)
|
||||||
except:
|
except:
|
||||||
# we'll get a logger.warning with more details in _save_services
|
# we'll get a logger.warning with more details in _save_services
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('service_add_failed', service=name))
|
raise YunohostError('service_add_failed', service=name)
|
||||||
|
|
||||||
logger.success(m18n.n('service_added', service=name))
|
logger.success(m18n.n('service_added', service=name))
|
||||||
|
|
||||||
|
@ -103,13 +102,13 @@ def service_remove(name):
|
||||||
try:
|
try:
|
||||||
del services[name]
|
del services[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('service_unknown', service=name))
|
raise YunohostError('service_unknown', service=name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_save_services(services)
|
_save_services(services)
|
||||||
except:
|
except:
|
||||||
# we'll get a logger.warning with more details in _save_services
|
# we'll get a logger.warning with more details in _save_services
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('service_remove_failed', service=name))
|
raise YunohostError('service_remove_failed', service=name)
|
||||||
|
|
||||||
logger.success(m18n.n('service_removed', service=name))
|
logger.success(m18n.n('service_removed', service=name))
|
||||||
|
|
||||||
|
@ -130,10 +129,7 @@ def service_start(names):
|
||||||
logger.success(m18n.n('service_started', service=name))
|
logger.success(m18n.n('service_started', service=name))
|
||||||
else:
|
else:
|
||||||
if service_status(name)['status'] != 'running':
|
if service_status(name)['status'] != 'running':
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('service_start_failed', service=name, logs=_get_journalctl_logs(name))
|
||||||
m18n.n('service_start_failed',
|
|
||||||
service=name,
|
|
||||||
logs=_get_journalctl_logs(name)))
|
|
||||||
logger.debug(m18n.n('service_already_started', service=name))
|
logger.debug(m18n.n('service_already_started', service=name))
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,10 +148,7 @@ def service_stop(names):
|
||||||
logger.success(m18n.n('service_stopped', service=name))
|
logger.success(m18n.n('service_stopped', service=name))
|
||||||
else:
|
else:
|
||||||
if service_status(name)['status'] != 'inactive':
|
if service_status(name)['status'] != 'inactive':
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('service_stop_failed', service=name, logs=_get_journalctl_logs(name))
|
||||||
m18n.n('service_stop_failed',
|
|
||||||
service=name,
|
|
||||||
logs=_get_journalctl_logs(name)))
|
|
||||||
logger.debug(m18n.n('service_already_stopped', service=name))
|
logger.debug(m18n.n('service_already_stopped', service=name))
|
||||||
|
|
||||||
@is_unit_operation()
|
@is_unit_operation()
|
||||||
|
@ -174,10 +167,7 @@ def service_enable(operation_logger, names):
|
||||||
if _run_service_command('enable', name):
|
if _run_service_command('enable', name):
|
||||||
logger.success(m18n.n('service_enabled', service=name))
|
logger.success(m18n.n('service_enabled', service=name))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('service_enable_failed', service=name, logs=_get_journalctl_logs(name))
|
||||||
m18n.n('service_enable_failed',
|
|
||||||
service=name,
|
|
||||||
logs=_get_journalctl_logs(name)))
|
|
||||||
|
|
||||||
|
|
||||||
def service_disable(names):
|
def service_disable(names):
|
||||||
|
@ -194,10 +184,7 @@ def service_disable(names):
|
||||||
if _run_service_command('disable', name):
|
if _run_service_command('disable', name):
|
||||||
logger.success(m18n.n('service_disabled', service=name))
|
logger.success(m18n.n('service_disabled', service=name))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('service_disable_failed', service=name, logs=_get_journalctl_logs(name))
|
||||||
m18n.n('service_disable_failed',
|
|
||||||
service=name,
|
|
||||||
logs=_get_journalctl_logs(name)))
|
|
||||||
|
|
||||||
|
|
||||||
def service_status(names=[]):
|
def service_status(names=[]):
|
||||||
|
@ -220,8 +207,7 @@ def service_status(names=[]):
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
if check_names and name not in services.keys():
|
if check_names and name not in services.keys():
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('service_unknown', service=name)
|
||||||
m18n.n('service_unknown', service=name))
|
|
||||||
|
|
||||||
# this "service" isn't a service actually so we skip it
|
# this "service" isn't a service actually so we skip it
|
||||||
#
|
#
|
||||||
|
@ -320,10 +306,10 @@ def service_log(name, number=50):
|
||||||
services = _get_services()
|
services = _get_services()
|
||||||
|
|
||||||
if name not in services.keys():
|
if name not in services.keys():
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('service_unknown', service=name))
|
raise YunohostError('service_unknown', service=name)
|
||||||
|
|
||||||
if 'log' not in services[name]:
|
if 'log' not in services[name]:
|
||||||
raise MoulinetteError(errno.EPERM, m18n.n('service_no_log', service=name))
|
raise YunohostError('service_no_log', service=name)
|
||||||
|
|
||||||
log_list = services[name]['log']
|
log_list = services[name]['log']
|
||||||
|
|
||||||
|
@ -431,9 +417,8 @@ def service_regen_conf(operation_logger, names=[], with_diff=False, force=False,
|
||||||
names = pre_result['succeed'].keys()
|
names = pre_result['succeed'].keys()
|
||||||
|
|
||||||
if not names:
|
if not names:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('service_regenconf_failed',
|
||||||
m18n.n('service_regenconf_failed',
|
services=', '.join(pre_result['failed']))
|
||||||
services=', '.join(pre_result['failed'])))
|
|
||||||
|
|
||||||
# Set the processing method
|
# Set the processing method
|
||||||
_regen = _process_regen_conf if not dry_run else lambda *a, **k: True
|
_regen = _process_regen_conf if not dry_run else lambda *a, **k: True
|
||||||
|
@ -609,7 +594,7 @@ def _run_service_command(action, service):
|
||||||
"""
|
"""
|
||||||
services = _get_services()
|
services = _get_services()
|
||||||
if service not in services.keys():
|
if service not in services.keys():
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('service_unknown', service=service))
|
raise YunohostError('service_unknown', service=service)
|
||||||
|
|
||||||
possible_actions = ['start', 'stop', 'restart', 'reload', 'enable', 'disable']
|
possible_actions = ['start', 'stop', 'restart', 'reload', 'enable', 'disable']
|
||||||
if action not in possible_actions:
|
if action not in possible_actions:
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.settings')
|
logger = getActionLogger('yunohost.settings')
|
||||||
|
@ -54,8 +53,7 @@ def settings_get(key, full=False):
|
||||||
settings = _get_settings()
|
settings = _get_settings()
|
||||||
|
|
||||||
if key not in settings:
|
if key not in settings:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_key_doesnt_exists', settings_key=key)
|
||||||
'global_settings_key_doesnt_exists', settings_key=key))
|
|
||||||
|
|
||||||
if full:
|
if full:
|
||||||
return settings[key]
|
return settings[key]
|
||||||
|
@ -83,44 +81,39 @@ def settings_set(key, value):
|
||||||
settings = _get_settings()
|
settings = _get_settings()
|
||||||
|
|
||||||
if key not in settings:
|
if key not in settings:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_key_doesnt_exists', settings_key=key)
|
||||||
'global_settings_key_doesnt_exists', settings_key=key))
|
|
||||||
|
|
||||||
key_type = settings[key]["type"]
|
key_type = settings[key]["type"]
|
||||||
|
|
||||||
if key_type == "bool":
|
if key_type == "bool":
|
||||||
if not isinstance(value, bool):
|
if not isinstance(value, bool):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_bad_type_for_setting', setting=key,
|
||||||
'global_settings_bad_type_for_setting', setting=key,
|
received_type=type(value).__name__, expected_type=key_type)
|
||||||
received_type=type(value).__name__, expected_type=key_type))
|
|
||||||
elif key_type == "int":
|
elif key_type == "int":
|
||||||
if not isinstance(value, int) or isinstance(value, bool):
|
if not isinstance(value, int) or isinstance(value, bool):
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
try:
|
try:
|
||||||
value=int(value)
|
value=int(value)
|
||||||
except:
|
except:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_bad_type_for_setting',
|
||||||
'global_settings_bad_type_for_setting', setting=key,
|
setting=key,
|
||||||
received_type=type(value).__name__, expected_type=key_type))
|
received_type=type(value).__name__,
|
||||||
|
expected_type=key_type)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_bad_type_for_setting', setting=key,
|
||||||
'global_settings_bad_type_for_setting', setting=key,
|
received_type=type(value).__name__, expected_type=key_type)
|
||||||
received_type=type(value).__name__, expected_type=key_type))
|
|
||||||
elif key_type == "string":
|
elif key_type == "string":
|
||||||
if not isinstance(value, basestring):
|
if not isinstance(value, basestring):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_bad_type_for_setting', setting=key,
|
||||||
'global_settings_bad_type_for_setting', setting=key,
|
received_type=type(value).__name__, expected_type=key_type)
|
||||||
received_type=type(value).__name__, expected_type=key_type))
|
|
||||||
elif key_type == "enum":
|
elif key_type == "enum":
|
||||||
if value not in settings[key]["choices"]:
|
if value not in settings[key]["choices"]:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_bad_choice_for_enum', setting=key,
|
||||||
'global_settings_bad_choice_for_enum', setting=key,
|
|
||||||
received_type=type(value).__name__,
|
received_type=type(value).__name__,
|
||||||
expected_type=", ".join(settings[key]["choices"])))
|
expected_type=", ".join(settings[key]["choices"]))
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_unknown_type', setting=key,
|
||||||
'global_settings_unknown_type', setting=key,
|
unknown_type=key_type)
|
||||||
unknown_type=key_type))
|
|
||||||
|
|
||||||
settings[key]["value"] = value
|
settings[key]["value"] = value
|
||||||
|
|
||||||
|
@ -138,8 +131,7 @@ def settings_reset(key):
|
||||||
settings = _get_settings()
|
settings = _get_settings()
|
||||||
|
|
||||||
if key not in settings:
|
if key not in settings:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n(
|
raise YunohostError('global_settings_key_doesnt_exists', settings_key=key)
|
||||||
'global_settings_key_doesnt_exists', settings_key=key))
|
|
||||||
|
|
||||||
settings[key]["value"] = settings[key]["default"]
|
settings[key]["value"] = settings[key]["default"]
|
||||||
_save_settings(settings)
|
_save_settings(settings)
|
||||||
|
@ -215,8 +207,7 @@ def _get_settings():
|
||||||
setting_key=key))
|
setting_key=key))
|
||||||
unknown_settings[key] = value
|
unknown_settings[key] = value
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('global_settings_cant_open_settings', reason=e),
|
raise YunohostError('global_settings_cant_open_settings', reason=e)
|
||||||
exc_info=1)
|
|
||||||
|
|
||||||
if unknown_settings:
|
if unknown_settings:
|
||||||
try:
|
try:
|
||||||
|
@ -237,14 +228,10 @@ def _save_settings(settings, location=SETTINGS_PATH):
|
||||||
try:
|
try:
|
||||||
result = json.dumps(settings_without_description, indent=4)
|
result = json.dumps(settings_without_description, indent=4)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('global_settings_cant_serialize_settings', reason=e)
|
||||||
m18n.n('global_settings_cant_serialize_settings', reason=e),
|
|
||||||
exc_info=1)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(location, "w") as settings_fd:
|
with open(location, "w") as settings_fd:
|
||||||
settings_fd.write(result)
|
settings_fd.write(result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError('global_settings_cant_write_settings', reason=e)
|
||||||
m18n.n('global_settings_cant_write_settings', reason=e),
|
|
||||||
exc_info=1)
|
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import errno
|
|
||||||
import pwd
|
import pwd
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.filesystem import read_file, write_to_file, chown, chmod, mkdir
|
from moulinette.utils.filesystem import read_file, write_to_file, chown, chmod, mkdir
|
||||||
|
|
||||||
SSHD_CONFIG_PATH = "/etc/ssh/sshd_config"
|
SSHD_CONFIG_PATH = "/etc/ssh/sshd_config"
|
||||||
|
@ -23,7 +22,7 @@ def user_ssh_allow(auth, username):
|
||||||
# TODO it would be good to support different kind of shells
|
# TODO it would be good to support different kind of shells
|
||||||
|
|
||||||
if not _get_user_for_ssh(auth, username):
|
if not _get_user_for_ssh(auth, username):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('user_unknown', user=username))
|
raise YunohostError('user_unknown', user=username)
|
||||||
|
|
||||||
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'})
|
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'})
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ def user_ssh_disallow(auth, username):
|
||||||
# TODO it would be good to support different kind of shells
|
# TODO it would be good to support different kind of shells
|
||||||
|
|
||||||
if not _get_user_for_ssh(auth, username):
|
if not _get_user_for_ssh(auth, username):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('user_unknown', user=username))
|
raise YunohostError('user_unknown', user=username)
|
||||||
|
|
||||||
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'})
|
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'})
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import requests_mock
|
||||||
import glob
|
import glob
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
from yunohost.app import app_fetchlist, app_removelist, app_listlists, _using_legacy_appslist_system, _migrate_appslist_system, _register_new_appslist
|
from yunohost.app import app_fetchlist, app_removelist, app_listlists, _using_legacy_appslist_system, _migrate_appslist_system, _register_new_appslist
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ def test_appslist_list_register_conflict_name():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_register_new_appslist("https://lol.com/appslist.json", "dummy")
|
_register_new_appslist("https://lol.com/appslist.json", "dummy")
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
_register_new_appslist("https://lol.com/appslist2.json", "dummy")
|
_register_new_appslist("https://lol.com/appslist2.json", "dummy")
|
||||||
|
|
||||||
appslist_dict = app_listlists()
|
appslist_dict = app_listlists()
|
||||||
|
@ -94,7 +94,7 @@ def test_appslist_list_register_conflict_url():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_register_new_appslist("https://lol.com/appslist.json", "dummy")
|
_register_new_appslist("https://lol.com/appslist.json", "dummy")
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
_register_new_appslist("https://lol.com/appslist.json", "plopette")
|
_register_new_appslist("https://lol.com/appslist.json", "plopette")
|
||||||
|
|
||||||
appslist_dict = app_listlists()
|
appslist_dict = app_listlists()
|
||||||
|
@ -161,7 +161,7 @@ def test_appslist_fetch_unknownlist():
|
||||||
|
|
||||||
assert app_listlists() == {}
|
assert app_listlists() == {}
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
app_fetchlist(name="swag")
|
app_fetchlist(name="swag")
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ def test_appslist_fetch_url_but_no_name():
|
||||||
Do a fetchlist with url given, but no name given
|
Do a fetchlist with url given, but no name given
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
app_fetchlist(url=URL_OFFICIAL_APP_LIST)
|
app_fetchlist(url=URL_OFFICIAL_APP_LIST)
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ def test_appslist_remove_unknown():
|
||||||
Attempt to remove an unknown list
|
Attempt to remove an unknown list
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
app_removelist("dummy")
|
app_removelist("dummy")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError, init_authenticator
|
from moulinette.core import init_authenticator
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
from yunohost.app import app_install, app_remove
|
from yunohost.app import app_install, app_remove
|
||||||
from yunohost.domain import _get_maindomain, domain_url_available, _normalize_domain_path
|
from yunohost.domain import _get_maindomain, domain_url_available, _normalize_domain_path
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ def test_urlavailable():
|
||||||
assert domain_url_available(auth, maindomain, "/macnuggets")
|
assert domain_url_available(auth, maindomain, "/macnuggets")
|
||||||
|
|
||||||
# We don't know the domain yolo.swag
|
# We don't know the domain yolo.swag
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
assert domain_url_available(auth, "yolo.swag", "/macnuggets")
|
assert domain_url_available(auth, "yolo.swag", "/macnuggets")
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,13 +55,13 @@ def test_registerurl():
|
||||||
assert not domain_url_available(auth, maindomain, "/urlregisterapp")
|
assert not domain_url_available(auth, maindomain, "/urlregisterapp")
|
||||||
|
|
||||||
# Try installing at same location
|
# Try installing at same location
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
app_install(auth, "./tests/apps/register_url_app_ynh",
|
app_install(auth, "./tests/apps/register_url_app_ynh",
|
||||||
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"))
|
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"))
|
||||||
|
|
||||||
|
|
||||||
def test_registerurl_baddomain():
|
def test_registerurl_baddomain():
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
app_install(auth, "./tests/apps/register_url_app_ynh",
|
app_install(auth, "./tests/apps/register_url_app_ynh",
|
||||||
args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"))
|
args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"))
|
||||||
|
|
|
@ -12,7 +12,7 @@ from yunohost.app import app_install, app_remove, app_ssowatconf
|
||||||
from yunohost.app import _is_installed
|
from yunohost.app import _is_installed
|
||||||
from yunohost.backup import backup_create, backup_restore, backup_list, backup_info, backup_delete
|
from yunohost.backup import backup_create, backup_restore, backup_list, backup_info, backup_delete
|
||||||
from yunohost.domain import _get_maindomain
|
from yunohost.domain import _get_maindomain
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
# Get main domain
|
# Get main domain
|
||||||
maindomain = ""
|
maindomain = ""
|
||||||
|
@ -214,7 +214,7 @@ def test_backup_system_part_that_does_not_exists(mocker):
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
|
|
||||||
# Create the backup
|
# Create the backup
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_create(system=["yolol"], apps=None)
|
backup_create(system=["yolol"], apps=None)
|
||||||
|
|
||||||
m18n.n.assert_any_call('backup_hook_unknown', hook="yolol")
|
m18n.n.assert_any_call('backup_hook_unknown', hook="yolol")
|
||||||
|
@ -295,7 +295,7 @@ def test_backup_script_failure_handling(monkeypatch, mocker):
|
||||||
monkeypatch.setattr("yunohost.backup.hook_exec", custom_hook_exec)
|
monkeypatch.setattr("yunohost.backup.hook_exec", custom_hook_exec)
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_create(system=None, apps=["backup_recommended_app"])
|
backup_create(system=None, apps=["backup_recommended_app"])
|
||||||
|
|
||||||
m18n.n.assert_any_call('backup_app_failed', app='backup_recommended_app')
|
m18n.n.assert_any_call('backup_app_failed', app='backup_recommended_app')
|
||||||
|
@ -315,7 +315,7 @@ def test_backup_not_enough_free_space(monkeypatch, mocker):
|
||||||
|
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_create(system=None, apps=["backup_recommended_app"])
|
backup_create(system=None, apps=["backup_recommended_app"])
|
||||||
|
|
||||||
m18n.n.assert_any_call('not_enough_disk_space', path=ANY)
|
m18n.n.assert_any_call('not_enough_disk_space', path=ANY)
|
||||||
|
@ -327,7 +327,7 @@ def test_backup_app_not_installed(mocker):
|
||||||
|
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_create(system=None, apps=["wordpress"])
|
backup_create(system=None, apps=["wordpress"])
|
||||||
|
|
||||||
m18n.n.assert_any_call("unbackup_app", app="wordpress")
|
m18n.n.assert_any_call("unbackup_app", app="wordpress")
|
||||||
|
@ -343,7 +343,7 @@ def test_backup_app_with_no_backup_script(mocker):
|
||||||
|
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_create(system=None, apps=["backup_recommended_app"])
|
backup_create(system=None, apps=["backup_recommended_app"])
|
||||||
|
|
||||||
m18n.n.assert_any_call("backup_with_no_backup_script_for_app", app="backup_recommended_app")
|
m18n.n.assert_any_call("backup_with_no_backup_script_for_app", app="backup_recommended_app")
|
||||||
|
@ -420,7 +420,7 @@ def test_restore_app_script_failure_handling(monkeypatch, mocker):
|
||||||
|
|
||||||
assert not _is_installed("wordpress")
|
assert not _is_installed("wordpress")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||||
apps=["wordpress"])
|
apps=["wordpress"])
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ def test_restore_app_not_enough_free_space(monkeypatch, mocker):
|
||||||
|
|
||||||
assert not _is_installed("wordpress")
|
assert not _is_installed("wordpress")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||||
apps=["wordpress"])
|
apps=["wordpress"])
|
||||||
|
|
||||||
|
@ -460,7 +460,7 @@ def test_restore_app_not_in_backup(mocker):
|
||||||
|
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||||
apps=["yoloswag"])
|
apps=["yoloswag"])
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ def test_restore_app_already_installed(mocker):
|
||||||
assert _is_installed("wordpress")
|
assert _is_installed("wordpress")
|
||||||
|
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||||
apps=["wordpress"])
|
apps=["wordpress"])
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ def test_restore_archive_with_no_json(mocker):
|
||||||
assert "badbackup" in backup_list()["archives"]
|
assert "badbackup" in backup_list()["archives"]
|
||||||
|
|
||||||
mocker.spy(m18n, "n")
|
mocker.spy(m18n, "n")
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
backup_restore(auth, name="badbackup", force=True)
|
backup_restore(auth, name="badbackup", force=True)
|
||||||
m18n.n.assert_any_call('backup_invalid_archive')
|
m18n.n.assert_any_call('backup_invalid_archive')
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from moulinette.core import init_authenticator
|
||||||
from yunohost.app import app_install, app_change_url, app_remove, app_map
|
from yunohost.app import app_install, app_change_url, app_remove, app_map
|
||||||
from yunohost.domain import _get_maindomain
|
from yunohost.domain import _get_maindomain
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
# Instantiate LDAP Authenticator
|
# Instantiate LDAP Authenticator
|
||||||
AUTH_IDENTIFIER = ('ldap', 'ldap-anonymous')
|
AUTH_IDENTIFIER = ('ldap', 'ldap-anonymous')
|
||||||
|
@ -57,5 +57,5 @@ def test_appchangeurl_sameurl():
|
||||||
install_changeurl_app("/changeurl")
|
install_changeurl_app("/changeurl")
|
||||||
check_changeurl_app("/changeurl")
|
check_changeurl_app("/changeurl")
|
||||||
|
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
app_change_url(auth, "change_url_app", maindomain, "changeurl")
|
app_change_url(auth, "change_url_app", maindomain, "changeurl")
|
||||||
|
|
|
@ -2,7 +2,7 @@ import os
|
||||||
import json
|
import json
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
from yunohost.settings import settings_get, settings_list, _get_settings, \
|
from yunohost.settings import settings_get, settings_list, _get_settings, \
|
||||||
settings_set, settings_reset, settings_reset_all, \
|
settings_set, settings_reset, settings_reset_all, \
|
||||||
|
@ -46,7 +46,7 @@ def test_settings_get_full_enum():
|
||||||
|
|
||||||
|
|
||||||
def test_settings_get_doesnt_exists():
|
def test_settings_get_doesnt_exists():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_get("doesnt.exists")
|
settings_get("doesnt.exists")
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,39 +70,39 @@ def test_settings_set_enum():
|
||||||
|
|
||||||
|
|
||||||
def test_settings_set_doesexit():
|
def test_settings_set_doesexit():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("doesnt.exist", True)
|
settings_set("doesnt.exist", True)
|
||||||
|
|
||||||
|
|
||||||
def test_settings_set_bad_type_bool():
|
def test_settings_set_bad_type_bool():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.bool", 42)
|
settings_set("example.bool", 42)
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.bool", "pouet")
|
settings_set("example.bool", "pouet")
|
||||||
|
|
||||||
|
|
||||||
def test_settings_set_bad_type_int():
|
def test_settings_set_bad_type_int():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.int", True)
|
settings_set("example.int", True)
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.int", "pouet")
|
settings_set("example.int", "pouet")
|
||||||
|
|
||||||
|
|
||||||
def test_settings_set_bad_type_string():
|
def test_settings_set_bad_type_string():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.string", True)
|
settings_set("example.string", True)
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.string", 42)
|
settings_set("example.string", 42)
|
||||||
|
|
||||||
|
|
||||||
def test_settings_set_bad_value_enum():
|
def test_settings_set_bad_value_enum():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.enum", True)
|
settings_set("example.enum", True)
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.enum", "e")
|
settings_set("example.enum", "e")
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.enum", 42)
|
settings_set("example.enum", 42)
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_set("example.enum", "pouet")
|
settings_set("example.enum", "pouet")
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ def test_reset():
|
||||||
|
|
||||||
|
|
||||||
def test_settings_reset_doesexit():
|
def test_settings_reset_doesexit():
|
||||||
with pytest.raises(MoulinetteError):
|
with pytest.raises(YunohostError):
|
||||||
settings_reset("doesnt.exist")
|
settings_reset("doesnt.exist")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import re
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import pwd
|
import pwd
|
||||||
|
@ -40,7 +39,8 @@ import apt
|
||||||
import apt.progress
|
import apt.progress
|
||||||
|
|
||||||
from moulinette import msettings, msignals, m18n
|
from moulinette import msettings, msignals, m18n
|
||||||
from moulinette.core import MoulinetteError, init_authenticator
|
from moulinette.core import init_authenticator
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.process import check_output
|
from moulinette.utils.process import check_output
|
||||||
from moulinette.utils.filesystem import read_json, write_to_json
|
from moulinette.utils.filesystem import read_json, write_to_json
|
||||||
|
@ -112,7 +112,7 @@ def tools_ldapinit():
|
||||||
pwd.getpwnam("admin")
|
pwd.getpwnam("admin")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error(m18n.n('ldap_init_failed_to_create_admin'))
|
logger.error(m18n.n('ldap_init_failed_to_create_admin'))
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('installation_failed'))
|
raise YunohostError('installation_failed')
|
||||||
|
|
||||||
logger.success(m18n.n('ldap_initialized'))
|
logger.success(m18n.n('ldap_initialized'))
|
||||||
return auth
|
return auth
|
||||||
|
@ -139,8 +139,7 @@ def tools_adminpw(auth, new_password, check_strength=True):
|
||||||
auth.update("cn=admin", { "userPassword": new_hash, })
|
auth.update("cn=admin", { "userPassword": new_hash, })
|
||||||
except:
|
except:
|
||||||
logger.exception('unable to change admin password')
|
logger.exception('unable to change admin password')
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('admin_password_change_failed')
|
||||||
m18n.n('admin_password_change_failed'))
|
|
||||||
else:
|
else:
|
||||||
# Write as root password
|
# Write as root password
|
||||||
try:
|
try:
|
||||||
|
@ -176,7 +175,7 @@ def tools_maindomain(operation_logger, auth, new_domain=None):
|
||||||
|
|
||||||
# Check domain exists
|
# Check domain exists
|
||||||
if new_domain not in domain_list(auth)['domains']:
|
if new_domain not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
raise YunohostError('domain_unknown')
|
||||||
|
|
||||||
operation_logger.related_to.append(('domain', new_domain))
|
operation_logger.related_to.append(('domain', new_domain))
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
@ -199,7 +198,7 @@ def tools_maindomain(operation_logger, auth, new_domain=None):
|
||||||
_set_maindomain(new_domain)
|
_set_maindomain(new_domain)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("%s" % e, exc_info=1)
|
logger.warning("%s" % e, exc_info=1)
|
||||||
raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed'))
|
raise YunohostError('maindomain_change_failed')
|
||||||
|
|
||||||
_set_hostname(new_domain)
|
_set_hostname(new_domain)
|
||||||
|
|
||||||
|
@ -248,7 +247,7 @@ def _set_hostname(hostname, pretty_hostname=None):
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logger.warning(command)
|
logger.warning(command)
|
||||||
logger.warning(out)
|
logger.warning(out)
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('domain_hostname_failed'))
|
raise YunohostError('domain_hostname_failed')
|
||||||
else:
|
else:
|
||||||
logger.debug(out)
|
logger.debug(out)
|
||||||
|
|
||||||
|
@ -289,8 +288,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
||||||
|
|
||||||
# Do some checks at first
|
# Do some checks at first
|
||||||
if os.path.isfile('/etc/yunohost/installed'):
|
if os.path.isfile('/etc/yunohost/installed'):
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('yunohost_already_installed')
|
||||||
m18n.n('yunohost_already_installed'))
|
|
||||||
|
|
||||||
# Check password
|
# Check password
|
||||||
if not force_password:
|
if not force_password:
|
||||||
|
@ -319,9 +317,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
||||||
dyndns = True
|
dyndns = True
|
||||||
# If not, abort the postinstall
|
# If not, abort the postinstall
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise YunohostError('dyndns_unavailable', domain=domain)
|
||||||
m18n.n('dyndns_unavailable',
|
|
||||||
domain=domain))
|
|
||||||
else:
|
else:
|
||||||
dyndns = False
|
dyndns = False
|
||||||
else:
|
else:
|
||||||
|
@ -364,8 +360,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
||||||
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
||||||
ssowat_conf = json.loads(str(json_conf.read()))
|
ssowat_conf = json.loads(str(json_conf.read()))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('ssowat_persistent_conf_read_error', error=str(e))
|
||||||
m18n.n('ssowat_persistent_conf_read_error', error=str(e)))
|
|
||||||
except IOError:
|
except IOError:
|
||||||
ssowat_conf = {}
|
ssowat_conf = {}
|
||||||
|
|
||||||
|
@ -378,8 +373,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
||||||
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
||||||
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('ssowat_persistent_conf_write_error', error=str(e))
|
||||||
m18n.n('ssowat_persistent_conf_write_error', error=str(e)))
|
|
||||||
|
|
||||||
os.system('chmod 644 /etc/ssowat/conf.json.persistent')
|
os.system('chmod 644 /etc/ssowat/conf.json.persistent')
|
||||||
|
|
||||||
|
@ -406,8 +400,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logger.warning(out)
|
logger.warning(out)
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('yunohost_ca_creation_failed')
|
||||||
m18n.n('yunohost_ca_creation_failed'))
|
|
||||||
else:
|
else:
|
||||||
logger.debug(out)
|
logger.debug(out)
|
||||||
|
|
||||||
|
@ -483,7 +476,7 @@ def tools_update(ignore_apps=False, ignore_packages=False):
|
||||||
# Update APT cache
|
# Update APT cache
|
||||||
logger.debug(m18n.n('updating_apt_cache'))
|
logger.debug(m18n.n('updating_apt_cache'))
|
||||||
if not cache.update():
|
if not cache.update():
|
||||||
raise MoulinetteError(errno.EPERM, m18n.n('update_cache_failed'))
|
raise YunohostError('update_cache_failed')
|
||||||
|
|
||||||
cache.open(None)
|
cache.open(None)
|
||||||
cache.upgrade(True)
|
cache.upgrade(True)
|
||||||
|
@ -502,7 +495,7 @@ def tools_update(ignore_apps=False, ignore_packages=False):
|
||||||
if not ignore_apps:
|
if not ignore_apps:
|
||||||
try:
|
try:
|
||||||
app_fetchlist()
|
app_fetchlist()
|
||||||
except MoulinetteError:
|
except YunohostError:
|
||||||
# FIXME : silent exception !?
|
# FIXME : silent exception !?
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -633,7 +626,7 @@ def tools_diagnosis(auth, private=False):
|
||||||
diagnosis['system'] = OrderedDict()
|
diagnosis['system'] = OrderedDict()
|
||||||
try:
|
try:
|
||||||
disks = monitor_disk(units=['filesystem'], human_readable=True)
|
disks = monitor_disk(units=['filesystem'], human_readable=True)
|
||||||
except (MoulinetteError, Fault) as e:
|
except (YunohostError, Fault) as e:
|
||||||
logger.warning(m18n.n('diagnosis_monitor_disk_error', error=format(e)), exc_info=1)
|
logger.warning(m18n.n('diagnosis_monitor_disk_error', error=format(e)), exc_info=1)
|
||||||
else:
|
else:
|
||||||
diagnosis['system']['disks'] = {}
|
diagnosis['system']['disks'] = {}
|
||||||
|
@ -649,7 +642,7 @@ def tools_diagnosis(auth, private=False):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
system = monitor_system(units=['cpu', 'memory'], human_readable=True)
|
system = monitor_system(units=['cpu', 'memory'], human_readable=True)
|
||||||
except MoulinetteError as e:
|
except YunohostError as e:
|
||||||
logger.warning(m18n.n('diagnosis_monitor_system_error', error=format(e)), exc_info=1)
|
logger.warning(m18n.n('diagnosis_monitor_system_error', error=format(e)), exc_info=1)
|
||||||
else:
|
else:
|
||||||
diagnosis['system']['memory'] = {
|
diagnosis['system']['memory'] = {
|
||||||
|
@ -675,7 +668,7 @@ def tools_diagnosis(auth, private=False):
|
||||||
# YNH Applications
|
# YNH Applications
|
||||||
try:
|
try:
|
||||||
applications = app_list()['apps']
|
applications = app_list()['apps']
|
||||||
except MoulinetteError as e:
|
except YunohostError as e:
|
||||||
diagnosis['applications'] = m18n.n('diagnosis_no_apps')
|
diagnosis['applications'] = m18n.n('diagnosis_no_apps')
|
||||||
else:
|
else:
|
||||||
diagnosis['applications'] = {}
|
diagnosis['applications'] = {}
|
||||||
|
@ -807,7 +800,7 @@ def tools_migrations_list(pending=False, done=False):
|
||||||
|
|
||||||
# Check for option conflict
|
# Check for option conflict
|
||||||
if pending and done:
|
if pending and done:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n("migrations_list_conflict_pending_done"))
|
raise YunohostError("migrations_list_conflict_pending_done")
|
||||||
|
|
||||||
# Get all migrations
|
# Get all migrations
|
||||||
migrations = _get_migrations_list()
|
migrations = _get_migrations_list()
|
||||||
|
@ -864,7 +857,7 @@ def tools_migrations_migrate(target=None, skip=False, auto=False, accept_disclai
|
||||||
|
|
||||||
# validate input, target must be "0" or a valid number
|
# validate input, target must be "0" or a valid number
|
||||||
elif target != 0 and target not in all_migration_numbers:
|
elif target != 0 and target not in all_migration_numbers:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('migrations_bad_value_for_target', ", ".join(map(str, all_migration_numbers))))
|
raise YunohostError('migrations_bad_value_for_target', ", ".join(map(str, all_migration_numbers)))
|
||||||
|
|
||||||
logger.debug(m18n.n('migrations_current_target', target))
|
logger.debug(m18n.n('migrations_current_target', target))
|
||||||
|
|
||||||
|
@ -1070,8 +1063,8 @@ def _load_migration(migration_file):
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('migrations_error_failed_to_load_migration',
|
raise YunohostError('migrations_error_failed_to_load_migration',
|
||||||
number=number, name=name))
|
number=number, name=name)
|
||||||
|
|
||||||
def _skip_all_migrations():
|
def _skip_all_migrations():
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -27,14 +27,13 @@ import os
|
||||||
import re
|
import re
|
||||||
import pwd
|
import pwd
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
import crypt
|
import crypt
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from moulinette import m18n
|
from moulinette import m18n
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from yunohost.service import service_status
|
from yunohost.service import service_status
|
||||||
from yunohost.log import is_unit_operation
|
from yunohost.log import is_unit_operation
|
||||||
|
@ -71,8 +70,7 @@ def user_list(auth, fields=None):
|
||||||
if attr in keys:
|
if attr in keys:
|
||||||
attrs.append(attr)
|
attrs.append(attr)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('field_invalid', attr)
|
||||||
m18n.n('field_invalid', attr))
|
|
||||||
else:
|
else:
|
||||||
attrs = ['uid', 'cn', 'mail', 'mailuserquota', 'loginShell']
|
attrs = ['uid', 'cn', 'mail', 'mailuserquota', 'loginShell']
|
||||||
|
|
||||||
|
@ -130,7 +128,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
||||||
# Validate uniqueness of username in system users
|
# Validate uniqueness of username in system users
|
||||||
all_existing_usernames = {x.pw_name for x in pwd.getpwall()}
|
all_existing_usernames = {x.pw_name for x in pwd.getpwall()}
|
||||||
if username in all_existing_usernames:
|
if username in all_existing_usernames:
|
||||||
raise MoulinetteError(errno.EEXIST, m18n.n('system_username_exists'))
|
raise YunohostError('system_username_exists')
|
||||||
|
|
||||||
main_domain = _get_maindomain()
|
main_domain = _get_maindomain()
|
||||||
aliases = [
|
aliases = [
|
||||||
|
@ -141,13 +139,11 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
||||||
]
|
]
|
||||||
|
|
||||||
if mail in aliases:
|
if mail in aliases:
|
||||||
raise MoulinetteError(errno.EEXIST,m18n.n('mail_unavailable'))
|
raise YunohostError('mail_unavailable')
|
||||||
|
|
||||||
# Check that the mail domain exists
|
# Check that the mail domain exists
|
||||||
if mail.split("@")[1] not in domain_list(auth)['domains']:
|
if mail.split("@")[1] not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('mail_domain_unknown', domain=mail.split("@")[1])
|
||||||
m18n.n('mail_domain_unknown',
|
|
||||||
domain=mail.split("@")[1]))
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -188,8 +184,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
||||||
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
||||||
ssowat_conf = json.loads(str(json_conf.read()))
|
ssowat_conf = json.loads(str(json_conf.read()))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('ssowat_persistent_conf_read_error', error=e.strerror)
|
||||||
m18n.n('ssowat_persistent_conf_read_error', error=e.strerror))
|
|
||||||
except IOError:
|
except IOError:
|
||||||
ssowat_conf = {}
|
ssowat_conf = {}
|
||||||
|
|
||||||
|
@ -199,8 +194,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
||||||
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
||||||
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise YunohostError('ssowat_persistent_conf_write_error', error=e.strerror)
|
||||||
m18n.n('ssowat_persistent_conf_write_error', error=e.strerror))
|
|
||||||
|
|
||||||
if auth.add('uid=%s,ou=users' % username, attr_dict):
|
if auth.add('uid=%s,ou=users' % username, attr_dict):
|
||||||
# Invalidate passwd to take user creation into account
|
# Invalidate passwd to take user creation into account
|
||||||
|
@ -226,7 +220,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
||||||
|
|
||||||
return {'fullname': fullname, 'username': username, 'mail': mail}
|
return {'fullname': fullname, 'username': username, 'mail': mail}
|
||||||
|
|
||||||
raise MoulinetteError(169, m18n.n('user_creation_failed'))
|
raise YunohostError('user_creation_failed')
|
||||||
|
|
||||||
|
|
||||||
@is_unit_operation([('username', 'user')])
|
@is_unit_operation([('username', 'user')])
|
||||||
|
@ -257,7 +251,7 @@ def user_delete(operation_logger, auth, username, purge=False):
|
||||||
if purge:
|
if purge:
|
||||||
subprocess.call(['rm', '-rf', '/home/{0}'.format(username)])
|
subprocess.call(['rm', '-rf', '/home/{0}'.format(username)])
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(169, m18n.n('user_deletion_failed'))
|
raise YunohostError('user_deletion_failed')
|
||||||
|
|
||||||
app_ssowatconf(auth)
|
app_ssowatconf(auth)
|
||||||
|
|
||||||
|
@ -296,7 +290,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
||||||
# Populate user informations
|
# Populate user informations
|
||||||
result = auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch)
|
result = auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch)
|
||||||
if not result:
|
if not result:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('user_unknown', user=username))
|
raise YunohostError('user_unknown', user=username)
|
||||||
user = result[0]
|
user = result[0]
|
||||||
|
|
||||||
# Get modifications from arguments
|
# Get modifications from arguments
|
||||||
|
@ -327,11 +321,9 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
||||||
]
|
]
|
||||||
auth.validate_uniqueness({'mail': mail})
|
auth.validate_uniqueness({'mail': mail})
|
||||||
if mail[mail.find('@') + 1:] not in domains:
|
if mail[mail.find('@') + 1:] not in domains:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:])
|
||||||
m18n.n('mail_domain_unknown',
|
|
||||||
domain=mail[mail.find('@') + 1:]))
|
|
||||||
if mail in aliases:
|
if mail in aliases:
|
||||||
raise MoulinetteError(errno.EEXIST,m18n.n('mail_unavailable'))
|
raise YunohostError('mail_unavailable')
|
||||||
|
|
||||||
del user['mail'][0]
|
del user['mail'][0]
|
||||||
new_attr_dict['mail'] = [mail] + user['mail']
|
new_attr_dict['mail'] = [mail] + user['mail']
|
||||||
|
@ -342,9 +334,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
||||||
for mail in add_mailalias:
|
for mail in add_mailalias:
|
||||||
auth.validate_uniqueness({'mail': mail})
|
auth.validate_uniqueness({'mail': mail})
|
||||||
if mail[mail.find('@') + 1:] not in domains:
|
if mail[mail.find('@') + 1:] not in domains:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:])
|
||||||
m18n.n('mail_domain_unknown',
|
|
||||||
domain=mail[mail.find('@') + 1:]))
|
|
||||||
user['mail'].append(mail)
|
user['mail'].append(mail)
|
||||||
new_attr_dict['mail'] = user['mail']
|
new_attr_dict['mail'] = user['mail']
|
||||||
|
|
||||||
|
@ -355,8 +345,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
||||||
if len(user['mail']) > 1 and mail in user['mail'][1:]:
|
if len(user['mail']) > 1 and mail in user['mail'][1:]:
|
||||||
user['mail'].remove(mail)
|
user['mail'].remove(mail)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('mail_alias_remove_failed', mail=mail)
|
||||||
m18n.n('mail_alias_remove_failed', mail=mail))
|
|
||||||
new_attr_dict['mail'] = user['mail']
|
new_attr_dict['mail'] = user['mail']
|
||||||
|
|
||||||
if add_mailforward:
|
if add_mailforward:
|
||||||
|
@ -375,8 +364,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
||||||
if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]:
|
if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]:
|
||||||
user['maildrop'].remove(mail)
|
user['maildrop'].remove(mail)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise YunohostError('mail_forward_remove_failed', mail=mail)
|
||||||
m18n.n('mail_forward_remove_failed', mail=mail))
|
|
||||||
new_attr_dict['maildrop'] = user['maildrop']
|
new_attr_dict['maildrop'] = user['maildrop']
|
||||||
|
|
||||||
if mailbox_quota is not None:
|
if mailbox_quota is not None:
|
||||||
|
@ -389,7 +377,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
||||||
app_ssowatconf(auth)
|
app_ssowatconf(auth)
|
||||||
return user_info(auth, username)
|
return user_info(auth, username)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(169, m18n.n('user_update_failed'))
|
raise YunohostError('user_update_failed')
|
||||||
|
|
||||||
|
|
||||||
def user_info(auth, username):
|
def user_info(auth, username):
|
||||||
|
@ -414,7 +402,7 @@ def user_info(auth, username):
|
||||||
if result:
|
if result:
|
||||||
user = result[0]
|
user = result[0]
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('user_unknown', user=username))
|
raise YunohostError('user_unknown', user=username)
|
||||||
|
|
||||||
result_dict = {
|
result_dict = {
|
||||||
'username': user['uid'][0],
|
'username': user['uid'][0],
|
||||||
|
@ -470,7 +458,7 @@ def user_info(auth, username):
|
||||||
if result:
|
if result:
|
||||||
return result_dict
|
return result_dict
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(167, m18n.n('user_info_failed'))
|
raise YunohostError('user_info_failed')
|
||||||
|
|
||||||
#
|
#
|
||||||
# SSH subcategory
|
# SSH subcategory
|
||||||
|
|
38
src/yunohost/utils/error.py
Normal file
38
src/yunohost/utils/error.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" License
|
||||||
|
|
||||||
|
Copyright (C) 2018 YUNOHOST.ORG
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program; if not, see http://www.gnu.org/licenses
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from moulinette.core import MoulinetteError
|
||||||
|
from moulinette import m18n
|
||||||
|
|
||||||
|
class YunohostError(MoulinetteError):
|
||||||
|
"""
|
||||||
|
Yunohost base exception
|
||||||
|
|
||||||
|
The (only?) main difference with MoulinetteError being that keys
|
||||||
|
are translated via m18n.n (namespace) instead of m18n.g (global?)
|
||||||
|
"""
|
||||||
|
def __init__(self, key, raw_msg=False, *args, **kwargs):
|
||||||
|
if raw_msg:
|
||||||
|
msg = key
|
||||||
|
else:
|
||||||
|
msg = m18n.n(key, *args, **kwargs)
|
||||||
|
super(YunohostError, self).__init__(msg, raw_msg=True)
|
||||||
|
|
|
@ -81,17 +81,15 @@ class PasswordValidator(object):
|
||||||
# on top (at least not the moulinette ones)
|
# on top (at least not the moulinette ones)
|
||||||
# because the moulinette needs to be correctly initialized
|
# because the moulinette needs to be correctly initialized
|
||||||
# as well as modules available in python's path.
|
# as well as modules available in python's path.
|
||||||
import errno
|
|
||||||
import logging
|
import logging
|
||||||
from moulinette import m18n
|
from yunohost.utils.error import YunohostError
|
||||||
from moulinette.core import MoulinetteError
|
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
logger = logging.getLogger('yunohost.utils.password')
|
logger = logging.getLogger('yunohost.utils.password')
|
||||||
|
|
||||||
status, msg = self.validation_summary(password)
|
status, msg = self.validation_summary(password)
|
||||||
if status == "error":
|
if status == "error":
|
||||||
raise MoulinetteError(1, m18n.n(msg))
|
raise YunohostError(msg)
|
||||||
|
|
||||||
def validation_summary(self, password):
|
def validation_summary(self, password):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
import errno
|
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
def yunopaste(data):
|
def yunopaste(data):
|
||||||
|
|
||||||
|
@ -13,17 +12,14 @@ def yunopaste(data):
|
||||||
try:
|
try:
|
||||||
r = requests.post("%s/documents" % paste_server, data=data, timeout=30)
|
r = requests.post("%s/documents" % paste_server, data=data, timeout=30)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError("Something wrong happened while trying to paste data on paste.yunohost.org : %s" % str(e), raw_msg=True)
|
||||||
"Something wrong happened while trying to paste data on paste.yunohost.org : %s" % str(e))
|
|
||||||
|
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError("Something wrong happened while trying to paste data on paste.yunohost.org : %s, %s" % (r.status_code, r.text), raw_msg=True)
|
||||||
"Something wrong happened while trying to paste data on paste.yunohost.org : %s, %s" % (r.status_code, r.text))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
url = json.loads(r.text)["key"]
|
url = json.loads(r.text)["key"]
|
||||||
except:
|
except:
|
||||||
raise MoulinetteError(errno.EIO,
|
raise YunohostError("Uhoh, couldn't parse the answer from paste.yunohost.org : %s" % r.text, raw_msg=True)
|
||||||
"Uhoh, couldn't parse the answer from paste.yunohost.org : %s" % r.text)
|
|
||||||
|
|
||||||
return "%s/raw/%s" % (paste_server, url)
|
return "%s/raw/%s" % (paste_server, url)
|
||||||
|
|
Loading…
Add table
Reference in a new issue