def invoke_package_manager_advanced()

in src/core/src/package_managers/ZypperPackageManager.py [0:0]


    def invoke_package_manager_advanced(self, command, raise_on_exception=True):
        """Get missing updates using the command input"""
        self.composite_logger.log_verbose("[ZPM] Invoking package manager. [Command={0}]".format(str(command)))
        repo_refresh_services_attempted = False

        for i in range(1, self.package_manager_max_retries + 1):
            self.set_lock_timeout_and_backup_original()
            code, out = self.env_layer.run_command_output(command, False, False)
            self.restore_original_lock_timeout()

            if code not in self.zypper_success_exit_codes:  # more known return codes should be added as appropriate
                # Refresh repo services if no repos are defined
                if code == self.zypper_exitcode_no_repos and command != self.repo_refresh_services and not repo_refresh_services_attempted:
                    self.composite_logger.log_warning("[ZPM] Warning: No repos defined on command: {0}".format(str(command)))
                    self.__refresh_repo_services()
                    repo_refresh_services_attempted = True
                    continue

                if code == self.zypper_exitcode_zypp_exit_err_commit:
                    # Run command again with --replacefiles to fix file conflicts
                    self.composite_logger.log_warning("[ZPM] Warning: Package conflict detected on command: {0}".format(str(command)))
                    modified_command = self.modify_upgrade_or_patch_command_to_replacefiles(command)
                    if modified_command is not None:
                        command = modified_command
                        self.composite_logger.log_debug("[ZPM] Retrying with modified command to replace files: {0}".format(str(command)))
                        continue

                self.log_errors_on_invoke(command, out, code)
                error_msg = 'Unexpected return code (' + str(code) + ') from package manager on command: ' + command
                self.status_handler.add_error_to_status(error_msg, Constants.PatchOperationErrorCodes.PACKAGE_MANAGER_FAILURE)

                # Not a retriable error code, so raise an exception
                if code not in self.zypper_retriable_exit_codes and raise_on_exception:
                    raise Exception(error_msg, "[{0}]".format(Constants.ERROR_ADDED_TO_STATUS))

                # Retriable error code, so check number of retries and wait then retry if applicable; otherwise, raise error after max retries
                if i < self.package_manager_max_retries:
                    self.composite_logger.log_warning("[ZPM] Exception on package manager invoke. [Exception={0}][RetryCount={1}]".format(error_msg, str(i)))
                    time.sleep(pow(2, i + 2))
                    continue
                else:
                    error_msg = "Unable to invoke package manager (retries exhausted) [{0}][RetryCount={1}]".format(error_msg, str(i))
                    self.status_handler.add_error_to_status(error_msg, Constants.PatchOperationErrorCodes.PACKAGE_MANAGER_FAILURE)
                    if raise_on_exception:
                        raise Exception(error_msg, "[{0}]".format(Constants.ERROR_ADDED_TO_STATUS))
            else:  # verbose diagnostic log
                self.log_success_on_invoke(code, out)

            self.__handle_zypper_updated_or_reboot_exit_codes(command, out, code)

            return out, code