diff --git a/locales/en.json b/locales/en.json index 694df0707..d998dd354 100644 --- a/locales/en.json +++ b/locales/en.json @@ -4,6 +4,7 @@ "admin_password": "Administration password", "admin_password_change_failed": "Unable to change password", "admin_password_changed": "The administration password has been changed", + "app_action_cannot_be_ran_because_required_services_down": "This app requires some services which are currently down. Before continuing, you should try to restart the following services (and possibly investigate why they are down) : {services}", "admin_password_too_long": "Please choose a password shorter than 127 characters", "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.", diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 8f2de0caa..658b4a936 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -42,7 +42,7 @@ from yunohost.utils.error import YunohostError from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import read_json -from yunohost.service import service_log, _run_service_command +from yunohost.service import service_log, service_status, _run_service_command from yunohost.utils import packages from yunohost.log import is_unit_operation, OperationLogger @@ -623,6 +623,7 @@ def app_upgrade(auth, app=[], url=None, file=None): # Check requirements _check_manifest_requirements(manifest, app_instance_name=app_instance_name) + _check_services_status_for_app(manifest.get("services", [])) app_setting_path = APPS_SETTING_PATH + '/' + app_instance_name @@ -778,6 +779,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on # Check requirements _check_manifest_requirements(manifest, app_id) + _check_services_status_for_app(manifest.get("services", [])) # Check if app can be forked instance_number = _installed_instance_number(app_id, last=True) + 1 @@ -2586,6 +2588,31 @@ def unstable_apps(): return output +def _check_services_status_for_app(services): + + logger.debug("Checking that required services are up and running...") + + # Some apps use php-fpm or php5-fpm which is now php7.0-fpm + def replace_alias(service): + if service in ["php-fpm", "php5-fpm"]: + return "php7.0-fpm" + else: + return service + services = [replace_alias(s) for s in services] + + # We only check those, mostly to ignore "custom" services + # (added by apps) and because those are the most popular + # services + service_filter = ["nginx", "php7.0-fpm", "mysql", "postfix"] + services = [s for s in services if s in service_filter] + + # List services currently down and raise an exception if any are found + faulty_services = [s for s, infos in service_status(services).items() if infos["active"] != "active"] + if faulty_services: + raise YunohostError('app_action_cannot_be_ran_because_required_services_down', + services=', '.join(faulty_services)) + + def _patch_php5(app_folder): files_to_patch = []