diff --git a/locales/en.json b/locales/en.json index 25e5a500a..95e297bc1 100644 --- a/locales/en.json +++ b/locales/en.json @@ -534,6 +534,7 @@ "regenconf_failed": "Could not regenerate the configuration for category(s): {categories}", "regenconf_pending_applying": "Applying pending configuration for category '{category}'…", "restore_already_installed_app": "An app with the ID '{app:s}' is already installed", + "restore_already_installed_apps": "The following apps can't be restored because they are already installed: {apps}", "restore_app_failed": "Could not restore the app '{app:s}'", "restore_cleaning_failed": "Could not clean up the temporary restoration directory", "restore_complete": "Restored", diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 1948e795c..449b52bd8 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -1004,10 +1004,20 @@ class RestoreManager(): logger.error(m18n.n('backup_archive_app_not_found', app=app)) - self.targets.set_wanted("apps", - apps, - self.info['apps'].keys(), - unknown_error) + to_be_restored = self.targets.set_wanted("apps", + apps, + self.info['apps'].keys(), + unknown_error) + + # If all apps to restore are already installed, stop right here. + # Otherwise, if at least one app can be restored, we keep going on + # because those which can be restored will indeed be restored + already_installed = [app for app in to_be_restored if _is_installed(app)] + if already_installed != []: + if already_installed == to_be_restored: + raise YunohostError("restore_already_installed_apps", apps=', '.join(already_installed)) + else: + logger.warning(m18n.n("restore_already_installed_apps", apps=', '.join(already_installed))) # # Archive mounting # @@ -1301,13 +1311,6 @@ class RestoreManager(): else: shutil.copy2(s, d) - # Start register change on system - related_to = [('app', app_instance_name)] - operation_logger = OperationLogger('backup_restore_app', related_to) - operation_logger.start() - - logger.info(m18n.n("app_start_restore", app=app_instance_name)) - # Check if the app is not already installed if _is_installed(app_instance_name): logger.error(m18n.n('restore_already_installed_app', @@ -1315,6 +1318,13 @@ class RestoreManager(): self.targets.set_result("apps", app_instance_name, "Error") return + # Start register change on system + related_to = [('app', app_instance_name)] + operation_logger = OperationLogger('backup_restore_app', related_to) + operation_logger.start() + + logger.info(m18n.n("app_start_restore", app=app_instance_name)) + app_dir_in_archive = os.path.join(self.work_dir, 'apps', app_instance_name) app_backup_in_archive = os.path.join(app_dir_in_archive, 'backup') app_settings_in_archive = os.path.join(app_dir_in_archive, 'settings') diff --git a/src/yunohost/tests/test_backuprestore.py b/src/yunohost/tests/test_backuprestore.py index 790d27d6c..aa443f2a5 100644 --- a/src/yunohost/tests/test_backuprestore.py +++ b/src/yunohost/tests/test_backuprestore.py @@ -475,10 +475,9 @@ def test_restore_app_already_installed(mocker): assert _is_installed("wordpress") - with message(mocker, 'restore_already_installed_app', app="wordpress"): - with raiseYunohostError(mocker, 'restore_nothings_done'): - backup_restore(system=None, name=backup_list()["archives"][0], - apps=["wordpress"]) + with message(mocker, 'restore_already_installed_apps', apps="wordpress"): + backup_restore(system=None, name=backup_list()["archives"][0], + apps=["wordpress"]) assert _is_installed("wordpress")