def _setupCallback(self, result, error=False, **kwargs): """ Callback for setup. :param result: server response :param error: indicates an error (boolean) """ if not super()._setupCallback(result, error=error, **kwargs): return # create the ports on the client side self._addAdapters(self._settings.get("adapters", 0)) if self._loading: self.loaded_signal.emit() else: self.setInitialized(True) log.info("QEMU VM instance {} has been created".format(self.name())) self.created_signal.emit(self.id()) self._module.addNode(self) for image_field in ["hda_disk_image", "hdb_disk_image", "hdc_disk_image", "hdd_disk_image", "initrd", "kernel_image", "cdrom_image"]: if image_field in result and result[image_field] is not None and result[image_field] != "": # The image is missing on remote server field = "{}_md5sum".format(image_field) if field not in result or result[field] is None or len(result[field]) == 0: ImageManager.instance().addMissingImage(result[image_field], self._server, "QEMU")
def _setupCallback(self, result, error=False, **kwargs): """ Callback for setup. :param result: server response :param error: indicates an error (boolean) """ if not super()._setupCallback(result, error=error, **kwargs): return self._dynamips_id = result["dynamips_id"] # create the ports on the client side self._insertAdapters(self._settings) if self._loading: self.loaded_signal.emit() else: self.setInitialized(True) log.debug("router {} has been created".format(self.name())) self.created_signal.emit(self.id()) self._module.addNode(self) # The image is missing on remote server if "image_md5sum" not in result or result["image_md5sum"] is None or len(result["image_md5sum"]) == 0: ImageManager.instance().addMissingImage(result["image"], self._server, "DYNAMIPS")
def _setupCallback(self, result, error=False, **kwargs): """ Callback for setup. :param result: server response :param error: indicates an error (boolean) """ if not super()._setupCallback(result, error=error, **kwargs): return # create the ports on the client side self._addAdapters(self._settings.get("ethernet_adapters", 0), self._settings.get("serial_adapters", 0)) if self._loading: self.loaded_signal.emit() else: self.setInitialized(True) log.info("IOU instance {} has been created".format(self.name())) self.created_signal.emit(self.id()) self._module.addNode(self) # The image is missing on remote server if "md5sum" not in result or result["md5sum"] is None or len(result["md5sum"]) == 0: ImageManager.instance().addMissingImage(result["path"], self._server, "IOU")
def image_manager(tmpdir, images_dir): ImageManager._instance = None settings = LOCAL_SERVER_SETTINGS settings['images_path'] = str(images_dir) LocalServerConfig.instance().setConfigFile(str(tmpdir / "test.cfg")) with patch('gns3.local_server_config.LocalServerConfig.loadSettings', return_value=LOCAL_SERVER_SETTINGS): yield ImageManager.instance() ImageManager._instance = None
def getIOUImage(cls, parent, server): """ :param parent: parent widget :param server: The server where the image is located :return: path to the IOU image or None """ if not cls._default_images_dir: cls._default_images_dir = cls.getImageDirectory() path, _ = QtWidgets.QFileDialog.getOpenFileName(parent, "Select an IOU image", cls._default_images_dir, "All file (*);;IOU image (*.bin *.image)", "IOU image (*.bin *.image)") if not path: return cls._default_images_dir = os.path.dirname(path) if not os.access(path, os.R_OK): QtWidgets.QMessageBox.critical(parent, "IOU image", "Cannot read {}".format(path)) return try: with open(path, "rb") as f: # read the first 7 bytes of the file. elf_header_start = f.read(7) except OSError as e: QtWidgets.QMessageBox.critical(parent, "IOU image", "Cannot read ELF magic number: {}".format(e)) return # file must start with the ELF magic number, be 32-bit or 64-bit, little endian and have an ELF version of 1 # (normal IOS image are big endian!) if elf_header_start != b'\x7fELF\x01\x01\x01' and elf_header_start != b'\x7fELF\x02\x01\x01': QtWidgets.QMessageBox.critical(parent, "IOU image", "Sorry, this is not a valid IOU image!") return try: os.makedirs(cls.getImageDirectory(), exist_ok=True) except OSError as e: QtWidgets.QMessageBox.critical(parent, "IOU images directory", "Could not create the IOU images directory {}: {}".format(cls.getImageDirectory(), e)) return path = ImageManager.instance().askCopyUploadImage(parent, path, server, "IOU") if os.path.exists(path) and not os.access(path, os.X_OK): QtWidgets.QMessageBox.warning(parent, "IOU image", "{} is not executable".format(path)) return path
def getDiskImage(cls, parent, server): if not cls._default_images_dir: cls._default_images_dir = cls.getImageDirectory() path, _ = QtWidgets.QFileDialog.getOpenFileName(parent, "Select a QEMU disk image", cls._default_images_dir) if not path: return cls._default_images_dir = os.path.dirname(path) if not os.access(path, os.R_OK): QtWidgets.QMessageBox.critical(parent, "QEMU disk image", "Cannot read {}".format(path)) return path = ImageManager.instance().askCopyUploadImage(parent, path, server, "QEMU") return path
def getDefaultIdlePC(path): """ Return the default IDLE PC for an image if the image exists or None otherwise """ if not os.path.isfile(path): path = os.path.join(ImageManager.instance().getDirectoryForType("DYNAMIPS"), path) if not os.path.isfile(path): return None try: md5sum = Dynamips._md5sum(path) log.debug("Get idlePC for %s. md5sum %s", path, md5sum) if md5sum in DEFAULT_IDLEPC: log.debug("IDLEPC found for %s", path) return DEFAULT_IDLEPC[md5sum] except OSError: return None
def getDiskImage(cls, parent, server): if not cls._default_images_dir: cls._default_images_dir = cls.getImageDirectory() path, _ = QtWidgets.QFileDialog.getOpenFileName( parent, "Select a QEMU disk image", cls._default_images_dir) if not path: return cls._default_images_dir = os.path.dirname(path) if not os.access(path, os.R_OK): QtWidgets.QMessageBox.critical(parent, "QEMU disk image", "Cannot read {}".format(path)) return path = ImageManager.instance().askCopyUploadImage( parent, path, server, "QEMU") return path
def load(self, node_info): """ Loads a router representation (from a topology file). :param node_info: representation of the node (dictionary) """ # for backward compatibility vm_id = dynamips_id = node_info.get("router_id") if not vm_id: vm_id = node_info.get("vm_id") dynamips_id = node_info.get("dynamips_id") vm_settings = {} for name, value in node_info["properties"].items(): if name in self._settings: vm_settings[name] = value name = vm_settings.pop("name") ram = vm_settings.pop("ram", PLATFORMS_DEFAULT_RAM[self._settings["platform"]]) image = vm_settings.pop("image") if self.server().isLocal(): # check and update the path to use the image in the images directory updated_image_path = os.path.join(ImageManager.instance().getDirectoryForType("DYNAMIPS"), image) if os.path.isfile(updated_image_path): image = updated_image_path elif not os.path.isfile(image): alternative_image = self._module.findAlternativeIOSImage(image, self) image = alternative_image["image"] if alternative_image["ram"]: ram = alternative_image["ram"] if alternative_image["idlepc"]: vm_settings["idlepc"] = alternative_image["idlepc"] log.info("router {} is loading".format(name)) self.setName(name) self._loading = True self._node_info = node_info self.loaded_signal.connect(self._updatePortSettings) self.setup(image, ram, name, vm_id, dynamips_id, vm_settings)
def load(self, node_info): """ Loads a router representation (from a topology file). :param node_info: representation of the node (dictionary) """ # for backward compatibility vm_id = dynamips_id = node_info.get("router_id") if not vm_id: vm_id = node_info.get("vm_id") dynamips_id = node_info.get("dynamips_id") vm_settings = {} for name, value in node_info["properties"].items(): if name in self._settings: vm_settings[name] = value name = vm_settings.pop("name") ram = vm_settings.pop("ram", PLATFORMS_DEFAULT_RAM[self._settings["platform"]]) image = vm_settings.pop("image", "") if self.server().isLocal(): # check and update the path to use the image in the images directory updated_image_path = os.path.join(ImageManager.instance().getDirectoryForType("DYNAMIPS"), image) if os.path.isfile(updated_image_path): image = updated_image_path elif not os.path.isfile(image): alternative_image = self._module.findAlternativeIOSImage(image, self) image = alternative_image["image"] if alternative_image["ram"]: ram = alternative_image["ram"] if alternative_image["idlepc"]: vm_settings["idlepc"] = alternative_image["idlepc"] log.info("router {} is loading".format(name)) self.setName(name) self._loading = True self._node_info = node_info self.loaded_signal.connect(self._updatePortSettings) self.setup(image, ram, name, vm_id, dynamips_id, vm_settings)
def load(self, node_info): """ Loads an IOU device representation (from a topology file). :param node_info: representation of the node (dictionary) """ super().load(node_info) # for backward compatibility vm_id = node_info.get("iou_id") if not vm_id: vm_id = node_info.get("vm_id") vm_settings = {} for name, value in node_info["properties"].items(): if name in self._settings: vm_settings[name] = value name = vm_settings.pop("name") path = vm_settings.pop("path") if "initial_config" in vm_settings: # transfer initial-config (post version 1.4) to startup-config vm_settings["startup_config"] = vm_settings["initial_config"] if self.server().isLocal(): # check and update the path to use the image in the images directory updated_path = os.path.join( ImageManager.instance().getDirectoryForType("IOU"), path) if os.path.isfile(updated_path): path = updated_path elif not os.path.isfile(path): path = self._module.findAlternativeIOUImage(path) log.info("iou device {} is loading".format(name)) self.setName(name) self._loading = True self._node_info = node_info self.loaded_signal.connect(self._updatePortSettings) self.setup(path, name, vm_id, vm_settings)
def load(self, node_info): """ Loads an IOU device representation (from a topology file). :param node_info: representation of the node (dictionary) """ super().load(node_info) # for backward compatibility vm_id = node_info.get("iou_id") if not vm_id: vm_id = node_info.get("vm_id") vm_settings = {} for name, value in node_info["properties"].items(): if name in self._settings: vm_settings[name] = value name = vm_settings.pop("name") path = vm_settings.pop("path") if "initial_config" in vm_settings: # transfer initial-config (post version 1.4) to startup-config vm_settings["startup_config"] = vm_settings["initial_config"] if self.server().isLocal(): # check and update the path to use the image in the images directory updated_path = os.path.join(ImageManager.instance().getDirectoryForType("IOU"), path) if os.path.isfile(updated_path): path = updated_path elif not os.path.isfile(path): path = self._module.findAlternativeIOUImage(path) log.info("iou device {} is loading".format(name)) self.setName(name) self._loading = True self._node_info = node_info self.loaded_signal.connect(self._updatePortSettings) self.setup(path, name, vm_id, vm_settings)
def getImageDirectory(): return ImageManager.instance().getDirectoryForType("QEMU")
def getIOSImage(cls, parent, server): """ :param parent: parent widget :param server: The server where the image is located :return: path to the IOS image or None """ if not cls._default_images_dir: cls._default_images_dir = cls.getImageDirectory() path, _ = QtWidgets.QFileDialog.getOpenFileName(parent, "Select an IOS image", cls._default_images_dir, "All files (*.*);;IOS image (*.bin *.image)", "IOS image (*.bin *.image)") if not path: return cls._default_images_dir = os.path.dirname(path) if not os.access(path, os.R_OK): QtWidgets.QMessageBox.critical(parent, "IOS image", "Cannot read {}".format(path)) return if sys.platform.startswith('win'): # Dynamips (Cygwin actually) doesn't like non ascii paths on Windows try: path.encode('ascii') except UnicodeEncodeError: QtWidgets.QMessageBox.warning(parent, "IOS image", "The IOS image filename should contains only ascii (English) characters.") try: with open(path, "rb") as f: # read the first 7 bytes of the file. elf_header_start = f.read(7) except OSError as e: QtWidgets.QMessageBox.critical(parent, "IOS image", "Cannot read ELF magic number: {}".format(e)) return # file must start with the ELF magic number, be 32-bit, big endian and have an ELF version of 1 if elf_header_start != b'\x7fELF\x01\x02\x01': QtWidgets.QMessageBox.critical(parent, "IOS image", "Sorry, this is not a valid IOS image!") return try: os.makedirs(cls.getImageDirectory(), exist_ok=True) except OSError as e: QtWidgets.QMessageBox.critical(parent, "IOS images directory", "Could not create the IOS images directory {}: {}".format(cls.getImageDirectory(), e)) return compressed = False try: compressed = isIOSCompressed(path) except (OSError, ValueError): pass # ignore errors if we cannot find out the IOS image is compressed. if compressed: reply = QtWidgets.QMessageBox.question(parent, "IOS image", "Would you like to decompress this IOS image?", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes: decompressed_image_path = os.path.join(cls.getImageDirectory(), os.path.basename(os.path.splitext(path)[0] + ".image")) worker = DecompressIOSWorker(path, decompressed_image_path) progress_dialog = ProgressDialog(worker, "IOS image", "Decompressing IOS image {}...".format(os.path.basename(path)), "Cancel", busy=True, parent=parent) progress_dialog.show() if progress_dialog.exec_() is not False: path = decompressed_image_path path = ImageManager.instance().askCopyUploadImage(parent, path, server, "DYNAMIPS") return path
def getImageDirectory(): return ImageManager.instance().getDirectoryForType("DYNAMIPS")
def image_manager(tmpdir, images_dir): ImageManager._instance = None with patch('gns3.servers.Servers.localServerSettings', return_value={'images_path': str(images_dir)}): yield ImageManager.instance()