From 97138e920986eb68e40cbb40c707e28e3079ca42 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 25 Nov 2019 19:07:52 +0100 Subject: [PATCH 001/104] Try to remove as many app_list() call as possible, replace them with a simple _installed_apps() --- src/yunohost/app.py | 34 +++++++------------ .../0011_setup_group_permission.py | 17 ++++++---- src/yunohost/tests/test_permission.py | 6 ++-- 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 0e4a473b4..4ecdc0db6 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -90,7 +90,7 @@ def app_list(filter=None, raw=False, installed=False, with_backup=False): app_dict = _load_apps_catalog() # Get app list from the app settings directory - for app in os.listdir(APPS_SETTING_PATH): + for app in _installed_apps(): if app not in app_dict: # Handle multi-instance case like wordpress__2 if '__' in app: @@ -452,19 +452,12 @@ def app_upgrade(app=[], url=None, file=None): from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback from yunohost.permission import permission_sync_to_user - try: - app_list() - except YunohostError: - raise YunohostError('apps_already_up_to_date') - - not_upgraded_apps = [] - apps = app # If no app is specified, upgrade all apps if not apps: # FIXME : not sure what's supposed to happen if there is a url and a file but no apps... if not url and not file: - apps = [app_["id"] for app_ in app_list(installed=True)["apps"]] + apps = _installed_apps() elif not isinstance(app, list): apps = [app] @@ -668,7 +661,10 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu # If we got an url like "https://github.com/foo/bar_ynh, we want to # extract "bar" and test if we know this app elif ('http://' in app) or ('https://' in app): - app_name_to_test = app.strip("/").split("/")[-1].replace("_ynh","") + app_name_to_test = app.strip("/").split("/")[-1].replace("_ynh", "") + else: + # FIXME : watdo if '@' in app ? + app_name_to_test = None if app_name_to_test in raw_app_list: @@ -1216,8 +1212,7 @@ def app_register_url(app, domain, path): # We cannot change the url of an app already installed simply by changing # the settings... - installed = app in app_list(installed=True, raw=True).keys() - if installed: + if _is_installed(app): settings = _get_app_settings(app) if "path" in settings.keys() and "domain" in settings.keys(): raise YunohostError('app_already_installed_cant_change_url') @@ -1263,19 +1258,13 @@ def app_ssowatconf(): redirected_regex = {main_domain + '/yunohost[\/]?$': 'https://' + main_domain + '/yunohost/sso/'} redirected_urls = {} - try: - apps_list = app_list(installed=True)['apps'] - except Exception as e: - logger.debug("cannot get installed app list because %s", e) - apps_list = [] - def _get_setting(settings, name): s = settings.get(name, None) return s.split(',') if s else [] - for app in apps_list: + for app in _installed_apps(): - app_settings = read_yaml(APPS_SETTING_PATH + app['id'] + '/settings.yml') + app_settings = read_yaml(APPS_SETTING_PATH + app + '/settings.yml') if 'domain' not in app_settings: continue @@ -1622,8 +1611,7 @@ def _get_all_installed_apps_id(): * ...' """ - all_apps_ids = [x["id"] for x in app_list(installed=True)["apps"]] - all_apps_ids = sorted(all_apps_ids) + all_apps_ids = sorted(_installed_apps()) all_apps_ids_formatted = "\n * ".join(all_apps_ids) all_apps_ids_formatted = "\n * " + all_apps_ids_formatted @@ -2269,6 +2257,8 @@ def _is_installed(app): """ return os.path.isdir(APPS_SETTING_PATH + app) +def _installed_apps(): + return os.listdir(APPS_SETTING_PATH) def _value_for_locale(values): """ diff --git a/src/yunohost/data_migrations/0011_setup_group_permission.py b/src/yunohost/data_migrations/0011_setup_group_permission.py index c80686344..e054915cf 100644 --- a/src/yunohost/data_migrations/0011_setup_group_permission.py +++ b/src/yunohost/data_migrations/0011_setup_group_permission.py @@ -8,7 +8,7 @@ from moulinette.utils.filesystem import read_yaml from yunohost.tools import Migration from yunohost.user import user_list, user_group_create, user_group_update -from yunohost.app import app_setting, app_list +from yunohost.app import app_setting, _installed_apps from yunohost.regenconf import regen_conf, BACKUP_CONF_DIR from yunohost.permission import permission_create, user_permission_update, permission_sync_to_user @@ -96,13 +96,16 @@ class MyMigration(Migration): def migrate_app_permission(self, app=None): logger.info(m18n.n("migration_0011_migrate_permission")) - if app: - apps = app_list(installed=True, filter=app)['apps'] - else: - apps = app_list(installed=True)['apps'] + apps = _installed_apps() - for app_info in apps: - app = app_info['id'] + if app: + if app not in apps: + logger.error("Can't migrate permission for app %s because it ain't installed..." % app) + apps = [] + else: + apps = [app] + + for app in apps: permission = app_setting(app, 'allowed_users') path = app_setting(app, 'path') domain = app_setting(app, 'domain') diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index b3fa9fefb..6d194d520 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -3,7 +3,7 @@ import pytest from conftest import message, raiseYunohostError -from yunohost.app import app_install, app_remove, app_change_url, app_list, app_map +from yunohost.app import app_install, app_remove, app_change_url, app_list, app_map, _installed_apps from yunohost.user import user_list, user_create, user_delete, \ user_group_list, user_group_delete from yunohost.permission import user_permission_update, user_permission_list, user_permission_reset, \ @@ -163,9 +163,7 @@ def check_permission_for_apps(): app_perms_prefix = set(p.split(".")[0] for p in app_perms) - installed_apps = {app['id'] for app in app_list(installed=True)['apps']} - - assert installed_apps == app_perms_prefix + assert set(_installed_apps()) == app_perms_prefix def can_access_webpage(webpath, logged_as=None): From 7518beaf2f8a02482b4b89e350d8fb6bdb65f263 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 25 Nov 2019 19:16:46 +0100 Subject: [PATCH 002/104] Fuck it we don't need these options --- data/actionsmap/yunohost.yml | 7 ------- src/yunohost/app.py | 25 +++++-------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 4cb108e3a..fbdd8aff6 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -548,9 +548,6 @@ app: action_help: List apps api: GET /apps arguments: - -f: - full: --filter - help: Name filter of app_id or app_name -r: full: --raw help: Return the full app_dict @@ -559,10 +556,6 @@ app: full: --installed help: Return only installed apps action: store_true - -b: - full: --with-backup - help: Return only apps with backup feature (force --installed filter) - action: store_true ### app_info() info: diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 4ecdc0db6..2b0bba33e 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -71,18 +71,14 @@ re_app_instance_name = re.compile( ) -def app_list(filter=None, raw=False, installed=False, with_backup=False): +def app_list(raw=False, installed=False): """ List apps Keyword argument: - filter -- Name filter of app_id or app_name raw -- Return the full app_dict installed -- Return only installed apps - with_backup -- Return only apps with backup feature (force --installed filter) - """ - installed = with_backup or installed list_dict = {} if raw else [] @@ -112,27 +108,16 @@ def app_list(filter=None, raw=False, installed=False, with_backup=False): app_info_dict = app_dict[app_id] - # Apply filter if there's one - if (filter and - (filter not in app_id) and - (filter not in app_info_dict['manifest']['name'])): - continue - # Ignore non-installed app if user wants only installed apps app_installed = _is_installed(app_id) if installed and not app_installed: continue - # Ignore apps which don't have backup/restore script if user wants - # only apps with backup features - if with_backup and ( - not os.path.isfile(APPS_SETTING_PATH + app_id + '/scripts/backup') or - not os.path.isfile(APPS_SETTING_PATH + app_id + '/scripts/restore') - ): - continue - if raw: app_info_dict['installed'] = app_installed + app_info_dict['supports_backup_restore'] = (app_installed and + os.path.isfile(APPS_SETTING_PATH + app_id + '/scripts/backup') and + os.path.isfile(APPS_SETTING_PATH + app_id + '/scripts/restore')) # dirty: we used to have manifest containing multi_instance value in form of a string # but we've switched to bool, this line ensure retrocompatibility @@ -173,7 +158,7 @@ def app_info(app, raw=False): manifest = _get_manifest_of_app(app_setting_path) if raw: - ret = app_list(filter=app, raw=True)[app] + ret = app_list(raw=True)[app] ret['settings'] = _get_app_settings(app) # Determine upgradability From 3951f5e1b8c6d76e54b7387d3124abe7930a2437 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 25 Nov 2019 21:05:00 +0100 Subject: [PATCH 003/104] Refactor the whole app_list and app_info madness ... --- data/actionsmap/yunohost.yml | 32 +++--- src/yunohost/app.py | 186 +++++++++++++++-------------------- src/yunohost/tools.py | 8 +- 3 files changed, 101 insertions(+), 125 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index fbdd8aff6..cf98ca8c8 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -543,35 +543,41 @@ app: category_help: Manage apps actions: + catalog: + action_help: Show the catalog of installable application + api: GET /appscatalog + arguments: + -f: + full: --full + help: Display all details, including the app manifest and various other infos + action: store_true + + ### app_list() list: - action_help: List apps + action_help: List installed apps api: GET /apps arguments: - -r: - full: --raw - help: Return the full app_dict - action: store_true - -i: - full: --installed - help: Return only installed apps + -f: + full: --full + help: Display all details, including the app manifest and various other infos action: store_true ### app_info() info: - action_help: Get information about an installed app + action_help: Show infos about a specific installed app api: GET /apps/ arguments: app: help: Specific app ID - -r: - full: --raw - help: Return the full app_dict + -f: + full: --full + help: Display all details, including the app manifest and various other infos action: store_true ### app_map() map: - action_help: List apps by domain + action_help: Show the mapping between urls and apps api: GET /appsmap arguments: -a: diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 2b0bba33e..1c4073893 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -71,76 +71,41 @@ re_app_instance_name = re.compile( ) -def app_list(raw=False, installed=False): +def app_catalog(full=False, all=False): """ - List apps - - Keyword argument: - raw -- Return the full app_dict - installed -- Return only installed apps + Return a dict of apps available to installation from Yunohost's app catalog """ - list_dict = {} if raw else [] - # Get app list from catalog cache - app_dict = _load_apps_catalog() + catalog = _load_apps_catalog() + installed_apps = set(_installed_apps()) - # Get app list from the app settings directory - for app in _installed_apps(): - if app not in app_dict: - # Handle multi-instance case like wordpress__2 - if '__' in app: - original_app = app[:app.index('__')] - if original_app in app_dict: - app_dict[app] = app_dict[original_app] - continue - # FIXME : What if it's not !?!? + for app, infos in catalog.items(): + infos["installed"] = app in installed_apps - manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app)) - app_dict[app] = {"manifest": manifest} + if not full: + catalog[app] = { + "description": _value_for_locale(infos['manifest']['description']), + "level": infos["level"], + } - app_dict[app]['repository'] = None - - # Sort app list - sorted_app_list = sorted(app_dict.keys()) - - for app_id in sorted_app_list: - - app_info_dict = app_dict[app_id] - - # Ignore non-installed app if user wants only installed apps - app_installed = _is_installed(app_id) - if installed and not app_installed: - continue - - if raw: - app_info_dict['installed'] = app_installed - app_info_dict['supports_backup_restore'] = (app_installed and - os.path.isfile(APPS_SETTING_PATH + app_id + '/scripts/backup') and - os.path.isfile(APPS_SETTING_PATH + app_id + '/scripts/restore')) - - # dirty: we used to have manifest containing multi_instance value in form of a string - # but we've switched to bool, this line ensure retrocompatibility - - app_info_dict["manifest"]["multi_instance"] = is_true(app_info_dict["manifest"].get("multi_instance", False)) - - list_dict[app_id] = app_info_dict - - else: - list_dict.append({ - 'id': app_id, - 'name': app_info_dict['manifest']['name'], - 'label': _get_app_settings(app_id).get("label", "?") if app_installed else None, - 'description': _value_for_locale(app_info_dict['manifest']['description']), - # FIXME: Temporarly allow undefined license - 'license': app_info_dict['manifest'].get('license', m18n.n('license_undefined')), - 'installed': app_installed - }) - - return {'apps': list_dict} if not raw else list_dict + return {"apps": catalog} -def app_info(app, raw=False): +def app_list(full=False): + """ + List installed apps + """ + out = [] + for app_id in sorted(_installed_apps()): + app_info_dict = app_info(app_id, full=full) + app_info_dict["id"] = app_id + out.append(app_info_dict) + + return {'apps': out} + + +def app_info(app, full=False): """ Get app info @@ -152,39 +117,47 @@ def app_info(app, raw=False): if not _is_installed(app): raise YunohostError('app_not_installed', app=app, all_apps=_get_all_installed_apps_id()) - app_setting_path = APPS_SETTING_PATH + app + local_manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app)) + settings = _get_app_settings(app) - # Retrieve manifest and status - manifest = _get_manifest_of_app(app_setting_path) - - if raw: - ret = app_list(raw=True)[app] - ret['settings'] = _get_app_settings(app) - - # Determine upgradability - # In case there is neither update_time nor install_time, we assume the app can/has to be upgraded - local_update_time = ret['settings'].get('update_time', ret['settings'].get('install_time', 0)) - - if 'lastUpdate' not in ret or 'git' not in ret: - upgradable = "url_required" - elif ret['lastUpdate'] > local_update_time: - upgradable = "yes" - else: - upgradable = "no" - - ret['upgradable'] = upgradable - ret['change_url'] = os.path.exists(os.path.join(app_setting_path, "scripts", "change_url")) - ret['version'] = manifest.get('version', '-') + ret = { + 'description': _value_for_locale(local_manifest['description']), + 'name': local_manifest['name'], + 'version': local_manifest.get('version', '-'), + } + if not full: return ret - info = { - 'name': manifest['name'], - 'description': _value_for_locale(manifest['description']), - 'license': manifest.get('license', m18n.n('license_undefined')), - 'version': manifest.get('version', '-'), - } - return info + ret["manifest"] = local_manifest + ret['settings'] = settings + + absolute_app_name = app if "__" not in app else app[:app.index('__')] # idk this is the name of the app even for multiinstance apps (so wordpress__2 -> wordpress) + ret["from_catalog"] = _load_apps_catalog().get(absolute_app_name, {}) + ret['upgradable'] = _app_upgradable(ret) + ret['supports_change_url'] = os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "change_url")) + ret['supports_backup_restore'] = (os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "backup")) and + os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "restore"))) + ret['supports_multi_instance'] = is_true(local_manifest.get("multi_instance", False)) + return ret + + +def _app_upgradable(app_infos): + + # Determine upgradability + # In case there is neither update_time nor install_time, we assume the app can/has to be upgraded + + if not app_infos.get("from_catalog", None): + return "url_required" + if not app_infos["from_catalog"].get("lastUpdate") or not app_infos["from_catalog"].get("git"): + return "url_required" + + settings = app_infos["settings"] + local_update_time = settings.get('update_time', settings.get('install_time', 0)) + if app_infos["from_catalog"]['lastUpdate'] > local_update_time: + return "yes" + else: + return "no" def app_map(app=None, raw=False, user=None): @@ -461,7 +434,7 @@ def app_upgrade(app=[], url=None, file=None): for number, app_instance_name in enumerate(apps): logger.info(m18n.n('app_upgrade_app_name', app=app_instance_name)) - app_dict = app_info(app_instance_name, raw=True) + app_dict = app_info(app_instance_name, full=True) if file and isinstance(file, dict): # We use this dirty hack to test chained upgrades in unit/functional tests @@ -636,7 +609,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu if answer.upper() != "Y": raise YunohostError("aborting") - raw_app_list = app_list(raw=True) + raw_app_list = _load_apps_catalog() if app in raw_app_list or ('@' in app) or ('http://' in app) or ('https://' in app): @@ -1292,7 +1265,7 @@ def app_ssowatconf(): protected_regex += _get_setting(app_settings, 'protected_regex') # New permission system - this_app_perms = {name: info for name, info in all_permissions.items() if name.startswith(app['id'] + ".")} + this_app_perms = {name: info for name, info in all_permissions.items() if name.startswith(app + ".")} for perm_name, perm_info in this_app_perms.items(): # Ignore permissions for which there's no url defined @@ -2135,17 +2108,16 @@ def _fetch_app_from_git(app): else: manifest['remote']['revision'] = revision else: - app_dict = app_list(raw=True) + app_dict = _load_apps_catalog() - if app in app_dict: - app_info = app_dict[app] - app_info['manifest']['lastUpdate'] = app_info['lastUpdate'] - manifest = app_info['manifest'] - else: + if app not in app_dict: raise YunohostError('app_unknown') - - if 'git' not in app_info: + elif 'git' not in app_dict[app]: raise YunohostError('app_unsupported_remote_type') + + app_info = app_dict[app] + app_info['manifest']['lastUpdate'] = app_info['lastUpdate'] + manifest = app_info['manifest'] url = app_info['git']['url'] if 'github.com' in url: @@ -2242,9 +2214,11 @@ def _is_installed(app): """ return os.path.isdir(APPS_SETTING_PATH + app) + def _installed_apps(): return os.listdir(APPS_SETTING_PATH) + def _value_for_locale(values): """ Return proper value for current locale @@ -2755,16 +2729,12 @@ def random_password(length=8): def unstable_apps(): - raw_app_installed = app_list(installed=True, raw=True) output = [] - for app, infos in raw_app_installed.items(): + for infos in app_list(full=True): - repo = infos.get("repository", None) - state = infos.get("state", None) - - if repo is None or state in ["inprogress", "notworking"]: - output.append(app) + if not infos.get("from_catalog") or infos.get("from_catalog").get("state") in ["inprogress", "notworking"]: + output.append(infos["id"]) return output diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index c05933dc0..520dab822 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -470,17 +470,17 @@ def _list_upgradable_apps(): app_list_installed = os.listdir(APPS_SETTING_PATH) for app_id in app_list_installed: - app_dict = app_info(app_id, raw=True) + app_dict = app_info(app_id, full=True) if app_dict["upgradable"] == "yes": # FIXME : would make more sense for these infos to be computed # directly in app_info and used to check the upgradability of # the app... - current_version = app_dict.get("version", "?") + current_version = app_dict.get("manifest", {}).get("version", "?") current_commit = app_dict.get("settings", {}).get("current_revision", "?")[:7] - new_version = app_dict.get("manifest",{}).get("version","?") - new_commit = app_dict.get("git", {}).get("revision", "?")[:7] + new_version = app_dict.get("from_catalog", {}).get("manifest", {}).get("version", "?") + new_commit = app_dict.get("from_catalog", {}).get("git", {}).get("revision", "?")[:7] if current_version == new_version: current_version += " (" + current_commit + ")" From 06fe3504b338e6ffc5e9e2ff0fe0f5b174d36a9a Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 25 Nov 2019 21:40:21 +0100 Subject: [PATCH 004/104] Change app catalog API to support categories --- data/actionsmap/yunohost.yml | 5 +- src/yunohost/app.py | 64 +++++++++++++++++--------- src/yunohost/tests/test_appscatalog.py | 36 ++++++++++----- 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index cf98ca8c8..3a4c9db97 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -551,7 +551,10 @@ app: full: --full help: Display all details, including the app manifest and various other infos action: store_true - + -c: + full: --with-categories + help: Also return a list of app categories + action: store_true ### app_list() list: diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 1c4073893..a54a18c6f 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -57,7 +57,7 @@ APP_TMP_FOLDER = INSTALL_TMP + '/from_file' APPS_CATALOG_CACHE = '/var/cache/yunohost/repo' APPS_CATALOG_CONF = '/etc/yunohost/apps_catalog.yml' APPS_CATALOG_CRON_PATH = "/etc/cron.daily/yunohost-fetch-apps-catalog" -APPS_CATALOG_API_VERSION = 1 +APPS_CATALOG_API_VERSION = 2 APPS_CATALOG_DEFAULT_URL = "https://app.yunohost.org/default" re_github_repo = re.compile( @@ -71,7 +71,7 @@ re_app_instance_name = re.compile( ) -def app_catalog(full=False, all=False): +def app_catalog(full=False, with_categories=False): """ Return a dict of apps available to installation from Yunohost's app catalog """ @@ -80,16 +80,32 @@ def app_catalog(full=False, all=False): catalog = _load_apps_catalog() installed_apps = set(_installed_apps()) - for app, infos in catalog.items(): + # Trim info for apps if not using --full + for app, infos in catalog["apps"].items(): infos["installed"] = app in installed_apps + infos["manifest"]["description"] = _value_for_locale(infos['manifest']['description']) + if not full: - catalog[app] = { - "description": _value_for_locale(infos['manifest']['description']), + catalog["apps"][app] = { + "description": infos['manifest']['description'], "level": infos["level"], } - return {"apps": catalog} + # Trim info for categories if not using --full + for category in catalog["categories"]: + category["title"] = _value_for_locale(category["title"]) + category["description"] = _value_for_locale(category["description"]) + + if not full: + catalog["categories"] = [{"id": c["id"], + "description": c["description"]} + for c in catalog["categories"]] + + if not with_categories: + return {"apps": catalog["apps"]} + else: + return {"apps": catalog["apps"], "categories": catalog["categories"]} def app_list(full=False): @@ -107,12 +123,7 @@ def app_list(full=False): def app_info(app, full=False): """ - Get app info - - Keyword argument: - app -- Specific app ID - raw -- Return the full app_dict - + Get info for a specific app """ if not _is_installed(app): raise YunohostError('app_not_installed', app=app, all_apps=_get_all_installed_apps_id()) @@ -133,7 +144,7 @@ def app_info(app, full=False): ret['settings'] = settings absolute_app_name = app if "__" not in app else app[:app.index('__')] # idk this is the name of the app even for multiinstance apps (so wordpress__2 -> wordpress) - ret["from_catalog"] = _load_apps_catalog().get(absolute_app_name, {}) + ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {}) ret['upgradable'] = _app_upgradable(ret) ret['supports_change_url'] = os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "change_url")) ret['supports_backup_restore'] = (os.path.exists(os.path.join(APPS_SETTING_PATH, app, "scripts", "backup")) and @@ -609,7 +620,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu if answer.upper() != "Y": raise YunohostError("aborting") - raw_app_list = _load_apps_catalog() + raw_app_list = _load_apps_catalog()["apps"] if app in raw_app_list or ('@' in app) or ('http://' in app) or ('https://' in app): @@ -2108,7 +2119,7 @@ def _fetch_app_from_git(app): else: manifest['remote']['revision'] = revision else: - app_dict = _load_apps_catalog() + app_dict = _load_apps_catalog()["apps"] if app not in app_dict: raise YunohostError('app_unknown') @@ -2645,11 +2656,14 @@ def _update_apps_catalog(): def _load_apps_catalog(): """ - Read all the apps catalog cache files and build a single dict (app_dict) - corresponding to all known apps in all indexes + Read all the apps catalog cache files and build a single dict (merged_catalog) + corresponding to all known apps and categories """ - app_dict = {} + merged_catalog = { + "apps": {}, + "categories": [] + } for apps_catalog_id in [L["id"] for L in _read_apps_catalog_list()]: @@ -2672,18 +2686,22 @@ def _load_apps_catalog(): del apps_catalog_content["from_api_version"] # Add apps from this catalog to the output - for app, info in apps_catalog_content.items(): + for app, info in apps_catalog_content["apps"].items(): # (N.B. : there's a small edge case where multiple apps catalog could be listing the same apps ... # in which case we keep only the first one found) - if app in app_dict: - logger.warning("Duplicate app %s found between apps catalog %s and %s" % (app, apps_catalog_id, app_dict[app]['repository'])) + if app in merged_catalog["apps"]: + logger.warning("Duplicate app %s found between apps catalog %s and %s" + % (app, apps_catalog_id, merged_catalog["apps"][app]['repository'])) continue info['repository'] = apps_catalog_id - app_dict[app] = info + merged_catalog["apps"][app] = info - return app_dict + # Annnnd categories + merged_catalog["categories"] += apps_catalog_content["categories"] + + return merged_catalog # # ############################### # diff --git a/src/yunohost/tests/test_appscatalog.py b/src/yunohost/tests/test_appscatalog.py index 613b59012..39a0be206 100644 --- a/src/yunohost/tests/test_appscatalog.py +++ b/src/yunohost/tests/test_appscatalog.py @@ -14,6 +14,7 @@ from yunohost.app import (_initialize_apps_catalog_system, _update_apps_catalog, _actual_apps_catalog_api_url, _load_apps_catalog, + app_catalog, logger, APPS_CATALOG_CACHE, APPS_CATALOG_CONF, @@ -25,8 +26,14 @@ APPS_CATALOG_DEFAULT_URL_FULL = _actual_apps_catalog_api_url(APPS_CATALOG_DEFAUL CRON_FOLDER, CRON_NAME = APPS_CATALOG_CRON_PATH.rsplit("/", 1) DUMMY_APP_CATALOG = """{ - "foo": {"id": "foo", "level": 4}, - "bar": {"id": "bar", "level": 7} + "apps": { + "foo": {"id": "foo", "level": 4, "category": "yolo", "manifest":{"description": "Foo"}}, + "bar": {"id": "bar", "level": 7, "category": "swag", "manifest":{"description": "Bar"}} + }, + "categories": [ + {"id": "yolo", "description": "YoLo"}, + {"id": "swag", "description": "sWaG"} + ] } """ @@ -107,7 +114,7 @@ def test_apps_catalog_emptylist(): assert not len(apps_catalog_list) -def test_apps_catalog_update_success(mocker): +def test_apps_catalog_update_nominal(mocker): # Initialize ... _initialize_apps_catalog_system() @@ -130,9 +137,16 @@ def test_apps_catalog_update_success(mocker): # Cache shouldn't be empty anymore empty assert glob.glob(APPS_CATALOG_CACHE + "/*") - app_dict = _load_apps_catalog() - assert "foo" in app_dict.keys() - assert "bar" in app_dict.keys() + # And if we load the catalog, we sould find + # - foo and bar as apps (unordered), + # - yolo and swag as categories (ordered) + catalog = app_catalog(with_categories=True) + + assert "apps" in catalog + assert set(catalog["apps"].keys()) == set(["foo", "bar"]) + + assert "categories" in catalog + assert [c["id"] for c in catalog["categories"]] == ["yolo", "swag"] def test_apps_catalog_update_404(mocker): @@ -219,7 +233,7 @@ def test_apps_catalog_load_with_empty_cache(mocker): # Try to load the apps catalog # This should implicitly trigger an update in the background mocker.spy(m18n, "n") - app_dict = _load_apps_catalog() + app_dict = _load_apps_catalog()["apps"] m18n.n.assert_any_call("apps_catalog_obsolete_cache") m18n.n.assert_any_call("apps_catalog_update_success") @@ -252,7 +266,7 @@ def test_apps_catalog_load_with_conflicts_between_lists(mocker): # Try to load the apps catalog # This should implicitly trigger an update in the background mocker.spy(logger, "warning") - app_dict = _load_apps_catalog() + app_dict = _load_apps_catalog()["apps"] logger.warning.assert_any_call(AnyStringWith("Duplicate")) # Cache shouldn't be empty anymore empty @@ -291,7 +305,7 @@ def test_apps_catalog_load_with_oudated_api_version(mocker): m.register_uri("GET", APPS_CATALOG_DEFAULT_URL_FULL, text=DUMMY_APP_CATALOG) mocker.spy(m18n, "n") - app_dict = _load_apps_catalog() + app_dict = _load_apps_catalog()["apps"] m18n.n.assert_any_call("apps_catalog_update_success") assert "foo" in app_dict.keys() @@ -329,7 +343,7 @@ def test_apps_catalog_migrate_legacy_explicitly(): assert cron_job_is_there() # Reading the apps_catalog should work - app_dict = _load_apps_catalog() + app_dict = _load_apps_catalog()["apps"] assert "foo" in app_dict.keys() assert "bar" in app_dict.keys() @@ -343,7 +357,7 @@ def test_apps_catalog_migrate_legacy_implicitly(): with requests_mock.Mocker() as m: m.register_uri("GET", APPS_CATALOG_DEFAULT_URL_FULL, text=DUMMY_APP_CATALOG) - app_dict = _load_apps_catalog() + app_dict = _load_apps_catalog()["apps"] assert "foo" in app_dict.keys() assert "bar" in app_dict.keys() From 97e5d3b992fbe25f84946060c9a4e40922e4558f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 27 Nov 2019 23:58:36 +0100 Subject: [PATCH 005/104] Remove those random sudo which are useless yet triggers LDAP warning when LDAP is in bad state --- data/helpers.d/apt | 2 +- data/helpers.d/backup | 24 +++++++++++----------- data/helpers.d/logging | 4 ++-- data/helpers.d/logrotate | 6 +++--- data/helpers.d/mysql | 8 ++++---- data/helpers.d/nginx | 2 +- data/helpers.d/php | 8 ++++---- data/helpers.d/postgresql | 10 ++++----- data/helpers.d/setting | 4 ++-- data/helpers.d/string | 2 +- data/helpers.d/systemd | 8 ++++---- data/helpers.d/user | 6 +++--- data/hooks/backup/05-conf_ldap | 4 ++-- data/hooks/conf_regen/01-yunohost | 14 ++++++------- data/hooks/conf_regen/02-ssl | 6 +++--- data/hooks/conf_regen/06-slapd | 2 +- data/hooks/conf_regen/09-nslcd | 2 +- data/hooks/conf_regen/12-metronome | 12 +++++------ data/hooks/conf_regen/15-nginx | 8 ++++---- data/hooks/conf_regen/19-postfix | 4 ++-- data/hooks/conf_regen/25-dovecot | 20 +++++++++--------- data/hooks/conf_regen/31-rspamd | 24 +++++++++++----------- data/hooks/conf_regen/34-mysql | 16 +++++++-------- data/hooks/conf_regen/37-avahi-daemon | 2 +- data/hooks/conf_regen/40-glances | 2 +- data/hooks/conf_regen/43-dnsmasq | 4 ++-- data/hooks/conf_regen/46-nsswitch | 2 +- data/hooks/conf_regen/52-fail2ban | 2 +- data/hooks/restore/05-conf_ldap | 2 +- data/hooks/restore/08-conf_ssh | 4 ++-- data/hooks/restore/11-conf_ynh_mysql | 16 +++++++-------- data/hooks/restore/14-conf_ssowat | 2 +- data/hooks/restore/17-data_home | 2 +- data/hooks/restore/20-conf_ynh_firewall | 4 ++-- data/hooks/restore/21-conf_ynh_certs | 8 ++++---- data/hooks/restore/23-data_mail | 8 ++++---- data/hooks/restore/26-conf_xmpp | 6 +++--- data/hooks/restore/29-conf_nginx | 4 ++-- data/hooks/restore/32-conf_cron | 4 ++-- data/hooks/restore/40-conf_ynh_currenthost | 2 +- src/yunohost/tools.py | 6 +++--- 41 files changed, 138 insertions(+), 138 deletions(-) diff --git a/data/helpers.d/apt b/data/helpers.d/apt index da2740d01..55c85c90b 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -13,7 +13,7 @@ ynh_wait_dpkg_free() { for try in `seq 1 17` do # Check if /var/lib/dpkg/lock is used by another process - if sudo lsof /var/lib/dpkg/lock > /dev/null + if lsof /var/lib/dpkg/lock > /dev/null then echo "apt is already in use..." # Sleep an exponential time at each round diff --git a/data/helpers.d/backup b/data/helpers.d/backup index d3ffffcd3..590e951a5 100644 --- a/data/helpers.d/backup +++ b/data/helpers.d/backup @@ -179,7 +179,7 @@ ynh_restore () { # usage: _get_archive_path ORIGIN_PATH _get_archive_path () { # For security reasons we use csv python library to read the CSV - sudo python -c " + python -c " import sys import csv with open(sys.argv[1], 'r') as backup_file: @@ -302,7 +302,7 @@ ynh_store_file_checksum () { ynh_handle_getopts_args "$@" local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_' - ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(sudo md5sum "$file" | cut -d' ' -f1) + ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(md5sum "$file" | cut -d' ' -f1) # If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup if [ -n "${backup_file_checksum-}" ] @@ -339,11 +339,11 @@ ynh_backup_if_checksum_is_different () { backup_file_checksum="" if [ -n "$checksum_value" ] then # Proceed only if a value was stored into the app settings - if [ -e $file ] && ! echo "$checksum_value $file" | sudo md5sum -c --status + if [ -e $file ] && ! echo "$checksum_value $file" | md5sum -c --status then # If the checksum is now different backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')" - sudo mkdir -p "$(dirname "$backup_file_checksum")" - sudo cp -a "$file" "$backup_file_checksum" # Backup the current file + mkdir -p "$(dirname "$backup_file_checksum")" + cp -a "$file" "$backup_file_checksum" # Backup the current file ynh_print_warn "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file_checksum" echo "$backup_file_checksum" # Return the name of the backup file fi @@ -394,7 +394,7 @@ ynh_backup_before_upgrade () { if [ "$NO_BACKUP_UPGRADE" -eq 0 ] then # Check if a backup already exists with the prefix 1 - if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1 + if yunohost backup list | grep -q $app_bck-pre-upgrade1 then # Prefix becomes 2 to preserve the previous backup backup_number=2 @@ -402,14 +402,14 @@ ynh_backup_before_upgrade () { fi # Create backup - sudo BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug + BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug if [ "$?" -eq 0 ] then # If the backup succeeded, remove the previous backup - if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number + if yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number then # Remove the previous backup only if it exists - sudo yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null + yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null fi else ynh_die --message="Backup failed, the upgrade process was aborted." @@ -438,12 +438,12 @@ ynh_restore_upgradebackup () { if [ "$NO_BACKUP_UPGRADE" -eq 0 ] then # Check if an existing backup can be found before removing and restoring the application. - if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number + if yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number then # Remove the application then restore it - sudo yunohost app remove $app + yunohost app remove $app # Restore the backup - sudo yunohost backup restore $app_bck-pre-upgrade$backup_number --apps $app --force --debug + yunohost backup restore $app_bck-pre-upgrade$backup_number --apps $app --force --debug ynh_die --message="The app was restored to the way it was before the failed upgrade." fi else diff --git a/data/helpers.d/logging b/data/helpers.d/logging index be33b75a5..89fb89c6e 100644 --- a/data/helpers.d/logging +++ b/data/helpers.d/logging @@ -46,10 +46,10 @@ ynh_print_info() { # Requires YunoHost version 2.6.4 or higher. ynh_no_log() { local ynh_cli_log=/var/log/yunohost/yunohost-cli.log - sudo cp -a ${ynh_cli_log} ${ynh_cli_log}-move + cp -a ${ynh_cli_log} ${ynh_cli_log}-move eval $@ local exit_code=$? - sudo mv ${ynh_cli_log}-move ${ynh_cli_log} + mv ${ynh_cli_log}-move ${ynh_cli_log} return $? } diff --git a/data/helpers.d/logrotate b/data/helpers.d/logrotate index 82cdee6a5..9e2429218 100644 --- a/data/helpers.d/logrotate +++ b/data/helpers.d/logrotate @@ -90,8 +90,8 @@ $logfile { $su_directive } EOF - sudo mkdir -p $(dirname "$logfile") # Create the log directory, if not exist - cat ${app}-logrotate | sudo $customtee /etc/logrotate.d/$app > /dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee) + mkdir -p $(dirname "$logfile") # Create the log directory, if not exist + cat ${app}-logrotate | $customtee /etc/logrotate.d/$app > /dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee) } # Remove the app's logrotate config. @@ -101,6 +101,6 @@ EOF # Requires YunoHost version 2.6.4 or higher. ynh_remove_logrotate () { if [ -e "/etc/logrotate.d/$app" ]; then - sudo rm "/etc/logrotate.d/$app" + rm "/etc/logrotate.d/$app" fi } diff --git a/data/helpers.d/mysql b/data/helpers.d/mysql index e9cf59b3c..91d4abcd2 100644 --- a/data/helpers.d/mysql +++ b/data/helpers.d/mysql @@ -44,7 +44,7 @@ ynh_mysql_execute_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" - ynh_mysql_connect_as --user="root" --password="$(sudo cat $MYSQL_ROOT_PWD_FILE)" \ + ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \ --database="$database" <<< "$sql" } @@ -65,7 +65,7 @@ ynh_mysql_execute_file_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" - ynh_mysql_connect_as --user="root" --password="$(sudo cat $MYSQL_ROOT_PWD_FILE)" \ + ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \ --database="$database" < "$file" } @@ -126,7 +126,7 @@ ynh_mysql_dump_db() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - mysqldump -u "root" -p"$(sudo cat $MYSQL_ROOT_PWD_FILE)" --single-transaction --skip-dump-date "$database" + mysqldump -u "root" -p"$(cat $MYSQL_ROOT_PWD_FILE)" --single-transaction --skip-dump-date "$database" } # Create a user @@ -223,7 +223,7 @@ ynh_mysql_remove_db () { # Manage arguments with getopts ynh_handle_getopts_args "$@" - local mysql_root_password=$(sudo cat $MYSQL_ROOT_PWD_FILE) + local mysql_root_password=$(cat $MYSQL_ROOT_PWD_FILE) if mysqlshow -u root -p$mysql_root_password | grep -q "^| $db_name"; then # Check if the database exists ynh_mysql_drop_db $db_name # Remove the database else diff --git a/data/helpers.d/nginx b/data/helpers.d/nginx index ce6b61d3c..e3e45d2d4 100644 --- a/data/helpers.d/nginx +++ b/data/helpers.d/nginx @@ -22,7 +22,7 @@ ynh_add_nginx_config () { finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf" local others_var=${1:-} ynh_backup_if_checksum_is_different --file="$finalnginxconf" - sudo cp ../conf/nginx.conf "$finalnginxconf" + cp ../conf/nginx.conf "$finalnginxconf" # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable. # Substitute in a nginx config file only if the variable is not empty diff --git a/data/helpers.d/php b/data/helpers.d/php index c9e3ba9ed..41af467c5 100644 --- a/data/helpers.d/php +++ b/data/helpers.d/php @@ -28,12 +28,12 @@ ynh_add_fpm_config () { ynh_app_setting_set --app=$app --key=fpm_service --value="$fpm_service" finalphpconf="$fpm_config_dir/pool.d/$app.conf" ynh_backup_if_checksum_is_different --file="$finalphpconf" - sudo cp ../conf/php-fpm.conf "$finalphpconf" + cp ../conf/php-fpm.conf "$finalphpconf" ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$finalphpconf" ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalphpconf" ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$finalphpconf" ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$phpversion" --target_file="$finalphpconf" - sudo chown root: "$finalphpconf" + chown root: "$finalphpconf" ynh_store_file_checksum --file="$finalphpconf" if [ -e "../conf/php-fpm.ini" ] @@ -41,8 +41,8 @@ ynh_add_fpm_config () { echo "Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead." >&2 finalphpini="$fpm_config_dir/conf.d/20-$app.ini" ynh_backup_if_checksum_is_different "$finalphpini" - sudo cp ../conf/php-fpm.ini "$finalphpini" - sudo chown root: "$finalphpini" + cp ../conf/php-fpm.ini "$finalphpini" + chown root: "$finalphpini" ynh_store_file_checksum "$finalphpini" fi ynh_systemd_action --service_name=$fpm_service --action=reload diff --git a/data/helpers.d/postgresql b/data/helpers.d/postgresql index d252ae2dc..6d8524e54 100644 --- a/data/helpers.d/postgresql +++ b/data/helpers.d/postgresql @@ -45,7 +45,7 @@ ynh_psql_execute_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" - ynh_psql_connect_as --user="postgres" --password="$(sudo cat $PSQL_ROOT_PWD_FILE)" \ + ynh_psql_connect_as --user="postgres" --password="$(cat $PSQL_ROOT_PWD_FILE)" \ --database="$database" <<<"$sql" } @@ -66,7 +66,7 @@ ynh_psql_execute_file_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" - ynh_psql_connect_as --user="postgres" --password="$(sudo cat $PSQL_ROOT_PWD_FILE)" \ + ynh_psql_connect_as --user="postgres" --password="$(cat $PSQL_ROOT_PWD_FILE)" \ --database="$database" <"$file" } @@ -160,7 +160,7 @@ ynh_psql_user_exists() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(sudo cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='$user';" | grep --quiet "$user" ; then + if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='$user';" | grep --quiet "$user" ; then return 1 else return 0 @@ -179,7 +179,7 @@ ynh_psql_database_exists() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(sudo cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT datname FROM pg_database WHERE datname='$database';" | grep --quiet "$database"; then + if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT datname FROM pg_database WHERE datname='$database';" | grep --quiet "$database"; then return 1 else return 0 @@ -243,7 +243,7 @@ ynh_psql_remove_db() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - local psql_root_password=$(sudo cat $PSQL_ROOT_PWD_FILE) + local psql_root_password=$(cat $PSQL_ROOT_PWD_FILE) if ynh_psql_database_exists --database=$db_name; then # Check if the database exists ynh_psql_drop_db $db_name # Remove the database else diff --git a/data/helpers.d/setting b/data/helpers.d/setting index f0963444a..0e5ae15cc 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -211,7 +211,7 @@ ynh_webpath_available () { # Manage arguments with getopts ynh_handle_getopts_args "$@" - sudo yunohost domain url-available $domain $path_url + yunohost domain url-available $domain $path_url } # Register/book a web path for an app @@ -234,7 +234,7 @@ ynh_webpath_register () { # Manage arguments with getopts ynh_handle_getopts_args "$@" - sudo yunohost app register-url $app $domain $path_url + yunohost app register-url $app $domain $path_url } # Create a new permission for the app diff --git a/data/helpers.d/string b/data/helpers.d/string index fcbc5190d..e50f781fe 100644 --- a/data/helpers.d/string +++ b/data/helpers.d/string @@ -49,7 +49,7 @@ ynh_replace_string () { match_string=${match_string//${delimit}/"\\${delimit}"} replace_string=${replace_string//${delimit}/"\\${delimit}"} - sudo sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$target_file" + sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$target_file" } # Substitute/replace a special string by another in a file diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index 105678b88..960382f8f 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -28,7 +28,7 @@ ynh_add_systemd_config () { finalsystemdconf="/etc/systemd/system/$service.service" ynh_backup_if_checksum_is_different --file="$finalsystemdconf" - sudo cp ../conf/$template "$finalsystemdconf" + cp ../conf/$template "$finalsystemdconf" # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable. # Substitute in a nginx config file only if the variable is not empty @@ -40,9 +40,9 @@ ynh_add_systemd_config () { fi ynh_store_file_checksum --file="$finalsystemdconf" - sudo chown root: "$finalsystemdconf" - sudo systemctl enable $service - sudo systemctl daemon-reload + chown root: "$finalsystemdconf" + systemctl enable $service + systemctl daemon-reload } # Remove the dedicated systemd config diff --git a/data/helpers.d/user b/data/helpers.d/user index e7890ccb2..7051ed4c0 100644 --- a/data/helpers.d/user +++ b/data/helpers.d/user @@ -16,7 +16,7 @@ ynh_user_exists() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - sudo yunohost user list --output-as json | grep -q "\"username\": \"${username}\"" + yunohost user list --output-as json | grep -q "\"username\": \"${username}\"" } # Retrieve a YunoHost user information @@ -38,7 +38,7 @@ ynh_user_get_info() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - sudo yunohost user info "$username" --output-as plain | ynh_get_plain_key "$key" + yunohost user info "$username" --output-as plain | ynh_get_plain_key "$key" } # Get the list of YunoHost users @@ -50,7 +50,7 @@ ynh_user_get_info() { # # Requires YunoHost version 2.4.0 or higher. ynh_user_list() { - sudo yunohost user list --output-as plain --quiet \ + yunohost user list --output-as plain --quiet \ | awk '/^##username$/{getline; print}' } diff --git a/data/hooks/backup/05-conf_ldap b/data/hooks/backup/05-conf_ldap index 9ae22095e..75b4c2075 100755 --- a/data/hooks/backup/05-conf_ldap +++ b/data/hooks/backup/05-conf_ldap @@ -11,7 +11,7 @@ backup_dir="${1}/conf/ldap" # Backup the configuration ynh_backup "/etc/ldap/slapd.conf" "${backup_dir}/slapd.conf" -sudo slapcat -b cn=config -l "${backup_dir}/cn=config.master.ldif" +slapcat -b cn=config -l "${backup_dir}/cn=config.master.ldif" # Backup the database -sudo slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif" +slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif" diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index 5528236cf..236619079 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -38,20 +38,20 @@ do_pre_regen() { if [[ -f $services_path ]]; then tmp_services_path="${services_path}-tmp" new_services_path="${services_path}-new" - sudo cp "$services_path" "$tmp_services_path" + cp "$services_path" "$tmp_services_path" _update_services "$new_services_path" || { - sudo mv "$tmp_services_path" "$services_path" + mv "$tmp_services_path" "$services_path" exit 1 } if [[ -f $new_services_path ]]; then # replace services.yml with new one - sudo mv "$new_services_path" "$services_path" - sudo mv "$tmp_services_path" "${services_path}-old" + mv "$new_services_path" "$services_path" + mv "$tmp_services_path" "${services_path}-old" else - sudo rm -f "$tmp_services_path" + rm -f "$tmp_services_path" fi else - sudo cp services.yml /etc/yunohost/services.yml + cp services.yml /etc/yunohost/services.yml fi # add cron job for diagnosis to be ran at 7h and 19h + a random delay between @@ -66,7 +66,7 @@ EOF } _update_services() { - sudo python2 - << EOF + python2 - << EOF import yaml diff --git a/data/hooks/conf_regen/02-ssl b/data/hooks/conf_regen/02-ssl index 1df3a3260..a893b21e1 100755 --- a/data/hooks/conf_regen/02-ssl +++ b/data/hooks/conf_regen/02-ssl @@ -99,13 +99,13 @@ do_post_regen() { [[ -f "${index_txt}" ]] || { if [[ -f "${index_txt}.saved" ]]; then # use saved database from 2.2 - sudo cp "${index_txt}.saved" "${index_txt}" + cp "${index_txt}.saved" "${index_txt}" elif [[ -f "${index_txt}.old" ]]; then # ... or use the state-1 database - sudo cp "${index_txt}.old" "${index_txt}" + cp "${index_txt}.old" "${index_txt}" else # ... or create an empty one - sudo touch "${index_txt}" + touch "${index_txt}" fi } diff --git a/data/hooks/conf_regen/06-slapd b/data/hooks/conf_regen/06-slapd index 4f7adda78..35a8fcf2e 100755 --- a/data/hooks/conf_regen/06-slapd +++ b/data/hooks/conf_regen/06-slapd @@ -126,7 +126,7 @@ do_post_regen() { # wait a maximum time of 5 minutes # yes, force-reload behave like a restart number_of_wait=0 - while ! sudo su admin -c '' && ((number_of_wait < 60)) + while ! su admin -c '' && ((number_of_wait < 60)) do sleep 5 ((number_of_wait += 1)) diff --git a/data/hooks/conf_regen/09-nslcd b/data/hooks/conf_regen/09-nslcd index 5071ac1fd..7090fc758 100755 --- a/data/hooks/conf_regen/09-nslcd +++ b/data/hooks/conf_regen/09-nslcd @@ -14,7 +14,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || sudo service nslcd restart + || service nslcd restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/12-metronome b/data/hooks/conf_regen/12-metronome index 7047af660..fbd956e7c 100755 --- a/data/hooks/conf_regen/12-metronome +++ b/data/hooks/conf_regen/12-metronome @@ -14,7 +14,7 @@ do_pre_regen() { # retrieve variables main_domain=$(cat /etc/yunohost/current_host) - domain_list=$(sudo yunohost domain list --output-as plain --quiet) + domain_list=$(yunohost domain list --output-as plain --quiet) # install main conf file cat metronome.cfg.lua \ @@ -42,19 +42,19 @@ do_post_regen() { regen_conf_files=$1 # retrieve variables - domain_list=$(sudo yunohost domain list --output-as plain --quiet) + domain_list=$(yunohost domain list --output-as plain --quiet) # create metronome directories for domains for domain in $domain_list; do - sudo mkdir -p "/var/lib/metronome/${domain//./%2e}/pep" + mkdir -p "/var/lib/metronome/${domain//./%2e}/pep" done # fix some permissions - sudo chown -R metronome: /var/lib/metronome/ - sudo chown -R metronome: /etc/metronome/conf.d/ + chown -R metronome: /var/lib/metronome/ + chown -R metronome: /etc/metronome/conf.d/ [[ -z "$regen_conf_files" ]] \ - || sudo service metronome restart + || service metronome restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/15-nginx b/data/hooks/conf_regen/15-nginx index 59654a771..55a5494b2 100755 --- a/data/hooks/conf_regen/15-nginx +++ b/data/hooks/conf_regen/15-nginx @@ -45,7 +45,7 @@ do_pre_regen() { # retrieve variables main_domain=$(cat /etc/yunohost/current_host) - domain_list=$(sudo yunohost domain list --output-as plain --quiet) + domain_list=$(yunohost domain list --output-as plain --quiet) # Support different strategy for security configurations export compatibility="$(yunohost settings get 'security.nginx.compatibility')" @@ -102,15 +102,15 @@ do_post_regen() { [ -z "$regen_conf_files" ] && exit 0 # retrieve variables - domain_list=$(sudo yunohost domain list --output-as plain --quiet) + domain_list=$(yunohost domain list --output-as plain --quiet) # create NGINX conf directories for domains for domain in $domain_list; do - sudo mkdir -p "/etc/nginx/conf.d/${domain}.d" + mkdir -p "/etc/nginx/conf.d/${domain}.d" done # Reload nginx configuration - pgrep nginx && sudo service nginx reload + pgrep nginx && service nginx reload } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/19-postfix b/data/hooks/conf_regen/19-postfix index b37425984..0f09f0299 100755 --- a/data/hooks/conf_regen/19-postfix +++ b/data/hooks/conf_regen/19-postfix @@ -20,7 +20,7 @@ do_pre_regen() { # prepare main.cf conf file main_domain=$(cat /etc/yunohost/current_host) - domain_list=$(sudo yunohost domain list --output-as plain --quiet | tr '\n' ' ') + domain_list=$(yunohost domain list --output-as plain --quiet | tr '\n' ' ') # Support different strategy for security configurations export compatibility="$(yunohost settings get 'security.postfix.compatibility')" @@ -49,7 +49,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || { sudo service postfix restart && sudo service postsrsd restart; } + || { service postfix restart && service postsrsd restart; } } diff --git a/data/hooks/conf_regen/25-dovecot b/data/hooks/conf_regen/25-dovecot index d7136df4d..46c9bdf3e 100755 --- a/data/hooks/conf_regen/25-dovecot +++ b/data/hooks/conf_regen/25-dovecot @@ -36,28 +36,28 @@ do_pre_regen() { do_post_regen() { regen_conf_files=$1 - sudo mkdir -p "/etc/dovecot/yunohost.d/pre-ext.d" - sudo mkdir -p "/etc/dovecot/yunohost.d/post-ext.d" + mkdir -p "/etc/dovecot/yunohost.d/pre-ext.d" + mkdir -p "/etc/dovecot/yunohost.d/post-ext.d" # create vmail user id vmail > /dev/null 2>&1 \ - || sudo adduser --system --ingroup mail --uid 500 vmail + || adduser --system --ingroup mail --uid 500 vmail # fix permissions - sudo chown -R vmail:mail /etc/dovecot/global_script - sudo chmod 770 /etc/dovecot/global_script - sudo chown root:mail /var/mail - sudo chmod 1775 /var/mail + chown -R vmail:mail /etc/dovecot/global_script + chmod 770 /etc/dovecot/global_script + chown root:mail /var/mail + chmod 1775 /var/mail [ -z "$regen_conf_files" ] && exit 0 # compile sieve script [[ "$regen_conf_files" =~ dovecot\.sieve ]] && { - sudo sievec /etc/dovecot/global_script/dovecot.sieve - sudo chown -R vmail:mail /etc/dovecot/global_script + sievec /etc/dovecot/global_script/dovecot.sieve + chown -R vmail:mail /etc/dovecot/global_script } - sudo service dovecot restart + service dovecot restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/31-rspamd b/data/hooks/conf_regen/31-rspamd index d263d9cc9..26fea4336 100755 --- a/data/hooks/conf_regen/31-rspamd +++ b/data/hooks/conf_regen/31-rspamd @@ -22,11 +22,11 @@ do_post_regen() { ## # create DKIM directory with proper permission - sudo mkdir -p /etc/dkim - sudo chown _rspamd /etc/dkim + mkdir -p /etc/dkim + chown _rspamd /etc/dkim # retrieve domain list - domain_list=$(sudo yunohost domain list --output-as plain --quiet) + domain_list=$(yunohost domain list --output-as plain --quiet) # create DKIM key for domains for domain in $domain_list; do @@ -34,30 +34,30 @@ do_post_regen() { [ ! -f "$domain_key" ] && { # We use a 1024 bit size because nsupdate doesn't seem to be able to # handle 2048... - sudo opendkim-genkey --domain="$domain" \ + opendkim-genkey --domain="$domain" \ --selector=mail --directory=/etc/dkim -b 1024 - sudo mv /etc/dkim/mail.private "$domain_key" - sudo mv /etc/dkim/mail.txt "/etc/dkim/${domain}.mail.txt" + mv /etc/dkim/mail.private "$domain_key" + mv /etc/dkim/mail.txt "/etc/dkim/${domain}.mail.txt" } done # fix DKIM keys permissions - sudo chown _rspamd /etc/dkim/*.mail.key - sudo chmod 400 /etc/dkim/*.mail.key + chown _rspamd /etc/dkim/*.mail.key + chmod 400 /etc/dkim/*.mail.key regen_conf_files=$1 [ -z "$regen_conf_files" ] && exit 0 # compile sieve script [[ "$regen_conf_files" =~ rspamd\.sieve ]] && { - sudo sievec /etc/dovecot/global_script/rspamd.sieve - sudo chown -R vmail:mail /etc/dovecot/global_script - sudo systemctl restart dovecot + sievec /etc/dovecot/global_script/rspamd.sieve + chown -R vmail:mail /etc/dovecot/global_script + systemctl restart dovecot } # Restart rspamd due to the upgrade # https://rspamd.com/announce/2016/08/01/rspamd-1.3.1.html - sudo systemctl -q restart rspamd.service + systemctl -q restart rspamd.service } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/34-mysql b/data/hooks/conf_regen/34-mysql index 8f7b5455e..43f9fdde1 100755 --- a/data/hooks/conf_regen/34-mysql +++ b/data/hooks/conf_regen/34-mysql @@ -18,12 +18,12 @@ do_post_regen() { if [ ! -f /etc/yunohost/mysql ]; then # ensure that mysql is running - sudo systemctl -q is-active mysql.service \ - || sudo service mysql start + systemctl -q is-active mysql.service \ + || service mysql start # generate and set new root password mysql_password=$(ynh_string_random 10) - sudo mysqladmin -s -u root -pyunohost password "$mysql_password" || { + mysqladmin -s -u root -pyunohost password "$mysql_password" || { if [ $FORCE -eq 1 ]; then echo "It seems that you have already configured MySQL." \ "YunoHost needs to have a root access to MySQL to runs its" \ @@ -31,13 +31,13 @@ do_post_regen() { "You can find this new password in /etc/yunohost/mysql." >&2 # set new password with debconf - sudo debconf-set-selections << EOF + debconf-set-selections << EOF $MYSQL_PKG mysql-server/root_password password $mysql_password $MYSQL_PKG mysql-server/root_password_again password $mysql_password EOF # reconfigure Debian package - sudo dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 + dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 else echo "It seems that you have already configured MySQL." \ "YunoHost needs to have a root access to MySQL to runs its" \ @@ -49,12 +49,12 @@ EOF } # store new root password - echo "$mysql_password" | sudo tee /etc/yunohost/mysql - sudo chmod 400 /etc/yunohost/mysql + echo "$mysql_password" | tee /etc/yunohost/mysql + chmod 400 /etc/yunohost/mysql fi [[ -z "$regen_conf_files" ]] \ - || sudo service mysql restart + || service mysql restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/37-avahi-daemon b/data/hooks/conf_regen/37-avahi-daemon index 655a2e054..239c3ad0c 100755 --- a/data/hooks/conf_regen/37-avahi-daemon +++ b/data/hooks/conf_regen/37-avahi-daemon @@ -15,7 +15,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || sudo service avahi-daemon restart + || service avahi-daemon restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/40-glances b/data/hooks/conf_regen/40-glances index a19d35d56..70b8f4b5a 100755 --- a/data/hooks/conf_regen/40-glances +++ b/data/hooks/conf_regen/40-glances @@ -14,7 +14,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || sudo service glances restart + || service glances restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/43-dnsmasq b/data/hooks/conf_regen/43-dnsmasq index ed795c058..90e96a04c 100755 --- a/data/hooks/conf_regen/43-dnsmasq +++ b/data/hooks/conf_regen/43-dnsmasq @@ -26,7 +26,7 @@ do_pre_regen() { ynh_validate_ip4 "$ipv4" || ipv4='127.0.0.1' ipv6=$(curl -s -6 https://ip6.yunohost.org 2>/dev/null || true) ynh_validate_ip6 "$ipv6" || ipv6='' - domain_list=$(sudo yunohost domain list --output-as plain --quiet) + domain_list=$(yunohost domain list --output-as plain --quiet) # add domain conf files for domain in $domain_list; do @@ -51,7 +51,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || sudo service dnsmasq restart + || service dnsmasq restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/46-nsswitch b/data/hooks/conf_regen/46-nsswitch index 06a596e44..fa9b07511 100755 --- a/data/hooks/conf_regen/46-nsswitch +++ b/data/hooks/conf_regen/46-nsswitch @@ -14,7 +14,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || sudo service unscd restart + || service unscd restart } FORCE=${2:-0} diff --git a/data/hooks/conf_regen/52-fail2ban b/data/hooks/conf_regen/52-fail2ban index 950f27b5b..3cb499db7 100755 --- a/data/hooks/conf_regen/52-fail2ban +++ b/data/hooks/conf_regen/52-fail2ban @@ -20,7 +20,7 @@ do_post_regen() { regen_conf_files=$1 [[ -z "$regen_conf_files" ]] \ - || sudo service fail2ban restart + || service fail2ban restart } FORCE=${2:-0} diff --git a/data/hooks/restore/05-conf_ldap b/data/hooks/restore/05-conf_ldap index eb6824993..74093136d 100644 --- a/data/hooks/restore/05-conf_ldap +++ b/data/hooks/restore/05-conf_ldap @@ -5,7 +5,7 @@ if [[ $EUID -ne 0 ]]; then # We need to execute this script as root, since the ldap # service will be shut down during the operation (and sudo # won't be available) - sudo /bin/bash $(readlink -f $0) $1 + /bin/bash $(readlink -f $0) $1 else diff --git a/data/hooks/restore/08-conf_ssh b/data/hooks/restore/08-conf_ssh index 0c0f9bf9b..4b69d1696 100644 --- a/data/hooks/restore/08-conf_ssh +++ b/data/hooks/restore/08-conf_ssh @@ -1,8 +1,8 @@ backup_dir="$1/conf/ssh" if [ -d /etc/ssh/ ]; then - sudo cp -a $backup_dir/. /etc/ssh - sudo service ssh restart + cp -a $backup_dir/. /etc/ssh + service ssh restart else echo "SSH is not installed" fi diff --git a/data/hooks/restore/11-conf_ynh_mysql b/data/hooks/restore/11-conf_ynh_mysql index 24cdb1e79..f54641d6f 100644 --- a/data/hooks/restore/11-conf_ynh_mysql +++ b/data/hooks/restore/11-conf_ynh_mysql @@ -9,15 +9,15 @@ service mysql status >/dev/null 2>&1 \ # retrieve current and new password [ -f /etc/yunohost/mysql ] \ - && curr_pwd=$(sudo cat /etc/yunohost/mysql) -new_pwd=$(sudo cat "${backup_dir}/root_pwd" || sudo cat "${backup_dir}/mysql") + && curr_pwd=$(cat /etc/yunohost/mysql) +new_pwd=$(cat "${backup_dir}/root_pwd" || cat "${backup_dir}/mysql") [ -z "$curr_pwd" ] && curr_pwd="yunohost" [ -z "$new_pwd" ] && { new_pwd=$(ynh_string_random 10) } # attempt to change it -sudo mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || { +mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || { echo "It seems that you have already configured MySQL." \ "YunoHost needs to have a root access to MySQL to runs its" \ @@ -25,18 +25,18 @@ sudo mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || { "You can find this new password in /etc/yunohost/mysql." >&2 # set new password with debconf - sudo debconf-set-selections << EOF + debconf-set-selections << EOF $MYSQL_PKG mysql-server/root_password password $new_pwd $MYSQL_PKG mysql-server/root_password_again password $new_pwd EOF # reconfigure Debian package - sudo dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 + dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 } # store new root password -echo "$new_pwd" | sudo tee /etc/yunohost/mysql -sudo chmod 400 /etc/yunohost/mysql +echo "$new_pwd" | tee /etc/yunohost/mysql +chmod 400 /etc/yunohost/mysql # reload the grant tables -sudo mysqladmin -s -u root -p"$new_pwd" reload +mysqladmin -s -u root -p"$new_pwd" reload diff --git a/data/hooks/restore/14-conf_ssowat b/data/hooks/restore/14-conf_ssowat index 01ac787ee..71a011488 100644 --- a/data/hooks/restore/14-conf_ssowat +++ b/data/hooks/restore/14-conf_ssowat @@ -1,3 +1,3 @@ backup_dir="$1/conf/ssowat" -sudo cp -a $backup_dir/. /etc/ssowat +cp -a $backup_dir/. /etc/ssowat diff --git a/data/hooks/restore/17-data_home b/data/hooks/restore/17-data_home index a7ba2733c..6226eab6d 100644 --- a/data/hooks/restore/17-data_home +++ b/data/hooks/restore/17-data_home @@ -1,3 +1,3 @@ backup_dir="$1/data/home" -sudo cp -a $backup_dir/. /home +cp -a $backup_dir/. /home diff --git a/data/hooks/restore/20-conf_ynh_firewall b/data/hooks/restore/20-conf_ynh_firewall index c0ee18818..1789aed1e 100644 --- a/data/hooks/restore/20-conf_ynh_firewall +++ b/data/hooks/restore/20-conf_ynh_firewall @@ -1,4 +1,4 @@ backup_dir="$1/conf/ynh/firewall" -sudo cp -a $backup_dir/. /etc/yunohost -sudo yunohost firewall reload +cp -a $backup_dir/. /etc/yunohost +yunohost firewall reload diff --git a/data/hooks/restore/21-conf_ynh_certs b/data/hooks/restore/21-conf_ynh_certs index 34e651319..983bfb5a1 100644 --- a/data/hooks/restore/21-conf_ynh_certs +++ b/data/hooks/restore/21-conf_ynh_certs @@ -1,7 +1,7 @@ backup_dir="$1/conf/ynh/certs" -sudo mkdir -p /etc/yunohost/certs/ +mkdir -p /etc/yunohost/certs/ -sudo cp -a $backup_dir/. /etc/yunohost/certs/ -sudo service nginx reload -sudo service metronome reload +cp -a $backup_dir/. /etc/yunohost/certs/ +service nginx reload +service metronome reload diff --git a/data/hooks/restore/23-data_mail b/data/hooks/restore/23-data_mail index 81b9b923f..f9fd6e699 100644 --- a/data/hooks/restore/23-data_mail +++ b/data/hooks/restore/23-data_mail @@ -1,8 +1,8 @@ backup_dir="$1/data/mail" -sudo cp -a $backup_dir/. /var/mail/ || echo 'No mail found' -sudo chown -R vmail:mail /var/mail/ +cp -a $backup_dir/. /var/mail/ || echo 'No mail found' +chown -R vmail:mail /var/mail/ # Restart services to use migrated certs -sudo service postfix restart -sudo service dovecot restart +service postfix restart +service dovecot restart diff --git a/data/hooks/restore/26-conf_xmpp b/data/hooks/restore/26-conf_xmpp index 61692b316..a300a7268 100644 --- a/data/hooks/restore/26-conf_xmpp +++ b/data/hooks/restore/26-conf_xmpp @@ -1,7 +1,7 @@ backup_dir="$1/conf/xmpp" -sudo cp -a $backup_dir/etc/. /etc/metronome -sudo cp -a $backup_dir/var/. /var/lib/metronome +cp -a $backup_dir/etc/. /etc/metronome +cp -a $backup_dir/var/. /var/lib/metronome # Restart to apply new conf and certs -sudo service metronome restart +service metronome restart diff --git a/data/hooks/restore/29-conf_nginx b/data/hooks/restore/29-conf_nginx index 0795f53df..7288f52f3 100644 --- a/data/hooks/restore/29-conf_nginx +++ b/data/hooks/restore/29-conf_nginx @@ -1,7 +1,7 @@ backup_dir="$1/conf/nginx" # Copy all conf except apps specific conf located in DOMAIN.d -sudo find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec sudo cp -a {} /etc/nginx/conf.d/ \; +find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec cp -a {} /etc/nginx/conf.d/ \; # Restart to use new conf and certs -sudo service nginx restart +service nginx restart diff --git a/data/hooks/restore/32-conf_cron b/data/hooks/restore/32-conf_cron index 68657963e..59a2bde61 100644 --- a/data/hooks/restore/32-conf_cron +++ b/data/hooks/restore/32-conf_cron @@ -1,6 +1,6 @@ backup_dir="$1/conf/cron" -sudo cp -a $backup_dir/. /etc/cron.d +cp -a $backup_dir/. /etc/cron.d # Restart just in case -sudo service cron restart +service cron restart diff --git a/data/hooks/restore/40-conf_ynh_currenthost b/data/hooks/restore/40-conf_ynh_currenthost index a0bdf94d3..700e806b4 100644 --- a/data/hooks/restore/40-conf_ynh_currenthost +++ b/data/hooks/restore/40-conf_ynh_currenthost @@ -1,3 +1,3 @@ backup_dir="$1/conf/ynh" -sudo cp -a "${backup_dir}/current_host" /etc/yunohost/current_host +cp -a "${backup_dir}/current_host" /etc/yunohost/current_host diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index c05933dc0..e081f1b3a 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -180,9 +180,9 @@ def _set_hostname(hostname, pretty_hostname=None): # Then call hostnamectl commands = [ - "sudo hostnamectl --static set-hostname".split() + [hostname], - "sudo hostnamectl --transient set-hostname".split() + [hostname], - "sudo hostnamectl --pretty set-hostname".split() + [pretty_hostname] + "hostnamectl --static set-hostname".split() + [hostname], + "hostnamectl --transient set-hostname".split() + [hostname], + "hostnamectl --pretty set-hostname".split() + [pretty_hostname] ] for command in commands: From 32b6c2eccfdecc16269c32cb4fc916fbcf5d4b52 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 29 Nov 2019 20:39:18 +0900 Subject: [PATCH 006/104] Visitors permission needs All Users --- data/helpers.d/setting | 2 +- locales/en.json | 2 +- src/yunohost/app.py | 6 +++--- src/yunohost/permission.py | 18 +++++++++++++----- src/yunohost/tests/test_backuprestore.py | 4 ++-- src/yunohost/tests/test_permission.py | 8 ++++---- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index f0963444a..93386c9dd 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -189,7 +189,7 @@ EOF # We need this because app temporarily set the app as unprotected to configure it with curl... if [[ "$3" =~ ^(unprotected|skipped)_ ]] && [[ "${4:-}" == "/" ]] then - ynh_permission_update --permission "main" --remove "all_users" --add "visitors" + ynh_permission_update --permission "main" --add "visitors" fi } diff --git a/locales/en.json b/locales/en.json index b3e79ca92..71e17a7c8 100644 --- a/locales/en.json +++ b/locales/en.json @@ -471,7 +471,7 @@ "permission_cannot_remove_main": "Removing a main permission is not allowed", "permission_created": "Permission '{permission:s}' created", "permission_creation_failed": "Could not create permission '{permission}': {error}", - "permission_currently_allowed_for_visitors": "This permission is currently granted to visitors in addition to other groups. You probably want to either remove the 'visitors' permission or remove the other groups it is currently granted to.", + "permission_allowed_for_visitors_but_not_for_all_users": "Visitors can't be granted if all users is not already granted.", "permission_currently_allowed_for_all_users": "This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.", "permission_deleted": "Permission '{permission:s}' deleted", "permission_deletion_failed": "Could not delete permission '{permission}': {error}", diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 0e4a473b4..5ccca1394 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -959,12 +959,12 @@ def _migrate_legacy_permissions(app): # If the current permission says app is protected, but there are legacy rules saying it should be public... if app_perm_currently_allowed == ["all_users"] and settings_say_it_should_be_public: # Make it public - user_permission_update(app + ".main", remove="all_users", add="visitors", sync_perm=False) + user_permission_update(app + ".main", add="visitors", sync_perm=False) # If the current permission says app is public, but there are no setting saying it should be public... if app_perm_currently_allowed == ["visitors"] and not settings_say_it_should_be_public: # Make is private - user_permission_update(app + ".main", remove="visitors", add="all_users", sync_perm=False) + user_permission_update(app + ".main", remove="visitors", sync_perm=False) @is_unit_operation() @@ -1194,7 +1194,7 @@ def app_setting(app, key, value=None, delete=False): # We need this because app temporarily set the app as unprotected to configure it with curl... if key.startswith("unprotected_") or key.startswith("skipped_") and value == "/": from permission import user_permission_update - user_permission_update(app + ".main", remove="all_users", add="visitors") + user_permission_update(app + ".main", add="visitors") def app_register_url(app, domain, path): diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 0b88254ce..90f1bb9f0 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -140,12 +140,14 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, # If we end up with something like allowed groups is ["all_users", "volunteers"] # we shall warn the users that they should probably choose between one or the other, # because the current situation is probably not what they expect / is temporary ? - - if len(new_allowed_groups) > 1: - if "all_users" in new_allowed_groups: + + if "all_users" in new_allowed_groups: + if len(new_allowed_groups) > 1 and "visitors" not in new_allowed_groups or len(new_allowed_groups) > 2: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) - if "visitors" in new_allowed_groups: - logger.warning(m18n.n("permission_currently_allowed_for_visitors")) + + # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. + if "visitors" in new_allowed_groups and "all_users" not in new_allowed_groups: + raise YunohostError('permission_allowed_for_visitors_but_not_for_all_users') # Don't update LDAP if we update exactly the same values if set(new_allowed_groups) == set(current_allowed_groups): @@ -258,6 +260,12 @@ def permission_create(operation_logger, permission, url=None, allowed=None, sync if url: attr_dict['URL'] = url + if allowed is not None: + if "visitors" in allowed and "all_users" not in allowed: + if not isinstance(allowed, list): + allowed = [allowed] + allowed.append("all_users") + # Validate that the groups to add actually exist all_existing_groups = user_group_list()['groups'].keys() allowed_ = [] if allowed is None else [allowed] if not isinstance(allowed, list) else allowed diff --git a/src/yunohost/tests/test_backuprestore.py b/src/yunohost/tests/test_backuprestore.py index 48fe7f5d8..d6bc1bb31 100644 --- a/src/yunohost/tests/test_backuprestore.py +++ b/src/yunohost/tests/test_backuprestore.py @@ -510,7 +510,7 @@ def test_backup_and_restore_permission_app(mocker): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert res['permissions_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] @@ -524,7 +524,7 @@ def test_backup_and_restore_permission_app(mocker): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert res['permissions_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index b3fa9fefb..f11d215f1 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -460,13 +460,13 @@ def test_permission_app_propagation_on_ssowat(): args="domain=%s&path=%s&is_public=1&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True) res = user_permission_list(full=True)['permissions'] - assert res['permissions_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] app_webroot = "https://%s/urlpermissionapp" % maindomain assert can_access_webpage(app_webroot, logged_as=None) assert can_access_webpage(app_webroot, logged_as="alice") - user_permission_update("permissions_app.main", remove="visitors", add="bob") + user_permission_update("permissions_app.main", remove=["visitors", "all_users"], add="bob") res = user_permission_list(full=True)['permissions'] assert not can_access_webpage(app_webroot, logged_as=None) @@ -491,7 +491,7 @@ def test_permission_legacy_app_propagation_on_ssowat(): # App is configured as public by default using the legacy unprotected_uri mechanics # It should automatically be migrated during the install res = user_permission_list(full=True)['permissions'] - assert res['legacy_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['legacy_app.main']['allowed'] and "all_users" in res['legacy_app.main']['allowed'] app_webroot = "https://%s/legacy" % maindomain @@ -499,7 +499,7 @@ def test_permission_legacy_app_propagation_on_ssowat(): assert can_access_webpage(app_webroot, logged_as="alice") # Try to update the permission and check that permissions are still consistent - user_permission_update("legacy_app.main", remove="visitors", add="bob") + user_permission_update("legacy_app.main", remove=["visitors", "all_users"], add="bob") assert not can_access_webpage(app_webroot, logged_as=None) assert not can_access_webpage(app_webroot, logged_as="alice") From 9697ca8e4b730b3c9ad1187d8fdce8b0f03d14ee Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 29 Nov 2019 15:51:43 +0100 Subject: [PATCH 007/104] Let's convert this in list in all cases (+ simplify later core) --- src/yunohost/permission.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 90f1bb9f0..6603d6bdc 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -140,11 +140,11 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, # If we end up with something like allowed groups is ["all_users", "volunteers"] # we shall warn the users that they should probably choose between one or the other, # because the current situation is probably not what they expect / is temporary ? - + if "all_users" in new_allowed_groups: if len(new_allowed_groups) > 1 and "visitors" not in new_allowed_groups or len(new_allowed_groups) > 2: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) - + # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. if "visitors" in new_allowed_groups and "all_users" not in new_allowed_groups: raise YunohostError('permission_allowed_for_visitors_but_not_for_all_users') @@ -261,15 +261,14 @@ def permission_create(operation_logger, permission, url=None, allowed=None, sync attr_dict['URL'] = url if allowed is not None: + if not isinstance(allowed, list): + allowed = [allowed] if "visitors" in allowed and "all_users" not in allowed: - if not isinstance(allowed, list): - allowed = [allowed] allowed.append("all_users") # Validate that the groups to add actually exist all_existing_groups = user_group_list()['groups'].keys() - allowed_ = [] if allowed is None else [allowed] if not isinstance(allowed, list) else allowed - for group in allowed_: + for group in allowed or []: if group not in all_existing_groups: raise YunohostError('group_unknown', group=group) From 7247c9f7aa7c3870e41e9954f93e52284322010c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 29 Nov 2019 16:06:26 +0100 Subject: [PATCH 008/104] Let's keep one thread per line for readability + easier to indentify the issue --- src/yunohost/tests/test_backuprestore.py | 6 ++++-- src/yunohost/tests/test_permission.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/yunohost/tests/test_backuprestore.py b/src/yunohost/tests/test_backuprestore.py index d6bc1bb31..bcba21bb6 100644 --- a/src/yunohost/tests/test_backuprestore.py +++ b/src/yunohost/tests/test_backuprestore.py @@ -510,7 +510,8 @@ def test_backup_and_restore_permission_app(mocker): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] + assert "visitors" in res['permissions_app.main']['allowed'] + assert "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] @@ -524,7 +525,8 @@ def test_backup_and_restore_permission_app(mocker): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] + assert "visitors" in res['permissions_app.main']['allowed'] + assert "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index f11d215f1..a4bd570e5 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -460,7 +460,8 @@ def test_permission_app_propagation_on_ssowat(): args="domain=%s&path=%s&is_public=1&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True) res = user_permission_list(full=True)['permissions'] - assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] + assert "visitors" in res['permissions_app.main']['allowed'] + assert "all_users" in res['permissions_app.main']['allowed'] app_webroot = "https://%s/urlpermissionapp" % maindomain assert can_access_webpage(app_webroot, logged_as=None) @@ -491,7 +492,8 @@ def test_permission_legacy_app_propagation_on_ssowat(): # App is configured as public by default using the legacy unprotected_uri mechanics # It should automatically be migrated during the install res = user_permission_list(full=True)['permissions'] - assert "visitors" in res['legacy_app.main']['allowed'] and "all_users" in res['legacy_app.main']['allowed'] + assert "visitors" in res['legacy_app.main']['allowed'] + assert "all_users" in res['legacy_app.main']['allowed'] app_webroot = "https://%s/legacy" % maindomain From 54a5ecebd763c8999f038c756e6ff915e110b80c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 29 Nov 2019 16:41:50 +0100 Subject: [PATCH 009/104] Try to improve readability for these conditions --- src/yunohost/permission.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 6603d6bdc..75a00d6c5 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -138,11 +138,12 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, new_allowed_groups = [g for g in new_allowed_groups if g not in groups_to_remove] # If we end up with something like allowed groups is ["all_users", "volunteers"] - # we shall warn the users that they should probably choose between one or the other, - # because the current situation is probably not what they expect / is temporary ? - - if "all_users" in new_allowed_groups: - if len(new_allowed_groups) > 1 and "visitors" not in new_allowed_groups or len(new_allowed_groups) > 2: + # we shall warn the users that they should probably choose between one or + # the other, because the current situation is probably not what they expect + # / is temporary ? Note that it's fine to have ["all_users", "visitors"] + # though, but it's not fine to have ["all_users", "visitors", "volunteers"] + if "all_users" in new_allowed_groups and len(new_allowed_groups) >= 2: + if "visitors" not in new_allowed_groups or len(new_allowed_groups) >= 3: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. From df3051f2de14bd6adb7f109ae1b62f114f889b66 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 30 Nov 2019 18:10:39 +0100 Subject: [PATCH 010/104] Handle subtag title internationalization also --- src/yunohost/app.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index a54a18c6f..276897eb8 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -96,6 +96,8 @@ def app_catalog(full=False, with_categories=False): for category in catalog["categories"]: category["title"] = _value_for_locale(category["title"]) category["description"] = _value_for_locale(category["description"]) + for subtags in category.get("subtags", []): + subtags["title"] = _value_for_locale(subtags["title"]) if not full: catalog["categories"] = [{"id": c["id"], From c97a839630e0011442a588b7f56eb0ca8f7a974b Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 1 Dec 2019 18:41:47 +0100 Subject: [PATCH 011/104] Custom service description: let's be a bit smarter and use the one from the systemd service if it exists --- src/yunohost/service.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index f8553fbf7..748037df6 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -79,7 +79,16 @@ def service_add(name, description=None, log=None, log_type="file", test_status=N if description: services[name]['description'] = description else: - logger.warning("/!\\ Packager ! You added a custom service without specifying a description. Please add --description to explain what the service does in a similar fashion to existing services.") + # Try to get the description from systemd service + out = subprocess.check_output("systemctl show %s | grep '^Description='" % name, shell=True) + out = out.replace("Description=", "") + # If the service does not yet exists or if the description is empty, + # systemd will anyway return foo.service as default value, so we wanna + # make sure there's actually something here. + if out == name + ".service": + logger.warning("/!\\ Packager ! You added a custom service without specifying a description. Please add a proper Description in the systemd configuration, or use --description to explain what the service does in a similar fashion to existing services.") + else: + services[name]['description'] = out if need_lock: services[name]['need_lock'] = True From 99e70af08ce6a6f1bf94e8c27af70a6e209902fe Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 2 Dec 2019 18:09:43 +0100 Subject: [PATCH 012/104] Additonal cleaning of legacy stuff when using new permission system + avoid duplicated entries in (un)protected_urls --- src/yunohost/app.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 0e4a473b4..8897cb427 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1328,16 +1328,18 @@ def app_ssowatconf(): # FIXME : gotta handle regex-urls here... meh url = _sanitized_absolute_url(perm_info["url"]) if "visitors" in perm_info["allowed"]: - unprotected_urls.append(url) + if url not in unprotected_urls: + unprotected_urls.append(url) - # Legacy stuff : we remove now unprotected-urls that might have been declared as protected earlier... + # Legacy stuff : we remove now protected-urls that might have been declared as unprotected earlier... protected_urls = [u for u in protected_urls if u != url] else: - # TODO : small optimization to implement : we don't need to explictly add all the app roots - protected_urls.append(url) + if url not in protected_urls: + protected_urls.append(url) - # Legacy stuff : we remove now unprotected-urls that might have been declared as protected earlier... + # Legacy stuff : we remove now unprotected-urls / skipped-urls that might have been declared as protected earlier... unprotected_urls = [u for u in unprotected_urls if u != url] + skipped_urls = [u for u in skipped_urls if u != url] for domain in domains: skipped_urls.extend([domain + '/yunohost/admin', domain + '/yunohost/api']) From 442cec170d68f7d068816695b45663d1b612185d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 2 Dec 2019 19:04:07 +0100 Subject: [PATCH 013/104] Implicitly add all_users when adding visitors group --- locales/en.json | 3 ++- src/yunohost/permission.py | 12 +++++++++--- src/yunohost/tests/test_permission.py | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/locales/en.json b/locales/en.json index 71e17a7c8..08fc6b74e 100644 --- a/locales/en.json +++ b/locales/en.json @@ -464,14 +464,15 @@ "pattern_positive_number": "Must be a positive number", "pattern_username": "Must be lower-case alphanumeric and underscore characters only", "pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}", + "permission_all_users_implicitly_added": "The permission was also implicitly granted to 'all_users' because it is required to allow the special group 'visitors'", "permission_already_allowed": "Group '{group}' already has permission '{permission}' enabled", "permission_already_disallowed": "Group '{group}' already has permission '{permission}' disabled'", "permission_already_exist": "Permission '{permission}' already exists", "permission_already_up_to_date": "The permission was not updated because the addition/removal requests already match the current state.", + "permission_cannot_remove_all_users_while_visitors_allowed": "You can't remove this permission for 'all_users' while it is still allowed for 'visitors'", "permission_cannot_remove_main": "Removing a main permission is not allowed", "permission_created": "Permission '{permission:s}' created", "permission_creation_failed": "Could not create permission '{permission}': {error}", - "permission_allowed_for_visitors_but_not_for_all_users": "Visitors can't be granted if all users is not already granted.", "permission_currently_allowed_for_all_users": "This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.", "permission_deleted": "Permission '{permission:s}' deleted", "permission_deletion_failed": "Could not delete permission '{permission}': {error}", diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 75a00d6c5..5fe9f327f 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -146,9 +146,15 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, if "visitors" not in new_allowed_groups or len(new_allowed_groups) >= 3: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) - # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. - if "visitors" in new_allowed_groups and "all_users" not in new_allowed_groups: - raise YunohostError('permission_allowed_for_visitors_but_not_for_all_users') + # If visitors are to be added, we shall make sure that "all_users" are also allowed + # (e.g. if visitors are allowed to visit nextcloud, you still want to allow people to log in ...) + if add and "visitors" in groups_to_add and "all_users" not in new_allowed_groups: + new_allowed_groups.append("all_users") + logger.warning(m18n.n("permission_all_users_implicitly_added")) + # If all_users are to be added, yet visitors are still to allowed, then we + # refuse it (c.f. previous comment...) + if remove and "all_users" in groups_to_remove and "visitors" in new_allowed_groups: + raise YunohostError('permission_cannot_remove_all_users_while_visitors_allowed') # Don't update LDAP if we update exactly the same values if set(new_allowed_groups) == set(current_allowed_groups): diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index a4bd570e5..2e53f13a7 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -313,6 +313,27 @@ def test_permission_add_and_remove_group(mocker): assert res['wiki.main']['corresponding_users'] == ["alice"] +def test_permission_adding_visitors_implicitly_add_all_users(mocker): + + res = user_permission_list(full=True)['permissions'] + assert res['blog.main']['allowed'] == ["alice"] + + with message(mocker, "permission_updated", permission="blog.main"): + user_permission_update("blog.main", add="visitors") + + res = user_permission_list(full=True)['permissions'] + assert set(res['blog.main']['allowed']) == set(["alice", "visitors", "all_users"]) + + +def test_permission_cant_remove_all_users_if_visitors_allowed(mocker): + + with message(mocker, "permission_updated", permission="blog.main"): + user_permission_update("blog.main", add=["visitors", "all_users"]) + + with raiseYunohostError(mocker, 'permission_cannot_remove_all_users_while_visitors_allowed'): + user_permission_update("blog.main", remove="all_users") + + def test_permission_add_group_already_allowed(mocker): with message(mocker, "permission_already_allowed", permission="blog.main", group="alice"): user_permission_update("blog.main", add="alice") From 7b6d6d78723d88a7267618dc1648f160a247127b Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Fri, 22 Nov 2019 23:10:49 +0000 Subject: [PATCH 014/104] Translated using Weblate (Catalan) Currently translated at 100.0% (605 of 605 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index 26fd8c889..a079c519f 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -406,7 +406,7 @@ "regenconf_file_updated": "El fitxer de configuració «{conf}» ha estat actualitzat", "regenconf_now_managed_by_yunohost": "El fitxer de configuració «{conf}» serà gestionat per YunoHost a partir d'ara (categoria {category}).", "regenconf_up_to_date": "La configuració ja està al dia per la categoria «{category}»", - "regenconf_updated": "La configuració per la categoria «{category}» ha estat actualitzada", + "regenconf_updated": "S'ha actualitzat la configuració per la categoria «{category}»", "regenconf_would_be_updated": "La configuració hagués estat actualitzada per la categoria «{category}»", "regenconf_dry_pending_applying": "Verificació de la configuració pendent que s'hauria d'haver aplicat per la categoria «{category}»…", "regenconf_failed": "No s'ha pogut regenerar la configuració per la/les categoria/es : {categories}", @@ -457,10 +457,10 @@ "service_description_ssh": "Permet la connexió remota al servidor via terminal (protocol SSH)", "service_description_yunohost-api": "Gestiona les interaccions entre la interfície web de YunoHost i el sistema", "service_description_yunohost-firewall": "Gestiona els ports de connexió oberts i tancats als serveis", - "service_disable_failed": "No s'han pogut deshabilitar el servei «{service:s}»\n\nRegistres recents: {logs:s}", - "service_disabled": "S'ha deshabilitat el servei «{service:s}»", - "service_enable_failed": "No s'ha pogut activar el servei «{service:s}»\n\nRegistres recents: {log:s}", - "service_enabled": "S'ha activat el servei «{service:s}»", + "service_disable_failed": "No s'han pogut fer que el servei «{service:s}» no comenci a l'arrancada.\n\nRegistres recents: {logs:s}", + "service_disabled": "El servei «{service:s}» ja no començarà al arrancar el sistema.", + "service_enable_failed": "No s'ha pogut fer que el servei «{service:s}» comenci automàticament a l'arrancada.\n\nRegistres recents: {log:s}", + "service_enabled": "El servei «{service:s}» començarà automàticament durant l'arrancada del sistema.", "service_no_log": "No hi ha cap registre pel servei «{service:s}»", "service_regen_conf_is_deprecated": "«yunohost service regen-conf» està desfasat! Utilitzeu «yunohost tools regen-conf» en el seu lloc.", "service_remove_failed": "No s'ha pogut eliminar el servei «{service:s}»", @@ -663,10 +663,10 @@ "diagnosis_ip_weird_resolvconf_details": "En canvi, aquest fitxer hauria de ser un enllaç simbòlic cap a /etc/resolvconf/run/resolv.conf i que aquest apunti cap a 127.0.0.1 (dnsmasq). La configuració del «resolver» real s'hauria de fer via /etc/resolv.dnsmaq.conf.", "diagnosis_dns_good_conf": "Bona configuració DNS pel domini {domain} (categoria {category})", "diagnosis_dns_bad_conf": "Configuració DNS incorrecta o inexistent pel domini {domain} (categoria {category})", - "diagnosis_dns_missing_record": "Segons la configuració DNS recomanada, hauríeu d'afegir un registre DNS de tipus {0}, nom {1} i valor {2}", - "diagnosis_dns_discrepancy": "Segons la configuració DNS recomanada, el valor pel registre DNS de tipus {0} i nom {1} hauria de ser {2}, en comptes de {3}.", + "diagnosis_dns_missing_record": "Segons la configuració DNS recomanada, hauríeu d'afegir un registre DNS de tipus {0}, nom {1} i valor {2}. Hi ha més informació a https://yunohost.org/dns_config.", + "diagnosis_dns_discrepancy": "El registre DNS de tipus {0} i nom {1} no concorda amb la configuració recomanada. Valor actual: {2}. Valor esperat: {3}. Més informació a https://yunohost.org/dns_config.", "diagnosis_services_good_status": "El servei {service} està {status} tal i com s'esperava!", - "diagnosis_services_bad_status": "El servei {service} està {status} :/", + "diagnosis_services_bad_status": "El servei {service} està {status} :(", "diagnosis_diskusage_verylow": "El lloc d'emmagatzematge {mountpoint} (en l'aparell {device}) només té disponibles {free_abs_GB} GB ({free_percent}%). Hauríeu de considerar alliberar una mica d'espai.", "diagnosis_diskusage_low": "El lloc d'emmagatzematge {mountpoint} (en l'aparell {device}) només té disponibles {free_abs_GB} GB ({free_percent}%). Aneu amb compte.", "diagnosis_diskusage_ok": "El lloc d'emmagatzematge {mountpoint} (en l'aparell {device}) encara té {free_abs_GB} GB ({free_percent}%) lliures!", @@ -704,5 +704,17 @@ "diagnosis_mail_ougoing_port_25_blocked": "Sembla que el port de sortida 25 està bloquejat. Hauríeu d'intentar desbloquejar-lo al panell de configuració del proveïdor d'accés a internet (o allotjador). Mentrestant, el servidor no podrà enviar correus a altres servidors.", "diagnosis_description_mail": "Correu electrònic", "migration_description_0013_futureproof_apps_catalog_system": "Migrar al nou sistema de catàleg d'aplicacions resistent al pas del temps", - "app_upgrade_script_failed": "Hi ha hagut un error en el script d'actualització de l'aplicació" + "app_upgrade_script_failed": "Hi ha hagut un error en el script d'actualització de l'aplicació", + "diagnosis_services_bad_status_tip": "Podeu intentar reiniciar el servei, i si no funciona, podeu mirar els registres del servei utilitzant «yunohost service log {0}» o a través de «Serveis» a la secció de la pàgina web d'administració.", + "diagnosis_ports_forwarding_tip": "Per arreglar aquest problema, segurament s'ha de configurar el reenviament de ports en el router tal i s'explica a https://yunohost.org/isp_box_config", + "diagnosis_http_bad_status_code": "No s'ha pogut connectar al servidor com esperat, ha retornat un codi d'estat erroni. Podria ser que una altra màquina hagi contestat en lloc del servidor. S'hauria de comprovar que el reenviament del port 80 sigui correcte, que la configuració NGINX està actualitzada i que el reverse-proxy no està interferint.", + "diagnosis_no_cache": "Encara no hi ha memòria cau pel diagnòstic de la categoria «{category}»", + "diagnosis_http_timeout": "S'ha exhaurit el temps d'esperar intentant connectar amb el servidor des de l'exterior. Sembla que no s'hi pot accedir. S'hauria de comprovar que el reenviament del port 80 és correcte, que NGINX funciona, i que el tallafocs no està interferint.", + "diagnosis_http_connection_error": "Error de connexió: no s'ha pogut connectar amb el domini demanat, segurament és inaccessible.", + "diagnosis_http_unknown_error": "Hi ha hagut un error intentant accedir al domini, segurament és inaccessible.", + "yunohost_postinstall_end_tip": "S'ha completat la post-instal·lació. Per acabar la configuració, considereu:\n - afegir un primer usuari a través de la secció «Usuaris» a la pàgina web d'administració (o emprant «yunohost user create » a la línia d'ordres);\n - diagnosticar els problemes esperant a ser resolts per un correcte funcionament del servidor a través de la secció «Diagnòstics» a la pàgina web d'administració (o emprant «yunohost diagnosis run» a la línia d'ordres);\n - llegir les seccions «Finalizing your setup» i «Getting to know Yunohost» a la documentació per administradors: https://yunohost.org/admindoc.", + "migration_description_0014_remove_app_status_json": "Eliminar els fitxers d'aplicació status.json heretats", + "diagnosis_services_running": "El servei {service} s'està executant!", + "diagnosis_services_conf_broken": "La configuració pel servei {service} està trencada!", + "diagnosis_ports_needed_by": "És necessari exposar aquest port pel servei {0}" } From 6e606cc64dbb0860f94b2bb31c7db2918b90bf6d Mon Sep 17 00:00:00 2001 From: Kay0u Date: Fri, 29 Nov 2019 20:39:18 +0900 Subject: [PATCH 015/104] Visitors permission needs All Users --- data/helpers.d/setting | 2 +- locales/en.json | 2 +- src/yunohost/app.py | 6 +++--- src/yunohost/permission.py | 18 +++++++++++++----- src/yunohost/tests/test_backuprestore.py | 4 ++-- src/yunohost/tests/test_permission.py | 8 ++++---- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index 8046dfab4..9dbbe93fa 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -189,7 +189,7 @@ EOF # We need this because app temporarily set the app as unprotected to configure it with curl... if [[ "$3" =~ ^(unprotected|skipped)_ ]] && [[ "${4:-}" == "/" ]] then - ynh_permission_update --permission "main" --remove "all_users" --add "visitors" + ynh_permission_update --permission "main" --add "visitors" fi } diff --git a/locales/en.json b/locales/en.json index 6c7d0b42d..d93d2b5f4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -422,7 +422,7 @@ "permission_cannot_remove_main": "Removing a main permission is not allowed", "permission_created": "Permission '{permission:s}' created", "permission_creation_failed": "Could not create permission '{permission}': {error}", - "permission_currently_allowed_for_visitors": "This permission is currently granted to visitors in addition to other groups. You probably want to either remove the 'visitors' permission or remove the other groups it is currently granted to.", + "permission_allowed_for_visitors_but_not_for_all_users": "Visitors can't be granted if all users is not already granted.", "permission_currently_allowed_for_all_users": "This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.", "permission_deleted": "Permission '{permission:s}' deleted", "permission_deletion_failed": "Could not delete permission '{permission}': {error}", diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 2d32fc0cc..063d0f97d 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1169,12 +1169,12 @@ def _migrate_legacy_permissions(app): # If the current permission says app is protected, but there are legacy rules saying it should be public... if app_perm_currently_allowed == ["all_users"] and settings_say_it_should_be_public: # Make it public - user_permission_update(app + ".main", remove="all_users", add="visitors", sync_perm=False) + user_permission_update(app + ".main", add="visitors", sync_perm=False) # If the current permission says app is public, but there are no setting saying it should be public... if app_perm_currently_allowed == ["visitors"] and not settings_say_it_should_be_public: # Make is private - user_permission_update(app + ".main", remove="visitors", add="all_users", sync_perm=False) + user_permission_update(app + ".main", remove="visitors", sync_perm=False) @is_unit_operation() @@ -1423,7 +1423,7 @@ def app_setting(app, key, value=None, delete=False): # We need this because app temporarily set the app as unprotected to configure it with curl... if key.startswith("unprotected_") or key.startswith("skipped_") and value == "/": from permission import user_permission_update - user_permission_update(app + ".main", remove="all_users", add="visitors") + user_permission_update(app + ".main", add="visitors") def app_checkport(port): diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index ad06c0487..011e8265d 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -140,12 +140,14 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, # If we end up with something like allowed groups is ["all_users", "volunteers"] # we shall warn the users that they should probably choose between one or the other, # because the current situation is probably not what they expect / is temporary ? - - if len(new_allowed_groups) > 1: - if "all_users" in new_allowed_groups: + + if "all_users" in new_allowed_groups: + if len(new_allowed_groups) > 1 and "visitors" not in new_allowed_groups or len(new_allowed_groups) > 2: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) - if "visitors" in new_allowed_groups: - logger.warning(m18n.n("permission_currently_allowed_for_visitors")) + + # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. + if "visitors" in new_allowed_groups and "all_users" not in new_allowed_groups: + raise YunohostError('permission_allowed_for_visitors_but_not_for_all_users') # Don't update LDAP if we update exactly the same values if set(new_allowed_groups) == set(current_allowed_groups): @@ -258,6 +260,12 @@ def permission_create(operation_logger, permission, url=None, allowed=None, sync if url: attr_dict['URL'] = url + if allowed is not None: + if "visitors" in allowed and "all_users" not in allowed: + if not isinstance(allowed, list): + allowed = [allowed] + allowed.append("all_users") + # Validate that the groups to add actually exist all_existing_groups = user_group_list()['groups'].keys() allowed_ = [] if allowed is None else [allowed] if not isinstance(allowed, list) else allowed diff --git a/src/yunohost/tests/test_backuprestore.py b/src/yunohost/tests/test_backuprestore.py index d67ccfe37..3662226e1 100644 --- a/src/yunohost/tests/test_backuprestore.py +++ b/src/yunohost/tests/test_backuprestore.py @@ -510,7 +510,7 @@ def test_backup_and_restore_permission_app(): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert res['permissions_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] @@ -524,7 +524,7 @@ def test_backup_and_restore_permission_app(): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert res['permissions_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index b3fa9fefb..f11d215f1 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -460,13 +460,13 @@ def test_permission_app_propagation_on_ssowat(): args="domain=%s&path=%s&is_public=1&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True) res = user_permission_list(full=True)['permissions'] - assert res['permissions_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] app_webroot = "https://%s/urlpermissionapp" % maindomain assert can_access_webpage(app_webroot, logged_as=None) assert can_access_webpage(app_webroot, logged_as="alice") - user_permission_update("permissions_app.main", remove="visitors", add="bob") + user_permission_update("permissions_app.main", remove=["visitors", "all_users"], add="bob") res = user_permission_list(full=True)['permissions'] assert not can_access_webpage(app_webroot, logged_as=None) @@ -491,7 +491,7 @@ def test_permission_legacy_app_propagation_on_ssowat(): # App is configured as public by default using the legacy unprotected_uri mechanics # It should automatically be migrated during the install res = user_permission_list(full=True)['permissions'] - assert res['legacy_app.main']['allowed'] == ["visitors"] + assert "visitors" in res['legacy_app.main']['allowed'] and "all_users" in res['legacy_app.main']['allowed'] app_webroot = "https://%s/legacy" % maindomain @@ -499,7 +499,7 @@ def test_permission_legacy_app_propagation_on_ssowat(): assert can_access_webpage(app_webroot, logged_as="alice") # Try to update the permission and check that permissions are still consistent - user_permission_update("legacy_app.main", remove="visitors", add="bob") + user_permission_update("legacy_app.main", remove=["visitors", "all_users"], add="bob") assert not can_access_webpage(app_webroot, logged_as=None) assert not can_access_webpage(app_webroot, logged_as="alice") From df3c7688981ff06cb1a39fb26548535e76864e25 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 29 Nov 2019 15:51:43 +0100 Subject: [PATCH 016/104] Let's convert this in list in all cases (+ simplify later core) --- src/yunohost/permission.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 011e8265d..049c62729 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -140,11 +140,11 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, # If we end up with something like allowed groups is ["all_users", "volunteers"] # we shall warn the users that they should probably choose between one or the other, # because the current situation is probably not what they expect / is temporary ? - + if "all_users" in new_allowed_groups: if len(new_allowed_groups) > 1 and "visitors" not in new_allowed_groups or len(new_allowed_groups) > 2: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) - + # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. if "visitors" in new_allowed_groups and "all_users" not in new_allowed_groups: raise YunohostError('permission_allowed_for_visitors_but_not_for_all_users') @@ -261,15 +261,14 @@ def permission_create(operation_logger, permission, url=None, allowed=None, sync attr_dict['URL'] = url if allowed is not None: + if not isinstance(allowed, list): + allowed = [allowed] if "visitors" in allowed and "all_users" not in allowed: - if not isinstance(allowed, list): - allowed = [allowed] allowed.append("all_users") # Validate that the groups to add actually exist all_existing_groups = user_group_list()['groups'].keys() - allowed_ = [] if allowed is None else [allowed] if not isinstance(allowed, list) else allowed - for group in allowed_: + for group in allowed or []: if group not in all_existing_groups: raise YunohostError('group_unknown', group=group) From af054b3b85384c27d83b4eb17f1ad76fe2113ad9 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 29 Nov 2019 16:06:26 +0100 Subject: [PATCH 017/104] Let's keep one thread per line for readability + easier to indentify the issue --- src/yunohost/tests/test_backuprestore.py | 6 ++++-- src/yunohost/tests/test_permission.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/yunohost/tests/test_backuprestore.py b/src/yunohost/tests/test_backuprestore.py index 3662226e1..3265fa228 100644 --- a/src/yunohost/tests/test_backuprestore.py +++ b/src/yunohost/tests/test_backuprestore.py @@ -510,7 +510,8 @@ def test_backup_and_restore_permission_app(): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] + assert "visitors" in res['permissions_app.main']['allowed'] + assert "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] @@ -524,7 +525,8 @@ def test_backup_and_restore_permission_app(): assert res['permissions_app.admin']['url'] == "/admin" assert res['permissions_app.dev']['url'] == "/dev" - assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] + assert "visitors" in res['permissions_app.main']['allowed'] + assert "all_users" in res['permissions_app.main']['allowed'] assert res['permissions_app.admin']['allowed'] == ["alice"] assert res['permissions_app.dev']['allowed'] == [] diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index f11d215f1..a4bd570e5 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -460,7 +460,8 @@ def test_permission_app_propagation_on_ssowat(): args="domain=%s&path=%s&is_public=1&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True) res = user_permission_list(full=True)['permissions'] - assert "visitors" in res['permissions_app.main']['allowed'] and "all_users" in res['permissions_app.main']['allowed'] + assert "visitors" in res['permissions_app.main']['allowed'] + assert "all_users" in res['permissions_app.main']['allowed'] app_webroot = "https://%s/urlpermissionapp" % maindomain assert can_access_webpage(app_webroot, logged_as=None) @@ -491,7 +492,8 @@ def test_permission_legacy_app_propagation_on_ssowat(): # App is configured as public by default using the legacy unprotected_uri mechanics # It should automatically be migrated during the install res = user_permission_list(full=True)['permissions'] - assert "visitors" in res['legacy_app.main']['allowed'] and "all_users" in res['legacy_app.main']['allowed'] + assert "visitors" in res['legacy_app.main']['allowed'] + assert "all_users" in res['legacy_app.main']['allowed'] app_webroot = "https://%s/legacy" % maindomain From a5866e67b96f3e189ec43042d94cff97d0c5df83 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 29 Nov 2019 16:41:50 +0100 Subject: [PATCH 018/104] Try to improve readability for these conditions --- src/yunohost/permission.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 049c62729..b4abf4ca7 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -138,11 +138,12 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, new_allowed_groups = [g for g in new_allowed_groups if g not in groups_to_remove] # If we end up with something like allowed groups is ["all_users", "volunteers"] - # we shall warn the users that they should probably choose between one or the other, - # because the current situation is probably not what they expect / is temporary ? - - if "all_users" in new_allowed_groups: - if len(new_allowed_groups) > 1 and "visitors" not in new_allowed_groups or len(new_allowed_groups) > 2: + # we shall warn the users that they should probably choose between one or + # the other, because the current situation is probably not what they expect + # / is temporary ? Note that it's fine to have ["all_users", "visitors"] + # though, but it's not fine to have ["all_users", "visitors", "volunteers"] + if "all_users" in new_allowed_groups and len(new_allowed_groups) >= 2: + if "visitors" not in new_allowed_groups or len(new_allowed_groups) >= 3: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. From a044f3ad7ea87bbeb12fefccae1804d59ce55ac0 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 2 Dec 2019 19:04:07 +0100 Subject: [PATCH 019/104] Implicitly add all_users when adding visitors group --- locales/en.json | 3 ++- src/yunohost/permission.py | 12 +++++++++--- src/yunohost/tests/test_permission.py | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/locales/en.json b/locales/en.json index d93d2b5f4..17014cad0 100644 --- a/locales/en.json +++ b/locales/en.json @@ -415,14 +415,15 @@ "pattern_positive_number": "Must be a positive number", "pattern_username": "Must be lower-case alphanumeric and underscore characters only", "pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}", + "permission_all_users_implicitly_added": "The permission was also implicitly granted to 'all_users' because it is required to allow the special group 'visitors'", "permission_already_allowed": "Group '{group}' already has permission '{permission}' enabled", "permission_already_disallowed": "Group '{group}' already has permission '{permission}' disabled'", "permission_already_exist": "Permission '{permission}' already exists", "permission_already_up_to_date": "The permission was not updated because the addition/removal requests already match the current state.", + "permission_cannot_remove_all_users_while_visitors_allowed": "You can't remove this permission for 'all_users' while it is still allowed for 'visitors'", "permission_cannot_remove_main": "Removing a main permission is not allowed", "permission_created": "Permission '{permission:s}' created", "permission_creation_failed": "Could not create permission '{permission}': {error}", - "permission_allowed_for_visitors_but_not_for_all_users": "Visitors can't be granted if all users is not already granted.", "permission_currently_allowed_for_all_users": "This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.", "permission_deleted": "Permission '{permission:s}' deleted", "permission_deletion_failed": "Could not delete permission '{permission}': {error}", diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index b4abf4ca7..9cc7c7534 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -146,9 +146,15 @@ def user_permission_update(operation_logger, permission, add=None, remove=None, if "visitors" not in new_allowed_groups or len(new_allowed_groups) >= 3: logger.warning(m18n.n("permission_currently_allowed_for_all_users")) - # If visitors are allowed, but not all users, it can break some applications, so we prohibit it. - if "visitors" in new_allowed_groups and "all_users" not in new_allowed_groups: - raise YunohostError('permission_allowed_for_visitors_but_not_for_all_users') + # If visitors are to be added, we shall make sure that "all_users" are also allowed + # (e.g. if visitors are allowed to visit nextcloud, you still want to allow people to log in ...) + if add and "visitors" in groups_to_add and "all_users" not in new_allowed_groups: + new_allowed_groups.append("all_users") + logger.warning(m18n.n("permission_all_users_implicitly_added")) + # If all_users are to be added, yet visitors are still to allowed, then we + # refuse it (c.f. previous comment...) + if remove and "all_users" in groups_to_remove and "visitors" in new_allowed_groups: + raise YunohostError('permission_cannot_remove_all_users_while_visitors_allowed') # Don't update LDAP if we update exactly the same values if set(new_allowed_groups) == set(current_allowed_groups): diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index a4bd570e5..2e53f13a7 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -313,6 +313,27 @@ def test_permission_add_and_remove_group(mocker): assert res['wiki.main']['corresponding_users'] == ["alice"] +def test_permission_adding_visitors_implicitly_add_all_users(mocker): + + res = user_permission_list(full=True)['permissions'] + assert res['blog.main']['allowed'] == ["alice"] + + with message(mocker, "permission_updated", permission="blog.main"): + user_permission_update("blog.main", add="visitors") + + res = user_permission_list(full=True)['permissions'] + assert set(res['blog.main']['allowed']) == set(["alice", "visitors", "all_users"]) + + +def test_permission_cant_remove_all_users_if_visitors_allowed(mocker): + + with message(mocker, "permission_updated", permission="blog.main"): + user_permission_update("blog.main", add=["visitors", "all_users"]) + + with raiseYunohostError(mocker, 'permission_cannot_remove_all_users_while_visitors_allowed'): + user_permission_update("blog.main", remove="all_users") + + def test_permission_add_group_already_allowed(mocker): with message(mocker, "permission_already_allowed", permission="blog.main", group="alice"): user_permission_update("blog.main", add="alice") From e9c01c2f893587cd7f65f020f6f5ca693ccce3e4 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 2 Dec 2019 18:09:43 +0100 Subject: [PATCH 020/104] Additonal cleaning of legacy stuff when using new permission system + avoid duplicated entries in (un)protected_urls --- src/yunohost/app.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 063d0f97d..8ce5ed783 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1662,16 +1662,18 @@ def app_ssowatconf(): # FIXME : gotta handle regex-urls here... meh url = _sanitized_absolute_url(perm_info["url"]) if "visitors" in perm_info["allowed"]: - unprotected_urls.append(url) + if url not in unprotected_urls: + unprotected_urls.append(url) - # Legacy stuff : we remove now unprotected-urls that might have been declared as protected earlier... + # Legacy stuff : we remove now protected-urls that might have been declared as unprotected earlier... protected_urls = [u for u in protected_urls if u != url] else: - # TODO : small optimization to implement : we don't need to explictly add all the app roots - protected_urls.append(url) + if url not in protected_urls: + protected_urls.append(url) - # Legacy stuff : we remove now unprotected-urls that might have been declared as protected earlier... + # Legacy stuff : we remove now unprotected-urls / skipped-urls that might have been declared as protected earlier... unprotected_urls = [u for u in unprotected_urls if u != url] + skipped_urls = [u for u in skipped_urls if u != url] for domain in domains: skipped_urls.extend([domain + '/yunohost/admin', domain + '/yunohost/api']) From d966407ff03d492c096d273bd0c1bb087217f17c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 2 Dec 2019 20:41:42 +0100 Subject: [PATCH 021/104] Let's not remove all_users here since it shall be added if visitors are allowed --- src/yunohost/data_migrations/0011_setup_group_permission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/data_migrations/0011_setup_group_permission.py b/src/yunohost/data_migrations/0011_setup_group_permission.py index c80686344..b07e5d21b 100644 --- a/src/yunohost/data_migrations/0011_setup_group_permission.py +++ b/src/yunohost/data_migrations/0011_setup_group_permission.py @@ -119,7 +119,7 @@ class MyMigration(Migration): # Migrate classic public app still using the legacy unprotected_uris if app_setting(app, "unprotected_uris") == "/" or app_setting(app, "skipped_uris") == "/": - user_permission_update(app+".main", remove="all_users", add="visitors", sync_perm=False) + user_permission_update(app+".main", add="visitors", sync_perm=False) permission_sync_to_user() From 8f4a1757f49fdf1402452485af8e33c6392b29c1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 2 Dec 2019 20:45:03 +0100 Subject: [PATCH 022/104] Update changelog for 3.7.0.4 --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index f8a83d0b3..25a7469de 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +yunohost (3.7.0.4) testing; urgency=low + + - [fix] Also add all_users when allowing visitors (#855) + - [fix] Fix handling of skipped_uris (c.f. also SSOwat#149) + - [i18n] Improve translations for Catalan + + -- Alexandre Aubin Mon, 2 Dev 2019 20:44:00 +0000 + yunohost (3.7.0.3) testing; urgency=low - [mod] Some refactoring for permissions create/update/reset (#837) From 5c2748ba85aa3a80244355c2e552e06b4dc71d79 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 2 Dec 2019 22:32:59 +0100 Subject: [PATCH 023/104] [fix] This DNS resolver in ipv6 is unreachable --- data/templates/dnsmasq/plain/resolv.dnsmasq.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/data/templates/dnsmasq/plain/resolv.dnsmasq.conf b/data/templates/dnsmasq/plain/resolv.dnsmasq.conf index 6b3bb95d3..ce8515054 100644 --- a/data/templates/dnsmasq/plain/resolv.dnsmasq.conf +++ b/data/templates/dnsmasq/plain/resolv.dnsmasq.conf @@ -32,7 +32,6 @@ nameserver 85.214.20.141 nameserver 195.160.173.53 # (DE) AS250 nameserver 194.150.168.168 -nameserver 2001:4ce8::53 # (DE) Ideal-Hosting nameserver 84.200.69.80 nameserver 2001:1608:10:25::1c04:b12f From 1e3410be4471daf38ebb5fe2ace7bc7828d6dd80 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Fri, 6 Dec 2019 10:05:08 +0000 Subject: [PATCH 024/104] Translated using Weblate (French) Currently translated at 100.0% (607 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 6ddb16de7..11f171347 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -673,7 +673,7 @@ "diagnosis_ip_not_connected_at_all": "Le serveur ne semble pas du tout connecté à Internet !?", "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais soyer prudent en utilisant un fichier /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Au lieu de cela, ce fichier devrait être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Les résolveurs réels doivent être configurés via /etc/resolv.dnsmasq.conf.", - "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS de type {0}, nom {1} et valeur {2}", + "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS de type {0}, nom {1} et valeur {2}. Vous pouvez consulter https://yunohost.org/dns_config pour plus d'informations.", "diagnosis_diskusage_ok": "Le stockage {mountpoint} (sur le périphérique {device}) a toujours {espace libre {free_abs_GB} GB ({free_percent}%) !", "diagnosis_ram_ok": "Le système dispose toujours de {available_abs_MB} MB ({available_percent}%) de RAM sur {total_abs_MB} MB.", "diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !", @@ -699,7 +699,7 @@ "diagnosis_ip_broken_resolvconf": "La résolution du nom de domaine semble cassée sur votre serveur, ce qui semble lié au fait que /etc/resolv.conf ne pointe pas vers 127.0.0.1.", "diagnosis_dns_good_conf": "Bonne configuration DNS pour le domaine {domain} (catégorie {category})", "diagnosis_dns_bad_conf": "Configuration DNS incorrecte/manquante pour le domaine {domain} (catégorie {category})", - "diagnosis_dns_discrepancy": "Selon la configuration DNS recommandée, la valeur de l'enregistrement DNS de type {0} et nom {1} doit être {2} et non {3}.", + "diagnosis_dns_discrepancy": "L'enregistrement DNS de type {0} et nom {1} ne correspond pas à la configuration recommandée. Valeur actuelle: {2}. Valeur exceptée: {3}. Vous pouvez consulter https://yunohost.org/dns_config pour plus d'informations.", "diagnosis_services_bad_status": "Le service {service} est {status} :-(", "diagnosis_services_good_status": "Le service {service} est {status} comme prévu !", "diagnosis_diskusage_verylow": "Le stockage {mountpoint} (sur le périphérique {device}) ne dispose que de {free_abs_GB} Go ({free_percent}%). Vous devriez vraiment envisager de nettoyer un peu d'espace.", @@ -747,8 +747,15 @@ "diagnosis_services_running": "Le service {service} s'exécute correctement !", "diagnosis_services_conf_broken": "La configuration est cassée pour le service {service} !", "diagnosis_ports_needed_by": "Rendre ce port accessible est nécessaire pour le service {0}", - "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez très probablement configurer le transfert de port sur votre routeur Internet comme décrit dans https://yunohost.org/port_forwarding", + "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez probablement configurer la redirection de port sur votre routeur Internet, comme décrit dans https://yunohost.org/isp_box_config.", "diagnosis_http_connection_error": "Erreur de connexion : impossible de se connecter au domaine demandé, il est probablement injoignable.", "diagnosis_no_cache": "Pas encore de diagnostique de cache pour la catégorie « {category} »", - "diagnosis_http_unknown_error": "Une erreur est survenue en essayant de joindre votre domaine, il est probablement injoignable." + "diagnosis_http_unknown_error": "Une erreur est survenue en essayant de joindre votre domaine, il est probablement injoignable.", + "permission_all_users_implicitly_added": "La permission a également été implicitement accordée à 'all_users' car il est nécessaire pour permettre au groupe spécial 'visiteurs'", + "permission_cannot_remove_all_users_while_visitors_allowed": "Vous ne pouvez pas supprimer cette autorisation pour 'all_users' alors qu'elle est toujours autorisée pour 'visiteurs'", + "yunohost_postinstall_end_tip": "La post-installation terminée! Pour finaliser votre configuration, veuillez considérer:\n - ajout d'un premier utilisateur via la section \"Utilisateurs\" de l'administrateur Web (ou \"utilisateur yunohost créer \" en ligne de commande);\n - diagnostiquez les problèmes en attente de résolution du problème afin que votre serveur fonctionne le mieux possible dans la section \"Diagnostic\" de l'administrateur Web (ou \"Exécution du diagnostic yunohost\" en ligne de commande);\n - lecture des parties \"Finalisation de votre configuration\" et \"Découverte de Yunohost\" dans la documentation de l'administrateur: https://yunohost.org/admindoc.", + "diagnosis_services_bad_status_tip": "Vous pouvez essayer de redémarrer le service. Si cela ne fonctionne pas, consultez les journaux de service à l'aide de 'yunohost service log {0}' ou de la section 'Services' de l'administrateur Web.", + "diagnosis_http_bad_status_code": "N'a pas pu atteindre votre serveur comme prévu, il a renvoyé un code d'état incorrect. Il se peut qu'une autre machine réponde à la place de votre serveur. Vérifiez que vous transférez correctement le port 80, que votre configuration nginx est à jour et qu’un proxy inverse n’interfère pas.", + "diagnosis_http_timeout": "Expiration du délai en essayant de contacter votre serveur de l'extérieur. Il semble être inaccessible. Vérifiez que vous transférez correctement le port 80, que nginx est en cours d’exécution et qu’un pare-feu n’interfère pas.", + "global_settings_setting_pop3_enabled": "Activer le protocole POP3 pour le serveur de messagerie" } From 40c6846ef32b9d43ece167c22e1949d261f60226 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 09:38:30 +0000 Subject: [PATCH 025/104] Translated using Weblate (Portuguese) Currently translated at 8.4% (51 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pt/ --- locales/pt.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/pt.json b/locales/pt.json index a23265ab4..e068a2284 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -193,5 +193,6 @@ "backup_borg_not_implemented": "O método de backup Borg ainda não foi implementado.", "backup_cant_mount_uncompress_archive": "Não foi possível montar em modo leitura o diretorio de arquivos não comprimido", "backup_copying_to_organize_the_archive": "Copiando {size:s}MB para organizar o arquivo", - "app_change_url_identical_domains": "O antigo e o novo domínio / url_path são idênticos ('{domain:s}{path:s}'), nada para fazer." + "app_change_url_identical_domains": "O antigo e o novo domínio / url_path são idênticos ('{domain:s}{path:s}'), nada para fazer.", + "password_too_simple_1": "A senha precisa ter pelo menos 8 caracteres" } From 871d7705ae75c72ec5a455c8740515aad638000f Mon Sep 17 00:00:00 2001 From: elie gavoty Date: Wed, 4 Dec 2019 13:50:24 +0000 Subject: [PATCH 026/104] Translated using Weblate (German) Currently translated at 33.6% (204 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 08fdff7e4..b2d0f3673 100644 --- a/locales/de.json +++ b/locales/de.json @@ -417,5 +417,18 @@ "app_full_domain_unavailable": "Es tut uns leid, aber diese Anwendung erfordert die Installation auf einer eigenen Domain, aber einige andere Anwendungen sind bereits auf der Domäne'{domain}' installiert. Eine mögliche Lösung ist das Hinzufügen und Verwenden einer Subdomain, die dieser Anwendung zugeordnet ist.", "app_install_failed": "Installation von {app} fehlgeschlagen: {error}", "app_install_script_failed": "Im Installationsscript ist ein Fehler aufgetreten", - "app_remove_after_failed_install": "Entfernen der App nach fehlgeschlagener Installation…" + "app_remove_after_failed_install": "Entfernen der App nach fehlgeschlagener Installation…", + "app_upgrade_script_failed": "Es ist ein Fehler im App-Upgrade-Skript aufgetreten", + "diagnosis_basesystem_host": "Server läuft unter Debian {debian_version}.", + "diagnosis_basesystem_kernel": "Server läuft unter Linux-Kernel {kernel_version}", + "diagnosis_basesystem_ynh_single_version": "{0} Version: {1} ({2})", + "diagnosis_basesystem_ynh_main_version": "Server läuft YunoHost {main_version} ({repo})", + "diagnosis_basesystem_ynh_inconsistent_versions": "Sie verwenden inkonsistente Versionen der YunoHost-Pakete... wahrscheinlich wegen eines fehlgeschlagenen oder teilweisen Upgrades.", + "diagnosis_display_tip_web": "Sie können den Abschnitt Diagnose (im Startbildschirm) aufrufen, um die gefundenen Probleme anzuzeigen.", + "apps_catalog_init_success": "Apps-Katalogsystem initialisiert!", + "apps_catalog_updating": "Aktualisierung des Applikationskatalogs...", + "apps_catalog_failed_to_download": "Der {apps_catalog} Apps-Katalog kann nicht heruntergeladen werden: {error}", + "apps_catalog_obsolete_cache": "Der Cache des Apps-Katalogs ist leer oder veraltet.", + "apps_catalog_update_success": "Der Apps-Katalog wurde aktualisiert!", + "password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein" } From 32b571691452dffe7257937aeb1b543f89aeb5ad Mon Sep 17 00:00:00 2001 From: Yasss Gurl Date: Sat, 21 Dec 2019 16:48:09 +0000 Subject: [PATCH 027/104] Translated using Weblate (German) Currently translated at 33.6% (204 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/locales/de.json b/locales/de.json index b2d0f3673..83b4b1210 100644 --- a/locales/de.json +++ b/locales/de.json @@ -254,7 +254,7 @@ "certmanager_domain_cert_not_selfsigned": "Das Zertifikat der Domain {domain:s} is kein selbstsigniertes Zertifikat. Bist du dir sicher, dass du es ersetzen willst? (Benutze --force)", "certmanager_certificate_fetching_or_enabling_failed": "Es scheint so als wäre die Aktivierung des Zertifikats für die Domain {domain:s} fehlgeschlagen...", "certmanager_attempt_to_renew_nonLE_cert": "Das Zertifikat der Domain {domain:s} wurde nicht von Let's Encrypt ausgestellt. Es kann nicht automatisch erneuert werden!", - "certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain:s} läuft in Kürze ab! Benutze --force um diese Nachricht zu umgehen", + "certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain:s} läuft nicht in Kürze ab! (Benutze --force um diese Nachricht zu umgehen)", "certmanager_domain_http_not_working": "Es scheint so, dass die Domain {domain:s} nicht über HTTP erreicht werden kann. Bitte überprüfe, ob deine DNS und nginx Konfiguration in Ordnung ist", "certmanager_error_no_A_record": "Kein DNS 'A' Eintrag für die Domain {domain:s} gefunden. Dein Domainname muss auf diese Maschine weitergeleitet werden, um ein Let's Encrypt Zertifikat installieren zu können! (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )", "certmanager_domain_dns_ip_differs_from_public_ip": "Der DNS 'A' Eintrag der Domain {domain:s} unterscheidet sich von dieser Server-IP. Wenn du gerade deinen A Eintrag verändert hast, warte bitte etwas, damit die Änderungen wirksam werden (du kannst die DNS Propagation mittels Website überprüfen) (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )", @@ -318,12 +318,12 @@ "confirm_app_install_thirdparty": "WARNUNG! Das Installieren von Anwendungen von Drittanbietern kann die Integrität und Sicherheit Deines Systems beeinträchtigen. Du solltest es wahrscheinlich NICHT installieren, es sei denn, Du weisst, was Du tust. Bist du bereit, dieses Risiko einzugehen? [{answers: s}] ", "confirm_app_install_danger": "WARNUNG! Diese Anwendung ist noch experimentell (wenn nicht ausdrücklich \"not working\"/\"funktioniert nicht\") und es ist wahrscheinlich, dass Dein System Schaden nimmt! Du solltest es wahrscheinlich NICHT installieren, es sei denn, Du weisst, was Du tust. Bist du bereit, dieses Risiko einzugehen? [{answers: s}] ", "confirm_app_install_warning": "Warnung: Diese Anwendung funktioniert möglicherweise, ist jedoch nicht gut in YunoHost integriert. Einige Funktionen wie Single Sign-On und Backup / Restore sind möglicherweise nicht verfügbar. Trotzdem installieren? [{answers: s}] ", - "backup_with_no_restore_script_for_app": "App {app: s} hat kein Wiederherstellungsskript. Das Backup dieser App kann nicht automatisch wiederhergestellt werden.", - "backup_with_no_backup_script_for_app": "App {app: s} hat kein Sicherungsskript. Ignoriere es.", - "backup_unable_to_organize_files": "Dateien im Archiv können mit der schnellen Methode nicht organisiert werden", - "backup_system_part_failed": "Der Systemteil '{part: s}' kann nicht gesichert werden", + "backup_with_no_restore_script_for_app": "Die App {app: s} hat kein Wiederherstellungsskript. Das Backup dieser App kann nicht automatisch wiederhergestellt werden.", + "backup_with_no_backup_script_for_app": "Die App {app: s} hat kein Sicherungsskript. Ignoriere es.", + "backup_unable_to_organize_files": "Dateien im Archiv konnten nicht mit der schnellen Methode organisiert werden", + "backup_system_part_failed": "Der Systemteil '{part: s}' konnte nicht gesichert werden", "backup_permission": "Sicherungsberechtigung für App {app: s}", - "backup_output_symlink_dir_broken": "Sie haben einen fehlerhaften Symlink anstelle Ihres Archivverzeichnisses '{path: s}'. Möglicherweise haben Sie ein spezielles Setup, um Ihre Daten auf einem anderen Dateisystem zu sichern. In diesem Fall haben Sie wahrscheinlich vergessen, Ihre Festplatte oder Ihren USB-Schlüssel erneut einzuhängen oder anzuschließen.", + "backup_output_symlink_dir_broken": "Ihr Archivverzeichnis '{path:s}' ist ein fehlerhafter Symlink. Vielleicht haben Sie vergessen, das Speichermedium, auf das er verweist, neu zu mounten oder einzustecken.", "backup_mount_archive_for_restore": "Archiv für Wiederherstellung vorbereiten…", "backup_method_tar_finished": "Tar-Backup-Archiv erstellt", "backup_method_custom_finished": "Benutzerdefinierte Sicherungsmethode '{method: s}' beendet", @@ -335,7 +335,7 @@ "backup_csv_creation_failed": "Die zur Wiederherstellung erforderliche CSV-Datei kann nicht erstellt werden", "backup_couldnt_bind": "{Src: s} konnte nicht an {dest: s} angebunden werden.", "backup_borg_not_implemented": "Die Borg-Sicherungsmethode ist noch nicht implementiert", - "backup_ask_for_copying_if_needed": "Einige Dateien konnten mit der Methode, die es vermeidet vorübergehend Speicherplatz auf dem System zu verschwenden, nicht gesichert werden. Zur Durchführung der Sicherung sollten vorübergehend {size: s} MB verwendet werden. Sind Sie einverstanden?", + "backup_ask_for_copying_if_needed": "Möchten Sie die Sicherung mit {size:s} MB temporär durchführen? (Dieser Weg wird verwendet, da einige Dateien nicht mit einer effizienteren Methode vorbereitet werden konnten).", "backup_actually_backuping": "Erstellt ein Backup-Archiv aus den gesammelten Dateien …", "ask_path": "Pfad", "ask_new_path": "Neuer Pfad", @@ -352,10 +352,10 @@ "app_not_upgraded": "Die App '{failed_app}' konnte nicht aktualisiert werden. Infolgedessen wurden die folgenden App-Upgrades abgebrochen: {apps}", "app_make_default_location_already_used": "Die App \"{app}\" kann nicht als Standard für die Domain \"{domain}\" festgelegt werden. Sie wird bereits von der App \"{other_app}\" verwendet", "aborting": "Breche ab.", - "app_action_cannot_be_ran_because_required_services_down": "Diese App erfordert einige Dienste, die derzeit nicht verfügbar sind. Bevor Sie fortfahren, sollten Sie versuchen, die folgenden Dienste neu zu starten (und möglicherweise untersuchen, warum sie nicht verfügbar sind): {services}", + "app_action_cannot_be_ran_because_required_services_down": "Diese erforderlichen Dienste sollten zur Durchführung dieser Aktion laufen: {services}. Versuchen Sie, sie neu zu starten, um fortzufahren (und möglicherweise zu untersuchen, warum sie nicht verfügbar sind).", "already_up_to_date": "Nichts zu tun. Alles ist bereits auf dem neusten Stand.", "admin_password_too_long": "Bitte ein Passwort kürzer als 127 Zeichen wählen", - "app_action_broke_system": "Diese Aktion hat anscheinend diese wichtigen Services gestört: {services}", + "app_action_broke_system": "Diese Aktion scheint diese wichtigen Dienste unterbrochen zu haben: {services}", "apps_already_up_to_date": "Alle Apps sind bereits aktuell", "backup_copying_to_organize_the_archive": "Kopieren von {size: s} MB, um das Archiv zu organisieren", "app_upgrade_stopped": "Das Upgrade aller Anwendungen wurde gestoppt, um mögliche Schäden zu vermeiden, da das Upgrade der vorherigen Anwendung fehlgeschlagen ist", From e87797dacf03629301319088c537967107cd57c7 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 08:59:44 +0000 Subject: [PATCH 028/104] Translated using Weblate (Italian) Currently translated at 19.4% (118 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/it/ --- locales/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index 22cf9e2b0..fc2355e7f 100644 --- a/locales/it.json +++ b/locales/it.json @@ -316,7 +316,7 @@ "certmanager_cert_signing_failed": "Firma del nuovo certificato fallita", "good_practices_about_user_password": "Ora stai per impostare una nuova password utente. La password dovrebbe essere di almeno 8 caratteri - anche se è buona pratica utilizzare password più lunghe (es. una sequenza di parole) e/o utilizzare vari tipi di caratteri (maiuscole, minuscole, numeri e simboli).", "password_listed": "Questa password è una tra le più utilizzate al mondo. Per favore scegline una più unica.", - "password_too_simple_1": "La password deve essere lunga almeno 8 caratteri", + "password_too_simple_1": "La password deve contenere almeno 8 caratteri", "password_too_simple_2": "La password deve essere lunga almeno 8 caratteri e contenere numeri, maiuscole e minuscole", "password_too_simple_3": "La password deve essere lunga almeno 8 caratteri e contenere numeri, maiuscole e minuscole e simboli", "password_too_simple_4": "La password deve essere lunga almeno 12 caratteri e contenere numeri, maiuscole e minuscole", From 3859db213a59a1b6d4ae48f814945a5c01818541 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 09:57:05 +0000 Subject: [PATCH 029/104] Translated using Weblate (Dutch) Currently translated at 6.6% (40 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/nl/ --- locales/nl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/nl.json b/locales/nl.json index 166df89ff..df554f7e2 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -138,5 +138,6 @@ "backup_deleted": "Backup werd verwijderd", "backup_extracting_archive": "Backup archief uitpakken...", "backup_hook_unknown": "backup hook '{hook:s}' onbekend", - "backup_nothings_done": "Niets om op te slaan" + "backup_nothings_done": "Niets om op te slaan", + "password_too_simple_1": "Het wachtwoord moet minimaal 8 tekens lang zijn" } From b540e56c4680343a3baed89555b293d30fbe226a Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Wed, 4 Dec 2019 21:42:12 +0000 Subject: [PATCH 030/104] Translated using Weblate (Catalan) Currently translated at 100.0% (607 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index 00b9b9e19..40977469c 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -491,7 +491,7 @@ "tools_upgrade_regular_packages": "Actualitzant els paquets «normals» (no relacionats amb YunoHost)…", "tools_upgrade_regular_packages_failed": "No s'han pogut actualitzar els paquets següents: {packages_list}", "tools_upgrade_special_packages": "Actualitzant els paquets «especials» (relacionats amb YunoHost)…", - "tools_upgrade_special_packages_explanation": "Aquesta acció s'acabarà, però l'actualització especial continuarà en segon pla. No comenceu cap altra acció al servidor en els pròxims ~10 minuts (depèn de la velocitat del maquinari). Un cop acabat, pot ser que us hagueu de tornar a connectar a la interfície d'administració. Els registres de l'actualització estaran disponibles a Eines → Registres (a la interfície d'administració) o amb «yunohost log list» (des de la línia d'ordres).", + "tools_upgrade_special_packages_explanation": "Aquesta actualització especial continuarà en segon pla. No comenceu cap altra acció al servidor en els pròxims ~10 minuts (depèn de la velocitat del maquinari). Després d'això, pot ser que us hagueu de tornar a connectar a la interfície d'administració. Els registres de l'actualització estaran disponibles a Eines → Registres (a la interfície d'administració) o utilitzant «yunohost log list» (des de la línia d'ordres).", "tools_upgrade_special_packages_completed": "Actualització dels paquets YunoHost acabada.\nPremeu [Enter] per tornar a la línia d'ordres", "unbackup_app": "L'aplicació «{app:s}» no serà guardada", "unexpected_error": "Hi ha hagut un error inesperat: {error}", @@ -716,5 +716,8 @@ "migration_description_0014_remove_app_status_json": "Eliminar els fitxers d'aplicació status.json heretats", "diagnosis_services_running": "El servei {service} s'està executant!", "diagnosis_services_conf_broken": "La configuració pel servei {service} està trencada!", - "diagnosis_ports_needed_by": "És necessari exposar aquest port pel servei {0}" + "diagnosis_ports_needed_by": "És necessari exposar aquest port pel servei {0}", + "permission_all_users_implicitly_added": "El permís també s'ha donat implícitament a «all_users» ja que és necessari per atorgar-lo al grup «visitors»", + "permission_cannot_remove_all_users_while_visitors_allowed": "No podeu retirar el permís a «all_users» mentre encara el tingui el grup «visitors»", + "global_settings_setting_pop3_enabled": "Activa el protocol POP3 per al servidor de correu" } From b5d494decde5fa515bb8ba5d44bbc0757ab7b1d9 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 09:06:40 +0000 Subject: [PATCH 031/104] Translated using Weblate (Russian) Currently translated at 1.8% (11 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ru/ --- locales/ru.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index 306a8763a..ed0a4c183 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -42,5 +42,6 @@ "appslist_retrieve_error": "Невозможно получить список удаленных приложений {appslist:s}: {error:s}", "appslist_unknown": "Список приложений {appslist:s} неизвестен.", "appslist_url_already_tracked": "Это уже зарегистрированный список приложений с url{url:s}.", - "installation_complete": "Установка завершена" + "installation_complete": "Установка завершена", + "password_too_simple_1": "Пароль должен быть не менее 8 символов" } From aed4e8c0d245d7501ca1b0c7f25a8b7e3b11f3f8 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 08:31:58 +0000 Subject: [PATCH 032/104] Translated using Weblate (Hungarian) Currently translated at 1.0% (6 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/hu/ --- locales/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/hu.json b/locales/hu.json index a6df4d680..b39882148 100644 --- a/locales/hu.json +++ b/locales/hu.json @@ -9,5 +9,6 @@ "app_already_up_to_date": "{app:s} napra kész", "app_argument_choice_invalid": "{name:s} érvénytelen választás, csak egyike lehet {choices:s} közül", "app_argument_invalid": "'{name:s}' hibás paraméter érték :{error:s}", - "app_argument_required": "Parameter '{name:s}' kötelező" + "app_argument_required": "Parameter '{name:s}' kötelező", + "password_too_simple_1": "A jelszónak legalább 8 karakter hosszúnak kell lennie" } From 419913066612099cfb8e72bc2e2aa6c4f7c7283c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Sun, 15 Dec 2019 12:06:43 +0000 Subject: [PATCH 033/104] Translated using Weblate (Occitan) Currently translated at 41.5% (252 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/oc/ --- locales/oc.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/oc.json b/locales/oc.json index bbe30ac05..d3eb33e12 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -698,5 +698,12 @@ "apps_catalog_obsolete_cache": "La memòria cache del catalòg d’aplicacion es voida o obsolèta.", "apps_catalog_update_success": "Lo catalòg d’aplicacions es a jorn !", "diagnosis_mail_ougoing_port_25_ok": "Lo pòrt de sortida 25 es pas blocat e lo corrièr electronic pòt partir als autres servidors.", - "diagnosis_description_mail": "Corrièl" + "diagnosis_description_mail": "Corrièl", + "app_upgrade_script_failed": "Una error s’es producha pendent l’execucion de l’script de mesa a nivèl de l’aplicacion", + "diagnosis_cant_run_because_of_dep": "Execucion impossibla del diagnostic per {category} mentre que i a de problèmas importants ligats amb {dep}.", + "diagnosis_found_errors_and_warnings": "Avèm trobat {errors} problèma(s) important(s) (e {warnings} avis(es)) ligats a {category} !", + "diagnosis_failed": "Recuperacion impossibla dels resultats del diagnostic per la categoria « {category} » : {error}", + "diagnosis_ip_broken_dnsresolution": "La resolucion del nom de domeni es copada per una rason… Lo parafuòc bloca las requèstas DNS ?", + "diagnosis_no_cache": "I a pas encara de diagnostic de cache per la categoria « {category} »", + "apps_catalog_init_success": "Sistèma de catalòg d’aplicacion iniciat !" } From d52e4ad176fe647d299e9b09ab890a5f65dfe796 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Fri, 6 Dec 2019 10:13:07 +0000 Subject: [PATCH 034/104] Translated using Weblate (Esperanto) Currently translated at 100.0% (607 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/eo/ --- locales/eo.json | 140 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 30 deletions(-) diff --git a/locales/eo.json b/locales/eo.json index 4b8a76d3c..f303a57ee 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -19,10 +19,10 @@ "yunohost_installing": "Instalante YunoHost…", "service_description_glances": "Monitoras sistemajn informojn en via servilo", "service_description_metronome": "Mastrumas XMPP tujmesaĝilon kontojn", - "service_description_mysql": "Stokas aplikaĵojn datojn (SQL datumbazo)", + "service_description_mysql": "Butikigas datumojn de programoj (SQL datumbazo)", "service_description_nginx": "Servas aŭ permesas atingi ĉiujn retejojn gastigita sur via servilo", "service_description_nslcd": "Mastrumas Yunohost uzantojn konektojn per komanda linio", - "service_description_php7.0-fpm": "Rulas aplikaĵojn skibita en PHP kun nginx", + "service_description_php7.0-fpm": "Ekzekutas programojn skribitajn en PHP kun NGINX", "service_description_postfix": "Uzita por sendi kaj ricevi retpoŝtojn", "service_description_redis-server": "Specialita datumbazo uzita por rapida datumo atingo, atendovicoj kaj komunikadoj inter programoj", "service_description_rmilter": "Kontrolas diversajn parametrojn en retpoŝtoj", @@ -30,9 +30,9 @@ "service_description_slapd": "Stokas uzantojn, domajnojn kaj rilatajn informojn", "service_description_ssh": "Permesas al vi konekti al via servilo kun fora terminalo (SSH protokolo)", "service_description_yunohost-api": "Mastrumas interagojn inter la YunoHost retinterfaco kaj la sistemo", - "service_description_yunohost-firewall": "Mastrumas malfermitajn kaj fermitajn konektejojn al servoj", - "service_disable_failed": "Ne povis malŝalti la servon '{service:s}'\n\nFreŝaj protokoloj de la servo : {logs:s}", - "service_disabled": "'{service: s}' servo malŝaltita", + "service_description_yunohost-firewall": "Administras malfermajn kaj fermajn konektajn havenojn al servoj", + "service_disable_failed": "Ne povis fari la servon '{service:s}' ne komenci ĉe la ekkuro.\n\nLastatempaj servaj protokoloj: {logs:s}", + "service_disabled": "La servo '{service:s}' ne plu komenciĝos kiam sistemo ekos.", "action_invalid": "Nevalida ago « {action:s} »", "admin_password": "Pasvorto de la estro", "admin_password_too_long": "Bonvolu elekti pasvorton pli mallonga ol 127 signoj", @@ -90,7 +90,7 @@ "app_requirements_failed": "Certaines exigences ne sont pas remplies pour {app}: {error}", "backup_no_uncompress_archive_dir": "Ne ekzistas tia nekompremita arkiva dosierujo", "password_too_simple_1": "Pasvorto devas esti almenaŭ 8 signojn longa", - "app_upgrade_failed": "Ne povis ĝisdatigi {app:s}", + "app_upgrade_failed": "Ne povis ĝisdatigi {app:s}: {error}", "app_upgrade_several_apps": "La sekvaj apliko estos altgradigitaj: {apps}", "backup_archive_open_failed": "Ne povis malfermi la rezervan ar archiveivon", "ask_lastname": "Familia nomo", @@ -197,12 +197,12 @@ "migration_0011_failed_to_remove_stale_object": "Ne povis forigi neuzatan objekton {dn}: {error}", "migrations_already_ran": "Tiuj migradoj estas jam faritaj: {ids}", "migrations_no_such_migration": "Estas neniu migrado nomata '{id}'", - "permission_already_allowed": "Grupo '{group}' jam havas permeson '{permission}' ebligita'", + "permission_already_allowed": "Grupo '{group}' jam havas rajtigitan permeson '{permission}'", "permission_already_disallowed": "Grupo '{group}' jam havas permeson '{permission}' malebligita'", "permission_cannot_remove_main": "Forigo de ĉefa permeso ne rajtas", "permission_creation_failed": "Ne povis krei permeson '{permission}': {error}", - "tools_update_failed_to_app_fetchlist": "Ne povis ĝisdatigi la aparatojn de YunoHost ĉar: {error}", - "user_already_exists": "Uzanto {uzanto} jam ekzistas", + "tools_update_failed_to_app_fetchlist": "Ne povis ĝisdatigi la listojn de aplikoj de YunoHost ĉar: {error}", + "user_already_exists": "La uzanto '{user}' jam ekzistas", "migrations_pending_cant_rerun": "Tiuj migradoj ankoraŭ estas pritraktataj, do ne plu rajtas esti ekzekutitaj: {ids}", "migrations_running_forward": "Kuranta migrado {id}…", "migrations_success_forward": "Migrado {id} kompletigita", @@ -213,7 +213,7 @@ "permission_not_found": "Permesita \"{permission:s}\" ne trovita", "restore_not_enough_disk_space": "Ne sufiĉa spaco (spaco: {free_space:d} B, necesa spaco: {needed_space:d} B, sekureca marĝeno: {margin:d} B)", "tools_upgrade_regular_packages": "Nun ĝisdatigi 'regulajn' (ne-yunohost-rilatajn) pakojn …", - "tools_upgrade_special_packages_explanation": "Ĉi tiu ago finiĝos, sed la fakta speciala ĝisdatigo daŭros en fono. Bonvolu ne komenci iun alian agon en via servilo en la sekvaj ~ 10 minutoj (depende de via aparata rapideco). Unufoje mi plenumis, vi eble devos ensaluti en la retpaĝo. La ĝisdatiga registro estos havebla en Iloj → Madero (sur la retpaĝo) aŭ tra 'yunohost-registro-listo' (el la komandlinio).", + "tools_upgrade_special_packages_explanation": "La speciala ĝisdatigo daŭros en fono. Bonvolu ne komenci aliajn agojn en via servilo la sekvajn ~ 10 minutojn (depende de la aparata rapideco). Post tio, vi eble devos re-ensaluti sur la retadreso. La ĝisdatiga registro estos havebla en Iloj → Ensaluto (en la retadreso) aŭ uzante 'yunohost-logliston' (el la komandlinio).", "unrestore_app": "App '{app:s}' ne restarigos", "group_created": "Grupo '{group}' kreita", "group_creation_failed": "Ne povis krei la grupon '{group}': {error}", @@ -236,7 +236,7 @@ "regenconf_file_backed_up": "Agordodosiero '{conf}' estis rezervita al '{backup}'", "migration_0007_cannot_restart": "SSH ne rekomencas post provi nuligi la migradan numeron 6.", "migration_description_0006_sync_admin_and_root_passwords": "Sinkronigu admin kaj radikajn pasvortojn", - "updating_app_lists": "Akirante haveblajn ĝisdatigojn por aplikoj…", + "updating_app_lists": "Akirante haveblajn ĝisdatigojn por programoj…", "iptables_unavailable": "Vi ne povas ludi kun iptables ĉi tie. Vi estas en ujo aŭ via kerno ne subtenas ĝin", "global_settings_cant_write_settings": "Ne eblis konservi agordojn, tial: {reason:s}", "service_added": "La servo '{service:s}' aldonis", @@ -279,7 +279,7 @@ "migrate_tsig_start": "Detektita ŝlosila algoritmo nesufiĉa por TSIG-subskribo de la domajno '{domain}', komencanta migradon al la pli sekura HMAC-SHA-512", "ldap_init_failed_to_create_admin": "LDAP-iniciato ne povis krei administran uzanton", "backup_output_directory_required": "Vi devas provizi elirejan dosierujon por la sekurkopio", - "tools_upgrade_cant_unhold_critical_packages": "Ne povis malhelpi kritikajn pakojn…", + "tools_upgrade_cant_unhold_critical_packages": "Ne povis malŝalti kritikajn pakojn…", "diagnosis_monitor_disk_error": "Ne povis monitori diskojn: {error}", "log_link_to_log": "Plena ŝtipo de ĉi tiu operacio: ' {desc} '", "service_no_log": "Neniu registro por montri por servo '{service:s}'", @@ -317,7 +317,7 @@ "log_app_removelist": "Forigu aplikan liston", "global_settings_setting_example_enum": "Ekzemplo enum elekto", "hook_exec_not_terminated": "Skripto ne finiĝis ĝuste: {path:s}", - "service_stopped": "'{service:s}' servo ĉesis", + "service_stopped": "Servo '{service:s}' ĉesis", "restore_failed": "Ne povis restarigi sistemon", "confirm_app_install_danger": "Danĝero! Ĉi tiu apliko estas konata ankoraŭ eksperimenta (se ne eksplicite ne funkcias)! Vi probable ne devas instali ĝin krom se vi scias kion vi faras. NENIU SUBTENO estos provizita se ĉi tiu app ne funkcias aŭ rompas vian sistemon ... Se vi pretas riski ĉiuokaze, tajpu '{answers: s}'", "log_operation_unit_unclosed_properly": "Operaciumo ne estis fermita ĝuste", @@ -362,21 +362,21 @@ "log_corrupted_md_file": "La YAD-metadata dosiero asociita kun protokoloj estas damaĝita: '{md_file}\nEraro: {error} '", "downloading": "Elŝutante …", "user_deleted": "Uzanto forigita", - "service_enable_failed": "Ne eblis ŝalti la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}", + "service_enable_failed": "Ne povis fari la servon '{service:s}' aŭtomate komenci ĉe la ekkuro.\n\nLastatempaj servaj protokoloj: {logs:s}", "tools_upgrade_special_packages": "Nun ĝisdatigi 'specialajn' (rilatajn al yunohost)…", "domains_available": "Haveblaj domajnoj:", "dyndns_registered": "Registrita domajno DynDNS", "service_description_fail2ban": "Protektas kontraŭ bruta forto kaj aliaj specoj de atakoj de la interreto", "file_does_not_exist": "La dosiero {path:s} ne ekzistas.", - "yunohost_not_installed": "YunoHost estas malĝuste aŭ ne ĝuste instalita. Bonvolu prilabori 'yunohost tools postinstall'", + "yunohost_not_installed": "YunoHost ne estas ĝuste instalita. Bonvolu prilabori 'yunohost tools postinstall'", "migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 estas instalita, sed ne postgresql 9.6‽ Io stranga eble okazis en via sistemo: (…", "restore_removing_tmp_dir_failed": "Ne povis forigi malnovan provizoran dosierujon", "certmanager_cannot_read_cert": "Io malbona okazis, kiam mi provis malfermi aktualan atestilon por domajno {domain:s} (dosiero: {file:s}), kialo: {reason:s}", - "service_removed": "'{service:s}' servo forigita", + "service_removed": "Servo '{service:s}' forigita", "certmanager_hit_rate_limit": "Tro multaj atestiloj jam eldonitaj por ĉi tiu ĝusta aro de domajnoj {domain:s} antaŭ nelonge. Bonvolu reprovi poste. Vidu https://letsencrypt.org/docs/rate-limits/ por pliaj detaloj", "migration_0005_not_enough_space": "Disponigu sufiĉan spacon en {path} por ruli la migradon.", "pattern_firstname": "Devas esti valida antaŭnomo", - "migration_description_0010_migrate_to_apps_json": "Forigu malvalorigitajn aparatojn kaj uzu anstataŭe la novan unuigitan liston \"apps.json\"", + "migration_description_0010_migrate_to_apps_json": "Forigu malvalorigitajn katalogajn programojn kaj uzu anstataŭe la novan unuigitan liston de \"apps.json\" (malaktuale anstataŭita per migrado 13)", "domain_cert_gen_failed": "Ne povis generi atestilon", "regenconf_file_kept_back": "La agorda dosiero '{conf}' estas atendita forigi per regen-conf (kategorio {category}), sed ĝi estis konservita.", "migrate_tsig_wait_4": "30 sekundoj …", @@ -432,7 +432,7 @@ "backup_php5_to_php7_migration_may_fail": "Ne povis konverti vian ar archiveivon por subteni PHP 7, vi eble ne povas restarigi viajn PHP-programojn (kialo: {error:s})", "log_backup_restore_system": "Restarigi sistemon de rezerva arkivo", "log_app_change_url": "Ŝanĝu la URL de la apliko '{}'", - "service_already_started": "La servo '{service:s}' estas jam komencita", + "service_already_started": "La servo '{service:s}' jam funkcias", "license_undefined": "nedifinita", "global_settings_setting_security_password_admin_strength": "Admin pasvorta forto", "service_reload_or_restart_failed": "Ne povis reŝargi aŭ rekomenci la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}", @@ -455,7 +455,7 @@ "regenconf_file_updated": "Agordodosiero '{conf}' ĝisdatigita", "log_help_to_get_log": "Por vidi la protokolon de la operacio '{desc}', uzu la komandon 'yunohost log display {name}'", "global_settings_setting_security_nginx_compatibility": "Kongruo vs sekureca kompromiso por la TTT-servilo NGINX. Afektas la ĉifradojn (kaj aliajn aspektojn pri sekureco)", - "no_internet_connection": "Servilo ne konektita al la interreto", + "no_internet_connection": "La servilo ne estas konektita al la interreto", "migration_0008_dsa": "• La DSA-ŝlosilo estos malŝaltita. Tial vi eble bezonos nuligi spuran averton de via SSH-kliento kaj revizii la fingrospuron de via servilo;", "migration_0003_restoring_origin_nginx_conf": "Fileia dosiero /etc/nginx/nginx.conf estis iel redaktita. La migrado reaperos unue al sia originala stato ... La antaŭa dosiero estos havebla kiel {backup_dest}.", "migrate_tsig_end": "Migrado al HMAC-SHA-512 finiĝis", @@ -467,7 +467,7 @@ "service_description_avahi-daemon": "Permesas al vi atingi vian servilon uzante 'yunohost.local' en via loka reto", "certmanager_attempt_to_replace_valid_cert": "Vi provas anstataŭigi bonan kaj validan atestilon por domajno {domajno:s}! (Uzu --forte pretervidi)", "monitor_stats_period_unavailable": "Ne ekzistas disponeblaj statistikoj por la periodo", - "regenconf_updated": "Agordo por kategorio '{category}' ĝisdatigita", + "regenconf_updated": "Agordo ĝisdatigita por '{category}'", "update_apt_cache_warning": "Io iris malbone dum la ĝisdatigo de la kaŝmemoro de APT (paka administranto de Debian). Jen rubujo de la sources.list-linioj, kiuj povus helpi identigi problemajn liniojn:\n{sourcelist}", "regenconf_dry_pending_applying": "Kontrolado de pritraktata agordo, kiu estus aplikita por kategorio '{category}'…", "regenconf_file_copy_failed": "Ne povis kopii la novan agordodosieron '{new}' al '{conf}'", @@ -478,7 +478,7 @@ "maindomain_change_failed": "Ne povis ŝanĝi la ĉefan domajnon", "mail_domain_unknown": "Nevalida retadreso por domajno '{domain:s}'. Bonvolu uzi domajnon administritan de ĉi tiu servilo.", "migrations_cant_reach_migration_file": "Ne povis aliri migrajn dosierojn ĉe la vojo '% s'", - "pattern_email": "Devas esti valida retpoŝtadreso (t.e.iu@domain.org)", + "pattern_email": "Devas esti valida retpoŝta adreso (t.e. iu@ekzemple.com)", "mail_alias_remove_failed": "Ne povis forigi retpoŝton alias '{mail:s}'", "regenconf_file_manually_removed": "La dosiero de agordo '{conf}' estis forigita permane, kaj ne estos kreita", "monitor_enabled": "Servilo-monitorado nun", @@ -501,7 +501,7 @@ "log_app_install": "Instalu la aplikon '{}'", "service_description_dnsmasq": "Traktas rezolucion de domajna nomo (DNS)", "global_settings_unknown_type": "Neatendita situacio, la agordo {setting:s} ŝajnas havi la tipon {unknown_type:s} sed ĝi ne estas tipo subtenata de la sistemo.", - "migration_0003_problematic_apps_warning": "Bonvolu noti, ke la sekvaj eventuale problemaj instalitaj apps estis detektitaj. Ĝi aspektas, ke tiuj ne estis instalitaj de aparato aŭ ne estas markitaj kiel \"funkciantaj\". Tial ne eblas garantii, ke ili ankoraŭ funkcios post la ĝisdatigo: {problematic_apps}", + "migration_0003_problematic_apps_warning": "Bonvolu noti, ke la sekvaj eventuale problemaj instalitaj programoj estis detektitaj. Ŝajnas, ke tiuj ne estis instalitaj el app_katalogo aŭ ne estas markitaj kiel \"funkciantaj\". Tial ne eblas garantii, ke ili ankoraŭ funkcios post la ĝisdatigo: {problematic_apps}", "domain_hostname_failed": "Ne povis agordi novan gastigilon. Ĉi tio eble kaŭzos problemon poste (eble bone).", "server_reboot": "La servilo rekomenciĝos", "regenconf_failed": "Ne povis regeneri la agordon por kategorio(j): {categories}", @@ -510,7 +510,7 @@ "service_unknown": "Nekonata servo '{service:s}'", "migration_0003_start": "Komencante migradon al Stretch. La protokoloj haveblos en {logfile}.", "monitor_stats_no_update": "Neniuj monitoradaj statistikoj ĝisdatigi", - "domain_deletion_failed": "Ne povis forigi domajnon {domain}: {error}", + "domain_deletion_failed": "Ne eblas forigi domajnon {domain}: {error}", "log_user_update": "Ĝisdatigu uzantinformojn de '{}'", "user_creation_failed": "Ne povis krei uzanton {user}: {error}", "migrations_migration_has_failed": "Migrado {id} ne kompletigis, abolis. Eraro: {exception}", @@ -529,13 +529,13 @@ "migration_0007_cancelled": "Ne povis plibonigi la manieron kiel via SSH-agordo estas administrita.", "migrate_tsig_failed": "Ne povis migri la DynDNS-domajnon '{domain}' al HMAC-SHA-512, ruliĝante. Eraro: {error_code}, {error}", "pattern_lastname": "Devas esti valida familinomo", - "service_enabled": "'{service:s}' servo malŝaltita", + "service_enabled": "La servo '{service:s}' nun aŭtomate komenciĝos dum sistemaj botoj.", "certmanager_no_cert_file": "Ne povis legi la atestan dosieron por la domajno {domain:s} (dosiero: {file:s})", "migration_0008_port": "• Vi devos konekti uzante la havenon 22 anstataŭ via nuna kutimo SSH-haveno. Sentu vin libera reconfiguri ĝin;", - "domain_creation_failed": "Ne povis krei domajnon {domain}: {error}", + "domain_creation_failed": "Ne eblas krei domajnon {domain}: {error}", "certmanager_domain_http_not_working": "Ŝajnas ke la domajno {domain:s} ne atingeblas per HTTP. Kontrolu, ke via DNS kaj NGINX-agordo ĝustas", - "domain_cannot_remove_main": "Ne eblas forigi ĉefan domajnon. Fiksu unu unue", - "service_reloaded_or_restarted": "'{service:s}' servo reŝarĝis aŭ rekomencis", + "domain_cannot_remove_main": "Vi ne povas forigi '{domain:s}' ĉar ĝi estas la ĉefa domajno, vi bezonas unue agordi alian domajnon kiel la ĉefan domajnon per uzado de 'yunohost domain main-domain -n ', jen la listo de kandidataj domajnoj. : {other_domainsj:s}", + "service_reloaded_or_restarted": "La servo '{service:s}' estis reŝarĝita aŭ rekomencita", "mysql_db_initialized": "La datumbazo MySQL jam estas pravalorizita", "log_domain_add": "Aldonu '{}' domajnon en sisteman agordon", "global_settings_bad_type_for_setting": "Malbona tipo por agordo {setting:s}, ricevita {received_type:s}, atendata {expected_type:s}", @@ -543,11 +543,11 @@ "dyndns_cron_installed": "Kreita laboro DynDNS cron", "system_username_exists": "Uzantnomo jam ekzistas en la listo de uzantoj de sistemo", "firewall_reloaded": "Fajroŝirmilo reŝarĝis", - "service_restarted": "'{service:s}' servo rekomencis", + "service_restarted": "Servo '{service:s}' rekomencis", "pattern_username": "Devas esti minuskulaj literoj kaj minuskloj nur", "extracting": "Eltirante…", "restore_app_failed": "Ne povis restarigi la programon '{app:s}'", - "yunohost_configured": "YunoHost nun agordis", + "yunohost_configured": "YunoHost nun estas agordita", "certmanager_self_ca_conf_file_not_found": "Ne povis trovi agorddosieron por mem-subskriba aŭtoritato (dosiero: {file:s})", "log_app_remove": "Forigu la aplikon '{}'", "service_restart_failed": "Ne povis rekomenci la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}", @@ -579,5 +579,85 @@ "diagnosis_cache_still_valid": "(Kaŝmemoro ankoraŭ validas por {category} diagnozo. Ankoraŭ ne re-diagnoza!)", "diagnosis_cant_run_because_of_dep": "Ne eblas fari diagnozon por {category} dum estas gravaj problemoj rilataj al {dep}.", "diagnosis_display_tip_cli": "Vi povas aranĝi 'yunohost diagnosis show --issues' por aperigi la trovitajn problemojn.", - "diagnosis_failed_for_category": "Diagnozo malsukcesis por kategorio '{category}': {error}" + "diagnosis_failed_for_category": "Diagnozo malsukcesis por kategorio '{category}': {error}", + "app_upgrade_script_failed": "Eraro okazis en la skripto pri ĝisdatiga programo", + "diagnosis_diskusage_verylow": "Stokado {mountpoint} (sur aparato {device)) restas nur {free_abs_GB} GB ({free_percent}%) spaco. Vi vere konsideru purigi iom da spaco.", + "diagnosis_ram_verylow": "La sistemo nur restas {available_abs_MB} MB ({available_percent}%) RAM! (el {total_abs_MB} MB)", + "diagnosis_mail_ougoing_port_25_blocked": "Eliranta haveno 25 ŝajnas esti blokita. Vi devas provi malŝlosi ĝin en via agorda panelo de provizanto (aŭ gastiganto). Dume la servilo ne povos sendi retpoŝtojn al aliaj serviloj.", + "diagnosis_http_bad_status_code": "Ne povis atingi vian servilon kiel atendite, ĝi redonis malbonan statuskodon. Povas esti, ke alia maŝino respondis anstataŭ via servilo. Vi devus kontroli, ke vi ĝuste redonas la havenon 80, ke via nginx-agordo ĝisdatigas kaj ke reverso-prokuro ne interbatalas.", + "main_domain_changed": "La ĉefa domajno estis ŝanĝita", + "permission_all_users_implicitly_added": "La permeso ankaŭ estis implicite donita al 'all_users' ĉar ĝi bezonas por permesi al la 'visitors' de la speciala grupo", + "yunohost_postinstall_end_tip": "La post-instalado finiĝis! Por fini vian agordon, bonvolu konsideri:\n - aldonado de unua uzanto tra la sekcio 'Uzantoj' de la retadreso (aŭ 'yunohost user create ' en komandlinio);\n - diagnozi problemojn atendantajn solvi por ke via servilo funkciu kiel eble plej glate tra la sekcio 'Diagnosis' de la retadministrado (aŭ 'yunohost diagnosis run' en komandlinio);\n - legante la partojn 'Finigi vian agordon' kaj 'Ekkoni Yunohost' en la administra dokumentado: https://yunohost.org/admindoc.", + "permission_cannot_remove_all_users_while_visitors_allowed": "Vi ne povas forigi ĉi tiun permeson por 'all_users' dum ĝi tamen estas permesita por 'visitors'", + "migration_description_0014_remove_app_status_json": "Forigi heredajn dosierojn", + "diagnosis_ip_connected_ipv4": "La servilo estas konektita al la interreto per IPv4 !", + "diagnosis_ip_no_ipv4": "La servilo ne havas funkciantan IPv4.", + "diagnosis_ip_connected_ipv6": "La servilo estas konektita al la interreto per IPv6 !", + "diagnosis_ip_no_ipv6": "La servilo ne havas funkciantan IPv6.", + "diagnosis_ip_not_connected_at_all": "La servilo tute ne ŝajnas esti konektita al la Interreto !?", + "diagnosis_ip_dnsresolution_working": "Rezolucio pri domajna nomo funkcias !", + "diagnosis_ip_weird_resolvconf": "DNS-rezolucio ŝajnas funkcii, sed atentu, ke vi ŝajnas uzi kutimon /etc/resolv.conf.", + "diagnosis_ip_weird_resolvconf_details": "Anstataŭe, ĉi tiu dosiero estu ligilo kun /etc/resolvconf/run/resolv.conf mem montrante al 127.0.0.1 (dnsmasq). La efektivaj solvantoj devas agordi per /etc/resolv.dnsmasq.conf.", + "diagnosis_dns_good_conf": "Bona DNS-agordo por domajno {domain} (kategorio {category})", + "diagnosis_dns_bad_conf": "Malbona / mankas DNS-agordo por domajno {domain} (kategorio {category})", + "diagnosis_ram_ok": "La sistemo ankoraŭ havas {available_abs_MB} MB ({available_percent}%) RAM forlasita de {total_abs_MB} MB.", + "diagnosis_swap_none": "La sistemo tute ne havas interŝanĝon. Vi devus pripensi aldoni almenaŭ 256 MB da interŝanĝo por eviti situaciojn en kiuj la sistemo restas sen memoro.", + "diagnosis_swap_notsomuch": "La sistemo havas nur {total_MB} MB-interŝanĝon. Vi konsideru havi almenaŭ 256 MB por eviti situaciojn en kiuj la sistemo restas sen memoro.", + "diagnosis_regenconf_manually_modified_details": "Ĉi tio probable estas bona tiel longe kiel vi scias kion vi faras;)!", + "diagnosis_regenconf_manually_modified_debian": "Agordodosiero {file} estis modifita permane kompare kun la defaŭlta Debian.", + "diagnosis_regenconf_manually_modified_debian_details": "Ĉi tio probable estas bona, sed devas observi ĝin...", + "diagnosis_regenconf_nginx_conf_broken": "La agordo de nginx ŝajnas rompi !", + "diagnosis_security_all_good": "Neniu kritika sekureca vundebleco estis trovita.", + "diagnosis_security_vulnerable_to_meltdown": "Vi ŝajnas vundebla al la kritiko-vundebleco de Meltdown", + "diagnosis_no_cache": "Neniu diagnoza kaŝmemoro por kategorio '{category}'", + "diagnosis_ip_broken_dnsresolution": "Rezolucio pri domajna nomo rompiĝas pro iu kialo ... Ĉu fajroŝirmilo blokas DNS-petojn ?", + "diagnosis_ip_broken_resolvconf": "Rezolucio pri domajna nomo ŝajnas esti rompita en via servilo, kiu ŝajnas rilata al /etc/resolv.conf ne notante 127.0.0.1.", + "diagnosis_dns_missing_record": "Laŭ la rekomendita DNS-agordo, vi devas aldoni DNS-registron kun tipo {0}, nomo {1} kaj valoro {2}. Vi povas kontroli https://yunohost.org/dns_config por pliaj informoj.", + "diagnosis_dns_discrepancy": "La DNS-registro kun tipo {0} kaj nomo {1} ne kongruas kun la rekomendita agordo. Nuna valoro: {2}. Esceptita valoro: {3}. Vi povas kontroli https://yunohost.org/dns_config por pliaj informoj.", + "diagnosis_services_conf_broken": "Agordo estas rompita por servo {service} !", + "diagnosis_services_bad_status": "Servo {service} estas {status} :(", + "diagnosis_ram_low": "La sistemo havas {available_abs_MB} MB ({available_percent}%) RAM forlasita de {total_abs_MB} MB. Estu zorgema.", + "diagnosis_swap_ok": "La sistemo havas {total_MB} MB da interŝanĝoj!", + "diagnosis_mail_ougoing_port_25_ok": "Eliranta haveno 25 ne estas blokita kaj retpoŝto povas esti sendita al aliaj serviloj.", + "diagnosis_regenconf_allgood": "Ĉiuj agordaj dosieroj kongruas kun la rekomendita agordo!", + "diagnosis_regenconf_manually_modified": "Agordodosiero {file} estis permane modifita.", + "diagnosis_description_ip": "Interreta konektebleco", + "diagnosis_description_dnsrecords": "Registroj DNS", + "diagnosis_description_services": "Servo kontrolas staton", + "diagnosis_description_systemresources": "Rimedaj sistemoj", + "diagnosis_description_security": "Sekurecaj kontroloj", + "diagnosis_ports_could_not_diagnose": "Ne povis diagnozi, ĉu haveblaj havenoj de ekstere. Eraro: {error}", + "diagnosis_services_bad_status_tip": "Vi povas provi rekomenci la servon, kaj se ĝi ne funkcias, trarigardu la servajn protokolojn uzante 'yunohost service log {0}' aŭ tra la sekcio 'Servoj' de la retadreso.", + "diagnosis_security_vulnerable_to_meltdown_details": "Por ripari tion, vi devas ĝisdatigi vian sistemon kaj rekomenci por ŝarĝi la novan linux-kernon (aŭ kontaktu vian servilan provizanton se ĉi tio ne funkcias). Vidu https://meltdownattack.com/ por pliaj informoj.", + "diagnosis_description_basesystem": "Baza sistemo", + "diagnosis_description_regenconf": "Sistemaj agordoj", + "main_domain_change_failed": "Ne eblas ŝanĝi la ĉefan domajnon", + "log_domain_main_domain": "Faru '{}' kiel ĉefa domajno", + "diagnosis_http_timeout": "Tempolimigita dum provado kontakti vian servilon de ekstere. Ĝi ŝajnas esti neatingebla. Vi devus kontroli, ke vi ĝuste redonas la havenon 80, ke nginx funkcias kaj ke fajroŝirmilo ne interbatalas.", + "diagnosis_http_connection_error": "Rilata eraro: ne povis konektiĝi al la petita domajno, tre probable ĝi estas neatingebla.", + "diagnosis_http_unknown_error": "Eraro okazis dum provado atingi vian domajnon, tre probable ĝi estas neatingebla.", + "migration_description_0013_futureproof_apps_catalog_system": "Migru al la nova katalogosistemo pri estontecaj programoj", + "diagnosis_ignored_issues": "(+ {nb_ignored} ignorataj aferoj))", + "diagnosis_found_errors": "Trovis {errors} signifa(j) afero(j) rilata al {category}!", + "diagnosis_found_errors_and_warnings": "Trovis {errors} signifaj problemo (j) (kaj {warnings} averto) rilataj al {category}!", + "diagnosis_diskusage_low": "Stokado {mountpoint} (sur aparato {device)) restas nur {free_abs_GB} GB ({free_percent}%) spaco. Estu zorgema.", + "diagnosis_diskusage_ok": "Stokado {mountpoint} (sur aparato {device) ankoraŭ restas {free_abs_GB} GB ({free_percent}%) spaco!", + "global_settings_setting_pop3_enabled": "Ebligu la protokolon POP3 por la poŝta servilo", + "diagnosis_unknown_categories": "La jenaj kategorioj estas nekonataj: {categories}", + "diagnosis_services_running": "Servo {service} funkcias!", + "diagnosis_ports_unreachable": "Haveno {port} ne atingeblas de ekstere.", + "diagnosis_ports_ok": "Haveno {port} atingeblas de ekstere.", + "diagnosis_ports_needed_by": "Eksponi ĉi tiun havenon necesas por servo {0}", + "diagnosis_ports_forwarding_tip": "Por solvi ĉi tiun problemon, plej probable vi devas agordi la plusendon de haveno en via interreta enkursigilo kiel priskribite en https://yunohost.org/isp_box_config", + "diagnosis_http_could_not_diagnose": "Ne povis diagnozi, ĉu atingeblas domajno de ekstere. Eraro: {error}", + "diagnosis_http_ok": "Domajno {domain} atingeblas de ekstere.", + "diagnosis_http_unreachable": "Domajno {domain} estas atingebla per HTTP de ekstere.", + "domain_cannot_remove_main_add_new_one": "Vi ne povas forigi '{domain:s}' ĉar ĝi estas la ĉefa domajno kaj via sola domajno, vi devas unue aldoni alian domajnon uzante ''yunohost domain add ', tiam agordi kiel ĉefan domajnon uzante 'yunohost domain main-domain -n ' kaj tiam vi povas forigi la domajnon' {domain: s} 'uzante' yunohost domain remove {domain:s} '.'", + "permission_require_account": "Permesilo {permission} nur havas sencon por uzantoj, kiuj havas konton, kaj tial ne rajtas esti ebligitaj por vizitantoj.", + "diagnosis_found_warnings": "Trovitaj {warnings} ero (j) kiuj povus esti plibonigitaj por {category}.", + "diagnosis_everything_ok": "Ĉio aspektas bone por {category}!", + "diagnosis_failed": "Malsukcesis preni la diagnozan rezulton por kategorio '{category}': {error}", + "diagnosis_description_ports": "Ekspoziciaj havenoj", + "diagnosis_description_http": "HTTP-ekspozicio", + "diagnosis_description_mail": "Retpoŝto" } From 93adb03fa296c31e91ffed9495196fd5300cce69 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 08:51:49 +0000 Subject: [PATCH 035/104] Translated using Weblate (Hindi) Currently translated at 3.8% (23 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/hi/ --- locales/hi.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/hi.json b/locales/hi.json index 015fd4e5e..23d391c47 100644 --- a/locales/hi.json +++ b/locales/hi.json @@ -77,5 +77,6 @@ "domain_deleted": "डोमेन डिलीट कर दिया गया है", "domain_deletion_failed": "डोमेन डिलीट करने में असमर्थ", "domain_dyndns_already_subscribed": "DynDNS डोमेन पहले ही सब्स्क्राइड है", - "domain_dyndns_invalid": "DynDNS के साथ इनवैलिड डोमिन इस्तेमाल किया गया" + "domain_dyndns_invalid": "DynDNS के साथ इनवैलिड डोमिन इस्तेमाल किया गया", + "password_too_simple_1": "पासवर्ड को कम से कम 8 वर्ण लंबा होना चाहिए" } From 73c3d25a5b61ae72ac82d75553dcaa20662a22ab Mon Sep 17 00:00:00 2001 From: amirale qt Date: Thu, 19 Dec 2019 09:45:20 +0000 Subject: [PATCH 036/104] Translated using Weblate (Polish) Currently translated at 0.2% (1 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pl/ --- locales/pl.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/pl.json b/locales/pl.json index 0967ef424..f1417a80c 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -1 +1,3 @@ -{} +{ + "password_too_simple_1": "Hasło musi mieć co najmniej 8 znaków" +} From 57c65c9d411ee14a9faf8848e5b681dd0709f2ab Mon Sep 17 00:00:00 2001 From: ButterflyOfFire Date: Thu, 26 Dec 2019 20:34:46 +0000 Subject: [PATCH 037/104] Translated using Weblate (Arabic) Currently translated at 14.2% (86 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ar/ --- locales/ar.json | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/locales/ar.json b/locales/ar.json index fba086bc4..828f41a8f 100644 --- a/locales/ar.json +++ b/locales/ar.json @@ -211,8 +211,8 @@ "mail_domain_unknown": "Unknown mail address domain '{domain:s}'", "mail_forward_remove_failed": "Unable to remove mail forward '{mail:s}'", "mailbox_used_space_dovecot_down": "Dovecot mailbox service need to be up, if you want to get mailbox used space", - "main_domain_change_failed": "Unable to change the main domain", - "main_domain_changed": "The main domain has been changed", + "main_domain_change_failed": "تعذّر تغيير النطاق الأساسي", + "main_domain_changed": "تم تغيير النطاق الأساسي", "migrate_tsig_end": "Migration to hmac-sha512 finished", "migrate_tsig_failed": "Migrating the dyndns domain {domain} to hmac-sha512 failed, rolling back. Error: {error_code} - {error}", "migrate_tsig_start": "Not secure enough key algorithm detected for TSIG signature of domain '{domain}', initiating migration to the more secure one hmac-sha512", @@ -443,5 +443,19 @@ "dyndns_could_not_check_available": "لا يمكن التحقق مِن أنّ {domain:s} متوفر على {provider:s}.", "backup_mount_archive_for_restore": "جارٍ تهيئة النسخة الاحتياطية للاسترجاع…", "root_password_replaced_by_admin_password": "لقد تم استبدال كلمة سر الجذر root بالكلمة الإدارية لـ admin.", - "app_upgrade_stopped": "لقد تم إلغاء تحديث كافة التطبيقات لتجنب حادث بسبب فشل تحديث التطبيق السابق" + "app_upgrade_stopped": "لقد تم إلغاء تحديث كافة التطبيقات لتجنب حادث بسبب فشل تحديث التطبيق السابق", + "app_action_broke_system": "يبدو أنّ هذا الإجراء أدّى إلى تحطيم خدمات مهمّة: {services}", + "diagnosis_basesystem_host": "هذا الخادم يُشغّل ديبيان {debian_version}.", + "diagnosis_basesystem_kernel": "هذا الخادم يُشغّل نواة لينكس {kernel_version}", + "diagnosis_basesystem_ynh_single_version": "{0} الإصدار: {1} ({2})", + "diagnosis_basesystem_ynh_main_version": "هذا الخادم يُشغّل YunoHost {main_version} ({repo})", + "diagnosis_everything_ok": "كل شيء على ما يرام في {category}!", + "diagnosis_ip_connected_ipv4": "الخادم مُتّصل بالإنترنت عبر IPv4!", + "diagnosis_ip_connected_ipv6": "الخادم مُتّصل بالإنترنت عبر IPv6!", + "diagnosis_ip_not_connected_at_all": "يبدو أنّ الخادم غير مُتّصل بتاتا بالإنترنت!؟", + "app_install_failed": "لا يمكن تنصيب {app}: {error}", + "apps_already_up_to_date": "كافة التطبيقات مُحدّثة", + "app_remove_after_failed_install": "جارٍ حذف التطبيق بعدما فشل تنصيبها…", + "apps_catalog_updating": "جارٍ تحديث فهرس التطبيقات…", + "apps_catalog_update_success": "تم تحديث فهرس التطبيقات!" } From 882ed5700d8e563a5015169f0eaa2f367f80339e Mon Sep 17 00:00:00 2001 From: Alvaro Date: Tue, 24 Dec 2019 11:25:23 +0000 Subject: [PATCH 038/104] Translated using Weblate (Spanish) Currently translated at 89.1% (541 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/locales/es.json b/locales/es.json index d1daf16f7..729e262b5 100644 --- a/locales/es.json +++ b/locales/es.json @@ -27,7 +27,7 @@ "app_sources_fetch_failed": "No se pudieron obtener los archivos con el código fuente, ¿es el URL correcto?", "app_unknown": "Aplicación desconocida", "app_unsupported_remote_type": "Tipo remoto no soportado por la aplicación", - "app_upgrade_failed": "No se pudo actualizar {app:s}", + "app_upgrade_failed": "No se pudo actualizar {app:s}: {error}", "app_upgraded": "Actualizado {app:s}", "appslist_fetched": "Lista de aplicaciones «{appslist:s}» actualizada", "appslist_removed": "Eliminada la lista de aplicaciones «{appslist:s}»", @@ -658,5 +658,29 @@ "diagnosis_ignored_issues": "(+ {nb_ignored} problema(s) ignorado(s))", "diagnosis_found_errors": "¡Encontrado(s) error(es) significativo(s) {errors} relacionado(s) con {category}!", "diagnosis_found_warnings": "Encontrado elemento(s) {warnings} que puede(n) ser mejorado(s) para {category}.", - "diagnosis_everything_ok": "¡Todo se ve bien para {category}!" + "diagnosis_everything_ok": "¡Todo se ve bien para {category}!", + "app_upgrade_script_failed": "Ha ocurrido un error en el script de actualización de la app", + "diagnosis_no_cache": "Todavía no hay una caché de diagnóstico para la categoría '{category}'", + "diagnosis_ip_no_ipv4": "IPv4 en el servidor no está funcionando.", + "diagnosis_ip_not_connected_at_all": "¿¡Está conectado el servidor a internet!?", + "diagnosis_ip_broken_resolvconf": "DNS parece no funcionar en tu servidor, lo que parece estar relacionado con /etc/resolv.conf no apuntando a 127.0.0.1.", + "diagnosis_dns_missing_record": "Según la configuración DNS recomendada, deberías añadir un registro DNS de tipo {0}, nombre {1} y valor {2}. Puedes consultar https://yunohost.org/dns_config para más información.", + "diagnosis_diskusage_low": "El almacenamiento {mountpoint} (en dispositivo {device}) solo tiene {free_abs_GB} GB ({free_percent}%) de espacio disponible. Ten cuidado.", + "diagnosis_services_bad_status_tip": "Puedes intentar reiniciar el servicio, y si no funciona, echar un vistazo a los logs del servicio usando 'yunohost service log {0}' o a través de la sección 'Servicios' en webadmin.", + "diagnosis_ip_connected_ipv6": "¡El servidor está conectado a internet a través de IPv6!", + "diagnosis_ip_no_ipv6": "IPv6 en el servidor no está funcionando.", + "diagnosis_ip_dnsresolution_working": "¡DNS no está funcionando!", + "diagnosis_ip_broken_dnsresolution": "DNS parece que no funciona por alguna razón... ¿Hay algún firewall bloqueando peticiones DNS?", + "diagnosis_ip_weird_resolvconf": "Parece que DNS funciona, pero ten cuidado, porque estás utilizando /etc/resolv.conf modificado.", + "diagnosis_ip_weird_resolvconf_details": "En su lugar, este fichero debería ser un enlace simbólico a /etc/resolvconf/run/resolv.conf apuntando a 127.0.0.1 (dnsmasq). Los resolvedores reales deben configurarse a través de /etc/resolv.dnsmasq.conf.", + "diagnosis_dns_good_conf": "Buena configuración DNS para el dominio {domain} (categoría {category})", + "diagnosis_dns_bad_conf": "Mala configuración DNS o configuración DNS faltante para el dominio {domain} (categoría {category})", + "diagnosis_dns_discrepancy": "El registro DNS con tipo {0} y nombre {1} no se corresponde a la configuración recomendada. Valor actual: {2}. Valor esperado: {3}. Puedes consultar https://yunohost.org/dns_config para más información.", + "diagnosis_services_bad_status": "El servicio {service} está {status} :(", + "diagnosis_diskusage_verylow": "El almacenamiento {mountpoint} (en el dispositivo {device}) sólo tiene {free_abs_GB} GB ({free_percent}%) de espacio disponible. Deberías considerar la posibilidad de limpiar algo de espacio.", + "diagnosis_diskusage_ok": "¡El almacenamiento {mountpoint} (en el dispositivo {device}) todavía tiene {free_abs_GB} GB ({free_percent}%) de espacio libre!", + "diagnosis_services_conf_broken": "¡Mala configuración para el servicio {service}!", + "diagnosis_services_running": "¡El servicio {service} está en ejecución!", + "diagnosis_failed": "No se ha podido obtener el resultado del diagnóstico para la categoría '{category}': {error}", + "diagnosis_ip_connected_ipv4": "¡El servidor está conectado a internet a través de IPv4!" } From 70405bb6485f3b9fb2b6b695faa6957987e08bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Sat, 28 Dec 2019 17:45:54 +0000 Subject: [PATCH 039/104] Translated using Weblate (Occitan) Currently translated at 49.9% (303 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/oc/ --- locales/oc.json | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/locales/oc.json b/locales/oc.json index d3eb33e12..7979a22df 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -6,15 +6,15 @@ "app_already_up_to_date": "{app:s} es ja a jorn", "installation_complete": "Installacion acabada", "app_id_invalid": "ID d’aplicacion incorrècte", - "app_install_files_invalid": "Fichièrs d’installacion incorrèctes", + "app_install_files_invalid": "Installacion impossibla d’aquestes fichièrs", "app_no_upgrade": "Pas cap d’aplicacion d’actualizar", "app_not_correctly_installed": "{app:s} sembla pas ben installat", - "app_not_installed": "L’aplicacion {app:s} es pas installat. Vaquí la lista de las aplicacions installadas : {all_apps}", + "app_not_installed": "Impossible de trobar l’aplicacion {app:s}. Vaquí la lista de las aplicacions installadas : {all_apps}", "app_not_properly_removed": "{app:s} es pas estat corrèctament suprimit", - "app_removed": "{app:s} es estat suprimit", + "app_removed": "{app:s} es estada suprimida", "app_unknown": "Aplicacion desconeguda", "app_upgrade_app_name": "Actualizacion de l’aplicacion {app}…", - "app_upgrade_failed": "Impossible d’actualizar {app:s}", + "app_upgrade_failed": "Impossible d’actualizar {app:s} : {error}", "app_upgrade_some_app_failed": "D’aplicacions se pòdon pas actualizar", "app_upgraded": "{app:s} es estada actualizada", "appslist_fetched": "Recuperacion de la lista d’aplicacions {appslist:s} corrèctament realizada", @@ -36,11 +36,11 @@ "backup_action_required": "Devètz precisar çò que cal salvagardar", "backup_app_failed": "Impossible de salvagardar l’aplicacion « {app:s} »", "backup_applying_method_copy": "Còpia de totes los fichièrs dins la salvagarda…", - "backup_applying_method_tar": "Creacion de l’archiu tar de la salvagarda…", - "backup_archive_name_exists": "Un archiu de salvagarda amb aquesta nom existís ja", + "backup_applying_method_tar": "Creacion de l’archiu TAR de la salvagarda…", + "backup_archive_name_exists": "Un archiu de salvagarda amb aquesta nom existís ja.", "backup_archive_name_unknown": "L’archiu local de salvagarda apelat « {name:s} » es desconegut", "action_invalid": "Accion « {action:s} » incorrècta", - "app_argument_choice_invalid": "Causida invalida pel paramètre « {name:s} », cal que siá un de {choices:s}", + "app_argument_choice_invalid": "Utilizatz una de las opcions « {choices:s} » per l’argument « {name:s} »", "app_argument_invalid": "Causissètz una valor invalida pel paramètre « {name:s} » : {error:s}", "app_argument_required": "Lo paramètre « {name:s} » es requesit", "app_change_url_failed_nginx_reload": "Reaviada de NGINX impossibla. Vaquí la sortida de « nginx -t » :\n{nginx_errors:s}", @@ -50,14 +50,14 @@ "app_extraction_failed": "Extraccion dels fichièrs d’installacion impossibla", "app_incompatible": "L’aplicacion {app} es pas compatibla amb vòstra version de YunoHost", "app_location_already_used": "L’aplicacion « {app} » es ja installada dins ({path})", - "app_manifest_invalid": "Manifest d’aplicacion incorrècte : {error}", + "app_manifest_invalid": "I a quicòm que truca amb lo manifest de l’aplicacion : {error}", "app_package_need_update": "Lo paquet de l’aplicacion {app} deu èsser actualizat per poder seguir los cambiaments de YunoHost", "app_requirements_checking": "Verificacion dels paquets requesits per {app}…", "app_sources_fetch_failed": "Recuperacion dels fichièrs fonts impossibla, l’URL es corrècta ?", "app_unsupported_remote_type": "Lo tipe alonhat utilizat per l’aplicacion es pas suportat", "appslist_retrieve_error": "Impossible de recuperar la lista d’aplicacions alonhadas {appslist:s} : {error:s}", "backup_archive_app_not_found": "L’aplicacion « {app:s} » es pas estada trobada dins l’archiu de la salvagarda", - "backup_archive_broken_link": "Impossible d‘accedir a l’archiu de salvagarda (ligam invalid cap a {path:s})", + "backup_archive_broken_link": "Impossible d’accedir a l’archiu de salvagarda (ligam invalid cap a {path:s})", "backup_archive_mount_failed": "Lo montatge de l’archiu de salvagarda a fracassat", "backup_archive_open_failed": "Impossible de dobrir l’archiu de salvagarda", "backup_archive_system_part_not_available": "La part « {part:s} » del sistèma es pas disponibla dins aquesta salvagarda", @@ -65,7 +65,7 @@ "backup_copying_to_organize_the_archive": "Còpia de {size:s} Mio per organizar l’archiu", "backup_created": "Salvagarda acabada", "backup_creating_archive": "Creacion de l’archiu de salvagarda…", - "backup_creation_failed": "Impossible de crear la salvagarda", + "backup_creation_failed": "Creacion impossibla de l’archiu de salvagarda", "app_already_installed_cant_change_url": "Aquesta aplicacion es ja installada. Aquesta foncion pòt pas simplament cambiar l’URL. Agachatz « app changeurl » s’es disponible.", "app_change_no_change_url_script": "L’aplicacion {app_name:s} pren pas en compte lo cambiament d’URL, poiretz aver de l’actualizar.", "app_change_url_no_script": "L’aplicacion {app_name:s} pren pas en compte lo cambiament d’URL, benlèu que vos cal l’actualizar.", @@ -73,19 +73,19 @@ "app_location_install_failed": "Impossible d’installar l’aplicacion a aqueste emplaçament per causa de conflicte amb l’aplicacion {other_app} qu’es ja installada sus {other_path}", "app_location_unavailable": "Aquesta URL es pas disponibla o en conflicte amb una aplicacion existenta :\n{apps:s}", "appslist_corrupted_json": "Cargament impossible de la lista d’aplicacion. Sembla que {filename:s} siá gastat.", - "backup_delete_error": "Impossible de suprimir « {path:s} »", + "backup_delete_error": "Supression impossibla de « {path:s} »", "backup_deleted": "La salvagarda es estada suprimida", "backup_hook_unknown": "Script de salvagarda « {hook:s} » desconegut", - "backup_invalid_archive": "Archiu de salvagarda incorrècte", + "backup_invalid_archive": "Aquò es pas un archiu de salvagarda", "backup_method_borg_finished": "La salvagarda dins Borg es acabada", "backup_method_copy_finished": "La còpia de salvagarda es acabada", - "backup_method_tar_finished": "L’archiu tar de la salvagarda es estat creat", + "backup_method_tar_finished": "L’archiu TAR de la salvagarda es estat creat", "backup_output_directory_not_empty": "Lo dorsièr de sortida es pas void", "backup_output_directory_required": "Vos cal especificar un dorsièr de sortida per la salvagarda", "backup_running_app_script": "Lançament de l’escript de salvagarda de l’aplicacion « {app:s} »...", "backup_running_hooks": "Execucion dels scripts de salvagarda…", "backup_system_part_failed": "Impossible de salvagardar la part « {part:s} » del sistèma", - "app_requirements_failed": "Impossible de complir las condicions requesidas per {app} : {error}", + "app_requirements_failed": "Impossible de complir unas condicions requesidas per {app} : {error}", "app_requirements_unmeet": "Las condicions requesidas per {app} son pas complidas, lo paquet {pkgname} ({version}) deu èsser {spec}", "appslist_could_not_migrate": "Migracion de la lista impossibla {appslist:s} ! Impossible d’analizar l’URL… L’anciana tasca cron es estada servada dins {bkp_file:s}.", "backup_abstract_method": "Aqueste metòde de salvagarda es pas encara implementat", @@ -399,7 +399,7 @@ "network_check_smtp_ko": "Lo trafic de corrièl sortent (pòrt 25 SMTP) sembla blocat per vòstra ret", "network_check_smtp_ok": "Lo trafic de corrièl sortent (pòrt 25 SMTP) es pas blocat", "pattern_mailbox_quota": "Deu èsser una talha amb lo sufixe b/k/M/G/T o 0 per desactivar la quòta", - "backup_archive_writing_error": "Impossible d’ajustar los fichièrs a la salvagarda dins l’archiu comprimit", + "backup_archive_writing_error": "Impossible d’ajustar los fichièrs « {source:s} » a la salvagarda (nomenats dins l’archiu « {dest:s} »)dins l’archiu comprimit « {archive:s} »", "backup_cant_mount_uncompress_archive": "Impossible de montar en lectura sola lo repertòri de l’archiu descomprimit", "backup_no_uncompress_archive_dir": "Lo repertòri de l’archiu descomprimit existís pas", "pattern_username": "Deu èsser compausat solament de caractèrs alfanumerics en letras minusculas e de tirets basses", @@ -493,7 +493,7 @@ "service_conf_now_managed_by_yunohost": "Lo fichièr de configuracion « {conf} » es ara gerit per YunoHost.", "service_reloaded": "Lo servici « {servici:s} » es estat tornat cargar", "already_up_to_date": "I a pas res a far ! Tot es ja a jorn !", - "app_action_cannot_be_ran_because_required_services_down": "Aquesta aplicacion necessita unes servicis que son actualament encalats. Abans de contunhar deuriatz ensajar de reaviar los servicis seguents (e tanben cercar perque son tombats en pana) : {services}", + "app_action_cannot_be_ran_because_required_services_down": "Aquestas aplicacions necessitan d’èsser lançadas per poder executar aquesta accion : {services}. Abans de contunhar deuriatz ensajar de reaviar los servicis seguents (e tanben cercar perque son tombats en pana) : {services}", "confirm_app_install_warning": "Atencion : aquesta aplicacion fonciona mas non es pas ben integrada amb YunoHost. Unas foncionalitats coma l’autentificacion unica e la còpia de seguretat/restauracion pòdon èsser indisponiblas. volètz l’installar de totas manièras ? [{answers:s}] ", "confirm_app_install_danger": "ATENCION ! Aquesta aplicacion es encara experimentala (autrament dich, fonciona pas) e es possible que còpe lo sistèma ! Deuriatz PAS l’installar se non sabètz çò que fasètz. Volètz vertadièrament córrer aqueste risc ? [{answers:s}] ", "confirm_app_install_thirdparty": "ATENCION ! L’installacion d’aplicacions tèrças pòt comprometre l’integralitat e la seguretat del sistèma. Deuriatz PAS l’installar se non sabètz pas çò que fasètz. Volètz vertadièrament córrer aqueste risc ? [{answers:s}] ", @@ -705,5 +705,8 @@ "diagnosis_failed": "Recuperacion impossibla dels resultats del diagnostic per la categoria « {category} » : {error}", "diagnosis_ip_broken_dnsresolution": "La resolucion del nom de domeni es copada per una rason… Lo parafuòc bloca las requèstas DNS ?", "diagnosis_no_cache": "I a pas encara de diagnostic de cache per la categoria « {category} »", - "apps_catalog_init_success": "Sistèma de catalòg d’aplicacion iniciat !" + "apps_catalog_init_success": "Sistèma de catalòg d’aplicacion iniciat !", + "diagnosis_services_running": "Lo servici {service} es lançat !", + "diagnosis_services_conf_broken": "La configuracion es copada pel servici {service} !", + "diagnosis_ports_needed_by": "Es necessari qu’aqueste pòrt siá accessible pel servici {0}" } From 39563448efefb3bec76e8d53ce5f5ee640762c56 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Mon, 30 Dec 2019 14:01:52 +0000 Subject: [PATCH 040/104] Translated using Weblate (Greek) Currently translated at 0.2% (1 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/el/ --- locales/el.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/el.json b/locales/el.json index 0967ef424..615dfdd48 100644 --- a/locales/el.json +++ b/locales/el.json @@ -1 +1,3 @@ -{} +{ + "password_too_simple_1": "Ο κωδικός πρόσβασης πρέπει να έχει μήκος τουλάχιστον 8 χαρακτήρων" +} From c3f2e97e8d1f735000aee9edc5530ad1777f988e Mon Sep 17 00:00:00 2001 From: amirale qt Date: Mon, 30 Dec 2019 14:15:22 +0000 Subject: [PATCH 041/104] Translated using Weblate (Bengali (Bangladesh)) Currently translated at 0.2% (1 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/bn_BD/ --- locales/bn_BD.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/bn_BD.json b/locales/bn_BD.json index 0967ef424..b5425128d 100644 --- a/locales/bn_BD.json +++ b/locales/bn_BD.json @@ -1 +1,3 @@ -{} +{ + "password_too_simple_1": "পাসওয়ার্ডটি কমপক্ষে 8 টি অক্ষরের দীর্ঘ হওয়া দরকার" +} From d35dcbe968562b8a33dbd017fab1a6bcc3c7c1eb Mon Sep 17 00:00:00 2001 From: yalh76 Date: Wed, 8 Jan 2020 19:57:32 +0100 Subject: [PATCH 042/104] adaptation for various actions --- data/helpers.d/systemd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index 960382f8f..47e905f0f 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -135,7 +135,7 @@ ynh_systemd_action() { # Read the log until the sentence is found, that means the app finished to start. Or run until the timeout if grep --quiet "$line_match" "$templog" then - ynh_print_info --message="The service $service_name has correctly started." + ynh_print_info --message="The service $service_name has correctly executed the action ${action}." break fi if [ $i -eq 3 ]; then @@ -151,7 +151,7 @@ ynh_systemd_action() { fi if [ $i -eq $timeout ] then - ynh_print_warn --message="The service $service_name didn't fully started before the timeout." + ynh_print_warn --message="The service $service_name didn't fully executed the action ${action} before the timeout." ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:" journalctl --no-pager --lines=$length -u $service_name >&2 test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2 From 133ae3a22e12407ab55c2923306ffb80d0382c37 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 31 Dec 2019 15:29:37 +0000 Subject: [PATCH 043/104] Translated using Weblate (Italian) Currently translated at 19.4% (118 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/it/ --- locales/it.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index fc2355e7f..deaed8d8f 100644 --- a/locales/it.json +++ b/locales/it.json @@ -435,5 +435,6 @@ "migration_0003_not_jessie": "La distribuzione attuale non è Jessie!", "migration_0003_system_not_fully_up_to_date": "Il tuo sistema non è completamente aggiornato. Per favore prima esegui un aggiornamento normale prima di migrare a stretch.", "this_action_broke_dpkg": "Questa azione ha danneggiato dpkg/apt (i gestori di pacchetti del sistema)… Puoi provare a risolvere questo problema connettendoti via SSH ed eseguendo `sudo dpkg --configure -a`.", - "updating_app_lists": "Recupero degli aggiornamenti disponibili per le applicazioni…" + "updating_app_lists": "Recupero degli aggiornamenti disponibili per le applicazioni…", + "app_action_broke_system": "Questa azione sembra avere roto servizi importanti: {services}" } From 684e8cf1ff5580acb83a6600c39bc2b1259104d6 Mon Sep 17 00:00:00 2001 From: Jeroen Franssen Date: Fri, 10 Jan 2020 15:54:03 +0000 Subject: [PATCH 044/104] Translated using Weblate (Dutch) Currently translated at 7.4% (45 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/nl/ --- locales/nl.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/locales/nl.json b/locales/nl.json index df554f7e2..832ca4ea2 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -1,7 +1,7 @@ { "action_invalid": "Ongeldige actie '{action:s}'", "admin_password": "Administrator wachtwoord", - "admin_password_changed": "Het administratie wachtwoord is gewijzigd", + "admin_password_changed": "Het administratie wachtwoord werd gewijzigd", "app_already_installed": "{app:s} is al geïnstalleerd", "app_argument_invalid": "'{name:s}' bevat ongeldige waarde: {error:s}", "app_argument_required": "Het '{name:s}' moet ingevuld worden", @@ -139,5 +139,9 @@ "backup_extracting_archive": "Backup archief uitpakken...", "backup_hook_unknown": "backup hook '{hook:s}' onbekend", "backup_nothings_done": "Niets om op te slaan", - "password_too_simple_1": "Het wachtwoord moet minimaal 8 tekens lang zijn" + "password_too_simple_1": "Het wachtwoord moet minimaal 8 tekens lang zijn", + "already_up_to_date": "Er is niets te doen, alles is al up-to-date.", + "admin_password_too_long": "Gelieve een wachtwoord te kiezen met minder dan 127 karakters", + "app_action_cannot_be_ran_because_required_services_down": "De volgende diensten moeten actief zijn om deze actie uit te voeren: {services}. Probeer om deze te herstarten om verder te gaan (en om eventueel te onderzoeken waarom ze niet werken).", + "aborting": "Annulatie." } From b968dff2ee469f966922cdabfbb98b7c80d9ad5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Thu, 2 Jan 2020 11:24:20 +0000 Subject: [PATCH 045/104] Translated using Weblate (Occitan) Currently translated at 70.5% (428 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/oc/ --- locales/oc.json | 134 ++++++++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/locales/oc.json b/locales/oc.json index 7979a22df..4251a3307 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -80,7 +80,7 @@ "backup_method_borg_finished": "La salvagarda dins Borg es acabada", "backup_method_copy_finished": "La còpia de salvagarda es acabada", "backup_method_tar_finished": "L’archiu TAR de la salvagarda es estat creat", - "backup_output_directory_not_empty": "Lo dorsièr de sortida es pas void", + "backup_output_directory_not_empty": "Devètz causir un dorsièr de sortida void", "backup_output_directory_required": "Vos cal especificar un dorsièr de sortida per la salvagarda", "backup_running_app_script": "Lançament de l’escript de salvagarda de l’aplicacion « {app:s} »...", "backup_running_hooks": "Execucion dels scripts de salvagarda…", @@ -116,23 +116,23 @@ "backup_applying_method_borg": "Mandadís de totes los fichièrs a la salvagarda dins lo repertòri borg-backup…", "backup_csv_creation_failed": "Creacion impossibla del fichièr CSV necessari a las operacions futuras de restauracion", "backup_extracting_archive": "Extraccion de l’archiu de salvagarda…", - "backup_output_symlink_dir_broken": "Avètz un ligam simbolic copat allòc de vòstre repertòri d’archiu « {path:s} ». Poiriatz aver una configuracion personalizada per salvagardar vòstras donadas sus un autre sistèma de fichièrs, en aquel cas, saique oblidèretz de montar o de connectar lo disc o la clau USB.", + "backup_output_symlink_dir_broken": "Vòstre repertòri d’archiu « {path:s} » es un ligam simbolic copat. Saique oblidèretz de re/montar o de connectar supòrt.", "backup_with_no_backup_script_for_app": "L’aplicacion {app:s} a pas cap de script de salvagarda. I fasèm pas cas.", "backup_with_no_restore_script_for_app": "L’aplicacion {app:s} a pas cap de script de restauracion, poiretz pas restaurar automaticament la salvagarda d’aquesta aplicacion.", - "certmanager_acme_not_configured_for_domain": "Lo certificat del domeni {domain:s} sembla pas corrèctament installat. Mercés de lançar d’en primièr cert-install per aqueste domeni.", + "certmanager_acme_not_configured_for_domain": "Lo certificat pel domeni {domain:s} sembla pas corrèctament installat. Mercés de lançar d’en primièr « cert-install » per aqueste domeni.", "certmanager_attempt_to_renew_nonLE_cert": "Lo certificat pel domeni {domain:s} es pas provesit per Let’s Encrypt. Impossible de lo renovar automaticament !", "certmanager_attempt_to_renew_valid_cert": "Lo certificat pel domeni {domain:s} es a man d’expirar ! (Podètz utilizar --force se sabètz çò que fasètz)", "certmanager_cannot_read_cert": "Quicòm a trucat en ensajar de dobrir lo certificat actual pel domeni {domain:s} (fichièr : {file:s}), rason : {reason:s}", - "certmanager_cert_install_success": "Installacion capitada del certificat Let’s Encrypt pel domeni {domain:s} !", - "certmanager_cert_install_success_selfsigned": "Installacion capitada del certificat auto-signat pel domeni {domain:s} !", - "certmanager_cert_signing_failed": "Fracàs de la signatura del nòu certificat", - "certmanager_domain_cert_not_selfsigned": "Lo certificat del domeni {domain:s} es pas auto-signat. Volètz vertadièrament lo remplaçar ? (Utiliatz --force)", - "certmanager_domain_dns_ip_differs_from_public_ip": "L’enregistrament DNS « A » del domeni {domain:s} es diferent de l’adreça IP d’aqueste servidor. Se fa pauc qu’avètz modificat l’enregistrament « A », mercés d’esperar l’espandiment (qualques verificadors d’espandiment son disponibles en linha). (Se sabètz çò que fasèm, utilizatz --no-checks per desactivar aqueles contraròtles)", - "certmanager_domain_http_not_working": "Sembla que lo domeni {domain:s} es pas accessible via HTTP. Mercés de verificar que las configuracions DNS e nginx son corrèctas", - "certmanager_domain_unknown": "Domeni desconegut {domain:s}", + "certmanager_cert_install_success": "Lo certificat Let’s Encrypt es ara installat pel domeni « {domain:s} »", + "certmanager_cert_install_success_selfsigned": "Lo certificat auto-signat es ara installat pel domeni « {domain:s} »", + "certmanager_cert_signing_failed": "Signatura impossibla del nòu certificat", + "certmanager_domain_cert_not_selfsigned": "Lo certificat pel domeni {domain:s} es pas auto-signat. Volètz vertadièrament lo remplaçar ? (Utilizatz « --force » per o far)", + "certmanager_domain_dns_ip_differs_from_public_ip": "L’enregistrament DNS « A » pel domeni {domain:s} es diferent de l’adreça IP d’aqueste servidor. Se fa pauc qu’avètz modificat l’enregistrament « A », mercés d’esperar l’espandiment (qualques verificadors d’espandiment son disponibles en linha). (Se sabètz çò que fasèm, utilizatz --no-checks per desactivar aqueles contraròtles)", + "certmanager_domain_http_not_working": "Sembla que lo domeni {domain:s} es pas accessible via HTTP. Mercés de verificar que las configuracions DNS e NGINK son corrèctas", + "certmanager_domain_unknown": "Domeni desconegut « {domain:s} »", "certmanager_no_cert_file": "Lectura impossibla del fichièr del certificat pel domeni {domain:s} (fichièr : {file:s})", - "certmanager_self_ca_conf_file_not_found": "Lo fichièr de configuracion per l’autoritat del certificat auto-signat es introbabla (fichièr : {file:s})", - "certmanager_unable_to_parse_self_CA_name": "Analisi impossible lo nom de l’autoritat del certificat auto-signat (fichièr : {file:s})", + "certmanager_self_ca_conf_file_not_found": "Impossible de trobar lo fichièr de configuracion per l’autoritat del certificat auto-signat (fichièr : {file:s})", + "certmanager_unable_to_parse_self_CA_name": "Analisi impossibla del nom de l’autoritat del certificat auto-signat (fichièr : {file:s})", "custom_app_url_required": "Cal que donetz una URL per actualizar vòstra aplicacion personalizada {app:s}", "custom_appslist_name_required": "Cal que nomenetz vòstra lista d’aplicacions personalizadas", "diagnosis_debian_version_error": "Impossible de determinar la version de Debian : {error}", @@ -141,10 +141,10 @@ "dnsmasq_isnt_installed": "dnsmasq sembla pas èsser installat, mercés de lançar « apt-get remove bind9 && apt-get install dnsmasq »", "domain_cannot_remove_main": "Impossible de levar lo domeni màger. Definissètz un novèl domeni màger d’en primièr", "domain_cert_gen_failed": "Generacion del certificat impossibla", - "domain_created": "Lo domeni es creat", - "domain_creation_failed": "Creacion del certificat impossibla", - "domain_deleted": "Lo domeni es suprimit", - "domain_deletion_failed": "Supression impossibla del domeni", + "domain_created": "Domeni creat", + "domain_creation_failed": "Creacion del domeni {domain}: impossibla", + "domain_deleted": "Domeni suprimit", + "domain_deletion_failed": "Supression impossibla del domeni {domini}: {error}", "domain_dyndns_invalid": "Domeni incorrècte per una utilizacion amb DynDNS", "domain_dyndns_root_unknown": "Domeni DynDNS màger desconegut", "domain_exists": "Lo domeni existís ja", @@ -156,33 +156,33 @@ "done": "Acabat", "downloading": "Telecargament…", "dyndns_could_not_check_provide": "Impossible de verificar se {provider:s} pòt provesir {domain:s}.", - "dyndns_cron_installed": "La tasca cron pel domeni DynDNS es installada", - "dyndns_cron_remove_failed": "Impossible de levar la tasca cron pel domeni DynDNS a causa de {error}", - "dyndns_cron_removed": "La tasca cron pel domeni DynDNS es levada", + "dyndns_cron_installed": "Tasca cron pel domeni DynDNS creada", + "dyndns_cron_remove_failed": "Impossible de levar la tasca cron pel domeni DynDNS : {error}", + "dyndns_cron_removed": "Tasca cron pel domeni DynDNS levada", "dyndns_ip_update_failed": "Impossible d’actualizar l’adreça IP sul domeni DynDNS", - "dyndns_ip_updated": "Vòstra adreça IP es estada actualizada pel domeni DynDNS", - "dyndns_key_generating": "La clau DNS es a se generar, pòt trigar una estona…", + "dyndns_ip_updated": "Vòstra adreça IP actualizada pel domeni DynDNS", + "dyndns_key_generating": "La clau DNS es a se generar… pòt trigar una estona.", "dyndns_key_not_found": "Clau DNS introbabla pel domeni", "dyndns_no_domain_registered": "Cap de domeni pas enregistrat amb DynDNS", - "dyndns_registered": "Lo domeni DynDNS es enregistrat", - "dyndns_registration_failed": "Enregistrament del domeni DynDNS impossibla : {error:s}", + "dyndns_registered": "Domeni DynDNS enregistrat", + "dyndns_registration_failed": "Enregistrament del domeni DynDNS impossible : {error:s}", "dyndns_domain_not_provided": "Lo provesidor DynDNS {provider:s} pòt pas fornir lo domeni {domain:s}.", "dyndns_unavailable": "Lo domeni {domain:s} es pas disponible.", "extracting": "Extraccion…", "field_invalid": "Camp incorrècte : « {:s} »", "format_datetime_short": "%d/%m/%Y %H:%M", "global_settings_cant_open_settings": "Fracàs de la dobertura del fichièr de configuracion, rason : {reason:s}", - "global_settings_key_doesnt_exists": "La clau « {settings_key:s} » existís pas dins las configuracions globalas, podètz veire totas las claus disponiblas en picant « yunohost settings list »", - "global_settings_reset_success": "Capitada ! Vòstra configuracion precedenta es estada salvagarda dins {path:s}", + "global_settings_key_doesnt_exists": "La clau « {settings_key:s} » existís pas dins las configuracions globalas, podètz veire totas las claus disponiblas en executant « yunohost settings list »", + "global_settings_reset_success": "Configuracion precedenta ara salvagarda dins {path:s}", "global_settings_setting_example_bool": "Exemple d’opcion booleana", "global_settings_unknown_setting_from_settings_file": "Clau desconeguda dins los paramètres : {setting_key:s}, apartada e salvagardada dins /etc/yunohost/settings-unknown.json", - "installation_failed": "Fracàs de l’installacion", + "installation_failed": "Quicòm a trucat e l’installacion a pas reüssit", "invalid_url_format": "Format d’URL pas valid", "ldap_initialized": "L’annuari LDAP es inicializat", "license_undefined": "indefinida", "main_domain_change_failed": "Modificacion impossibla del domeni màger", "main_domain_changed": "Lo domeni màger es estat modificat", - "migrate_tsig_end": "La migracion cap a hmac-sha512 es acabada", + "migrate_tsig_end": "La migracion cap a HMAC-SHA512 es acabada", "migrate_tsig_wait_2": "2 minutas…", "migrate_tsig_wait_3": "1 minuta…", "migrate_tsig_wait_4": "30 segondas…", @@ -192,7 +192,7 @@ "migration_0003_start": "Aviada de la migracion cap a Stretech. Los jornals seràn disponibles dins {logfile}.", "migration_0003_patching_sources_list": "Petaçatge de sources.lists…", "migration_0003_main_upgrade": "Aviada de la mesa a nivèl màger…", - "migration_0003_fail2ban_upgrade": "Aviada de la mesa a nivèl de fail2ban…", + "migration_0003_fail2ban_upgrade": "Aviada de la mesa a nivèl de Fail2Ban…", "migration_0003_not_jessie": "La distribucion Debian actuala es pas Jessie !", "migrations_cant_reach_migration_file": "Impossible d’accedir als fichièrs de migracion amb lo camin %s", "migrations_current_target": "La cibla de migracion est {}", @@ -228,13 +228,13 @@ "port_unavailable": "Lo pòrt {port:d} es pas disponible", "restore_already_installed_app": "Una aplicacion es ja installada amb l’id « {app:s} »", "restore_app_failed": "Impossible de restaurar l’aplicacion « {app:s} »", - "backup_ask_for_copying_if_needed": "D’unes fichièrs an pas pogut èsser preparatz per la salvagarda en utilizar lo metòde qu’evita de gastar d’espaci sul sistèma de manièra temporària. Per lançar la salvagarda, cal utilizar temporàriament {size:s} Mo. Acceptatz ?", + "backup_ask_for_copying_if_needed": "Volètz far una salvagarda en utilizant {size:s} Mo temporàriament ? (Aqueste biais de far es emplegat perque unes fichièrs an pas pogut èsser preparats amb un metòde mai eficaç.)", "yunohost_not_installed": "YunoHost es pas installat o corrèctament installat. Mercés d’executar « yunohost tools postinstall »", - "backup_output_directory_forbidden": "Repertòri de destinacion defendut. Las salvagardas pòdon pas se realizar dins los repertòris bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives", + "backup_output_directory_forbidden": "Causissètz un repertòri de destinacion deferent. Las salvagardas pòdon pas se realizar dins los repertòris bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives", "certmanager_attempt_to_replace_valid_cert": "Sètz a remplaçar un certificat corrècte e valid pel domeni {domain:s} ! (Utilizatz --force per cortcircuitar)", - "certmanager_cert_renew_success": "Renovèlament capitat d’un certificat Let’s Encrypt pel domeni {domain:s} !", - "certmanager_certificate_fetching_or_enabling_failed": "Sembla d’aver fracassat l’activacion d’un nòu certificat per {domain:s}…", - "certmanager_conflicting_nginx_file": "Impossible de preparar lo domeni pel desfís ACME : lo fichièr de configuracion nginx {filepath:s} es en conflicte e deu èsser levat d’en primièr", + "certmanager_cert_renew_success": "Renovèlament capitat d’un certificat Let’s Encrypt pel domeni « {domain:s} »", + "certmanager_certificate_fetching_or_enabling_failed": "Sembla qu’utilizar lo nòu certificat per {domain:s} fonciona pas…", + "certmanager_conflicting_nginx_file": "Impossible de preparar lo domeni pel desfís ACME : lo fichièr de configuracion NGINX {filepath:s} es en conflicte e deu èsser levat d’en primièr", "certmanager_couldnt_fetch_intermediate_cert": "Expiracion del relambi pendent l’ensag de recuperacion del certificat intermediari dins de Let’s Encrypt. L’installacion / lo renovèlament es estat interromput - tornatz ensajar mai tard.", "certmanager_domain_not_resolved_locally": "Lo domeni {domain:s} pòt pas èsser determinat dins de vòstre servidor YunoHost. Pòt arribar s’avètz recentament modificat vòstre enregistrament DNS. Dins aqueste cas, mercés d’esperar unas oras per l’espandiment. Se lo problèma dura, consideratz ajustar {domain:s} a /etc/hosts. (Se sabètz çò que fasètz, utilizatz --no-checks per desactivar las verificacions.)", "certmanager_error_no_A_record": "Cap d’enregistrament DNS « A » pas trobat per {domain:s}. Vos cal indicar que lo nom de domeni mene a vòstra maquina per poder installar un certificat Let’S Encrypt ! (Se sabètz çò que fasètz, utilizatz --no-checks per desactivar las verificacions.)", @@ -245,25 +245,25 @@ "domain_dyndns_dynette_is_unreachable": "Impossible de contactar la dynette YunoHost, siá YunoHost pas es pas corrèctament connectat a Internet, siá lo servidor de la dynett es arrestat. Error : {error}", "domain_uninstall_app_first": "Una o mantuna aplicacions son installadas sus aqueste domeni. Mercés de las desinstallar d’en primièr abans de suprimir aqueste domeni", "firewall_reload_failed": "Impossible de recargar lo parafuòc", - "firewall_reloaded": "Lo parafuòc es estat recargat", + "firewall_reloaded": "Parafuòc recargat", "firewall_rules_cmd_failed": "Unas règlas del parafuòc an fracassat. Per mai informacions, consultatz lo jornal.", "global_settings_bad_choice_for_enum": "La valor del paramètre {setting:s} es incorrècta. Recebut : {received_type:s}, mas las opcions esperadas son : {expected_type:s}", - "global_settings_bad_type_for_setting": "Lo tipe del paramètre {setting:s} es incorrècte. Recebut : {received_type:s}, esperat {expected_type:s}", + "global_settings_bad_type_for_setting": "Lo tipe del paramètre {setting:s} es incorrècte, recebut : {received_type:s}, esperat {expected_type:s}", "global_settings_cant_write_settings": "Fracàs de l’escritura del fichièr de configuracion, rason : {reason:s}", "global_settings_setting_example_enum": "Exemple d’opcion de tipe enumeracion", "global_settings_setting_example_int": "Exemple d’opcion de tipe entièr", "global_settings_setting_example_string": "Exemple d’opcion de tipe cadena", "global_settings_unknown_type": "Situacion inesperada, la configuracion {setting:s} sembla d’aver lo tipe {unknown_type:s} mas es pas un tipe pres en carga pel sistèma.", - "hook_exec_failed": "Fracàs de l’execucion del script « {path:s} »", - "hook_exec_not_terminated": "L’execucion del escript « {path:s} » es pas acabada", + "hook_exec_failed": "Fracàs de l’execucion del script : « {path:s} »", + "hook_exec_not_terminated": "Lo escript « {path:s} » a pas acabat corrèctament", "hook_list_by_invalid": "La proprietat de tria de las accions es invalida", "hook_name_unknown": "Nom de script « {name:s} » desconegut", "ldap_init_failed_to_create_admin": "L’inicializacion de LDAP a pas pogut crear l’utilizaire admin", "mail_domain_unknown": "Lo domeni de corrièl « {domain:s} » es desconegut", "mailbox_used_space_dovecot_down": "Lo servici corrièl Dovecot deu èsser aviat, se volètz conéisser l’espaci ocupat per la messatjariá", - "migrate_tsig_failed": "La migracion del domeni dyndns {domain} cap a hmac-sha512 a pas capitat, anullacion de las modificacions. Error : {error_code} - {error}", - "migrate_tsig_wait": "Esperem 3 minutas que lo servidor dyndns prenga en compte la novèla clau…", - "migrate_tsig_not_needed": "Sembla qu’utilizatz pas un domeni dyndns, donc cap de migracion es pas necessària !", + "migrate_tsig_failed": "La migracion del domeni DynDNS {domain} cap a HMAC-SHA512 a pas capitat, anullacion de las modificacions. Error : {error_code} - {error}", + "migrate_tsig_wait": "Esperem 3 minutas que lo servidor DynDNS prenga en compte la novèla clau…", + "migrate_tsig_not_needed": "Sembla qu’utilizatz pas un domeni DynDNS, donc cap de migracion es pas necessària.", "migration_0003_yunohost_upgrade": "Aviada de la mesa a nivèl del paquet YunoHost… La migracion acabarà, mas l’actualizacion reala se realizarà tot bèl aprèp. Un còp acabada, poiretz vos reconnectar a l’administracion web.", "migration_0003_system_not_fully_up_to_date": "Lo sistèma es pas complètament a jorn. Mercés de lançar una mesa a jorn classica abans de començar la migracion per Stretch.", "migration_0003_modified_files": "Mercés de notar que los fichièrs seguents son estats detectats coma modificats manualament e poiràn èsser escafats a la fin de la mesa a nivèl : {manually_modified_files}", @@ -369,7 +369,7 @@ "update_cache_failed": "Impossible d’actualizar lo cache de l’APT", "mail_alias_remove_failed": "Supression impossibla de l’alias de corrièl « {mail:s} »", "mail_forward_remove_failed": "Supression impossibla del corrièl de transferiment « {mail:s} »", - "migrate_tsig_start": "L’algorisme de generacion de claus es pas pro securizat per la signatura TSIG del domeni « {domain} », lançament de la migracion cap a hmac-sha512 que’s mai securizat", + "migrate_tsig_start": "L’algorisme de generacion de claus es pas pro securizat per la signatura TSIG del domeni « {domain} », lançament de la migracion cap a un mai segur HMAC-SHA-512", "migration_description_0001_change_cert_group_to_sslcert": "Càmbia las permissions de grop dels certificats de « metronome » per « ssl-cert »", "migration_0003_restoring_origin_nginx_conf": "Vòstre fichièr /etc/nginx/nginx.conf es estat modificat manualament. La migracion reïnicializarà d’en primièr son estat origina… Lo fichièr precedent serà disponible coma {backup_dest}.", "migration_0003_still_on_jessie_after_main_upgrade": "Quicòm a trucat pendent la mesa a nivèl màger : lo sistèma es encara jos Jessie ?!? Per trobar lo problèma, agachatz {log}…", @@ -404,11 +404,11 @@ "backup_no_uncompress_archive_dir": "Lo repertòri de l’archiu descomprimit existís pas", "pattern_username": "Deu èsser compausat solament de caractèrs alfanumerics en letras minusculas e de tirets basses", "experimental_feature": "Atencion : aquesta foncionalitat es experimentala e deu pas èsser considerada coma establa, deuriatz pas l’utilizar levat que sapiatz çò que fasètz.", - "log_corrupted_md_file": "Lo fichièr yaml de metadonada amb los jornals d’audit es corromput : « {md_file} »\nError : {error:s}", + "log_corrupted_md_file": "Lo fichièr YAML de metadonadas ligat als jornals d’audit es damatjat : « {md_file} »\nError : {error:s}", "log_category_404": "La categoria de jornals d’audit « {category} » existís pas", "log_link_to_log": "Jornal complèt d’aquesta operacion : {desc}", "log_help_to_get_log": "Per veire lo jornal d’aquesta operacion « {desc} », utilizatz la comanda « yunohost log display {name} »", - "backup_php5_to_php7_migration_may_fail": "Impossible de convertir vòstre archiu per prendre en carga PHP 7, la restauracion de vòstras aplicacions PHP pòt reüssir pas (rason : {error:s})", + "backup_php5_to_php7_migration_may_fail": "Impossible de convertir vòstre archiu per prendre en carga PHP 7, la restauracion de vòstras aplicacions PHP pòt reüssir pas a restaurar vòstras aplicacions PHP (rason : {error:s})", "log_link_to_failed_log": "L’operacion « {desc} » a pas capitat ! Per obténer d’ajuda, mercés de fornir lo jornal complèt de l’operacion", "log_help_to_get_failed_log": "L’operacion « {desc} » a pas reüssit ! Per obténer d’ajuda, mercés de partejar lo jornal d’audit complèt d’aquesta operacion en utilizant la comanda « yunohost log display {name} --share »", "log_does_exists": "I a pas cap de jornal d’audit per l’operacion amb lo nom « {log} », utilizatz « yunohost log list » per veire totes los jornals d’operacion disponibles", @@ -421,7 +421,7 @@ "log_app_change_url": "Cambiar l’URL de l’aplicacion « {} »", "log_app_install": "Installar l’aplicacion « {} »", "log_app_remove": "Levar l’aplicacion « {} »", - "log_app_upgrade": "Actualizacion de l’aplicacion « {} »", + "log_app_upgrade": "Actualizar l’aplicacion « {} »", "log_app_makedefault": "Far venir « {} » l’aplicacion per defaut", "log_available_on_yunopaste": "Lo jornal es ara disponible via {url}", "log_backup_restore_system": "Restaurar lo sistèma a partir d’una salvagarda", @@ -432,14 +432,14 @@ "log_domain_remove": "Tirar lo domeni « {} » d’a la configuracion sistèma", "log_dyndns_subscribe": "S’abonar al subdomeni YunoHost « {} »", "log_dyndns_update": "Actualizar l’adreça IP ligada a vòstre jos-domeni YunoHost « {} »", - "log_letsencrypt_cert_install": "Installar lo certificat Let's encrypt sul domeni « {} »", + "log_letsencrypt_cert_install": "Installar un certificat Let's Encrypt sul domeni « {} »", "log_selfsigned_cert_install": "Installar lo certificat auto-signat sul domeni « {} »", - "log_letsencrypt_cert_renew": "Renovar lo certificat Let's encrypt de « {} »", + "log_letsencrypt_cert_renew": "Renovar lo certificat Let's Encrypt de « {} »", "log_service_enable": "Activar lo servici « {} »", "log_service_regen_conf": "Regenerar la configuracion sistèma de « {} »", "log_user_create": "Ajustar l’utilizaire « {} »", "log_user_delete": "Levar l’utilizaire « {} »", - "log_user_update": "Actualizar las informacions a l’utilizaire « {} »", + "log_user_update": "Actualizar las informacions de l’utilizaire « {} »", "log_domain_main_domain": "Far venir « {} » lo domeni màger", "log_tools_migrations_migrate_forward": "Migrar", "log_tools_migrations_migrate_backward": "Tornar en arrièr", @@ -449,8 +449,8 @@ "log_tools_reboot": "Reaviar lo servidor", "mail_unavailable": "Aquesta adreça electronica es reservada e deu èsser automaticament atribuida al tot bèl just primièr utilizaire", "migration_description_0004_php5_to_php7_pools": "Tornar configurar lo pools PHP per utilizar PHP 7 allòc del 5", - "migration_description_0005_postgresql_9p4_to_9p6": "Migracion de las basas de donadas de postgresql 9.4 cap a 9.6", - "migration_0005_postgresql_94_not_installed": "Postgresql es pas installat sul sistèma. Pas res de far !", + "migration_description_0005_postgresql_9p4_to_9p6": "Migracion de las basas de donadas de PostgreSQL9.4 cap a 9.6", + "migration_0005_postgresql_94_not_installed": "PostgreSQL es pas installat sul sistèma. I a pas res per far.", "migration_0005_postgresql_96_not_installed": "Avèm trobat que Postgresql 9.4 es installat, mas cap de version de Postgresql 9.6 pas trobada !? Quicòm d’estranh a degut arribar a vòstre sistèma :( …", "migration_0005_not_enough_space": "I a pas pro d’espaci disponible sus {path} per lançar la migracion d’aquela passa :(.", "recommend_to_add_first_user": "La post installacion es acabada, mas YunoHost fa besonh d’almens un utilizaire per foncionar coma cal. Vos cal n’ajustar un en utilizant la comanda « yunohost user create Date: Mon, 6 Jan 2020 07:34:40 +0000 Subject: [PATCH 046/104] Translated using Weblate (French) Currently translated at 100.0% (607 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 11f171347..f69dea8f9 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -420,12 +420,12 @@ "experimental_feature": "Attention : cette fonctionnalité est expérimentale et ne doit pas être considérée comme stable, vous ne devriez pas l’utiliser à moins que vous ne sachiez ce que vous faites.", "log_corrupted_md_file": "Le fichier YAML de métadonnées associé aux logs est corrompu : '{md_file}'\nErreur : {error}", "log_category_404": "Le journal de la catégorie '{category}' n’existe pas", - "log_link_to_log": "Journal historisé complet de cette opération : ' {desc} '", - "log_help_to_get_log": "Pour voir le journal historisé de cette opération '{desc}', utilisez la commande 'yunohost log display {name}'", + "log_link_to_log": "Journal complet de cette opération : ' {desc} '", + "log_help_to_get_log": "Pour voir le journal de cette opération '{desc}', utilisez la commande 'yunohost log display {name}'", "log_link_to_failed_log": "L’opération '{desc}' a échouée ! Pour obtenir de l’aide, merci de partager le journal de l'opération en cliquant ici", "backup_php5_to_php7_migration_may_fail": "Impossible de convertir votre archive pour prendre en charge PHP 7, vous pourriez ne plus pouvoir restaurer vos applications PHP (cause : {error:s})", "log_help_to_get_failed_log": "L’opération '{desc}' a échouée ! Pour obtenir de l’aide, merci de partager le journal de l'opération en utilisant la commande 'yunohost log display {name} --share'", - "log_does_exists": "Il n’existe pas de journal historisé de l’opération ayant pour nom '{log}', utiliser 'yunohost log list pour voir tous les fichiers de journaux historisés disponibles'", + "log_does_exists": "Il n’existe pas de journal de l’opération ayant pour nom '{log}', utiliser 'yunohost log list' pour voir tous les fichiers de journaux disponibles", "log_operation_unit_unclosed_properly": "L’opération ne s’est pas terminée correctement", "log_app_addaccess": "Ajouter l’accès à '{}'", "log_app_removeaccess": "Enlever l’accès à '{}'", @@ -437,7 +437,7 @@ "log_app_remove": "Enlever l’application '{}'", "log_app_upgrade": "Mettre à jour l’application '{}'", "log_app_makedefault": "Faire de '{}' l’application par défaut", - "log_available_on_yunopaste": "Le journal historisé est désormais disponible via {url}", + "log_available_on_yunopaste": "Le journal est désormais disponible via {url}", "log_backup_restore_system": "Restaurer le système depuis une archive de sauvegarde", "log_backup_restore_app": "Restaurer '{}' depuis une sauvegarde", "log_remove_on_failed_restore": "Retirer '{}' après un échec de restauration depuis une archive de sauvegarde", From cdbbef769e6d5a9e488816afcae9f0eb7c972333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Tue, 14 Jan 2020 01:04:20 +0000 Subject: [PATCH 047/104] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 17.6% (107 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/nb_NO/ --- locales/nb_NO.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/nb_NO.json b/locales/nb_NO.json index 4fe62eebb..f15388941 100644 --- a/locales/nb_NO.json +++ b/locales/nb_NO.json @@ -165,5 +165,7 @@ "log_link_to_log": "Full logg for denne operasjonen: '{desc}'", "log_help_to_get_log": "For å vise loggen for operasjonen '{desc}', bruk kommandoen 'yunohost log display {name}'", "log_app_clearaccess": "Fjern all tilgang til '{}'", - "log_user_create": "Legg til '{}' bruker" + "log_user_create": "Legg til '{}' bruker", + "app_change_url_success": "{app:s} nettadressen er nå {domain:s}{path:s}", + "app_install_failed": "Kunne ikke installere {app}: {error}" } From 6e427374ec614db7f0ae946af87da30c0f57e534 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 16 Jan 2020 00:34:11 +0700 Subject: [PATCH 048/104] fix legacy permission management --- data/helpers.d/setting | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index c862d4ef6..b07b552af 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -187,9 +187,15 @@ EOF # Fucking legacy permission management. # We need this because app temporarily set the app as unprotected to configure it with curl... - if [[ "$3" =~ ^(unprotected|skipped)_ ]] && [[ "${4:-}" == "/" ]] + if [[ "$3" =~ ^(unprotected|skipped)_ ]] then - ynh_permission_update --permission "main" --add "visitors" + if [[ "$1" == "set" ]] && [[ "${4:-}" == "/" ]] + then + ynh_permission_update --permission "main" --add "visitors" + elif [[ "$1" == "delete" ]] + then + ynh_permission_update --permission "main" --remove "visitors" + fi fi } From 9eaabe25decda204b6b4188479a2a1a2d4ef8d05 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 16 Jan 2020 01:21:14 +0700 Subject: [PATCH 049/104] add operation logger for config panel --- locales/en.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/en.json b/locales/en.json index 08fc6b74e..2d446e191 100644 --- a/locales/en.json +++ b/locales/en.json @@ -323,6 +323,9 @@ "log_app_remove": "Remove the '{}' app", "log_app_upgrade": "Upgrade the '{}' app", "log_app_makedefault": "Make '{}' the default app", + "log_app_action_run": "Run action of the '{}' app", + "log_app_config_show_panel": "Show the config panel of the '{}' app", + "log_app_config_apply": "Apply config to the '{}' app", "log_available_on_yunopaste": "This log is now available via {url}", "log_backup_restore_system": "Restore system from a backup archive", "log_backup_restore_app": "Restore '{}' from a backup archive", From 87a3ceb983620002b50a19c87cf4f97479ae11ad Mon Sep 17 00:00:00 2001 From: Kay0u Date: Sat, 25 Jan 2020 20:49:29 +0700 Subject: [PATCH 050/104] [FIX] bad response from the server --- data/hooks/diagnosis/14-ports.py | 22 +++++++++++++--------- data/hooks/diagnosis/16-http.py | 18 +++++++++++------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index f9694a9de..aaf31d561 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -26,16 +26,20 @@ class PortsDiagnoser(Diagnoser): ports[port] = service try: - r = requests.post('https://diagnosis.yunohost.org/check-ports', json={'ports': ports.keys()}, timeout=30).json() - if "status" not in r.keys(): - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - elif r["status"] == "error": - if "content" in r.keys(): - raise Exception(r["content"]) - else: + r = requests.post('https://diagnosis.yunohost.org/check-ports', json={'ports': ports.keys()}, timeout=30) + if r.status_code == 200: + r = r.json() + if "status" not in r.keys(): raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - elif r["status"] != "ok" or "ports" not in r.keys() or not isinstance(r["ports"], dict): - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + elif r["status"] == "error": + if "content" in r.keys(): + raise Exception(r["content"]) + else: + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + elif r["status"] != "ok" or "ports" not in r.keys() or not isinstance(r["ports"], dict): + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + else: + raise Exception("Bad response from the server https://diagnosis.yunohost.org : %s" % str(r.status_code)) except Exception as e: raise YunohostError("diagnosis_ports_could_not_diagnose", error=e) diff --git a/data/hooks/diagnosis/16-http.py b/data/hooks/diagnosis/16-http.py index c7955c805..ac30dad78 100644 --- a/data/hooks/diagnosis/16-http.py +++ b/data/hooks/diagnosis/16-http.py @@ -28,14 +28,18 @@ class HttpDiagnoser(Diagnoser): os.system("touch /tmp/.well-known/ynh-diagnosis/%s" % nonce) try: - r = requests.post('https://diagnosis.yunohost.org/check-http', json={'domain': domain, "nonce": nonce}, timeout=30).json() - if "status" not in r.keys(): - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - elif r["status"] == "error" and ("code" not in r.keys() or not r["code"].startswith("error_http_check_")): - if "content" in r.keys(): - raise Exception(r["content"]) - else: + r = requests.post('https://diagnosis.yunohost.org/check-http', json={'domain': domain, "nonce": nonce}, timeout=30) + if r.status_code == 200: + r = r.json() + if "status" not in r.keys(): raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + elif r["status"] == "error" and ("code" not in r.keys() or not r["code"].startswith("error_http_check_")): + if "content" in r.keys(): + raise Exception(r["content"]) + else: + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + else: + raise Exception("Bad response from the server https://diagnosis.yunohost.org : %s" % str(r.status_code)) except Exception as e: raise YunohostError("diagnosis_http_could_not_diagnose", error=e) From 026c666d7e2e8a826e0e7c986ec51977c685950c Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Jan 2020 14:24:59 +0700 Subject: [PATCH 051/104] remove visitors only for if current value is / --- data/helpers.d/setting | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index b07b552af..384fdc399 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -158,6 +158,11 @@ ynh_add_protected_uris() { # ynh_app_setting() { + if [[ "$1" == "delete" ]] && [[ "$3" =~ ^(unprotected|skipped)_ ]] + then + current_value=$(ynh_app_setting_get --app=$app --key=$3) + fi + ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python2.7 - < Date: Wed, 29 Jan 2020 21:17:14 +0700 Subject: [PATCH 052/104] more informations in hooks permission --- src/yunohost/permission.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 5fe9f327f..b9edb317d 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -471,15 +471,21 @@ def _update_ldap_group_permission(permission, allowed, sync_perm=True): app = permission.split(".")[0] sub_permission = permission.split(".")[1] - old_allowed_users = set(existing_permission["corresponding_users"]) - new_allowed_users = set(new_permission["corresponding_users"]) + old_corresponding_users = set(existing_permission["corresponding_users"]) + new_corresponding_users = set(new_permission["corresponding_users"]) - effectively_added_users = new_allowed_users - old_allowed_users - effectively_removed_users = old_allowed_users - new_allowed_users + old_allowed_users = set(existing_permission["allowed"]) + new_allowed_users = set(new_permission["allowed"]) - if effectively_added_users: - hook_callback('post_app_addaccess', args=[app, ','.join(effectively_added_users), sub_permission]) - if effectively_removed_users: - hook_callback('post_app_removeaccess', args=[app, ','.join(effectively_removed_users), sub_permission]) + effectively_added_users = new_corresponding_users - old_corresponding_users + effectively_removed_users = old_corresponding_users - new_corresponding_users + + effectively_added_group = new_allowed_users - old_allowed_users - effectively_added_users + effectively_removed_group = old_allowed_users - new_allowed_users - effectively_removed_users + + if effectively_added_users or effectively_added_group: + hook_callback('post_app_addaccess', args=[app, ','.join(effectively_added_users), sub_permission, ','.join(effectively_added_group)]) + if effectively_removed_users or effectively_removed_group: + hook_callback('post_app_removeaccess', args=[app, ','.join(effectively_removed_users), sub_permission, ','.join(effectively_removed_group)]) return new_permission From 1255b9d7c74dfff2a60371189a4a7cf115071c5e Mon Sep 17 00:00:00 2001 From: Arthur Lutz Date: Mon, 27 Jan 2020 13:31:33 +0100 Subject: [PATCH 053/104] [debian/copyright] fix URL --- debian/copyright | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/copyright b/debian/copyright index 8dd627ca5..59483b81e 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,5 +1,5 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Source: https://github.com/YunoHost/moulinette-yunohost +Source: https://github.com/YunoHost/yunohost Files: * Copyright: 2015 YUNOHOST.ORG From 62a98eb0733bbc4e396a071cf07d6a38fc2cd1a3 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Mon, 20 Jan 2020 22:55:53 +0700 Subject: [PATCH 054/104] Full permission url --- src/yunohost/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 30d3ab31b..b05d7b818 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1287,6 +1287,7 @@ def app_ssowatconf(): # FIXME : gotta handle regex-urls here... meh url = _sanitized_absolute_url(perm_info["url"]) + perm_info["url"] = url if "visitors" in perm_info["allowed"]: if url not in unprotected_urls: unprotected_urls.append(url) From f69ab4c7e29e130ff94187164a425485e7b1e19b Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 3 Feb 2020 23:05:35 +0100 Subject: [PATCH 055/104] English locale: spelling --- locales/en.json | 90 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/locales/en.json b/locales/en.json index 2d446e191..df1fbe3a0 100644 --- a/locales/en.json +++ b/locales/en.json @@ -3,13 +3,13 @@ "action_invalid": "Invalid action '{action:s}'", "admin_password": "Administration password", "admin_password_change_failed": "Cannot change password", - "admin_password_changed": "The administration password got changed", + "admin_password_changed": "The administration password was changed", "admin_password_too_long": "Please choose a password shorter than 127 characters", "already_up_to_date": "Nothing to do. Everything is already up-to-date.", "app_action_cannot_be_ran_because_required_services_down": "These required services should be running to run this action: {services}. Try restarting them to continue (and possibly investigate why they are down).", - "app_action_broke_system": "This action seem to have broke these important services: {services}", + "app_action_broke_system": "This action seems to have broken these important services: {services}", "app_already_installed": "{app:s} is already installed", - "app_already_installed_cant_change_url": "This app is already installed. The URL cannot be changed just by this function. Look into `app changeurl` if it's available.", + "app_already_installed_cant_change_url": "This app is already installed. The URL cannot be changed just by this function. Check in `app changeurl` if it's available.", "app_already_up_to_date": "{app:s} is already up-to-date", "app_argument_choice_invalid": "Use one of these choices '{choices:s}' for the argument '{name:s}'", "app_argument_invalid": "Pick a valid value for the argument '{name:s}': {error:s}", @@ -27,7 +27,7 @@ "app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain, '{domain}' is already in use by the other app '{other_app}'", "app_location_unavailable": "This URL is either unavailable, or conflicts with the already installed app(s):\n{apps:s}", "app_manifest_invalid": "Something is wrong with the app manifest: {error}", - "app_not_upgraded": "The app '{failed_app}' failed to upgrade, and as a consequence the following apps upgrades have been cancelled: {apps}", + "app_not_upgraded": "The app '{failed_app}' failed to upgrade, and as a consequence the following apps' upgrades have been cancelled: {apps}", "app_not_correctly_installed": "{app:s} seems to be incorrectly installed", "app_not_installed": "Could not find the app '{app:s}' in the list of installed apps: {all_apps}", "app_not_properly_removed": "{app:s} has not been properly removed", @@ -53,10 +53,10 @@ "apps_already_up_to_date": "All apps are already up-to-date", "apps_permission_not_found": "No permission found for the installed apps", "apps_permission_restoration_failed": "Permission '{permission:s}' for app {app:s} restoration has failed", - "apps_catalog_init_success": "Apps catalog system initialized!", - "apps_catalog_updating": "Updating applications catalog...", - "apps_catalog_failed_to_download": "Unable to download the {apps_catalog} apps catalog: {error}", - "apps_catalog_obsolete_cache": "The apps catalog cache is empty or obsolete.", + "apps_catalog_init_success": "App catalog system initialized!", + "apps_catalog_updating": "Updating application catalog...", + "apps_catalog_failed_to_download": "Unable to download the {apps_catalog} app catalog: {error}", + "apps_catalog_obsolete_cache": "The app catalog cache is empty or obsolete.", "apps_catalog_update_success": "The application catalog has been updated!", "ask_current_admin_password": "Current administration password", "ask_email": "E-mail address", @@ -85,7 +85,7 @@ "backup_ask_for_copying_if_needed": "Do you want to perform the backup using {size:s} MB temporarily? (This way is used since some files could not be prepared using a more efficient method.)", "backup_borg_not_implemented": "The Borg backup method is not yet implemented", "backup_cant_mount_uncompress_archive": "Could not mount the uncompressed archive as write protected", - "backup_cleaning_failed": "Could not clean-up the temporary backup folder", + "backup_cleaning_failed": "Could not clean up the temporary backup folder", "backup_copying_to_organize_the_archive": "Copying {size:s}MB to organize the archive", "backup_couldnt_bind": "Could not bind {src:s} to {dest:s}.", "backup_created": "Backup created", @@ -105,7 +105,7 @@ "backup_mount_archive_for_restore": "Preparing archive for restoration…", "backup_no_uncompress_archive_dir": "There is no such uncompressed archive directory", "backup_nothings_done": "Nothing to save", - "backup_output_directory_forbidden": "Pick a different output directory. Backups can not be created in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var or /home/yunohost.backup/archives sub-folders", + "backup_output_directory_forbidden": "Pick a different output directory. Backups cannot be created in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var or /home/yunohost.backup/archives sub-folders", "backup_output_directory_not_empty": "You should pick an empty output directory", "backup_output_directory_required": "You must provide an output directory for the backup", "backup_output_symlink_dir_broken": "Your archive directory '{path:s}' is a broken symlink. Maybe you forgot to re/mount or plug in the storage medium it points to.", @@ -129,7 +129,7 @@ "certmanager_conflicting_nginx_file": "Could not prepare domain for ACME challenge: the NGINX configuration file {filepath:s} is conflicting and should be removed first", "certmanager_couldnt_fetch_intermediate_cert": "Timed out when trying to fetch intermediate certificate from Let's Encrypt. Certificate installation/renewal aborted—please try again later.", "certmanager_domain_cert_not_selfsigned": "The certificate for domain {domain:s} is not self-signed. Are you sure you want to replace it? (Use '--force' to do so.)", - "certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for the domain '{domain:s}' is different from this server IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use '--no-checks' to turn off those checks.)", + "certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for the domain '{domain:s}' is different from this server's IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use '--no-checks' to turn off those checks.)", "certmanager_domain_http_not_working": "It seems the domain {domain:s} cannot be accessed through HTTP. Check that your DNS and NGINX configuration is correct", "certmanager_domain_unknown": "Unknown domain '{domain:s}'", "certmanager_error_no_A_record": "No DNS 'A' record found for '{domain:s}'. You need to make your domain name point to your machine to be able to install a Let's Encrypt certificate. (If you know what you are doing, use '--no-checks' to turn off those checks.)", @@ -139,17 +139,17 @@ "certmanager_self_ca_conf_file_not_found": "Could not find configuration file for self-signing authority (file: {file:s})", "certmanager_unable_to_parse_self_CA_name": "Could not parse name of self-signing authority (file: {file:s})", "confirm_app_install_warning": "Warning: This app may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers:s}] ", - "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or break your system… If you are willing to take that risk anyway, type '{answers:s}'", - "confirm_app_install_thirdparty": "DANGER! This app is not part of Yunohost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or break your system… If you are willing to take that risk anyway, type '{answers:s}'", + "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers:s}'", + "confirm_app_install_thirdparty": "DANGER! This app is not part of Yunohost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers:s}'", "custom_app_url_required": "You must provide a URL to upgrade your custom app {app:s}", "diagnosis_basesystem_host": "Server is running Debian {debian_version}.", "diagnosis_basesystem_kernel": "Server is running Linux kernel {kernel_version}", "diagnosis_basesystem_ynh_single_version": "{0} version: {1} ({2})", "diagnosis_basesystem_ynh_main_version": "Server is running YunoHost {main_version} ({repo})", - "diagnosis_basesystem_ynh_inconsistent_versions": "You are running inconsistents versions of the YunoHost packages ... most probably because of a failed or partial upgrade.", + "diagnosis_basesystem_ynh_inconsistent_versions": "You are running inconsistent versions of the YunoHost packages... most probably because of a failed or partial upgrade.", "diagnosis_display_tip_web": "You can go to the Diagnosis section (in the home screen) to see the issues found.", "diagnosis_display_tip_cli": "You can run 'yunohost diagnosis show --issues' to display the issues found.", - "diagnosis_failed_for_category": "Diagnosis failed for category '{category}' : {error}", + "diagnosis_failed_for_category": "Diagnosis failed for category '{category}': {error}", "diagnosis_cache_still_valid": "(Cache still valid for {category} diagnosis. Not re-diagnosing yet!)", "diagnosis_cant_run_because_of_dep": "Can't run diagnosis for {category} while there are important issues related to {dep}.", "diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))", @@ -157,15 +157,15 @@ "diagnosis_found_errors_and_warnings": "Found {errors} significant issue(s) (and {warnings} warning(s)) related to {category}!", "diagnosis_found_warnings": "Found {warnings} item(s) that could be improved for {category}.", "diagnosis_everything_ok": "Everything looks good for {category}!", - "diagnosis_failed": "Failed to fetch diagnosis result for category '{category}' : {error}", + "diagnosis_failed": "Failed to fetch diagnosis result for category '{category}': {error}", "diagnosis_no_cache": "No diagnosis cache yet for category '{category}'", "diagnosis_ip_connected_ipv4": "The server is connected to the Internet through IPv4 !", - "diagnosis_ip_no_ipv4": "The server does not have a working IPv4.", + "diagnosis_ip_no_ipv4": "The server does not have working IPv4.", "diagnosis_ip_connected_ipv6": "The server is connected to the Internet through IPv6 !", - "diagnosis_ip_no_ipv6": "The server does not have a working IPv6.", + "diagnosis_ip_no_ipv6": "The server does not have working IPv6.", "diagnosis_ip_not_connected_at_all": "The server does not seem to be connected to the Internet at all!?", "diagnosis_ip_dnsresolution_working": "Domain name resolution is working!", - "diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason ... Is a firewall blocking DNS requests ?", + "diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason... Is a firewall blocking DNS requests ?", "diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to /etc/resolv.conf not pointing to 127.0.0.1.", "diagnosis_ip_weird_resolvconf": "DNS resolution seems to be working, but be careful that you seem to be using a custom /etc/resolv.conf.", "diagnosis_ip_weird_resolvconf_details": "Instead, this file should be a symlink to /etc/resolvconf/run/resolv.conf itself pointing to 127.0.0.1 (dnsmasq). The actual resolvers should be configured via /etc/resolv.dnsmasq.conf.", @@ -187,7 +187,7 @@ "diagnosis_swap_notsomuch": "The system has only {total_MB} MB swap. You should consider having at least 256 MB to avoid situations where the system runs out of memory.", "diagnosis_swap_ok": "The system has {total_MB} MB of swap!", "diagnosis_mail_ougoing_port_25_ok": "Outgoing port 25 is not blocked and email can be sent to other servers.", - "diagnosis_mail_ougoing_port_25_blocked": "Outgoing port 25 appears to be blocked. You should try to unblock it in your internet service provider (or hoster) configuration panel. Meanwhile, the server won't be able to send emails to other servers.", + "diagnosis_mail_ougoing_port_25_blocked": "Outgoing port 25 appears to be blocked. You should try to unblock it in your internet service provider (or hosting provider) configuration panel. Meanwhile, the server won't be able to send emails to other servers.", "diagnosis_regenconf_allgood": "All configurations files are in line with the recommended configuration!", "diagnosis_regenconf_manually_modified": "Configuration file {file} was manually modified.", "diagnosis_regenconf_manually_modified_details": "This is probably OK as long as you know what you're doing ;) !", @@ -211,7 +211,7 @@ "diagnosis_ports_unreachable": "Port {port} is not reachable from outside.", "diagnosis_ports_ok": "Port {port} is reachable from outside.", "diagnosis_ports_needed_by": "Exposing this port is needed for service {0}", - "diagnosis_ports_forwarding_tip": "To fix this issue, most probably you need to configure port forwarding on your internet router as described in https://yunohost.org/isp_box_config", + "diagnosis_ports_forwarding_tip": "To fix this issue, you most probably need to configure port forwarding on your internet router as described in https://yunohost.org/isp_box_config", "diagnosis_http_could_not_diagnose": "Could not diagnose if domain is reachable from outside. Error: {error}", "diagnosis_http_ok": "Domain {domain} is reachable from outside.", "diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable. You should check that you're correctly forwarding port 80, that nginx is running, and that a firewall is not interfering.", @@ -219,8 +219,8 @@ "diagnosis_http_unknown_error": "An error happened while trying to reach your domain, it's very likely unreachable.", "diagnosis_http_bad_status_code": "Could not reach your server as expected, it returned a bad status code. It might be that another machine answered instead of your server. You should check that you're correctly forwarding port 80, that your nginx configuration is up to date, and that a reverse-proxy is not interfering.", "diagnosis_http_unreachable": "Domain {domain} is unreachable through HTTP from outside.", - "diagnosis_unknown_categories": "The following categories are unknown : {categories}", - "domain_cannot_remove_main": "You cannot remove '{domain:s}' since it's the main domain, you need first to set another domain as the main domain using 'yunohost domain main-domain -n ', here is the list of candidate domains: {other_domains:s}", + "diagnosis_unknown_categories": "The following categories are unknown: {categories}", + "domain_cannot_remove_main": "You cannot remove '{domain:s}' since it's the main domain, you first need to set another domain as the main domain using 'yunohost domain main-domain -n '; here is the list of candidate domains: {other_domains:s}", "domain_cannot_remove_main_add_new_one": "You cannot remove '{domain:s}' since it's the main domain and your only domain, you need to first add another domain using 'yunohost domain add ', then set is as the main domain using 'yunohost domain main-domain -n ' and then you can remove the domain '{domain:s}' using 'yunohost domain remove {domain:s}'.'", "domain_cert_gen_failed": "Could not generate certificate", "domain_created": "Domain created", @@ -238,7 +238,7 @@ "done": "Done", "downloading": "Downloading…", "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.", - "dpkg_lock_not_available": "This command can't be ran right now because another program seems to be using the lock of dpkg (the system package manager)", + "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", "dyndns_could_not_check_provide": "Could not check if {provider:s} can provide {domain:s}.", "dyndns_could_not_check_available": "Could not check if {domain:s} is available on {provider:s}.", "dyndns_cron_installed": "DynDNS cron job created", @@ -249,7 +249,7 @@ "dyndns_key_generating": "Generating DNS key… It may take a while.", "dyndns_key_not_found": "DNS key not found for the domain", "dyndns_no_domain_registered": "No domain registered with DynDNS", - "dyndns_provider_unreachable": "Unable to reach Dyndns provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.", + "dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.", "dyndns_registered": "DynDNS domain registered", "dyndns_registration_failed": "Could not register DynDNS domain: {error:s}", "dyndns_domain_not_provided": "DynDNS provider {provider:s} cannot provide domain {domain:s}.", @@ -262,7 +262,7 @@ "file_does_not_exist": "The file {path:s} does not exist.", "firewall_reload_failed": "Could not reload the firewall", "firewall_reloaded": "Firewall reloaded", - "firewall_rules_cmd_failed": "Some firewall rules commands have failed. More info in log.", + "firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.", "global_settings_bad_choice_for_enum": "Bad choice for setting {setting:s}, received '{choice:s}', but available choices are: {available_choices:s}", "global_settings_bad_type_for_setting": "Bad type for setting {setting:s}, received {received_type:s}, expected {expected_type:s}", "global_settings_cant_open_settings": "Could not open settings file, reason: {reason:s}", @@ -283,8 +283,8 @@ "global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key:s}', discard it and save it in /etc/yunohost/settings-unknown.json", "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Allow the use of (deprecated) DSA hostkey for the SSH daemon configuration", "global_settings_unknown_type": "Unexpected situation, the setting {setting:s} appears to have the type {unknown_type:s} but it is not a type supported by the system.", - "good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at-least 8 characters—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).", - "good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters—though it is good practice to use longer password (i.e. a passphrase) and/or to a variation of characters (uppercase, lowercase, digits and special characters).", + "good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).", + "good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to a variation of characters (uppercase, lowercase, digits and special characters).", "group_already_exist": "Group {group} already exists", "group_already_exist_on_system": "Group {group} already exists in the system groups", "group_created": "Group '{group}' created", @@ -316,7 +316,7 @@ "log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log display {name}'", "log_link_to_failed_log": "Could not complete the operation '{desc}'. Please provide the full log of this operation by clicking here to get help", "log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log display {name} --share' to get help", - "log_does_exists": "There is not operation log with the name '{log}', use 'yunohost log list' to see all available operation logs", + "log_does_exists": "There is no operation log with the name '{log}', use 'yunohost log list' to see all available operation logs", "log_operation_unit_unclosed_properly": "Operation unit has not been closed properly", "log_app_change_url": "Change the URL of the '{}' app", "log_app_install": "Install the '{}' app", @@ -339,7 +339,7 @@ "log_permission_create": "Create permission '{}'", "log_permission_delete": "Delete permission '{}'", "log_permission_url": "Update url related to permission '{}'", - "log_selfsigned_cert_install": "Install self signed certificate on '{}' domain", + "log_selfsigned_cert_install": "Install self-signed certificate on '{}' domain", "log_letsencrypt_cert_renew": "Renew '{}' Let's Encrypt certificate", "log_regen_conf": "Regenerate system configurations '{}'", "log_user_create": "Add '{}' user", @@ -350,7 +350,7 @@ "log_user_update": "Update user info of '{}'", "log_user_permission_update": "Update accesses for permission '{}'", "log_user_permission_reset": "Reset permission '{}'", - "log_domain_main_domain": "Make '{}' as main domain", + "log_domain_main_domain": "Make '{}' the main domain", "log_tools_migrations_migrate_forward": "Migrate forward", "log_tools_postinstall": "Postinstall your YunoHost server", "log_tools_upgrade": "Upgrade system packages", @@ -363,7 +363,7 @@ "mail_domain_unknown": "Invalid e-mail address for domain '{domain:s}'. Please, use a domain administrated by this server.", "mail_forward_remove_failed": "Could not remove e-mail forwarding '{mail:s}'", "mailbox_disabled": "E-mail turned off for user {user:s}", - "mailbox_used_space_dovecot_down": "The Dovecot mailbox service needs to be up, if you want to fetch used mailbox space", + "mailbox_used_space_dovecot_down": "The Dovecot mailbox service needs to be up if you want to fetch used mailbox space", "mail_unavailable": "This e-mail address is reserved and shall be automatically allocated to the very first user", "main_domain_change_failed": "Unable to change the main domain", "main_domain_changed": "The main domain has been changed", @@ -393,16 +393,16 @@ "migration_0003_patching_sources_list": "Patching the sources.lists…", "migration_0003_main_upgrade": "Starting main upgrade…", "migration_0003_fail2ban_upgrade": "Starting the Fail2Ban upgrade…", - "migration_0003_restoring_origin_nginx_conf": "Your file /etc/nginx/nginx.conf was edited somehow. The migration is going to reset to its original state first… The previous file will be available as {backup_dest}.", - "migration_0003_yunohost_upgrade": "Starting the YunoHost package upgrade… The migration will end, but the actual upgrade will happen immediately afterwards. After the operation is complete, you might have to log in on the webadmin page again.", + "migration_0003_restoring_origin_nginx_conf": "Your file /etc/nginx/nginx.conf was edited somehow. The migration is going to reset it to its original state first… The previous file will be available as {backup_dest}.", + "migration_0003_yunohost_upgrade": "Starting the YunoHost package upgrade… The migration will end, but the actual upgrade will happen immediately afterwards. After the operation is complete, you might have to log in to the webadmin page again.", "migration_0003_not_jessie": "The current Debian distribution is not Jessie!", "migration_0003_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Stretch.", "migration_0003_still_on_jessie_after_main_upgrade": "Something went wrong during the main upgrade: Is the system still on Jessie‽ To investigate the issue, please look at {log}:s…", "migration_0003_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.\n\nAdditionally, the port for SMTP, used by external e-mail clients (like Thunderbird or K9-Mail) was changed from 465 (SSL/TLS) to 587 (STARTTLS). The old port (465) will automatically be closed, and the new port (587) will be opened in the firewall. You and your users *will* have to adapt the configuration of your e-mail clients accordingly.", - "migration_0003_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from an apps_catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}", + "migration_0003_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from an app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}", "migration_0003_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}", "migration_0005_postgresql_94_not_installed": "PostgreSQL was not installed on your system. Nothing to do.", - "migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 is installed, but not postgresql 9.6‽ Something weird might have happened on your system:(…", + "migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 is installed, but not postgresql 9.6‽ Something weird might have happened on your system :(…", "migration_0005_not_enough_space": "Make sufficient space available in {path} to run the migration.", "migration_0006_disclaimer": "YunoHost now expects the admin and root passwords to be synchronized. This migration replaces your root password with the admin password.", "migration_0007_cancelled": "Could not improve the way your SSH configuration is managed.", @@ -412,7 +412,7 @@ "migration_0008_root": "• You will not be able to connect as root through SSH. Instead you should use the admin user;", "migration_0008_dsa": "• The DSA key will be turned off. Hence, you might need to invalidate a spooky warning from your SSH client, and recheck the fingerprint of your server;", "migration_0008_warning": "If you understand those warnings and want YunoHost to override your current configuration, run the migration. Otherwise, you can also skip the migration, though it is not recommended.", - "migration_0008_no_warning": "Overriding your SSH configuration should be safe, though this can not be promised! Run the migration to override it. Otherwise, you can also skip the migration, though it is not recommended.", + "migration_0008_no_warning": "Overriding your SSH configuration should be safe, though this cannot be promised! Run the migration to override it. Otherwise, you can also skip the migration, though it is not recommended.", "migration_0009_not_needed": "This migration already happened somehow… (?) Skipping.", "migration_0011_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.", "migration_0011_can_not_backup_before_migration": "The backup of the system could not be completed before the migration failed. Error: {error:s}", @@ -449,7 +449,7 @@ "operation_interrupted": "The operation was manually interrupted?", "package_unknown": "Unknown package '{pkgname}'", "packages_upgrade_failed": "Could not upgrade all the packages", - "password_listed": "This password is among the most used password in the world. Please choose something more unique.", + "password_listed": "This password is among the most used passwords in the world. Please choose something more unique.", "password_too_simple_1": "The password needs to be at least 8 characters long", "password_too_simple_2": "The password needs to be at least 8 characters long and contain a digit, upper and lower characters", "password_too_simple_3": "The password needs to be at least 8 characters long and contain a digit, upper, lower and special characters", @@ -466,7 +466,7 @@ "pattern_port_or_range": "Must be a valid port number (i.e. 0-65535) or range of ports (e.g. 100:200)", "pattern_positive_number": "Must be a positive number", "pattern_username": "Must be lower-case alphanumeric and underscore characters only", - "pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}", + "pattern_password_app": "Sorry, passwords cannot contain the following characters: {forbidden_chars}", "permission_all_users_implicitly_added": "The permission was also implicitly granted to 'all_users' because it is required to allow the special group 'visitors'", "permission_already_allowed": "Group '{group}' already has permission '{permission}' enabled", "permission_already_disallowed": "Group '{group}' already has permission '{permission}' disabled'", @@ -480,7 +480,7 @@ "permission_deleted": "Permission '{permission:s}' deleted", "permission_deletion_failed": "Could not delete permission '{permission}': {error}", "permission_not_found": "Permission '{permission:s}' not found", - "permission_update_failed": "Could not update permission '{permission}' : {error}", + "permission_update_failed": "Could not update permission '{permission}': {error}", "permission_updated": "Permission '{permission:s}' updated", "permission_update_nothing_to_do": "No permissions to update", "permission_require_account": "Permission {permission} only makes sense for users having an account, and therefore cannot be enabled for visitors.", @@ -508,8 +508,8 @@ "restore_confirm_yunohost_installed": "Do you really want to restore an already installed system? [{answers:s}]", "restore_extracting": "Extracting needed files from the archive…", "restore_failed": "Could not restore system", - "restore_hook_unavailable": "The restoration script for '{part:s}' not available on your system and not in the archive either", - "restore_may_be_not_enough_disk_space": "Your system seems does not have enough space (free: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)", + "restore_hook_unavailable": "Restoration script for '{part:s}' not available on your system and not in the archive either", + "restore_may_be_not_enough_disk_space": "Your system does not seem to have enough space (free: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)", "restore_not_enough_disk_space": "Not enough space (space: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)", "restore_nothings_done": "Nothing was restored", "restore_removing_tmp_dir_failed": "Could not remove an old temporary directory", @@ -523,7 +523,7 @@ "server_reboot": "The server will reboot", "server_reboot_confirm": "The server will reboot immediatly, are you sure? [{answers:s}]", "service_add_failed": "Could not add the service '{service:s}'", - "service_added": "The service '{service:s}' added", + "service_added": "The service '{service:s}' was added", "service_already_started": "The service '{service:s}' is running already", "service_already_stopped": "The service '{service:s}' has already been stopped", "service_cmd_exec_failed": "Could not execute the command '{command:s}'", @@ -575,7 +575,7 @@ "tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages…", "tools_upgrade_regular_packages_failed": "Could not upgrade packages: {packages_list}", "tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages…", - "tools_upgrade_special_packages_explanation": "The special upgrade will continue in background. Please don't start any other actions on your server the next ~10 minutes (depending on hardware speed). After this, you may have to re-log on the webadmin. The upgrade log will be available in Tools → Log (in the webadmin) or using 'yunohost log list' (from the command-line).", + "tools_upgrade_special_packages_explanation": "The special upgrade will continue in the background. Please don't start any other actions on your server for the next ~10 minutes (depending on hardware speed). After this, you may have to re-log in to the webadmin. The upgrade log will be available in Tools → Log (in the webadmin) or using 'yunohost log list' (from the command-line).", "tools_upgrade_special_packages_completed": "YunoHost package upgrade completed.\nPress [Enter] to get the command line back", "unbackup_app": "App '{app:s}' will not be saved", "unexpected_error": "Something unexpected went wrong: {error}", @@ -608,5 +608,5 @@ "yunohost_configured": "YunoHost is now configured", "yunohost_installing": "Installing YunoHost…", "yunohost_not_installed": "YunoHost is not correctly installed. Please run 'yunohost tools postinstall'", - "yunohost_postinstall_end_tip": "The post-install completed! To finalize your setup, please consider:\n - adding a first user through the 'Users' section of the webadmin (or 'yunohost user create ' in command-line) ;\n - diagnose issues waiting to be solved for your server to be running as smoothly as possible through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line) ;\n - reading the 'Finalizing your setup' and 'Getting to know Yunohost' parts in the admin documentation : https://yunohost.org/admindoc." + "yunohost_postinstall_end_tip": "The post-install completed! To finalize your setup, please consider:\n - adding a first user through the 'Users' section of the webadmin (or 'yunohost user create ' in command-line);\n - diagnose issues waiting to be solved for your server to be running as smoothly as possible through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line);\n - reading the 'Finalizing your setup' and 'Getting to know Yunohost' parts in the admin documentation: https://yunohost.org/admindoc." } From dc5ee76124e016f912bb33bcd3007a067867efd0 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Mon, 20 Jan 2020 22:55:53 +0700 Subject: [PATCH 056/104] Full permission url --- src/yunohost/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 8ce5ed783..0324a116a 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1661,6 +1661,7 @@ def app_ssowatconf(): # FIXME : gotta handle regex-urls here... meh url = _sanitized_absolute_url(perm_info["url"]) + perm_info["url"] = url if "visitors" in perm_info["allowed"]: if url not in unprotected_urls: unprotected_urls.append(url) From c7506fd3a92ec1f4dd77406e4cc58b910b900391 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Mon, 2 Dec 2019 22:32:59 +0100 Subject: [PATCH 057/104] [fix] This DNS resolver in ipv6 is unreachable --- data/templates/dnsmasq/plain/resolv.dnsmasq.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/data/templates/dnsmasq/plain/resolv.dnsmasq.conf b/data/templates/dnsmasq/plain/resolv.dnsmasq.conf index 6b3bb95d3..ce8515054 100644 --- a/data/templates/dnsmasq/plain/resolv.dnsmasq.conf +++ b/data/templates/dnsmasq/plain/resolv.dnsmasq.conf @@ -32,7 +32,6 @@ nameserver 85.214.20.141 nameserver 195.160.173.53 # (DE) AS250 nameserver 194.150.168.168 -nameserver 2001:4ce8::53 # (DE) Ideal-Hosting nameserver 84.200.69.80 nameserver 2001:1608:10:25::1c04:b12f From c163ae2949368ebfaa44cb65102cda0d60c80ad6 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 16 Jan 2020 00:34:11 +0700 Subject: [PATCH 058/104] fix legacy permission management --- data/helpers.d/setting | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index 9dbbe93fa..5bcd7af32 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -187,9 +187,15 @@ EOF # Fucking legacy permission management. # We need this because app temporarily set the app as unprotected to configure it with curl... - if [[ "$3" =~ ^(unprotected|skipped)_ ]] && [[ "${4:-}" == "/" ]] + if [[ "$3" =~ ^(unprotected|skipped)_ ]] then - ynh_permission_update --permission "main" --add "visitors" + if [[ "$1" == "set" ]] && [[ "${4:-}" == "/" ]] + then + ynh_permission_update --permission "main" --add "visitors" + elif [[ "$1" == "delete" ]] + then + ynh_permission_update --permission "main" --remove "visitors" + fi fi } From fc969ae1d448b4209c27c2cae8222fbcc12a5b64 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Jan 2020 14:24:59 +0700 Subject: [PATCH 059/104] remove visitors only for if current value is / --- data/helpers.d/setting | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/setting b/data/helpers.d/setting index 5bcd7af32..9f68cb5d9 100644 --- a/data/helpers.d/setting +++ b/data/helpers.d/setting @@ -158,7 +158,12 @@ ynh_add_protected_uris() { # ynh_app_setting() { - ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python - < Date: Wed, 29 Jan 2020 21:17:14 +0700 Subject: [PATCH 060/104] more informations in hooks permission --- src/yunohost/permission.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 9cc7c7534..9d3d8feda 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -471,16 +471,22 @@ def _update_ldap_group_permission(permission, allowed, sync_perm=True): app = permission.split(".")[0] sub_permission = permission.split(".")[1] - old_allowed_users = set(existing_permission["corresponding_users"]) - new_allowed_users = set(new_permission["corresponding_users"]) + old_corresponding_users = set(existing_permission["corresponding_users"]) + new_corresponding_users = set(new_permission["corresponding_users"]) - effectively_added_users = new_allowed_users - old_allowed_users - effectively_removed_users = old_allowed_users - new_allowed_users + old_allowed_users = set(existing_permission["allowed"]) + new_allowed_users = set(new_permission["allowed"]) - if effectively_added_users: - hook_callback('post_app_addaccess', args=[app, ','.join(effectively_added_users), sub_permission]) - if effectively_removed_users: - hook_callback('post_app_removeaccess', args=[app, ','.join(effectively_removed_users), sub_permission]) + effectively_added_users = new_corresponding_users - old_corresponding_users + effectively_removed_users = old_corresponding_users - new_corresponding_users + + effectively_added_group = new_allowed_users - old_allowed_users - effectively_added_users + effectively_removed_group = old_allowed_users - new_allowed_users - effectively_removed_users + + if effectively_added_users or effectively_added_group: + hook_callback('post_app_addaccess', args=[app, ','.join(effectively_added_users), sub_permission, ','.join(effectively_added_group)]) + if effectively_removed_users or effectively_removed_group: + hook_callback('post_app_removeaccess', args=[app, ','.join(effectively_removed_users), sub_permission, ','.join(effectively_removed_group)]) return new_permission From e6481b156fe7897b51d60d55ea2f63a22f50ae62 Mon Sep 17 00:00:00 2001 From: Jimmy Monin Date: Sat, 29 Feb 2020 22:07:45 +0100 Subject: [PATCH 061/104] Persist cookies between multiple ynh_local_curl calls for the same app --- data/helpers.d/utils | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/helpers.d/utils b/data/helpers.d/utils index d449f0c39..50671dba0 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -198,6 +198,7 @@ ynh_setup_source () { } # Curl abstraction to help with POST requests to local pages (such as installation forms) +# For multiple calls, cookies are persisted between each call for the same app # # $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?)) # @@ -238,7 +239,7 @@ ynh_local_curl () { sleep 2 # Curl the URL - curl --silent --show-error -kL -H "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url" + curl --silent --show-error -kL -H "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url" --cookie-jar /tmp/ynh-$app-cookie.txt --cookie /tmp/ynh-$app-cookie.txt } # Render templates with Jinja2 From 200ff2de3137f5bcff94aced28eaa745304903b7 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 5 Mar 2020 18:15:55 +0100 Subject: [PATCH 062/104] Micro issue from previous app list system rework --- src/yunohost/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index b05d7b818..056083b67 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -2754,7 +2754,7 @@ def unstable_apps(): output = [] - for infos in app_list(full=True): + for infos in app_list(full=True)["apps"]: if not infos.get("from_catalog") or infos.get("from_catalog").get("state") in ["inprogress", "notworking"]: output.append(infos["id"]) From 3bf2df16eeecbf804f92d1e30f5d7baa1ebbb4ed Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 5 Mar 2020 20:00:39 +0100 Subject: [PATCH 063/104] Fix tests for appscatalog ? --- src/yunohost/tests/test_appscatalog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yunohost/tests/test_appscatalog.py b/src/yunohost/tests/test_appscatalog.py index 39a0be206..a51d1085e 100644 --- a/src/yunohost/tests/test_appscatalog.py +++ b/src/yunohost/tests/test_appscatalog.py @@ -31,8 +31,8 @@ DUMMY_APP_CATALOG = """{ "bar": {"id": "bar", "level": 7, "category": "swag", "manifest":{"description": "Bar"}} }, "categories": [ - {"id": "yolo", "description": "YoLo"}, - {"id": "swag", "description": "sWaG"} + {"id": "yolo", "description": "YoLo", "title": "Yolo"}, + {"id": "swag", "description": "sWaG", "title": "Swag"} ] } """ From 1a7fcd09b0edd9f2907c235d6d4753d15720d0b3 Mon Sep 17 00:00:00 2001 From: Patrick Baeumel Date: Sun, 12 Jan 2020 10:37:39 +0000 Subject: [PATCH 064/104] Translated using Weblate (German) Currently translated at 33.8% (205 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 83b4b1210..e4b3b0c05 100644 --- a/locales/de.json +++ b/locales/de.json @@ -430,5 +430,6 @@ "apps_catalog_failed_to_download": "Der {apps_catalog} Apps-Katalog kann nicht heruntergeladen werden: {error}", "apps_catalog_obsolete_cache": "Der Cache des Apps-Katalogs ist leer oder veraltet.", "apps_catalog_update_success": "Der Apps-Katalog wurde aktualisiert!", - "password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein" + "password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein", + "diagnosis_display_tip_cli": "Sie können 'yunohost diagnosis show --issues' ausführen, um die gefundenen Probleme anzuzeigen." } From 3ebad369284e96883542e14991ab8a0d1a3c32c2 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Mon, 30 Dec 2019 14:25:33 +0000 Subject: [PATCH 065/104] Translated using Weblate (Chinese (Simplified)) Currently translated at 0.2% (1 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/zh_Hans/ --- locales/zh_Hans.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/zh_Hans.json b/locales/zh_Hans.json index 0967ef424..cb5d7002c 100644 --- a/locales/zh_Hans.json +++ b/locales/zh_Hans.json @@ -1 +1,3 @@ -{} +{ + "password_too_simple_1": "密码长度至少为8个字符" +} From 3774a2c7ad8dbd0efe7d588cb485e67a3e010800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quent=C3=AD?= Date: Fri, 17 Jan 2020 12:05:49 +0000 Subject: [PATCH 066/104] Translated using Weblate (Occitan) Currently translated at 70.8% (430 of 607 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/oc/ --- locales/oc.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/oc.json b/locales/oc.json index 4251a3307..e0fbaa45c 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -720,5 +720,7 @@ "diagnosis_ip_weird_resolvconf": "La resolucion del nom de domeni sembla foncionar, mas siatz prudent en utilizant un fichièr /etc/resolv.con personalizat.", "diagnosis_diskusage_verylow": "Lo lòc d’emmagazinatge {mountpoint} (sul periferic {device}) a solament {free_abs_GB} Go ({free_percent}%). Deuriatz considerar de liberar un pauc d’espaci.", "global_settings_setting_pop3_enabled": "Activar lo protocòl POP3 pel servidor de corrièr", - "diagnosis_diskusage_ok": "Lo lòc d’emmagazinatge {mountpoint} (sul periferic {device}) a encara {free_abs_GB} Go ({free_percent}%) de liure !" + "diagnosis_diskusage_ok": "Lo lòc d’emmagazinatge {mountpoint} (sul periferic {device}) a encara {free_abs_GB} Go ({free_percent}%) de liure !", + "diagnosis_swap_none": "Lo sistèma a pas cap de memòria d’escambi. Auriatz de considerar d’ajustar almens 256 Mo d’escambi per evitar las situacions ont lo sistèma manca de memòria.", + "diagnosis_swap_notsomuch": "Lo sistèma a solament {total_MB} de memòria d’escambi. Auriatz de considerar d’ajustar almens 256 Mo d’escambi per evitar las situacions ont lo sistèma manca de memòria." } From 45c35fdba58f0b80525ee6d434d00b0a22454a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lanie=20Chauvel?= Date: Fri, 17 Jan 2020 23:40:23 +0000 Subject: [PATCH 067/104] Translated using Weblate (French) Currently translated at 100.0% (610 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index f69dea8f9..eda84fabf 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -747,7 +747,7 @@ "diagnosis_services_running": "Le service {service} s'exécute correctement !", "diagnosis_services_conf_broken": "La configuration est cassée pour le service {service} !", "diagnosis_ports_needed_by": "Rendre ce port accessible est nécessaire pour le service {0}", - "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez probablement configurer la redirection de port sur votre routeur Internet, comme décrit dans https://yunohost.org/isp_box_config.", + "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez probablement configurer la redirection de port sur votre routeur Internet comme décrit sur https://yunohost.org/isp_box_config", "diagnosis_http_connection_error": "Erreur de connexion : impossible de se connecter au domaine demandé, il est probablement injoignable.", "diagnosis_no_cache": "Pas encore de diagnostique de cache pour la catégorie « {category} »", "diagnosis_http_unknown_error": "Une erreur est survenue en essayant de joindre votre domaine, il est probablement injoignable.", @@ -757,5 +757,8 @@ "diagnosis_services_bad_status_tip": "Vous pouvez essayer de redémarrer le service. Si cela ne fonctionne pas, consultez les journaux de service à l'aide de 'yunohost service log {0}' ou de la section 'Services' de l'administrateur Web.", "diagnosis_http_bad_status_code": "N'a pas pu atteindre votre serveur comme prévu, il a renvoyé un code d'état incorrect. Il se peut qu'une autre machine réponde à la place de votre serveur. Vérifiez que vous transférez correctement le port 80, que votre configuration nginx est à jour et qu’un proxy inverse n’interfère pas.", "diagnosis_http_timeout": "Expiration du délai en essayant de contacter votre serveur de l'extérieur. Il semble être inaccessible. Vérifiez que vous transférez correctement le port 80, que nginx est en cours d’exécution et qu’un pare-feu n’interfère pas.", - "global_settings_setting_pop3_enabled": "Activer le protocole POP3 pour le serveur de messagerie" + "global_settings_setting_pop3_enabled": "Activer le protocole POP3 pour le serveur de messagerie", + "log_app_action_run": "Lancer l’action de l’application '{}'", + "log_app_config_show_panel": "Montrer le panneau de configuration de l’application '{}'", + "log_app_config_apply": "Appliquer la configuration à l’application '{}'" } From b13cb78c97acc799be0e12eaea2585ad078f121d Mon Sep 17 00:00:00 2001 From: Armando FEMAT Date: Sat, 25 Jan 2020 12:35:02 +0000 Subject: [PATCH 068/104] Translated using Weblate (Spanish) Currently translated at 92.5% (564 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index 729e262b5..767dc6bfa 100644 --- a/locales/es.json +++ b/locales/es.json @@ -682,5 +682,28 @@ "diagnosis_services_conf_broken": "¡Mala configuración para el servicio {service}!", "diagnosis_services_running": "¡El servicio {service} está en ejecución!", "diagnosis_failed": "No se ha podido obtener el resultado del diagnóstico para la categoría '{category}': {error}", - "diagnosis_ip_connected_ipv4": "¡El servidor está conectado a internet a través de IPv4!" + "diagnosis_ip_connected_ipv4": "¡El servidor está conectado a internet a través de IPv4!", + "diagnosis_security_vulnerable_to_meltdown_details": "Para corregir esto, debieras actualizar y reiniciar tu sistema para cargar el nuevo kernel de Linux (o contacta tu proveedor si esto no funciona). Mas información en https://meltdownattack.com/", + "diagnosis_ram_verylow": "Al sistema le queda solamente {available_abs_MB} MB ({available_percent}%) de RAM! (De un total de {total_abs_MB} MB)", + "diagnosis_ram_low": "Al sistema le queda {available_abs_MB} MB ({available_percent}%) de RAM de un total de {total_abs_MB} MB. Cuidado.", + "diagnosis_ram_ok": "El sistema aun tiene {available_abs_MB} MB ({available_percent}%) de RAM de un total de {total_abs_MB} MB.", + "diagnosis_swap_none": "El sistema no tiene mas espacio de intercambio. Considera agregar por lo menos 256 MB de espacio de intercambio para evitar que el sistema se quede sin memoria.", + "diagnosis_swap_notsomuch": "Al sistema le queda solamente {total_MB} MB de espacio de intercambio. Considera agregar al menos 256 MB para evitar que el sistema se quede sin memoria.", + "diagnosis_mail_ougoing_port_25_ok": "El puerto de salida 25 no esta bloqueado y los correos electrónicos pueden ser enviados a otros servidores.", + "diagnosis_mail_ougoing_port_25_blocked": "El puerto de salida 25 parece estar bloqueado. Intenta desbloquearlo con el panel de configuración de tu proveedor de servicios de Internet (o hoster). Mientras tanto, el servidor no podrá enviar correos electrónicos a otros servidores.", + "diagnosis_regenconf_allgood": "Todos los archivos de configuración están en linea con la configuración recomendada!", + "diagnosis_regenconf_manually_modified": "El archivo de configuración {file} fue modificado manualmente.", + "diagnosis_regenconf_manually_modified_details": "Esto este probablemente BIEN siempre y cuando sepas lo que estas haciendo ;) !", + "diagnosis_regenconf_manually_modified_debian": "El archivos de configuración {file} fue modificado manualmente comparado con el valor predeterminado de Debian.", + "diagnosis_regenconf_manually_modified_debian_details": "Esto este probablemente BIEN, pero igual no lo pierdas de vista...", + "diagnosis_regenconf_nginx_conf_broken": "La configuración nginx parece rota!", + "diagnosis_security_all_good": "Ninguna vulnerabilidad critica de seguridad fue encontrada.", + "diagnosis_security_vulnerable_to_meltdown": "Pareces vulnerable a el colapso de vulnerabilidad critica de seguridad.", + "diagnosis_description_basesystem": "Sistema de base", + "diagnosis_description_ip": "Conectividad a Internet", + "diagnosis_description_dnsrecords": "Registro DNS", + "diagnosis_description_services": "Comprobación del estado de los servicios", + "diagnosis_description_ports": "Exposición de puertos", + "diagnosis_description_systemresources": "Recursos del sistema", + "diagnosis_swap_ok": "El sistema tiene {total_MB} MB de espacio de intercambio!" } From e506f93445c14830cfbc574c64c2dc4bcf765bc0 Mon Sep 17 00:00:00 2001 From: amirale qt Date: Fri, 24 Jan 2020 06:42:20 +0000 Subject: [PATCH 069/104] Translated using Weblate (Esperanto) Currently translated at 100.0% (610 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/eo/ --- locales/eo.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/eo.json b/locales/eo.json index f303a57ee..e204af4c6 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -659,5 +659,8 @@ "diagnosis_failed": "Malsukcesis preni la diagnozan rezulton por kategorio '{category}': {error}", "diagnosis_description_ports": "Ekspoziciaj havenoj", "diagnosis_description_http": "HTTP-ekspozicio", - "diagnosis_description_mail": "Retpoŝto" + "diagnosis_description_mail": "Retpoŝto", + "log_app_action_run": "Funkciigu agon de la apliko '{}'", + "log_app_config_show_panel": "Montri la agordan panelon de la apliko '{}'", + "log_app_config_apply": "Apliki agordon al la apliko '{}'" } From ee405971e5458d6061ddb138aa5316b191d318d7 Mon Sep 17 00:00:00 2001 From: Kayou Date: Fri, 31 Jan 2020 13:55:57 +0000 Subject: [PATCH 070/104] Translated using Weblate (French) Currently translated at 100.0% (610 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index eda84fabf..0e4c9bfd8 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -674,7 +674,7 @@ "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais soyer prudent en utilisant un fichier /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Au lieu de cela, ce fichier devrait être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Les résolveurs réels doivent être configurés via /etc/resolv.dnsmasq.conf.", "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS de type {0}, nom {1} et valeur {2}. Vous pouvez consulter https://yunohost.org/dns_config pour plus d'informations.", - "diagnosis_diskusage_ok": "Le stockage {mountpoint} (sur le périphérique {device}) a toujours {espace libre {free_abs_GB} GB ({free_percent}%) !", + "diagnosis_diskusage_ok": "Le stockage {mountpoint} (sur le périphérique {device}) a toujours {free_abs_GB} Go ({free_percent}%) d'espace libre !", "diagnosis_ram_ok": "Le système dispose toujours de {available_abs_MB} MB ({available_percent}%) de RAM sur {total_abs_MB} MB.", "diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !", "diagnosis_security_vulnerable_to_meltdown": "Vous semblez vulnérable à la vulnérabilité de sécurité critique de Meltdown", From 88be979d4013e7da7975d3c67f2b8df4213a307c Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Sun, 9 Feb 2020 12:13:52 +0000 Subject: [PATCH 071/104] Translated using Weblate (Catalan) Currently translated at 100.0% (610 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ca.json b/locales/ca.json index 40977469c..9e36d7009 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -719,5 +719,8 @@ "diagnosis_ports_needed_by": "És necessari exposar aquest port pel servei {0}", "permission_all_users_implicitly_added": "El permís també s'ha donat implícitament a «all_users» ja que és necessari per atorgar-lo al grup «visitors»", "permission_cannot_remove_all_users_while_visitors_allowed": "No podeu retirar el permís a «all_users» mentre encara el tingui el grup «visitors»", - "global_settings_setting_pop3_enabled": "Activa el protocol POP3 per al servidor de correu" + "global_settings_setting_pop3_enabled": "Activa el protocol POP3 per al servidor de correu", + "log_app_action_run": "Executa l'acció de l'aplicació «{}»", + "log_app_config_show_panel": "Mostra el taulell de configuració de l'aplicació «{}»", + "log_app_config_apply": "Afegeix la configuració a l'aplicació «{}»" } From 97e3493aa51500f1fc0c05b8086111e023d466b9 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Mon, 9 Mar 2020 20:00:38 +0000 Subject: [PATCH 072/104] Translated using Weblate (French) Currently translated at 100.0% (610 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 0e4c9bfd8..e10723b6b 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -671,7 +671,7 @@ "diagnosis_found_errors": "Trouvé {errors} problème(s) significatif(s) lié(s) à {category} !", "diagnosis_found_errors_and_warnings": "Trouvé {errors} problème(s) significatif(s) (et {warnings} (avertissement(s)) en relation avec {category} !", "diagnosis_ip_not_connected_at_all": "Le serveur ne semble pas du tout connecté à Internet !?", - "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais soyer prudent en utilisant un fichier /etc/resolv.conf personnalisé.", + "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais soyez prudent en utilisant un fichier /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Au lieu de cela, ce fichier devrait être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Les résolveurs réels doivent être configurés via /etc/resolv.dnsmasq.conf.", "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS de type {0}, nom {1} et valeur {2}. Vous pouvez consulter https://yunohost.org/dns_config pour plus d'informations.", "diagnosis_diskusage_ok": "Le stockage {mountpoint} (sur le périphérique {device}) a toujours {free_abs_GB} Go ({free_percent}%) d'espace libre !", From 59859429bc45b0e47cefd4ae285d3ce5d959f0f2 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 11 Mar 2020 09:29:12 +0000 Subject: [PATCH 073/104] Added translation using Weblate (Nepali) --- locales/ne.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 locales/ne.json diff --git a/locales/ne.json b/locales/ne.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/locales/ne.json @@ -0,0 +1 @@ +{} From addc4979ee7d2c2c7fe24cbf304b7565aa441f61 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Sun, 15 Mar 2020 15:16:26 +0000 Subject: [PATCH 074/104] Update changelog for 3.7.0.5 release --- debian/changelog | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 25a7469de..a7c0c0c35 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,21 @@ +yunohost (3.7.0.5) testing; urgency=low + + - [fix] Permission url (#871) + - [fix] DNS resolver (#859) + - [fix] Legacy permission management (#868, #855) + - [enh] More informations in hooks permission (#877) + + Thanks to all contributors <3 ! (Bram, ljf, Aleks, Josué Maniac, Kay0u) + + -- Kay0u Sun, 15 Mar 2020 15:07:24 +0000 + yunohost (3.7.0.4) testing; urgency=low - [fix] Also add all_users when allowing visitors (#855) - [fix] Fix handling of skipped_uris (c.f. also SSOwat#149) - [i18n] Improve translations for Catalan - -- Alexandre Aubin Mon, 2 Dev 2019 20:44:00 +0000 + -- Alexandre Aubin Mon, 2 Dec 2019 20:44:00 +0000 yunohost (3.7.0.3) testing; urgency=low From 3137e5ffd44b2a574daf6ddd3ffb38b0d59d7c7f Mon Sep 17 00:00:00 2001 From: Kayou Date: Sun, 15 Mar 2020 19:08:22 +0100 Subject: [PATCH 075/104] Update changelog --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index a7c0c0c35..de65b8901 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,7 +5,7 @@ yunohost (3.7.0.5) testing; urgency=low - [fix] Legacy permission management (#868, #855) - [enh] More informations in hooks permission (#877) - Thanks to all contributors <3 ! (Bram, ljf, Aleks, Josué Maniac, Kay0u) + Thanks to all contributors <3 ! (Bram, ljf, Aleks, Josué, Maniack, Kay0u) -- Kay0u Sun, 15 Mar 2020 15:07:24 +0000 From 1b174563314d3745fc13e8639ca145822868b842 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 15 Mar 2020 22:33:51 +0100 Subject: [PATCH 076/104] [fix] Make sure the group permission update contains unique elements --- src/yunohost/permission.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index b9edb317d..f6316424e 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -452,6 +452,9 @@ def _update_ldap_group_permission(permission, allowed, sync_perm=True): return existing_permission allowed = [allowed] if not isinstance(allowed, list) else allowed + + # Guarantee uniqueness of values in allowed, which would otherwise make ldap.update angry. + allowed = set(allowed) try: ldap.update('cn=%s,ou=permission' % permission, From 96be75e1774e7309a22337c015985f8d16e21a6e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 15 Mar 2020 22:33:51 +0100 Subject: [PATCH 077/104] [fix] Make sure the group permission update contains unique elements --- src/yunohost/permission.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 9d3d8feda..775a8cd71 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -452,6 +452,9 @@ def _update_ldap_group_permission(permission, allowed, sync_perm=True): return existing_permission allowed = [allowed] if not isinstance(allowed, list) else allowed + + # Guarantee uniqueness of values in allowed, which would otherwise make ldap.update angry. + allowed = set(allowed) try: ldap.update('cn=%s,ou=permission' % permission, From 9d4922eb81544d6f7035cf0b3c1d430274f41afc Mon Sep 17 00:00:00 2001 From: Kayou Date: Sun, 15 Mar 2020 19:08:22 +0100 Subject: [PATCH 078/104] Update changelog --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index a7c0c0c35..de65b8901 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,7 +5,7 @@ yunohost (3.7.0.5) testing; urgency=low - [fix] Legacy permission management (#868, #855) - [enh] More informations in hooks permission (#877) - Thanks to all contributors <3 ! (Bram, ljf, Aleks, Josué Maniac, Kay0u) + Thanks to all contributors <3 ! (Bram, ljf, Aleks, Josué, Maniack, Kay0u) -- Kay0u Sun, 15 Mar 2020 15:07:24 +0000 From b7a61f35cc46a50fbd9ef5ad5109f16eed6171ed Mon Sep 17 00:00:00 2001 From: kay0u Date: Sun, 15 Mar 2020 22:35:56 +0000 Subject: [PATCH 079/104] Update changelog for 3.7.0.6 release --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index de65b8901..8f0205f74 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +yunohost (3.7.0.6) testing; urgency=low + + - [fix] Make sure the group permission update contains unique elements + + Thanks to all contributors <3 ! (Aleks) + + -- Kay0u Sun, 15 Mar 2020 22:34:27 +0000 + yunohost (3.7.0.5) testing; urgency=low - [fix] Permission url (#871) From d6568eb25db553ef8c56758a97155b2c30028849 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 16 Mar 2020 00:55:16 +0100 Subject: [PATCH 080/104] Placeholder version number to avoid inconsistent build numbers between testing and unstable --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index 8f0205f74..c2b37fa64 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +yunohost (3.8.0~alpha) testing; urgency=low + + Placeholder for upcoming 3.8 to avoid funky stuff with version numbers in + builds etc. + + -- Alexandre Aubin Mon, 16 Mar 2020 01:00:00 +0000 + yunohost (3.7.0.6) testing; urgency=low - [fix] Make sure the group permission update contains unique elements From 0decb6477ef50b099eb0a84b01985261763e1c31 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 17 Mar 2020 21:21:28 +0100 Subject: [PATCH 081/104] Try to improve a few weird messages and translations --- locales/en.json | 2 +- locales/fr.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/en.json b/locales/en.json index df1fbe3a0..044f145e5 100644 --- a/locales/en.json +++ b/locales/en.json @@ -608,5 +608,5 @@ "yunohost_configured": "YunoHost is now configured", "yunohost_installing": "Installing YunoHost…", "yunohost_not_installed": "YunoHost is not correctly installed. Please run 'yunohost tools postinstall'", - "yunohost_postinstall_end_tip": "The post-install completed! To finalize your setup, please consider:\n - adding a first user through the 'Users' section of the webadmin (or 'yunohost user create ' in command-line);\n - diagnose issues waiting to be solved for your server to be running as smoothly as possible through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line);\n - reading the 'Finalizing your setup' and 'Getting to know Yunohost' parts in the admin documentation: https://yunohost.org/admindoc." + "yunohost_postinstall_end_tip": "The post-install completed! To finalize your setup, please consider:\n - adding a first user through the 'Users' section of the webadmin (or 'yunohost user create ' in command-line);\n - diagnose potential issues through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line);\n - reading the 'Finalizing your setup' and 'Getting to know Yunohost' parts in the admin documentation: https://yunohost.org/admindoc." } diff --git a/locales/fr.json b/locales/fr.json index e10723b6b..213e2e9ba 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -749,11 +749,11 @@ "diagnosis_ports_needed_by": "Rendre ce port accessible est nécessaire pour le service {0}", "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez probablement configurer la redirection de port sur votre routeur Internet comme décrit sur https://yunohost.org/isp_box_config", "diagnosis_http_connection_error": "Erreur de connexion : impossible de se connecter au domaine demandé, il est probablement injoignable.", - "diagnosis_no_cache": "Pas encore de diagnostique de cache pour la catégorie « {category} »", + "diagnosis_no_cache": "Pas encore de cache de diagnostique pour la catégorie « {category} »", "diagnosis_http_unknown_error": "Une erreur est survenue en essayant de joindre votre domaine, il est probablement injoignable.", "permission_all_users_implicitly_added": "La permission a également été implicitement accordée à 'all_users' car il est nécessaire pour permettre au groupe spécial 'visiteurs'", "permission_cannot_remove_all_users_while_visitors_allowed": "Vous ne pouvez pas supprimer cette autorisation pour 'all_users' alors qu'elle est toujours autorisée pour 'visiteurs'", - "yunohost_postinstall_end_tip": "La post-installation terminée! Pour finaliser votre configuration, veuillez considérer:\n - ajout d'un premier utilisateur via la section \"Utilisateurs\" de l'administrateur Web (ou \"utilisateur yunohost créer \" en ligne de commande);\n - diagnostiquez les problèmes en attente de résolution du problème afin que votre serveur fonctionne le mieux possible dans la section \"Diagnostic\" de l'administrateur Web (ou \"Exécution du diagnostic yunohost\" en ligne de commande);\n - lecture des parties \"Finalisation de votre configuration\" et \"Découverte de Yunohost\" dans la documentation de l'administrateur: https://yunohost.org/admindoc.", + "yunohost_postinstall_end_tip": "La post-installation terminée! Pour finaliser votre configuration, il est recommendé de :\n - ajouter un premier utilisateur depuis la section \"Utilisateurs\" de l'interface web (ou \"yunohost user create \" en ligne de commande);\n - diagnostiquer les potentiels problèmes dans la section \"Diagnostic\" de l'interface web (ou \"yunohost diagnosis run\" en ligne de commande);\n - lire les parties \"Finalisation de votre configuration\" et \"Découverte de Yunohost\" dans le guide de l'administrateur: https://yunohost.org/admindoc.", "diagnosis_services_bad_status_tip": "Vous pouvez essayer de redémarrer le service. Si cela ne fonctionne pas, consultez les journaux de service à l'aide de 'yunohost service log {0}' ou de la section 'Services' de l'administrateur Web.", "diagnosis_http_bad_status_code": "N'a pas pu atteindre votre serveur comme prévu, il a renvoyé un code d'état incorrect. Il se peut qu'une autre machine réponde à la place de votre serveur. Vérifiez que vous transférez correctement le port 80, que votre configuration nginx est à jour et qu’un proxy inverse n’interfère pas.", "diagnosis_http_timeout": "Expiration du délai en essayant de contacter votre serveur de l'extérieur. Il semble être inaccessible. Vérifiez que vous transférez correctement le port 80, que nginx est en cours d’exécution et qu’un pare-feu n’interfère pas.", From b5d18d63c7e28e17415ef8fc210b0030289eaa59 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 18 Mar 2020 01:30:31 +0100 Subject: [PATCH 082/104] Better handling of the didn't-run-diagnosis-ever-yet case (c.f. also commit for webadmin) --- locales/en.json | 1 + src/yunohost/diagnosis.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/locales/en.json b/locales/en.json index 044f145e5..d6784a78d 100644 --- a/locales/en.json +++ b/locales/en.json @@ -220,6 +220,7 @@ "diagnosis_http_bad_status_code": "Could not reach your server as expected, it returned a bad status code. It might be that another machine answered instead of your server. You should check that you're correctly forwarding port 80, that your nginx configuration is up to date, and that a reverse-proxy is not interfering.", "diagnosis_http_unreachable": "Domain {domain} is unreachable through HTTP from outside.", "diagnosis_unknown_categories": "The following categories are unknown: {categories}", + "diagnosis_never_ran_yet": "It looks like this server was setup recently and there's no diagnosis report to show yet. You should start by running a full diagnosis, either from the webadmin or using 'yunohost diagnosis run' from the command line.", "domain_cannot_remove_main": "You cannot remove '{domain:s}' since it's the main domain, you first need to set another domain as the main domain using 'yunohost domain main-domain -n '; here is the list of candidate domains: {other_domains:s}", "domain_cannot_remove_main_add_new_one": "You cannot remove '{domain:s}' since it's the main domain and your only domain, you need to first add another domain using 'yunohost domain add ', then set is as the main domain using 'yunohost domain main-domain -n ' and then you can remove the domain '{domain:s}' using 'yunohost domain remove {domain:s}'.'", "domain_cert_gen_failed": "Could not generate certificate", diff --git a/src/yunohost/diagnosis.py b/src/yunohost/diagnosis.py index 018140a49..db791fcdf 100644 --- a/src/yunohost/diagnosis.py +++ b/src/yunohost/diagnosis.py @@ -58,6 +58,10 @@ def diagnosis_show(categories=[], issues=False, full=False, share=False): if unknown_categories: raise YunohostError('diagnosis_unknown_categories', categories=", ".join(categories)) + if not os.path.exists(DIAGNOSIS_CACHE): + logger.warning(m18n.n("diagnosis_never_ran_yet")) + return + # Fetch all reports all_reports = [] for category in categories: From 2dbd6a5c1c491bbcd5d205f2971a5232b5ddd43c Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Fri, 13 Mar 2020 16:54:19 +0000 Subject: [PATCH 083/104] Translated using Weblate (Catalan) Currently translated at 100.0% (610 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index 9e36d7009..6950152c2 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -162,7 +162,7 @@ "admin_password_too_long": "Trieu una contrasenya de menys de 127 caràcters", "dpkg_is_broken": "No es pot fer això en aquest instant perquè dpkg/APT (els gestors de paquets del sistema) sembla estar mal configurat… Podeu intentar solucionar-ho connectant-vos per SSH i executant «sudo dpkg --configure -a».", "dnsmasq_isnt_installed": "sembla que dnsmasq no està instal·lat, executeu \"apt-get remove bind9 && apt-get install dnsmasq\"", - "domain_cannot_remove_main": "No es pot eliminar «{domain:s}» ja que és el domini principal, primer s'ha d'establir un nou domini principal utilitzant «yunohost domain main-domain -n », aquí hi ha una llista dels possibles dominis: {other_domains:s}", + "domain_cannot_remove_main": "No es pot eliminar «{domain:s}» ja que és el domini principal, primer s'ha d'establir un nou domini principal utilitzant «yunohost domain main-domain -n »; aquí hi ha una llista dels possibles dominis: {other_domains:s}", "domain_cert_gen_failed": "No s'ha pogut generar el certificat", "domain_created": "S'ha creat el domini", "domain_creation_failed": "No s'ha pogut crear el domini {domain}: {error}", @@ -601,7 +601,7 @@ "migrations_running_forward": "Executant la migració {id}…", "migrations_success_forward": "Migració {id} completada", "apps_already_up_to_date": "Ja estan actualitzades totes les aplicacions", - "dyndns_provider_unreachable": "No s'ha pogut connectar amb el proveïdor Dyndns {provider}: o el vostre YunoHost no està ben connectat a Internet o el servidor dynette està caigut.", + "dyndns_provider_unreachable": "No s'ha pogut connectar amb el proveïdor DynDNS {provider}: o el vostre YunoHost no està ben connectat a Internet o el servidor dynette està caigut.", "operation_interrupted": "S'ha interromput manualment l'operació?", "group_already_exist": "El grup {group} ja existeix", "group_already_exist_on_system": "El grup {group} ja existeix en els grups del sistema", @@ -641,7 +641,7 @@ "diagnosis_basesystem_ynh_single_version": "{0} versió: {1}({2})", "diagnosis_basesystem_ynh_inconsistent_versions": "Esteu utilitzant versions inconsistents dels paquets de YunoHost… probablement a causa d'una actualització fallida o parcial.", "diagnosis_display_tip_web": "Podeu anar a la secció de Diagnòstics (en la pantalla principal) per veure els errors que s'han trobat.", - "diagnosis_failed_for_category": "Ha fallat el diagnòstic per la categoria «{category}» : {error}", + "diagnosis_failed_for_category": "Ha fallat el diagnòstic per la categoria «{category}»: {error}", "diagnosis_display_tip_cli": "Podeu executar «yunohost diagnosis show --issues» per mostrar els errors que s'han trobat.", "diagnosis_cache_still_valid": "(La memòria cau encara és vàlida pel diagnòstic de {category}. No es tornar a diagnosticar de moment!)", "diagnosis_cant_run_because_of_dep": "No es pot fer el diagnòstic per {category} mentre hi ha problemes importants relacionats amb {dep}.", @@ -650,7 +650,7 @@ "diagnosis_found_errors_and_warnings": "S'ha trobat problema(es) important(s) {errors} (i avis(os) {warnings}) relacionats amb {category}!", "diagnosis_found_warnings": "S'han trobat ítems {warnings} que es podrien millorar per {category}.", "diagnosis_everything_ok": "Tot sembla correcte per {category}!", - "diagnosis_failed": "No s'han pogut obtenir els resultats del diagnòstic per la categoria «{category}» : {error}", + "diagnosis_failed": "No s'han pogut obtenir els resultats del diagnòstic per la categoria «{category}»: {error}", "diagnosis_ip_connected_ipv4": "El servidor està connectat a Internet amb IPv4!", "diagnosis_ip_no_ipv4": "El servidor no té una IPv4 que funcioni.", "diagnosis_ip_connected_ipv6": "El servidor està connectat a Internet amb IPv6!", @@ -706,7 +706,7 @@ "migration_description_0013_futureproof_apps_catalog_system": "Migrar al nou sistema de catàleg d'aplicacions resistent al pas del temps", "app_upgrade_script_failed": "Hi ha hagut un error en el script d'actualització de l'aplicació", "diagnosis_services_bad_status_tip": "Podeu intentar reiniciar el servei, i si no funciona, podeu mirar els registres del servei utilitzant «yunohost service log {0}» o a través de «Serveis» a la secció de la pàgina web d'administració.", - "diagnosis_ports_forwarding_tip": "Per arreglar aquest problema, segurament s'ha de configurar el reenviament de ports en el router tal i s'explica a https://yunohost.org/isp_box_config", + "diagnosis_ports_forwarding_tip": "Per arreglar aquest problema, segurament s'ha de configurar el reenviament de ports en el router tal i com s'explica a https://yunohost.org/isp_box_config", "diagnosis_http_bad_status_code": "No s'ha pogut connectar al servidor com esperat, ha retornat un codi d'estat erroni. Podria ser que una altra màquina hagi contestat en lloc del servidor. S'hauria de comprovar que el reenviament del port 80 sigui correcte, que la configuració NGINX està actualitzada i que el reverse-proxy no està interferint.", "diagnosis_no_cache": "Encara no hi ha memòria cau pel diagnòstic de la categoria «{category}»", "diagnosis_http_timeout": "S'ha exhaurit el temps d'esperar intentant connectar amb el servidor des de l'exterior. Sembla que no s'hi pot accedir. S'hauria de comprovar que el reenviament del port 80 és correcte, que NGINX funciona, i que el tallafocs no està interferint.", From 0691759190a0abcfc9999df9d7f316115f4262c6 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sat, 14 Mar 2020 16:22:46 +0000 Subject: [PATCH 084/104] Translated using Weblate (French) Currently translated at 96.9% (591 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 213e2e9ba..156b870ef 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -288,7 +288,7 @@ "appslist_migrating": "Migration de la liste d’applications '{appslist:s}' …", "appslist_could_not_migrate": "Impossible de migrer la liste '{appslist:s}' ! Impossible d’exploiter l’URL. L’ancienne tâche programmée a été conservée dans {bkp_file:s}.", "appslist_corrupted_json": "Impossible de charger la liste d’applications. Il semble que {filename:s} soit endommager.", - "app_already_installed_cant_change_url": "Cette application est déjà installée. L’URL ne peut pas être changé simplement par cette fonction. Regardez si cela est disponible avec `app changeurl`.", + "app_already_installed_cant_change_url": "Cette application est déjà installée. L’URL ne peut pas être changé simplement par cette fonction. Vérifiez si cela est disponible avec `app changeurl`.", "app_change_no_change_url_script": "L’application {app_name:s} ne prend pas encore en charge le changement d’URL, vous pourriez avoir besoin de la mettre à jour.", "app_change_url_failed_nginx_reload": "Le redémarrage de Nginx a échoué. Voici la sortie de 'nginx -t' :\n{nginx_errors:s}", "app_change_url_identical_domains": "L’ancien et le nouveau couple domaine/chemin_de_l'URL sont identiques pour ('{domain:s}{path:s}'), rien à faire.", @@ -617,7 +617,7 @@ "permission_updated": "Permission '{permission:s}' mise à jour", "permission_update_nothing_to_do": "Aucune autorisation pour mettre à jour", "remove_main_permission_not_allowed": "Supprimer l'autorisation principale n'est pas autorisé", - "dyndns_provider_unreachable": "Impossible d’atteindre le fournisseur Dyndns {provider}: votre YunoHost n’est pas correctement connecté à Internet ou le serveur Dynette est en panne.", + "dyndns_provider_unreachable": "Impossible d’atteindre le fournisseur DynDNS {provider}: votre YunoHost n’est pas correctement connecté à Internet ou le serveur Dynette est en panne.", "migration_0011_update_LDAP_schema": "Mise à jour du schéma LDAP…", "migrations_already_ran": "Ces migrations sont déjà effectuées: {ids}", "migrations_dependencies_not_satisfied": "Exécutez ces migrations: '{dependencies_id}', avant migration {id}.", @@ -684,7 +684,7 @@ "diagnosis_basesystem_ynh_main_version": "Le serveur exécute YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_inconsistent_versions": "Vous exécutez des versions incohérentes des packages YunoHost ... probablement à cause d'une mise à niveau partielle ou échouée.", "diagnosis_display_tip_cli": "Vous pouvez exécuter 'yunohost diagnosis show --issues' pour afficher les problèmes détectés.", - "diagnosis_failed_for_category": "Échec du diagnostic pour la catégorie '{category}' : {error}", + "diagnosis_failed_for_category": "Échec du diagnostic pour la catégorie '{category}': {error}", "diagnosis_cache_still_valid": "(Le cache est toujours valide pour le diagnostic {category}. Pas re-diagnostiquer pour le moment!)", "diagnosis_ignored_issues": "(+ {nb_ignored} questions ignorée(s))", "diagnosis_found_warnings": "Trouvé {warnings} objet(s) pouvant être amélioré(s) pour {category}.", @@ -695,7 +695,7 @@ "diagnosis_ip_connected_ipv6": "Le serveur est connecté à Internet via IPv6 !", "diagnosis_ip_no_ipv6": "Le serveur ne dispose pas d'une adresse IPv6 active.", "diagnosis_ip_dnsresolution_working": "La résolution de nom de domaine fonctionne !", - "diagnosis_ip_broken_dnsresolution": "La résolution du nom de domaine semble interrompue pour une raison quelconque ... Un pare-feu bloque-t-il les requêtes DNS ?", + "diagnosis_ip_broken_dnsresolution": "La résolution du nom de domaine semble interrompue pour une raison quelconque... Un pare-feu bloque-t-il les requêtes DNS ?", "diagnosis_ip_broken_resolvconf": "La résolution du nom de domaine semble cassée sur votre serveur, ce qui semble lié au fait que /etc/resolv.conf ne pointe pas vers 127.0.0.1.", "diagnosis_dns_good_conf": "Bonne configuration DNS pour le domaine {domain} (catégorie {category})", "diagnosis_dns_bad_conf": "Configuration DNS incorrecte/manquante pour le domaine {domain} (catégorie {category})", From 49f999795382c5c8c75c023cbb9ca3c4da5671b6 Mon Sep 17 00:00:00 2001 From: Gustavo M Date: Thu, 12 Mar 2020 22:55:53 +0000 Subject: [PATCH 085/104] Translated using Weblate (Portuguese) Currently translated at 8.7% (53 of 610 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pt/ --- locales/pt.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/locales/pt.json b/locales/pt.json index e068a2284..417800fd5 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -1,8 +1,8 @@ { "action_invalid": "Acção Inválida '{action:s}'", "admin_password": "Senha de administração", - "admin_password_change_failed": "Não foi possível alterar a senha", - "admin_password_changed": "A palavra-passe de administração foi alterada com sucesso", + "admin_password_change_failed": "Não é possível alterar a senha", + "admin_password_changed": "A senha da administração foi alterada", "app_already_installed": "{app:s} já está instalada", "app_extraction_failed": "Não foi possível extrair os ficheiros para instalação", "app_id_invalid": "A ID da aplicação é inválida", @@ -194,5 +194,6 @@ "backup_cant_mount_uncompress_archive": "Não foi possível montar em modo leitura o diretorio de arquivos não comprimido", "backup_copying_to_organize_the_archive": "Copiando {size:s}MB para organizar o arquivo", "app_change_url_identical_domains": "O antigo e o novo domínio / url_path são idênticos ('{domain:s}{path:s}'), nada para fazer.", - "password_too_simple_1": "A senha precisa ter pelo menos 8 caracteres" + "password_too_simple_1": "A senha precisa ter pelo menos 8 caracteres", + "admin_password_too_long": "Escolha uma senha que contenha menos de 127 caracteres" } From 69bc12454ecb95a7e5a25fdb385290c93f2f6fd5 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 21 Mar 2020 22:25:44 +0100 Subject: [PATCH 086/104] Reorder DNS tests to avoid random order in rendering --- data/hooks/diagnosis/12-dnsrecords.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/hooks/diagnosis/12-dnsrecords.py b/data/hooks/diagnosis/12-dnsrecords.py index e2f7bcc2d..96ac31d55 100644 --- a/data/hooks/diagnosis/12-dnsrecords.py +++ b/data/hooks/diagnosis/12-dnsrecords.py @@ -42,8 +42,10 @@ class DNSRecordsDiagnoser(Diagnoser): # Here if there are no AAAA record, we should add something to expect "no" AAAA record # to properly diagnose situations where people have a AAAA record but no IPv6 - for category, records in expected_configuration.items(): + categories = ["basic", "mail", "xmpp", "extra"] + for category in categories: + records = expected_configuration[category] discrepancies = [] for r in records: From 937d3396315d7574f4d133d88c34e3eaf892fed3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 21 Mar 2020 22:27:52 +0100 Subject: [PATCH 087/104] Add category to services to have more meaningful messages in reports about port forwarding checks --- data/hooks/diagnosis/14-ports.py | 10 ++++++---- data/templates/yunohost/services.yml | 15 ++++++++++++++- locales/en.json | 2 +- locales/fr.json | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index f9694a9de..11f26ceba 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -21,7 +21,8 @@ class PortsDiagnoser(Diagnoser): # 443: "nginx" # ... } ports = {} - for service, infos in _get_services().items(): + services = _get_services() + for service, infos in services.items(): for port in infos.get("needs_exposed_ports", []): ports[port] = service @@ -39,17 +40,18 @@ class PortsDiagnoser(Diagnoser): except Exception as e: raise YunohostError("diagnosis_ports_could_not_diagnose", error=e) - for port, service in ports.items(): + for port, service in sorted(ports.items()): + category = services[service].get("category", "[?]") if r["ports"].get(str(port), None) is not True: yield dict(meta={"port": port, "needed_by": service}, status="ERROR", summary=("diagnosis_ports_unreachable", {"port": port}), - details=[("diagnosis_ports_needed_by", (service,)), ("diagnosis_ports_forwarding_tip", ())]) + details=[("diagnosis_ports_needed_by", (service, category)), ("diagnosis_ports_forwarding_tip", ())]) else: yield dict(meta={"port": port, "needed_by": service}, status="SUCCESS", summary=("diagnosis_ports_ok", {"port": port}), - details=[("diagnosis_ports_needed_by", (service))]) + details=[("diagnosis_ports_needed_by", (service, category))]) def main(args, env, loggers): diff --git a/data/templates/yunohost/services.yml b/data/templates/yunohost/services.yml index b3c406f0f..fdf278fcf 100644 --- a/data/templates/yunohost/services.yml +++ b/data/templates/yunohost/services.yml @@ -3,40 +3,53 @@ dnsmasq: {} dovecot: log: [/var/log/mail.log,/var/log/mail.err] needs_exposed_ports: [993] + category: email fail2ban: log: /var/log/fail2ban.log + category: security metronome: log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err] needs_exposed_ports: [5222, 5269] + category: xmpp mysql: log: [/var/log/mysql.log,/var/log/mysql.err,/var/log/mysql/error.log] alternates: ['mariadb'] + category: database nginx: log: /var/log/nginx test_conf: nginx -t needs_exposed_ports: [80, 443] + category: web nslcd: {} php7.0-fpm: log: /var/log/php7.0-fpm.log test_conf: php-fpm7.0 --test + category: web postfix: log: [/var/log/mail.log,/var/log/mail.err] test_status: systemctl show postfix@- | grep -q "^SubState=running" needs_exposed_ports: [25, 587] + category: email redis-server: log: /var/log/redis/redis-server.log + category: database rspamd: log: /var/log/rspamd/rspamd.log -slapd: {} + category: email +slapd: + category: database ssh: log: /var/log/auth.log test_conf: sshd -t needs_exposed_ports: [22] + category: admin yunohost-api: log: /var/log/yunohost/yunohost-api.log + category: admin yunohost-firewall: need_lock: true test_status: iptables -S | grep "^-A INPUT" | grep " --dport" | grep -q ACCEPT + category: security glances: null nsswitch: null ssl: null diff --git a/locales/en.json b/locales/en.json index d6784a78d..3aa2a7074 100644 --- a/locales/en.json +++ b/locales/en.json @@ -210,7 +210,7 @@ "diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside. Error: {error}", "diagnosis_ports_unreachable": "Port {port} is not reachable from outside.", "diagnosis_ports_ok": "Port {port} is reachable from outside.", - "diagnosis_ports_needed_by": "Exposing this port is needed for service {0}", + "diagnosis_ports_needed_by": "Exposing this port is needed for {1} features (service {0})", "diagnosis_ports_forwarding_tip": "To fix this issue, you most probably need to configure port forwarding on your internet router as described in https://yunohost.org/isp_box_config", "diagnosis_http_could_not_diagnose": "Could not diagnose if domain is reachable from outside. Error: {error}", "diagnosis_http_ok": "Domain {domain} is reachable from outside.", diff --git a/locales/fr.json b/locales/fr.json index 156b870ef..5bcb74b11 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -746,7 +746,7 @@ "migration_description_0014_remove_app_status_json": "Supprimer les fichiers d'application status.json hérités", "diagnosis_services_running": "Le service {service} s'exécute correctement !", "diagnosis_services_conf_broken": "La configuration est cassée pour le service {service} !", - "diagnosis_ports_needed_by": "Rendre ce port accessible est nécessaire pour le service {0}", + "diagnosis_ports_needed_by": "Rendre ce port accessible est nécessaire pour les fonctionnalités de type {1} (service {0})", "diagnosis_ports_forwarding_tip": "Pour résoudre ce problème, vous devez probablement configurer la redirection de port sur votre routeur Internet comme décrit sur https://yunohost.org/isp_box_config", "diagnosis_http_connection_error": "Erreur de connexion : impossible de se connecter au domaine demandé, il est probablement injoignable.", "diagnosis_no_cache": "Pas encore de cache de diagnostique pour la catégorie « {category} »", From 986f38f6ed2230332838499fcc27601aae7280bb Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 21 Mar 2020 22:37:25 +0100 Subject: [PATCH 088/104] Try to fix / improve a few messages --- locales/en.json | 6 +++--- locales/fr.json | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/locales/en.json b/locales/en.json index 3aa2a7074..c6dfb99af 100644 --- a/locales/en.json +++ b/locales/en.json @@ -168,9 +168,9 @@ "diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason... Is a firewall blocking DNS requests ?", "diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to /etc/resolv.conf not pointing to 127.0.0.1.", "diagnosis_ip_weird_resolvconf": "DNS resolution seems to be working, but be careful that you seem to be using a custom /etc/resolv.conf.", - "diagnosis_ip_weird_resolvconf_details": "Instead, this file should be a symlink to /etc/resolvconf/run/resolv.conf itself pointing to 127.0.0.1 (dnsmasq). The actual resolvers should be configured via /etc/resolv.dnsmasq.conf.", + "diagnosis_ip_weird_resolvconf_details": "Instead, this file should be a symlink to /etc/resolvconf/run/resolv.conf itself pointing to 127.0.0.1 (dnsmasq). The actual resolvers should be configured in /etc/resolv.dnsmasq.conf.", "diagnosis_dns_good_conf": "Good DNS configuration for domain {domain} (category {category})", - "diagnosis_dns_bad_conf": "Bad / missing DNS configuration for domain {domain} (category {category})", + "diagnosis_dns_bad_conf": "Bad or missing DNS configuration for domain {domain} (category {category})", "diagnosis_dns_missing_record": "According to the recommended DNS configuration, you should add a DNS record with type {0}, name {1} and value {2}. You can check https://yunohost.org/dns_config for more info.", "diagnosis_dns_discrepancy": "The DNS record with type {0} and name {1} does not match the recommended configuration. Current value: {2}. Excepted value: {3}. You can check https://yunohost.org/dns_config for more info.", "diagnosis_services_running": "Service {service} is running!", @@ -217,7 +217,7 @@ "diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable. You should check that you're correctly forwarding port 80, that nginx is running, and that a firewall is not interfering.", "diagnosis_http_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.", "diagnosis_http_unknown_error": "An error happened while trying to reach your domain, it's very likely unreachable.", - "diagnosis_http_bad_status_code": "Could not reach your server as expected, it returned a bad status code. It might be that another machine answered instead of your server. You should check that you're correctly forwarding port 80, that your nginx configuration is up to date, and that a reverse-proxy is not interfering.", + "diagnosis_http_bad_status_code": "The diagnosis system could not reach your server. It might be that another machine answered instead of your server. You should check that you're correctly forwarding port 80, that your nginx configuration is up to date, and that a reverse-proxy is not interfering.", "diagnosis_http_unreachable": "Domain {domain} is unreachable through HTTP from outside.", "diagnosis_unknown_categories": "The following categories are unknown: {categories}", "diagnosis_never_ran_yet": "It looks like this server was setup recently and there's no diagnosis report to show yet. You should start by running a full diagnosis, either from the webadmin or using 'yunohost diagnosis run' from the command line.", diff --git a/locales/fr.json b/locales/fr.json index 5bcb74b11..50dc2e983 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -674,14 +674,14 @@ "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais soyez prudent en utilisant un fichier /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Au lieu de cela, ce fichier devrait être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Les résolveurs réels doivent être configurés via /etc/resolv.dnsmasq.conf.", "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS de type {0}, nom {1} et valeur {2}. Vous pouvez consulter https://yunohost.org/dns_config pour plus d'informations.", - "diagnosis_diskusage_ok": "Le stockage {mountpoint} (sur le périphérique {device}) a toujours {free_abs_GB} Go ({free_percent}%) d'espace libre !", - "diagnosis_ram_ok": "Le système dispose toujours de {available_abs_MB} MB ({available_percent}%) de RAM sur {total_abs_MB} MB.", + "diagnosis_diskusage_ok": "Le stockage {mountpoint} (sur le périphérique {device}) a encore {free_abs_GB} Go ({free_percent}%) d'espace libre !", + "diagnosis_ram_ok": "Le système dispose encore de {available_abs_MB} MB ({available_percent}%) de RAM sur {total_abs_MB} MB.", "diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !", "diagnosis_security_vulnerable_to_meltdown": "Vous semblez vulnérable à la vulnérabilité de sécurité critique de Meltdown", - "diagnosis_basesystem_host": "Le serveur exécute Debian {debian_version}.", - "diagnosis_basesystem_kernel": "Le serveur exécute le noyau Linux {kernel_version}", + "diagnosis_basesystem_host": "Le serveur utilise Debian {debian_version}.", + "diagnosis_basesystem_kernel": "Le serveur utilise le noyau Linux {kernel_version}", "diagnosis_basesystem_ynh_single_version": "{0} version: {1} ({2})", - "diagnosis_basesystem_ynh_main_version": "Le serveur exécute YunoHost {main_version} ({repo})", + "diagnosis_basesystem_ynh_main_version": "Le serveur utilise YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_inconsistent_versions": "Vous exécutez des versions incohérentes des packages YunoHost ... probablement à cause d'une mise à niveau partielle ou échouée.", "diagnosis_display_tip_cli": "Vous pouvez exécuter 'yunohost diagnosis show --issues' pour afficher les problèmes détectés.", "diagnosis_failed_for_category": "Échec du diagnostic pour la catégorie '{category}': {error}", @@ -690,15 +690,15 @@ "diagnosis_found_warnings": "Trouvé {warnings} objet(s) pouvant être amélioré(s) pour {category}.", "diagnosis_everything_ok": "Tout semble bien pour {category} !", "diagnosis_failed": "Impossible d'extraire le résultat du diagnostic pour la catégorie '{category}': {error}", - "diagnosis_ip_connected_ipv4": "Le serveur est connecté à Internet via IPv4 !", - "diagnosis_ip_no_ipv4": "Le serveur ne dispose pas d’une adresse IPv4 active.", - "diagnosis_ip_connected_ipv6": "Le serveur est connecté à Internet via IPv6 !", - "diagnosis_ip_no_ipv6": "Le serveur ne dispose pas d'une adresse IPv6 active.", + "diagnosis_ip_connected_ipv4": "Le serveur est connecté à Internet en IPv4 !", + "diagnosis_ip_no_ipv4": "Le serveur ne dispose pas d’une adresse IPv4.", + "diagnosis_ip_connected_ipv6": "Le serveur est connecté à Internet en IPv6 !", + "diagnosis_ip_no_ipv6": "Le serveur ne dispose pas d'une adresse IPv6.", "diagnosis_ip_dnsresolution_working": "La résolution de nom de domaine fonctionne !", "diagnosis_ip_broken_dnsresolution": "La résolution du nom de domaine semble interrompue pour une raison quelconque... Un pare-feu bloque-t-il les requêtes DNS ?", "diagnosis_ip_broken_resolvconf": "La résolution du nom de domaine semble cassée sur votre serveur, ce qui semble lié au fait que /etc/resolv.conf ne pointe pas vers 127.0.0.1.", "diagnosis_dns_good_conf": "Bonne configuration DNS pour le domaine {domain} (catégorie {category})", - "diagnosis_dns_bad_conf": "Configuration DNS incorrecte/manquante pour le domaine {domain} (catégorie {category})", + "diagnosis_dns_bad_conf": "Configuration DNS incorrecte ou manquante pour le domaine {domain} (catégorie {category})", "diagnosis_dns_discrepancy": "L'enregistrement DNS de type {0} et nom {1} ne correspond pas à la configuration recommandée. Valeur actuelle: {2}. Valeur exceptée: {3}. Vous pouvez consulter https://yunohost.org/dns_config pour plus d'informations.", "diagnosis_services_bad_status": "Le service {service} est {status} :-(", "diagnosis_services_good_status": "Le service {service} est {status} comme prévu !", @@ -723,7 +723,7 @@ "diagnosis_description_basesystem": "Système de base", "diagnosis_description_ip": "Connectivité Internet", "diagnosis_description_dnsrecords": "Enregistrements DNS", - "diagnosis_description_services": "Vérification de l'état des services", + "diagnosis_description_services": "État des services", "diagnosis_description_systemresources": "Ressources système", "diagnosis_description_ports": "Exposition des ports", "diagnosis_description_http": "Exposition HTTP", @@ -755,7 +755,7 @@ "permission_cannot_remove_all_users_while_visitors_allowed": "Vous ne pouvez pas supprimer cette autorisation pour 'all_users' alors qu'elle est toujours autorisée pour 'visiteurs'", "yunohost_postinstall_end_tip": "La post-installation terminée! Pour finaliser votre configuration, il est recommendé de :\n - ajouter un premier utilisateur depuis la section \"Utilisateurs\" de l'interface web (ou \"yunohost user create \" en ligne de commande);\n - diagnostiquer les potentiels problèmes dans la section \"Diagnostic\" de l'interface web (ou \"yunohost diagnosis run\" en ligne de commande);\n - lire les parties \"Finalisation de votre configuration\" et \"Découverte de Yunohost\" dans le guide de l'administrateur: https://yunohost.org/admindoc.", "diagnosis_services_bad_status_tip": "Vous pouvez essayer de redémarrer le service. Si cela ne fonctionne pas, consultez les journaux de service à l'aide de 'yunohost service log {0}' ou de la section 'Services' de l'administrateur Web.", - "diagnosis_http_bad_status_code": "N'a pas pu atteindre votre serveur comme prévu, il a renvoyé un code d'état incorrect. Il se peut qu'une autre machine réponde à la place de votre serveur. Vérifiez que vous transférez correctement le port 80, que votre configuration nginx est à jour et qu’un proxy inverse n’interfère pas.", + "diagnosis_http_bad_status_code": "Le système de diagnostique n'a pas réussi à contacter votre serveur. Il se peut qu'une autre machine réponde à la place de votre serveur. Vérifiez que le port 80 est correctement redirigé, que votre configuration nginx est à jour et qu’un reverse-proxy n’interfère pas.", "diagnosis_http_timeout": "Expiration du délai en essayant de contacter votre serveur de l'extérieur. Il semble être inaccessible. Vérifiez que vous transférez correctement le port 80, que nginx est en cours d’exécution et qu’un pare-feu n’interfère pas.", "global_settings_setting_pop3_enabled": "Activer le protocole POP3 pour le serveur de messagerie", "log_app_action_run": "Lancer l’action de l’application '{}'", From cc2288cc215e06ce38168d7669c513517af383a2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 21 Mar 2020 23:08:24 +0100 Subject: [PATCH 089/104] Rename http diagnoser to web, should feel slightly less technical --- data/hooks/diagnosis/{16-http.py => 21-web.py} | 4 ++-- data/hooks/diagnosis/{18-mail.py => 24-mail.py} | 0 locales/en.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename data/hooks/diagnosis/{16-http.py => 21-web.py} (96%) rename data/hooks/diagnosis/{18-mail.py => 24-mail.py} (100%) diff --git a/data/hooks/diagnosis/16-http.py b/data/hooks/diagnosis/21-web.py similarity index 96% rename from data/hooks/diagnosis/16-http.py rename to data/hooks/diagnosis/21-web.py index c7955c805..f7922fdd7 100644 --- a/data/hooks/diagnosis/16-http.py +++ b/data/hooks/diagnosis/21-web.py @@ -9,7 +9,7 @@ from yunohost.domain import domain_list from yunohost.utils.error import YunohostError -class HttpDiagnoser(Diagnoser): +class WebDiagnoser(Diagnoser): id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1] cache_duration = 3600 @@ -56,4 +56,4 @@ class HttpDiagnoser(Diagnoser): def main(args, env, loggers): - return HttpDiagnoser(args, env, loggers).diagnose() + return WebDiagnoser(args, env, loggers).diagnose() diff --git a/data/hooks/diagnosis/18-mail.py b/data/hooks/diagnosis/24-mail.py similarity index 100% rename from data/hooks/diagnosis/18-mail.py rename to data/hooks/diagnosis/24-mail.py diff --git a/locales/en.json b/locales/en.json index c6dfb99af..d70f964d2 100644 --- a/locales/en.json +++ b/locales/en.json @@ -203,7 +203,7 @@ "diagnosis_description_services": "Services status check", "diagnosis_description_systemresources": "System resources", "diagnosis_description_ports": "Ports exposure", - "diagnosis_description_http": "HTTP exposure", + "diagnosis_description_web": "Web", "diagnosis_description_mail": "Email", "diagnosis_description_regenconf": "System configurations", "diagnosis_description_security": "Security checks", @@ -213,12 +213,12 @@ "diagnosis_ports_needed_by": "Exposing this port is needed for {1} features (service {0})", "diagnosis_ports_forwarding_tip": "To fix this issue, you most probably need to configure port forwarding on your internet router as described in https://yunohost.org/isp_box_config", "diagnosis_http_could_not_diagnose": "Could not diagnose if domain is reachable from outside. Error: {error}", - "diagnosis_http_ok": "Domain {domain} is reachable from outside.", + "diagnosis_http_ok": "Domain {domain} is reachable through HTTP from outside the local network.", "diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable. You should check that you're correctly forwarding port 80, that nginx is running, and that a firewall is not interfering.", "diagnosis_http_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.", "diagnosis_http_unknown_error": "An error happened while trying to reach your domain, it's very likely unreachable.", "diagnosis_http_bad_status_code": "The diagnosis system could not reach your server. It might be that another machine answered instead of your server. You should check that you're correctly forwarding port 80, that your nginx configuration is up to date, and that a reverse-proxy is not interfering.", - "diagnosis_http_unreachable": "Domain {domain} is unreachable through HTTP from outside.", + "diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.", "diagnosis_unknown_categories": "The following categories are unknown: {categories}", "diagnosis_never_ran_yet": "It looks like this server was setup recently and there's no diagnosis report to show yet. You should start by running a full diagnosis, either from the webadmin or using 'yunohost diagnosis run' from the command line.", "domain_cannot_remove_main": "You cannot remove '{domain:s}' since it's the main domain, you first need to set another domain as the main domain using 'yunohost domain main-domain -n '; here is the list of candidate domains: {other_domains:s}", From b0b27f14587291cd22b87110d105a6998ed5bd2b Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Wed, 18 Mar 2020 23:09:52 +0000 Subject: [PATCH 090/104] Translated using Weblate (Catalan) Currently translated at 100.0% (611 of 611 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index 6950152c2..c09b31e01 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -712,7 +712,7 @@ "diagnosis_http_timeout": "S'ha exhaurit el temps d'esperar intentant connectar amb el servidor des de l'exterior. Sembla que no s'hi pot accedir. S'hauria de comprovar que el reenviament del port 80 és correcte, que NGINX funciona, i que el tallafocs no està interferint.", "diagnosis_http_connection_error": "Error de connexió: no s'ha pogut connectar amb el domini demanat, segurament és inaccessible.", "diagnosis_http_unknown_error": "Hi ha hagut un error intentant accedir al domini, segurament és inaccessible.", - "yunohost_postinstall_end_tip": "S'ha completat la post-instal·lació. Per acabar la configuració, considereu:\n - afegir un primer usuari a través de la secció «Usuaris» a la pàgina web d'administració (o emprant «yunohost user create » a la línia d'ordres);\n - diagnosticar els problemes esperant a ser resolts per un correcte funcionament del servidor a través de la secció «Diagnòstics» a la pàgina web d'administració (o emprant «yunohost diagnosis run» a la línia d'ordres);\n - llegir les seccions «Finalizing your setup» i «Getting to know Yunohost» a la documentació per administradors: https://yunohost.org/admindoc.", + "yunohost_postinstall_end_tip": "S'ha completat la post-instal·lació. Per acabar la configuració, considereu:\n - afegir un primer usuari a través de la secció «Usuaris» a la pàgina web d'administració (o emprant «yunohost user create » a la línia d'ordres);\n - diagnosticar possibles problemes a través de la secció «Diagnòstics» a la pàgina web d'administració (o emprant «yunohost diagnosis run» a la línia d'ordres);\n - llegir les seccions «Finalizing your setup» i «Getting to know Yunohost» a la documentació per administradors: https://yunohost.org/admindoc.", "migration_description_0014_remove_app_status_json": "Eliminar els fitxers d'aplicació status.json heretats", "diagnosis_services_running": "El servei {service} s'està executant!", "diagnosis_services_conf_broken": "La configuració pel servei {service} està trencada!", @@ -722,5 +722,6 @@ "global_settings_setting_pop3_enabled": "Activa el protocol POP3 per al servidor de correu", "log_app_action_run": "Executa l'acció de l'aplicació «{}»", "log_app_config_show_panel": "Mostra el taulell de configuració de l'aplicació «{}»", - "log_app_config_apply": "Afegeix la configuració a l'aplicació «{}»" + "log_app_config_apply": "Afegeix la configuració a l'aplicació «{}»", + "diagnosis_never_ran_yet": "Sembla que el servidor s'ha configurat recentment i encara no hi cap informe de diagnòstic per mostrar. S'ha d'executar un diagnòstic complet primer, ja sigui des de la pàgina web d'administració o utilitzant la comanda «yunohost diagnosis run» al terminal." } From 2215786d6efc267b80f18e24936ccec0d83309ee Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 22 Mar 2020 01:23:55 +0100 Subject: [PATCH 091/104] Attempt to anonymize data pasted to paste.yunohost.org (in particular domain names) --- src/yunohost/utils/yunopaste.py | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/yunohost/utils/yunopaste.py b/src/yunohost/utils/yunopaste.py index 89c62d761..530295735 100644 --- a/src/yunohost/utils/yunopaste.py +++ b/src/yunohost/utils/yunopaste.py @@ -2,14 +2,23 @@ import requests import json +import logging +from yunohost.domain import _get_maindomain, domain_list +from yunohost.utils.network import get_public_ip from yunohost.utils.error import YunohostError +logger = logging.getLogger('yunohost.utils.yunopaste') def yunopaste(data): paste_server = "https://paste.yunohost.org" + try: + data = anonymize(data) + except Exception as e: + logger.warning("For some reason, YunoHost was not able to anonymize the pasted data. Sorry about that. Be careful about sharing the link, as it may contain somewhat private infos like domain names or IP addresses. Error: %s" % e) + try: r = requests.post("%s/documents" % paste_server, data=data, timeout=30) except Exception as e: @@ -24,3 +33,39 @@ def yunopaste(data): raise YunohostError("Uhoh, couldn't parse the answer from paste.yunohost.org : %s" % r.text, raw_msg=True) return "%s/raw/%s" % (paste_server, url) + + +def anonymize(data): + + # First, let's replace every occurence of the main domain by "domain.tld" + # This should cover a good fraction of the info leaked + main_domain = _get_maindomain() + data = data.replace(main_domain, "maindomain.tld") + + # Next, let's replace other domains. We do this in increasing lengths, + # because e.g. knowing that the domain is a sub-domain of another domain may + # still be informative. + # So e.g. if there's jitsi.foobar.com as a subdomain of foobar.com, it may + # be interesting to know that the log is about a supposedly dedicated domain + # for jisti (hopefully this explanation make sense). + domains = domain_list()["domains"] + domains = sorted(domains, key=lambda d: len(d)) + + count = 2 + for domain in domains: + if domain not in data: + continue + data = data.replace(domain, "domain%s.tld" % count) + count += 1 + + # We also want to anonymize the ips + ipv4 = get_public_ip() + ipv6 = get_public_ip(6) + + if ipv4: + data = data.replace(str(ipv4), "xx.xx.xx.xx") + + if ipv6: + data = data.replace(str(ipv6), "xx:xx:xx:xx:xx:xx") + + return data From ec80cad64ac7a49fddc76bf3b15e1de5bc0f3a36 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 22 Mar 2020 01:28:37 +0100 Subject: [PATCH 092/104] [enh] Tell apt to explain what's wrong when there are unmet dependencies (#889) * Ask apt to explain what's wrong when dependencies fail to install * Add comment explaining the syntax Co-Authored-By: Maniack Crudelis Co-authored-by: Maniack Crudelis --- data/helpers.d/apt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/helpers.d/apt b/data/helpers.d/apt index 55c85c90b..b2c781faf 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -186,7 +186,10 @@ ynh_package_install_from_equivs () { (cd "$TMPDIR" equivs-build ./control 1> /dev/null dpkg --force-depends -i "./${pkgname}_${pkgversion}_all.deb" 2>&1) - ynh_package_install -f || ynh_die --message="Unable to install dependencies" + # If install fails we use "apt-get check" to try to debug and diagnose possible unmet dependencies + # Note the use of { } which allows to group commands without starting a subshell (otherwise the ynh_die wouldn't exit the current shell). + # Be careful with the syntax : the semicolon + space at the end is important! + ynh_package_install -f || { apt-get check 2>&1; ynh_die --message="Unable to install dependencies"; } [[ -n "$TMPDIR" ]] && rm -rf $TMPDIR # Remove the temp dir. # check if the package is actually installed From 4399c9b740b5c4901de76f5b2245df4b349eae89 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 22 Mar 2020 01:40:02 +0100 Subject: [PATCH 093/104] Tweak exception messages to hopefully help debugging if this happens --- data/hooks/diagnosis/14-ports.py | 2 +- data/hooks/diagnosis/16-http.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index aaf31d561..9c0e94721 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -39,7 +39,7 @@ class PortsDiagnoser(Diagnoser): elif r["status"] != "ok" or "ports" not in r.keys() or not isinstance(r["ports"], dict): raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) else: - raise Exception("Bad response from the server https://diagnosis.yunohost.org : %s" % str(r.status_code)) + raise Exception("Bad response from the server https://diagnosis.yunohost.org/check-ports : %s - %s" % (str(r.status_code), r.content)) except Exception as e: raise YunohostError("diagnosis_ports_could_not_diagnose", error=e) diff --git a/data/hooks/diagnosis/16-http.py b/data/hooks/diagnosis/16-http.py index ac30dad78..d36e85f41 100644 --- a/data/hooks/diagnosis/16-http.py +++ b/data/hooks/diagnosis/16-http.py @@ -39,7 +39,7 @@ class HttpDiagnoser(Diagnoser): else: raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) else: - raise Exception("Bad response from the server https://diagnosis.yunohost.org : %s" % str(r.status_code)) + raise Exception("Bad response from the server https://diagnosis.yunohost.org/check-http : %s - %s" % (str(r.status_code), r.content)) except Exception as e: raise YunohostError("diagnosis_http_could_not_diagnose", error=e) From fff2fcd67cf66a6dfab02baa9c3ec036e9941394 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 22 Mar 2020 01:41:58 +0100 Subject: [PATCH 094/104] Simplify identation (and diff) by reversing the if statement --- data/hooks/diagnosis/14-ports.py | 23 +++++++++++------------ data/hooks/diagnosis/16-http.py | 19 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index 9c0e94721..d81fd39cc 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -27,19 +27,18 @@ class PortsDiagnoser(Diagnoser): try: r = requests.post('https://diagnosis.yunohost.org/check-ports', json={'ports': ports.keys()}, timeout=30) - if r.status_code == 200: - r = r.json() - if "status" not in r.keys(): - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - elif r["status"] == "error": - if "content" in r.keys(): - raise Exception(r["content"]) - else: - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - elif r["status"] != "ok" or "ports" not in r.keys() or not isinstance(r["ports"], dict): - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - else: + if r.status_code != 200: raise Exception("Bad response from the server https://diagnosis.yunohost.org/check-ports : %s - %s" % (str(r.status_code), r.content)) + r = r.json() + if "status" not in r.keys(): + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + elif r["status"] == "error": + if "content" in r.keys(): + raise Exception(r["content"]) + else: + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + elif r["status"] != "ok" or "ports" not in r.keys() or not isinstance(r["ports"], dict): + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) except Exception as e: raise YunohostError("diagnosis_ports_could_not_diagnose", error=e) diff --git a/data/hooks/diagnosis/16-http.py b/data/hooks/diagnosis/16-http.py index d36e85f41..bd862b408 100644 --- a/data/hooks/diagnosis/16-http.py +++ b/data/hooks/diagnosis/16-http.py @@ -29,17 +29,16 @@ class HttpDiagnoser(Diagnoser): try: r = requests.post('https://diagnosis.yunohost.org/check-http', json={'domain': domain, "nonce": nonce}, timeout=30) - if r.status_code == 200: - r = r.json() - if "status" not in r.keys(): - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - elif r["status"] == "error" and ("code" not in r.keys() or not r["code"].startswith("error_http_check_")): - if "content" in r.keys(): - raise Exception(r["content"]) - else: - raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) - else: + if r.status_code != 200: raise Exception("Bad response from the server https://diagnosis.yunohost.org/check-http : %s - %s" % (str(r.status_code), r.content)) + r = r.json() + if "status" not in r.keys(): + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) + elif r["status"] == "error" and ("code" not in r.keys() or not r["code"].startswith("error_http_check_")): + if "content" in r.keys(): + raise Exception(r["content"]) + else: + raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) except Exception as e: raise YunohostError("diagnosis_http_could_not_diagnose", error=e) From 8085b3a2c2ead2963138a38f43d41aa9faffb19c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 23 Mar 2020 19:35:41 +0100 Subject: [PATCH 095/104] When dumping debug info after app script failure, be slightly smarter and stop at ynh_die to have more meaningul lines being shown --- src/yunohost/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 056083b67..0ffb28c8b 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -896,7 +896,7 @@ def dump_app_log_extract_for_debugging(operation_logger): line = line.strip().split(": ", 1)[1] lines_to_display.append(line) - if line.endswith("+ ynh_exit_properly"): + if line.endswith("+ ynh_exit_properly") or " + ynh_die " in line: break elif len(lines_to_display) > 20: lines_to_display.pop(0) From 8da5aa055d46530a65e4cbba6a792a0b63874d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Sun, 29 Dec 2019 21:06:28 +0100 Subject: [PATCH 096/104] Improve stability of unit tests --- src/yunohost/tests/test_apps.py | 28 +++++++++++++++++++++++++++ src/yunohost/tests/test_permission.py | 14 ++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index d9102edbe..a85a36061 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -13,6 +13,7 @@ from yunohost.app import app_install, app_remove, app_ssowatconf, _is_installed, from yunohost.domain import _get_maindomain, domain_add, domain_remove, domain_list from yunohost.utils.error import YunohostError from yunohost.tests.test_permission import check_LDAP_db_integrity, check_permission_for_apps +from yunohost.permission import user_permission_list, permission_delete def setup_function(function): @@ -60,6 +61,33 @@ def clean(): os.system("systemctl reset-failed nginx") # Reset failed quota for service to avoid running into start-limit rate ? os.system("systemctl start nginx") + # Clean permission + for permission_name in user_permission_list(short=True)["permissions"]: + if "legacy_app" in permission_name or \ + "full_domain_app" in permission_name or \ + "break_yo_system" in permission_name: + permission_delete(permission_name, force=True) + + # Clean database + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE legacy_app' \"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER legacy_app@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE legacy_app__2'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER legacy_app__2@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE legacy_app__3'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER legacy_app__3@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE full_domain'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER full_domain@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE full_domain__2'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER full_domain__2@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE full_domain__3'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER full_domain__3@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE break_yo_system'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER break_yo_system@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE break_yo_system__2'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER break_yo_system__2@localhost'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE break_yo_system__3'\"") + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER break_yo_system__3@localhost'\"") + @pytest.fixture(autouse=True) def check_LDAP_db_integrity_call(): diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index 636d9b4b1..c8ff77493 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -14,6 +14,20 @@ from yunohost.domain import _get_maindomain maindomain = _get_maindomain() dummy_password = "test123Ynh" +# Dirty patch of DNS resolution. Force the DNS to 127.0.0.1 address even if dnsmasq have the public address. +# Mainly used for 'can_access_webpage' function +import socket +dns_cache = {(maindomain, 443, 0, 1): [(2, 1, 6, '', ('127.0.0.1', 443))]} +prv_getaddrinfo = socket.getaddrinfo +def new_getaddrinfo(*args): + try: + return dns_cache[args] + except KeyError: + res = prv_getaddrinfo(*args) + dns_cache[args] = res + return res +socket.getaddrinfo = new_getaddrinfo + def clean_user_groups_permission(): for u in user_list()['users']: From 19fc1806a4d4aec584f76cbfc48253eb0022b02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Sun, 29 Dec 2019 23:12:03 +0100 Subject: [PATCH 097/104] Fix app catalog tests --- src/yunohost/tests/test_appscatalog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yunohost/tests/test_appscatalog.py b/src/yunohost/tests/test_appscatalog.py index a51d1085e..c3ece7907 100644 --- a/src/yunohost/tests/test_appscatalog.py +++ b/src/yunohost/tests/test_appscatalog.py @@ -31,8 +31,8 @@ DUMMY_APP_CATALOG = """{ "bar": {"id": "bar", "level": 7, "category": "swag", "manifest":{"description": "Bar"}} }, "categories": [ - {"id": "yolo", "description": "YoLo", "title": "Yolo"}, - {"id": "swag", "description": "sWaG", "title": "Swag"} + {"id": "yolo", "description": "YoLo", "title": {"en": "Yolo"}}, + {"id": "swag", "description": "sWaG", "title": {"en": "Swag"}} ] } """ From 97f50e396cad5a7d0ac31c8cfce18ae0352beba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Sun, 29 Dec 2019 23:36:43 +0100 Subject: [PATCH 098/104] Fix settings boolean value management --- src/yunohost/settings.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index 2427f8677..72477e4de 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -23,15 +23,18 @@ def is_boolean(value): arg -- The string to check Returns: - Boolean + (is_boolean, boolean_value) """ if isinstance(value, bool): - return True + return True, value elif isinstance(value, basestring): - return str(value).lower() in ['true', 'on', 'yes', 'false', 'off', 'no'] + if str(value).lower() in ['true', 'on', 'yes', 'false', 'off', 'no']: + return True, str(value).lower() in ['true', 'on', 'yes'] + else: + return False, None else: - return False + return False, None # a settings entry is in the form of: @@ -114,7 +117,10 @@ def settings_set(key, value): key_type = settings[key]["type"] if key_type == "bool": - if not is_boolean(value): + boolean_value = is_boolean(value) + if boolean_value[0]: + value = boolean_value[1] + else: raise YunohostError('global_settings_bad_type_for_setting', setting=key, received_type=type(value).__name__, expected_type=key_type) elif key_type == "int": From edd607402520153c534878f142fe3b7a1d0c8ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Mon, 30 Dec 2019 00:02:57 +0100 Subject: [PATCH 099/104] Force remove domain --- src/yunohost/tests/test_apps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index a85a36061..85cd85442 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -109,7 +109,7 @@ def secondary_domain(request): domain_add("example.test") def remove_example_domain(): - domain_remove("example.test") + domain_remove("example.test", force=True) request.addfinalizer(remove_example_domain) return "example.test" From 7e8a00b9dc2e7b47065cccd22e96a27e96f69bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Mon, 30 Dec 2019 00:11:01 +0100 Subject: [PATCH 100/104] Change scope secondary domain managment --- src/yunohost/tests/test_apps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index 85cd85442..fdfcc9176 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -102,14 +102,14 @@ def check_permission_for_apps_call(): yield check_permission_for_apps() -@pytest.fixture(scope="session") +@pytest.fixture(scope="module") def secondary_domain(request): if "example.test" not in domain_list()["domains"]: domain_add("example.test") def remove_example_domain(): - domain_remove("example.test", force=True) + domain_remove("example.test") request.addfinalizer(remove_example_domain) return "example.test" From 94c066dc53f347af09bdc5058521f0ca0de21abe Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 24 Mar 2020 04:47:21 +0100 Subject: [PATCH 101/104] Factorize stuff in cleaning function to avoid repeating so much stuff --- src/yunohost/tests/test_apps.py | 62 ++++++++------------------------- 1 file changed, 14 insertions(+), 48 deletions(-) diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index fdfcc9176..6bc625a91 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -30,65 +30,31 @@ def clean(): os.system("mkdir -p /etc/ssowat/") app_ssowatconf() - # Gotta first remove break yo system - # because some remaining stuff might - # make the other app_remove crashs ;P - if _is_installed("break_yo_system"): - app_remove("break_yo_system") + test_apps = ["break_yo_system", "legacy_app", "legacy_app__2", "full_domain_app"] - if _is_installed("legacy_app"): - app_remove("legacy_app") + for test_app in test_apps: - if _is_installed("full_domain_app"): - app_remove("full_domain_app") + if _is_installed(test_app): + app_remove(test_app) - to_remove = [] - to_remove += glob.glob("/etc/nginx/conf.d/*.d/*legacy*") - to_remove += glob.glob("/etc/nginx/conf.d/*.d/*full_domain*") - to_remove += glob.glob("/etc/nginx/conf.d/*.d/*break_yo_system*") - for filepath in to_remove: - os.remove(filepath) + for filepath in glob.glob("/etc/nginx/conf.d/*.d/*%s*" % test_app): + os.remove(filepath) + for folderpath in glob.glob("/etc/yunohost/apps/*%s*" % test_app): + shutil.rmtree(folderpath, ignore_errors=True) + for folderpath in glob.glob("/var/www/*%s*" % test_app): + shutil.rmtree(folderpath, ignore_errors=True) - to_remove = [] - to_remove += glob.glob("/etc/yunohost/apps/*legacy_app*") - to_remove += glob.glob("/etc/yunohost/apps/*full_domain_app*") - to_remove += glob.glob("/etc/yunohost/apps/*break_yo_system*") - to_remove += glob.glob("/var/www/*legacy*") - to_remove += glob.glob("/var/www/*full_domain*") - for folderpath in to_remove: - shutil.rmtree(folderpath, ignore_errors=True) + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE %s' \"" % test_app) + os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER %s@localhost'\"" % test_app) os.system("systemctl reset-failed nginx") # Reset failed quota for service to avoid running into start-limit rate ? os.system("systemctl start nginx") - # Clean permission + # Clean permissions for permission_name in user_permission_list(short=True)["permissions"]: - if "legacy_app" in permission_name or \ - "full_domain_app" in permission_name or \ - "break_yo_system" in permission_name: + if any(test_app in permission_name for test_app in test_apps): permission_delete(permission_name, force=True) - # Clean database - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE legacy_app' \"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER legacy_app@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE legacy_app__2'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER legacy_app__2@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE legacy_app__3'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER legacy_app__3@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE full_domain'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER full_domain@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE full_domain__2'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER full_domain__2@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE full_domain__3'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER full_domain__3@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE break_yo_system'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER break_yo_system@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE break_yo_system__2'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER break_yo_system__2@localhost'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE break_yo_system__3'\"") - os.system("bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER break_yo_system__3@localhost'\"") - - @pytest.fixture(autouse=True) def check_LDAP_db_integrity_call(): check_LDAP_db_integrity() From 6ed3ba97ce8732f76c55d2583da21791e2574f72 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 24 Mar 2020 20:22:28 +0100 Subject: [PATCH 102/104] Add permission to stuff to be indexed by slapd to avoid it flooding complains in syslog --- data/templates/slapd/slapd.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/data/templates/slapd/slapd.conf b/data/templates/slapd/slapd.conf index 76f249060..0750b43aa 100644 --- a/data/templates/slapd/slapd.conf +++ b/data/templates/slapd/slapd.conf @@ -75,6 +75,7 @@ index cn,mail eq index gidNumber,uidNumber eq index member,memberUid,uniqueMember eq index virtualdomain eq +index permission eq # Save the time that the entry gets modified, for database #1 lastmod on From aaa9805ff26ccdd5cabc93769da83b5087582fd8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 25 Mar 2020 04:01:33 +0100 Subject: [PATCH 103/104] Add detection for virt + arch + board model in basesystem diagnosis --- data/hooks/diagnosis/00-basesystem.py | 18 ++++++++++++++++-- locales/en.json | 4 +++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index 4add48fb2..bf7a27047 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -2,6 +2,7 @@ import os +from moulinette.utils.process import check_output from moulinette.utils.filesystem import read_file from yunohost.diagnosis import Diagnoser from yunohost.utils.packages import ynh_packages_version @@ -15,14 +16,27 @@ class BaseSystemDiagnoser(Diagnoser): def run(self): + # Detect virt technology (if not bare metal) and arch + # Also possibly the board name + virt = check_output("systemd-detect-virt").strip() or "bare-metal" + arch = check_output("dpkg --print-architecture").strip() + hardware = dict(meta={"test": "hardware"}, + status="INFO", + data={"virt": virt, "arch": arch}, + summary=("diagnosis_basesystem_hardware", {"virt": virt, "arch": arch})) + if os.path.exists("/proc/device-tree/model"): + model = read_file('/proc/device-tree/model').strip() + hardware["data"]["board"] = model + hardware["details"] = [("diagnosis_basesystem_hardware_board", (model,))] + + yield hardware + # Kernel version kernel_version = read_file('/proc/sys/kernel/osrelease').strip() yield dict(meta={"test": "kernel"}, status="INFO", summary=("diagnosis_basesystem_kernel", {"kernel_version": kernel_version})) - # FIXME / TODO : add virt/vm technology using systemd-detect-virt and/or machine arch - # Debian release debian_version = read_file("/etc/debian_version").strip() yield dict(meta={"test": "host"}, diff --git a/locales/en.json b/locales/en.json index d70f964d2..82be4003a 100644 --- a/locales/en.json +++ b/locales/en.json @@ -142,7 +142,9 @@ "confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers:s}'", "confirm_app_install_thirdparty": "DANGER! This app is not part of Yunohost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers:s}'", "custom_app_url_required": "You must provide a URL to upgrade your custom app {app:s}", - "diagnosis_basesystem_host": "Server is running Debian {debian_version}.", + "diagnosis_basesystem_hardware": "Server hardware architecture is {virt} {arch}", + "diagnosis_basesystem_hardware_board": "Server board model is {model}", + "diagnosis_basesystem_host": "Server is running Debian {debian_version}", "diagnosis_basesystem_kernel": "Server is running Linux kernel {kernel_version}", "diagnosis_basesystem_ynh_single_version": "{0} version: {1} ({2})", "diagnosis_basesystem_ynh_main_version": "Server is running YunoHost {main_version} ({repo})", From 9e8bc8f7fb8ce269e3cf711d7ad87b45b67fa365 Mon Sep 17 00:00:00 2001 From: xaloc33 Date: Sun, 22 Mar 2020 17:01:08 +0000 Subject: [PATCH 104/104] Translated using Weblate (Catalan) Currently translated at 100.0% (611 of 611 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index c09b31e01..b5a74af45 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -660,7 +660,7 @@ "diagnosis_ip_broken_dnsresolution": "La resolució de nom de domini falla per algun motiu… Està el tallafocs bloquejant les peticions DNS?", "diagnosis_ip_broken_resolvconf": "La resolució de nom de domini sembla caiguda en el servidor, podria estar relacionat amb el fet que /etc/resolv.conf no apunta cap a 127.0.0.1.", "diagnosis_ip_weird_resolvconf": "La resolució DNS sembla estar funcionant, però aneu amb compte ja que esteu utilitzant un versió personalitzada de /etc/resolv.conf.", - "diagnosis_ip_weird_resolvconf_details": "En canvi, aquest fitxer hauria de ser un enllaç simbòlic cap a /etc/resolvconf/run/resolv.conf i que aquest apunti cap a 127.0.0.1 (dnsmasq). La configuració del «resolver» real s'hauria de fer via /etc/resolv.dnsmaq.conf.", + "diagnosis_ip_weird_resolvconf_details": "En canvi, aquest fitxer hauria de ser un enllaç simbòlic cap a /etc/resolvconf/run/resolv.conf i que aquest apunti cap a 127.0.0.1 (dnsmasq). La configuració del «resolver» real s'hauria de fer a /etc/resolv.dnsmaq.conf.", "diagnosis_dns_good_conf": "Bona configuració DNS pel domini {domain} (categoria {category})", "diagnosis_dns_bad_conf": "Configuració DNS incorrecta o inexistent pel domini {domain} (categoria {category})", "diagnosis_dns_missing_record": "Segons la configuració DNS recomanada, hauríeu d'afegir un registre DNS de tipus {0}, nom {1} i valor {2}. Hi ha més informació a https://yunohost.org/dns_config.", @@ -692,8 +692,8 @@ "diagnosis_ports_could_not_diagnose": "No s'ha pogut diagnosticar si els ports són accessibles des de l'exterior. Error: {error}", "diagnosis_ports_unreachable": "El port {port} no és accessible des de l'exterior.", "diagnosis_ports_ok": "El port {port} és accessible des de l'exterior.", - "diagnosis_http_ok": "El domini {domain} és accessible des de l'exterior.", - "diagnosis_http_unreachable": "El domini {domain} no és accessible a través de HTTP des de l'exterior.", + "diagnosis_http_ok": "El domini {domain} és accessible per mitjà de HTTP des de fora de la xarxa local.", + "diagnosis_http_unreachable": "Sembla que el domini {domain} no és accessible a través de HTTP des de fora de la xarxa local.", "diagnosis_unknown_categories": "Les següents categories són desconegudes: {categories}", "apps_catalog_init_success": "S'ha iniciat el sistema de catàleg d'aplicacions!", "apps_catalog_updating": "S'està actualitzant el catàleg d'aplicacions…", @@ -707,7 +707,7 @@ "app_upgrade_script_failed": "Hi ha hagut un error en el script d'actualització de l'aplicació", "diagnosis_services_bad_status_tip": "Podeu intentar reiniciar el servei, i si no funciona, podeu mirar els registres del servei utilitzant «yunohost service log {0}» o a través de «Serveis» a la secció de la pàgina web d'administració.", "diagnosis_ports_forwarding_tip": "Per arreglar aquest problema, segurament s'ha de configurar el reenviament de ports en el router tal i com s'explica a https://yunohost.org/isp_box_config", - "diagnosis_http_bad_status_code": "No s'ha pogut connectar al servidor com esperat, ha retornat un codi d'estat erroni. Podria ser que una altra màquina hagi contestat en lloc del servidor. S'hauria de comprovar que el reenviament del port 80 sigui correcte, que la configuració NGINX està actualitzada i que el reverse-proxy no està interferint.", + "diagnosis_http_bad_status_code": "El sistema de diagnòstic no ha pogut connectar amb el servidor. Podria ser que una altra màquina hagi contestat en lloc del servidor. S'hauria de comprovar que el reenviament del port 80 sigui correcte, que la configuració NGINX està actualitzada i que el reverse-proxy no està interferint.", "diagnosis_no_cache": "Encara no hi ha memòria cau pel diagnòstic de la categoria «{category}»", "diagnosis_http_timeout": "S'ha exhaurit el temps d'esperar intentant connectar amb el servidor des de l'exterior. Sembla que no s'hi pot accedir. S'hauria de comprovar que el reenviament del port 80 és correcte, que NGINX funciona, i que el tallafocs no està interferint.", "diagnosis_http_connection_error": "Error de connexió: no s'ha pogut connectar amb el domini demanat, segurament és inaccessible.", @@ -716,12 +716,13 @@ "migration_description_0014_remove_app_status_json": "Eliminar els fitxers d'aplicació status.json heretats", "diagnosis_services_running": "El servei {service} s'està executant!", "diagnosis_services_conf_broken": "La configuració pel servei {service} està trencada!", - "diagnosis_ports_needed_by": "És necessari exposar aquest port pel servei {0}", + "diagnosis_ports_needed_by": "És necessari exposar aquest port per a les funcions {1} (servei {0})", "permission_all_users_implicitly_added": "El permís també s'ha donat implícitament a «all_users» ja que és necessari per atorgar-lo al grup «visitors»", "permission_cannot_remove_all_users_while_visitors_allowed": "No podeu retirar el permís a «all_users» mentre encara el tingui el grup «visitors»", "global_settings_setting_pop3_enabled": "Activa el protocol POP3 per al servidor de correu", "log_app_action_run": "Executa l'acció de l'aplicació «{}»", "log_app_config_show_panel": "Mostra el taulell de configuració de l'aplicació «{}»", "log_app_config_apply": "Afegeix la configuració a l'aplicació «{}»", - "diagnosis_never_ran_yet": "Sembla que el servidor s'ha configurat recentment i encara no hi cap informe de diagnòstic per mostrar. S'ha d'executar un diagnòstic complet primer, ja sigui des de la pàgina web d'administració o utilitzant la comanda «yunohost diagnosis run» al terminal." + "diagnosis_never_ran_yet": "Sembla que el servidor s'ha configurat recentment i encara no hi cap informe de diagnòstic per mostrar. S'ha d'executar un diagnòstic complet primer, ja sigui des de la pàgina web d'administració o utilitzant la comanda «yunohost diagnosis run» al terminal.", + "diagnosis_description_web": "Web" }