Merge pull request #832 from YunoHost/app_upgrade_error_management

Improve app_upgrade error management
This commit is contained in:
Alexandre Aubin 2019-11-15 16:37:37 +01:00 committed by GitHub
commit 179c50e763
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 48 deletions

View file

@ -28,7 +28,6 @@
"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_upgrade_stopped": "Upgrading all apps was stopped to prevent possible damage because one app could not be upgraded",
"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",
@ -47,7 +46,8 @@
"app_unsupported_remote_type": "Unsupported remote type used for the app",
"app_upgrade_several_apps": "The following apps will be upgraded: {apps}",
"app_upgrade_app_name": "Now upgrading {app}…",
"app_upgrade_failed": "Could not upgrade {app:s}",
"app_upgrade_failed": "Could not upgrade {app:s}: {error}",
"app_upgrade_script_failed": "An error occurred inside the app upgrade script",
"app_upgrade_some_app_failed": "Some apps could not be upgraded",
"app_upgraded": "{app:s} upgraded",
"apps_already_up_to_date": "All apps are already up-to-date",

View file

@ -557,50 +557,54 @@ def app_upgrade(app=[], url=None, file=None):
# Execute App upgrade script
os.system('chown -hR admin: %s' % INSTALL_TMP)
# Execute the app upgrade script
upgrade_failed = True
try:
upgrade_retcode = hook_exec(extracted_app_folder + '/scripts/upgrade',
args=args_list, env=env_dict)[0]
upgrade_failed = True if upgrade_retcode != 0 else False
if upgrade_failed:
error = m18n.n('app_upgrade_script_failed')
logger.exception(m18n.n("app_upgrade_failed", app=app_instance_name, error=error))
failure_message_with_debug_instructions = operation_logger.error(error)
# Script got manually interrupted ... N.B. : KeyboardInterrupt does not inherit from Exception
except (KeyboardInterrupt, EOFError):
upgrade_retcode = -1
error = m18n.n('operation_interrupted')
logger.exception(m18n.n("app_upgrade_failed", app=app_instance_name, error=error))
failure_message_with_debug_instructions = operation_logger.error(error)
# Something wrong happened in Yunohost's code (most probably hook_exec)
except Exception:
import traceback
logger.exception(m18n.n('unexpected_error', error=u"\n" + traceback.format_exc()))
error = m18n.n('unexpected_error', error=u"\n" + traceback.format_exc())
logger.exception(m18n.n("app_install_failed", app=app_instance_name, error=error))
failure_message_with_debug_instructions = operation_logger.error(error)
finally:
# Did the script succeed ?
if upgrade_retcode == -1:
error_msg = m18n.n('operation_interrupted')
operation_logger.error(error_msg)
elif upgrade_retcode != 0:
error_msg = m18n.n('app_upgrade_failed', app=app_instance_name)
operation_logger.error(error_msg)
# Did it broke the system ?
# Whatever happened (install success or failure) we check if it broke the system
# and warn the user about it
try:
broke_the_system = False
_assert_system_is_sane_for_app(manifest, "post")
except Exception as e:
broke_the_system = True
error_msg = operation_logger.error(str(e))
logger.exception(m18n.n("app_upgrade_failed", app=app_instance_name, error=str(e)))
failure_message_with_debug_instructions = operation_logger.error(str(e))
# If upgrade failed or broke the system,
# raise an error and interrupt all other pending upgrades
if upgrade_retcode != 0 or broke_the_system:
if upgrade_failed or broke_the_system:
# display this if there are remaining apps
if apps[number + 1:]:
logger.error(m18n.n('app_upgrade_stopped'))
not_upgraded_apps = apps[number:]
# we don't want to continue upgrading apps here in case that breaks
# everything
raise YunohostError('app_not_upgraded',
logger.error(m18n.n('app_not_upgraded',
failed_app=app_instance_name,
apps=', '.join(not_upgraded_apps))
else:
raise YunohostError(error_msg, raw_msg=True)
apps=', '.join(not_upgraded_apps)))
raise YunohostError(failure_message_with_debug_instructions, raw_msg=True)
# Otherwise we're good and keep going !
else:
now = int(time.time())
# TODO: Move install_time away from app_setting
app_setting(app_instance_name, 'update_time', now)