def get_path(self, path=''): """ :param path: :return: """ if not path: host = self.resource_config.backup_location if ':' not in host: scheme = self.resource_config.backup_type if not scheme or scheme.lower( ) == self.DEFAULT_FILE_SYSTEM.lower(): scheme = self.file_system scheme = re.sub('(:|/+).*$', '', scheme, re.DOTALL) # todo: clarify and remove this line in networking-devices # host = re.sub('^/+', '', host) host = '{}://{}'.format(scheme, host) path = host url = UrlParser.parse_url(path) if url[UrlParser.SCHEME].lower() in AUTHORIZATION_REQUIRED_STORAGE: if UrlParser.USERNAME not in url or not url[UrlParser.USERNAME]: url[UrlParser.USERNAME] = self.resource_config.backup_user if UrlParser.PASSWORD not in url or not url[UrlParser.PASSWORD]: url[UrlParser.PASSWORD] = self.resource_config.backup_user try: result = UrlParser.build_url(url) except Exception as e: self._logger.error('Failed to build url: {}'.format(e)) raise Exception('ConfigurationOperations', 'Failed to build path url to remote host') return result
def execute_flow(self, path, vrf, timeout): """Load a firmware onto the device :param path: The path to the firmware file, including the firmware file name :param vrf: Virtual Routing and Forwarding Name :param timeout: :return: """ full_path_dict = UrlParser().parse_url(path) firmware_file_name = full_path_dict.get(UrlParser.FILENAME) if not firmware_file_name: raise Exception(self.__class__.__name__, "Unable to find firmware file") connection_dict = UrlParser.parse_url(path) if connection_dict.get(UrlParser.PATH).endswith("/"): file_path = connection_dict.get( UrlParser.PATH) + connection_dict.get(UrlParser.FILENAME) else: file_path = connection_dict.get( UrlParser.PATH) + "/" + connection_dict.get(UrlParser.FILENAME) with self._cli_handler.get_cli_service( self._cli_handler.enable_mode) as enable_session: system_action = self.SYSTEM_ACTIONS_CLASS(enable_session, self._logger) try: return system_action.load_firmware( protocol=connection_dict.get(UrlParser.SCHEME), host=connection_dict.get(UrlParser.HOSTNAME), file_path=file_path) except: raise
def execute_flow(self, folder_path, configuration_type, vrf_management_name=None): """Execute Save flow. :param folder_path: :param configuration_type: :param vrf_management_name: :return: """ url = UrlParser.parse_url(folder_path) config_file = url.get(UrlParser.FILENAME) with self._cli_handler.get_cli_service( self._cli_handler.config_mode) as config_session: save_actions = SaveRestoreActions(cli_service=config_session, logger=self._logger) save_actions.save_config_file(config_file=config_file) if "://" in folder_path: with config_session.enter_mode(self._cli_handler.enable_mode): save_actions.export_config_file( config_file=config_file, remote_url=folder_path, user=url.get(UrlParser.USERNAME), password=url.get(UrlParser.PASSWORD), ) save_actions.delete_config_file(config_file=config_file)
def execute_flow(self, path, vrf, timeout): """Load a firmware onto the device :param path: The path to the firmware file, including the firmware file name :param vrf: Virtual Routing and Forwarding Name :param timeout: :return: """ with self._cli_handler.get_cli_service( self._cli_handler.enable_mode) as session: restore_action = AireosRestoreActions(session, self._logger) url = UrlParser.parse_url(path) restore_action.restore_data_type(self.DATA_TYPE) restore_action.restore_mode(url.get(UrlParser.SCHEME)) restore_action.restore_user(url.get(UrlParser.USERNAME)) restore_action.restore_password(url.get(UrlParser.PASSWORD)) restore_action.restore_server_ip(url.get(UrlParser.HOSTNAME)) port = url.get(UrlParser.PORT) if port: restore_action.restore_server_port(url.get(UrlParser.PORT)) restore_action.restore_config_name(url.get(UrlParser.FILENAME)) url_path = url.get(UrlParser.PATH) if url_path and url_path.startswith("/"): url_path = url_path[1:] restore_action.restore_path(url.get(url_path)) restore_action.restore_start(timeout) restore_action.reload(timeout)
def execute_flow(self, folder_path, configuration_type, vrf_management_name=None): """ Execute flow which save selected file to the provided destination :param folder_path: destination path where file will be saved :param configuration_type: source file, which will be saved :param vrf_management_name: Virtual Routing and Forwarding Name :return: saved configuration file name """ if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: configuration_type = configuration_type.lower() + "-config" if configuration_type not in ["running-config", "startup-config"]: raise Exception(self.__class__.__name__, "Device doesn't support saving '{}' configuration type".format(configuration_type)) connection_dict = UrlParser.parse_url(folder_path) if connection_dict.get(UrlParser.PATH).endswith("/"): file_path = connection_dict.get(UrlParser.PATH) + connection_dict.get(UrlParser.FILENAME) else: file_path = connection_dict.get(UrlParser.PATH) + "/" + connection_dict.get(UrlParser.FILENAME) with self._cli_handler.get_cli_service(self._cli_handler.enable_mode) as enable_session: save_action = self.SAVE_RESTORE_ACTIONS_CLASS(enable_session, self._logger) save_action.save(config=configuration_type, protocol=connection_dict.get(UrlParser.SCHEME), host=connection_dict.get(UrlParser.HOSTNAME), file_path=file_path)
def execute_flow(self, path, configuration_type, restore_method, vrf_management_name): """ Execute flow which restore selected file to the provided destination :param path: the path to the configuration file, including the configuration file name :param restore_method: the restore method to use when restoring the configuration file. Possible Values are append and override :param configuration_type: the configuration type to restore. Possible values are startup and running :param vrf_management_name: Virtual Routing and Forwarding Name """ if "-config" not in configuration_type: configuration_type += "-config" with self._cli_handler.get_cli_service(self._cli_handler.enable_mode) as session: restore_action = AireosRestoreActions(session, self._logger) url = UrlParser.parse_url(path) restore_action.restore_data_type(self.DATA_TYPE) restore_action.restore_mode(url.get(UrlParser.SCHEME)) restore_action.restore_user(url.get(UrlParser.USERNAME)) restore_action.restore_password(url.get(UrlParser.PASSWORD)) restore_action.restore_server_ip(url.get(UrlParser.HOSTNAME)) port = url.get(UrlParser.PORT) if port: restore_action.restore_server_port(url.get(UrlParser.PORT)) restore_action.restore_config_name(url.get(UrlParser.FILENAME)) url_path = url.get(UrlParser.PATH) if url_path and url_path.startswith("/"): url_path = url_path[1:] restore_action.restore_path(url_path) restore_action.restore_start()
def execute_flow(self, path, vrf, timeout): """Load a firmware onto the device :param path: The path to the firmware file, including the firmware file name :param vrf: Virtual Routing and Forwarding Name :param timeout: :return: """ full_path_dict = UrlParser().parse_url(path) firmware_file_name = full_path_dict.get(UrlParser.FILENAME) if not firmware_file_name: raise Exception(self.__class__.__name__, "Unable to find firmware file") with self._cli_handler.get_cli_service( self._cli_handler.enable_mode) as enable_session: system_action = SystemActions(enable_session, self._logger) iface_action = IFaceActions(enable_session, self._logger) system_action.copy(path, "flash:/") current_boot_settings = system_action.get_current_boot_config() current_boot_settings = re.sub("boot-start-marker|boot-end-marker", "", current_boot_settings) iface_action.clean_interface_switchport_config( current_boot_settings) with enable_session.enter_mode( self._cli_handler.config_mode) as config_session: firmware_action = FirmwareActions(config_session, self._logger) firmware_action.install_firmware(firmware_file_name) output = system_action.get_current_boot_config() if output.find(firmware_file_name) == -1: raise Exception( self.__class__.__name__, "Can't add firmware '{}' for boot!".format( firmware_file_name)) system_action.copy("running-config", "startup-config") system_action.reload_device(timeout) os_version = system_action.get_current_os_version() if os_version.find(firmware_file_name) == -1: raise Exception(self.__class__.__name__, "Failed to load firmware, Please check logs")
def _get_dst_path(bof_source, path): """Create file path on the remote resource. :param str bof_source: "cf1:", "cf3:" etc :param str path: ftp://ftp_host/file_name, etc """ file_name = UrlParser.parse_url(path)[UrlParser.FILENAME] return '{}\\{}'.format(bof_source, file_name)
def execute_flow(self, folder_path, configuration_type, vrf_management_name=None): """ Execute flow which save selected file to the provided destination :param folder_path: destination path where file will be saved :param configuration_type: source file, which will be saved :param vrf_management_name: Virtual Routing and Forwarding Name :return: saved configuration file name """ if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: configuration_type = configuration_type.lower() + "-config" if configuration_type not in ["running-config", "startup-config"]: raise Exception(self.__class__.__name__, "Device doesn't support saving '{}' configuration type".format(configuration_type)) url = UrlParser().parse_url(folder_path) with self._cli_handler.get_cli_service(self._cli_handler.enable_mode) as enable_session: system_action = SystemActions(enable_session, self._logger) save_action = SaveRestoreActions(enable_session, self._logger) if configuration_type == "running-config": # src_file = "{file_system}:/qualirunconfig.cfg".format(file_system=self.FILE_SYSTEM) src_file = "quali_run_config.cfg" save_action.save_runninig_config(dst_file=src_file) else: startup_config = system_action.display_startup_config() src_file = save_action.get_startup_config_filename(startup_config=startup_config) scheme = url.get(UrlParser.SCHEME).lower() if (not scheme or scheme == self.FILE_SYSTEM) and src_file != folder_path: save_action.copy_file(src_file=src_file, dst_file=folder_path) elif scheme in ["ftp", "tftp"]: save_action.put_file(server_address=url.get(UrlParser.HOSTNAME), src_file=src_file, dst_file=url.get(UrlParser.FILENAME)) else: raise Exception("Unsupported backup protocol {scheme}. " "Supported types are ftp, tftp of local({file_system})".format(scheme=scheme, file_system=self.FILE_SYSTEM))
def execute_flow(self, path, vrf, timeout): """Execute load firmware flow. :param path: :param vrf: :param timeout: :return: """ url = UrlParser.parse_url(path) file_name = self._get_firmware_file_name(path) with self._cli_handler.get_cli_service( self._cli_handler.sw_upgrade_config_mode) as config_session: commit_actions = CommitActions(cli_service=config_session, logger=self._logger) firmware_actions = FirmwareActions(cli_service=config_session, logger=self._logger) try: firmware_actions.set_remote_firmware_file(remote_url=path) firmware_actions.set_remote_firmware_user( user=url.get(UrlParser.USERNAME)) firmware_actions.set_remote_firmware_password( password=url.get(UrlParser.PASSWORD)) commit_actions.commit() except CommandExecutionException: self._logger.exception("Failed to set remote firmware file:") commit_actions.abort() raise firmware_actions.start_sw_upgrade() self._wait_for_image_validation(firmware_actions, file_name) boot_bank = firmware_actions.get_sw_upgrade_file_boot_bank( file_name=file_name) boot_bank = self._convert_boot_bank(boot_bank=boot_bank) try: firmware_actions.set_remote_firmware_boot_bank( boot_bank=boot_bank) commit_actions.commit() except CommandExecutionException: self._logger.exception( "Failed to set remote firmware file boot bank:") commit_actions.abort() raise try: self._logger.info("Rebooting device...") firmware_actions.system_reboot() except Exception: self._logger.debug("Reboot session exception:", exc_info=True) self._logger.info("Reconnecting session...") config_session.reconnect(timeout)
def _get_dst_path(self, src, old_config_path): match = re.search(r'cf\d+:[\\/]', old_config_path) try: file_system = match.group() except AttributeError: file_system = self.DEFAULT_FILESYSTEM file_name = UrlParser.parse_url(src).get(UrlParser.FILENAME) return file_system + file_name
def get_path(self, path=''): """ Validate incoming path, if path is empty, build it from resource attributes, If path is invalid - raise exception :param path: path to remote file storage :return: valid path or :raise Exception: """ if not path: host = self.resource_config.backup_location if ':' not in host: scheme = self.resource_config.backup_type if not scheme or scheme.lower( ) == self.DEFAULT_FILE_SYSTEM.lower(): scheme = self.file_system scheme = re.sub('(:|/+).*$', '', scheme, re.DOTALL) host = re.sub('^/+', '', host) host = '{}://{}'.format(scheme, host) path = host url = UrlParser.parse_url(path) if url[UrlParser.SCHEME].lower() in AUTHORIZATION_REQUIRED_STORAGE: if UrlParser.USERNAME not in url or not url[UrlParser.USERNAME]: url[UrlParser.USERNAME] = self.resource_config.backup_user if UrlParser.PASSWORD not in url or not url[UrlParser.PASSWORD]: url[UrlParser.PASSWORD] = self._api.DecryptPassword( self.resource_config.backup_password).Value try: result = UrlParser.build_url(url) except Exception as e: self._logger.error('Failed to build url: {}'.format(e)) raise Exception('ConfigurationOperations', 'Failed to build path url to remote host') return result
def prepare_action_map(source_file, destination_file): action_map = OrderedDict() if "://" in destination_file: url = UrlParser.parse_url(destination_file) dst_file_name = url.get(UrlParser.FILENAME) source_file_name = UrlParser.parse_url(source_file).get( UrlParser.FILENAME) action_map[r"[\[\(].*{}[\)\]]".format( dst_file_name)] = lambda session, logger: session.send_line( "", logger) action_map[r"[\[\(]{}[\)\]]".format( source_file_name)] = lambda session, logger: session.send_line( "", logger) else: destination_file_name = UrlParser.parse_url(destination_file).get( UrlParser.FILENAME) url = UrlParser.parse_url(source_file) source_file_name = url.get(UrlParser.FILENAME) action_map[r"(?!/)[\[\(]{}[\)\]]".format( destination_file_name )] = lambda session, logger: session.send_line("", logger) action_map[r"(?!/)[\[\(]{}[\)\]]".format( source_file_name)] = lambda session, logger: session.send_line( "", logger) host = url.get(UrlParser.HOSTNAME) if host: action_map[r"(?!/){}(?!/)".format( host)] = lambda session, logger: session.send_line("", logger) password = url.get(UrlParser.PASSWORD) if password: action_map[r"[Pp]assword:".format( source_file)] = lambda session, logger: session.send_line( password, logger) return action_map
def load_firmware(self, path, vrf_management_name=None): """Update firmware version on device by loading provided image, performs following steps: 1. Copy bin file from remote tftp server. 2. Clear in run config boot system section. 3. Set downloaded bin file as boot file and then reboot device. 4. Check if firmware was successfully installed. :param path: full path to firmware file on ftp/tftp location :param vrf_management_name: VRF Name :return: status / exception """ url = UrlParser.parse_url(path) required_keys = [UrlParser.FILENAME, UrlParser.HOSTNAME, UrlParser.SCHEME] if not url or not all(key in url for key in required_keys): raise Exception(self.__class__.__name__, "Path is wrong or empty") self.load_firmware_flow.execute_flow(path, vrf_management_name, self._timeout)
def _prepare_params_file_path(dst_path): url_dict = UrlParser.parse_url(dst_path) file_path = ('{}/{}'.format(url_dict[UrlParser.PATH], url_dict[UrlParser.FILENAME])).strip('/') params = { url_dict[UrlParser.SCHEME.lower()]: '', 'file_name': url_dict[UrlParser.FILENAME], 'file_path': file_path, 'host': url_dict[UrlParser.HOSTNAME], 'port': url_dict[UrlParser.PORT], 'user': url_dict[UrlParser.USERNAME], 'password': url_dict[UrlParser.PASSWORD], } if 'flash' in params and not params['file_name']: params['file_name'] = params['host'] return dict(filter(lambda (k, v): v is not None, params.items()))
def execute_flow(self, path, configuration_type, restore_method, vrf_management_name=None): """ Execute flow which save selected file to the provided destination :param path: the path to the configuration file, including the configuration file name :param restore_method: the restore method to use when restoring the configuration file. Possible Values are append and override :param configuration_type: the configuration type to restore. Possible values are startup and running :param vrf_management_name: Virtual Routing and Forwarding Name """ if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: configuration_type = configuration_type.lower() + "-config" if configuration_type not in ["running-config", "startup-config"]: raise Exception(self.__class__.__name__, "Device doesn't support restoring '{}' configuration type".format(configuration_type)) if not restore_method: restore_method = "override" url = UrlParser().parse_url(path) with self._cli_handler.get_cli_service(self._cli_handler.enable_mode) as enable_session: system_action = SystemActions(enable_session, self._logger) restore_action = SaveRestoreActions(enable_session, self._logger) if restore_method == "override": dst_file = "{file_system}:/{file_name}".format(file_system=self.FILE_SYSTEM, file_name=url.get(UrlParser.FILENAME)) scheme = url.get(UrlParser.SCHEME).lower() if not scheme or scheme == self.FILE_SYSTEM: restore_action.setup_startup_config(path) elif scheme in ["ftp", "tftp"]: restore_action.get_file(server_address=url.get(UrlParser.HOSTNAME), src_file="{path}/{file}".format(path=url.get(UrlParser.PATH).rstrip("/"), file=url.get(UrlParser.FILENAME)), dst_file=dst_file) restore_action.setup_startup_config(dst_file) if configuration_type == "running-config": system_action.reboot() else: raise Exception("Huawei do no yet support append operations on configuration files")
def execute_flow(self, path, configuration_type, restore_method, vrf_management_name=None): url = UrlParser.parse_url(path) config_file = url.get(UrlParser.FILENAME) with self._cli_handler.get_cli_service( self._cli_handler.config_mode) as config_session: restore_actions = SaveRestoreActions(cli_service=config_session, logger=self._logger) if "://" in path: with config_session.enter_mode(self._cli_handler.enable_mode): restore_actions.import_config_file( config_file=config_file, remote_url=path, user=url.get(UrlParser.USERNAME), password=url.get(UrlParser.PASSWORD), ) restore_actions.load_config_file(config_file=config_file)
def execute_flow(self, path, vrf, timeout): """Load a firmware onto the device :param path: The path to the firmware file, including the firmware file name :param vrf: Virtual Routing and Forwarding Name :param timeout: :return: """ full_path_dict = UrlParser().parse_url(path) firmware_file_name = full_path_dict.get(UrlParser.FILENAME) if not firmware_file_name: raise Exception(self.__class__.__name__, "Unable to find firmware file") with self._cli_handler.get_cli_service( self._cli_handler.enable_mode) as enable_session: system_action = SystemActions(enable_session, self._logger) dst_file_system = self._file_system firmware_dst_path = "{0}/{1}".format(dst_file_system, firmware_file_name) device_file_system = system_action.get_flash_folders_list() self._logger.info( "Discovered folders: {}".format(device_file_system)) if device_file_system: device_file_system.sort() for flash in device_file_system: if flash in self.BOOTFOLDER: self._logger.info( "Device has a {} folder".format(flash)) firmware_dst_path = "{0}/{1}".format( flash, firmware_file_name) self._logger.info( "Copying {} image".format(firmware_dst_path)) system_action.copy( path, firmware_dst_path, vrf=vrf, action_map=system_action.prepare_action_map( path, firmware_dst_path)) break if "flash-" in flash: firmware_dst_file_path = "{0}/{1}".format( flash, firmware_file_name) self._logger.info( "Copying {} image".format(firmware_dst_file_path)) system_action.copy( path, firmware_dst_file_path, vrf=vrf, action_map=system_action.prepare_action_map( path, firmware_dst_file_path)) else: self._logger.info("Copying {} image".format(firmware_dst_path)) system_action.copy(path, firmware_dst_path, vrf=vrf, action_map=system_action.prepare_action_map( path, firmware_dst_path)) self._logger.info("Get current boot configuration") current_boot = system_action.get_current_boot_image() self._logger.info("Modifying boot configuration") self._apply_firmware(enable_session, current_boot, firmware_dst_path) output = system_action.get_current_boot_config() new_boot_settings = re.sub( "^.*boot-start-marker|boot-end-marker.*", "", output) self._logger.info( "Boot config lines updated: {0}".format(new_boot_settings)) if output.find(firmware_file_name) == -1: raise Exception( self.__class__.__name__, "Can't add firmware '{}' for boot!".format( firmware_file_name)) system_action.copy(self.RUNNING_CONFIG, self.STARTUP_CONFIG, vrf=vrf, action_map=system_action.prepare_action_map( self.RUNNING_CONFIG, self.STARTUP_CONFIG)) if "CONSOLE" in enable_session.session.SESSION_TYPE: system_action.reload_device_via_console(timeout) else: system_action.reload_device(timeout) os_version = system_action.get_current_os_version() if os_version.find(firmware_file_name) == -1: raise Exception(self.__class__.__name__, "Failed to load firmware, Please check logs")
def execute_flow(self, path, configuration_type, restore_method, vrf_management_name=None): """ Execute flow which save selected file to the provided destination :param path: the path to the configuration file, including the configuration file name :param restore_method: the restore method to use when restoring the configuration file. Possible Values are append and override :param configuration_type: the configuration type to restore. Possible values are startup and running :param vrf_management_name: Virtual Routing and Forwarding Name """ _is_need_reload = False overwrite = False if not restore_method: restore_method = "override" if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: configuration_type = configuration_type.lower() + "-config" if configuration_type not in ["running-config", "startup-config"]: raise Exception( self.__class__.__name__, "Device doesn't support restoring '{}' configuration type". format(configuration_type)) connection_dict = UrlParser.parse_url(path) if connection_dict.get(UrlParser.PATH).endswith("/"): file_path = connection_dict.get( UrlParser.PATH) + connection_dict.get(UrlParser.FILENAME) else: file_path = connection_dict.get( UrlParser.PATH) + "/" + connection_dict.get(UrlParser.FILENAME) if configuration_type == "startup-config" and restore_method.lower( ) == "append": raise Exception( self.__class__.__name__, "Device doesn't support restoring '{0}' configuration type with '{1}' method" .format(configuration_type, restore_method)) elif configuration_type == "running-config" and restore_method.lower( ) == "override": if self._cli_handler.cli_type.lower() == "console": overwrite = True else: _is_need_reload = True configuration_type = "startup-config" with self._cli_handler.get_cli_service( self._cli_handler.enable_mode) as enable_session: restore_action = self.SAVE_RESTORE_ACTIONS_CLASS( enable_session, self._logger) system_action = SystemActions(enable_session, self._logger) restore_action.restore( config=configuration_type, protocol=connection_dict.get(UrlParser.SCHEME), host=connection_dict.get(UrlParser.HOSTNAME), file_path=file_path, overwrite=overwrite) if _is_need_reload: system_action.reboot()
def execute_flow(self, path, vrf, timeout): """Load a firmware onto the device :param path: The path to the firmware file, including the firmware file name :param vrf: Virtual Routing and Forwarding Name :param timeout: :return: """ success = False full_path_dict = UrlParser().parse_url(path) firmware_file_name = full_path_dict.get(UrlParser.FILENAME) password = full_path_dict.get(UrlParser.PASSWORD) remote_path = path.replace("{}".format(firmware_file_name), "").rstrip("/") if vrf and vrf not in remote_path: remote_path = remote_path.replace("{}".format(full_path_dict.get(UrlParser.HOSTNAME)), "{};{}".format(full_path_dict.get(UrlParser.HOSTNAME), vrf)) with self._cli_handler.get_cli_service(self._cli_handler.enable_mode) as enable_session: admin_actions = CiscoIOSXRAdminSystemActions(enable_session, self._logger) try: admin_actions.show_install_repository() remote_path = remote_path.replace(":{}".format(password), "") except: self._sync = "" self._is_old_iosxr = True self._cmd_admin_prefix = "" output = self._install_add_source(admin_actions=admin_actions, remote_path=remote_path, firmware_file_name=firmware_file_name, password=password) pkgs_for_install = self._filter_packages_for_install(admin_actions=admin_actions, output=output) if not pkgs_for_install: self._logger.info(admin_actions.prepare_output(self._result_dict)) raise Exception("Failed to load firmware: No new packages available to be installed (activated).") activate_output = admin_actions.install_activate(pkgs_for_install, admin=self._cmd_admin_prefix) if re.search(r"install operation \S+ continue asynchronously", activate_output, re.IGNORECASE) or not self._is_old_iosxr: operation_id = self._get_operation_id(activate_output) admin_actions.show_install_request(operation_id) admin_actions.retrieve_install_log(operation_id) commit_output = admin_actions.install_commit(admin=self._cmd_admin_prefix) if not self._is_old_iosxr: operation_id = self._get_operation_id(commit_output) admin_actions.show_install_request(operation_id) admin_actions.retrieve_install_log(operation_id) active_pkgs = admin_actions.show_install_active() for pkg in pkgs_for_install: package_name = re.sub("^.*:|.x86_64$", "", pkg) if package_name not in active_pkgs: self._result_dict[package_name] = "Failed to install package, please see logs for details." else: success = True self._result_dict[package_name] = "Package was successfully installed!" if not success: self._logger.error("Failed to load firmware.") raise Exception("Failed to load firmware. Please check logs for details.") self._logger.info(admin_actions.prepare_output(self._result_dict)) return admin_actions.prepare_output(self._result_dict)