Example #1
0
    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")
Example #2
0
    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")
Example #3
0
    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")
Example #4
0
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
Example #7
0
 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
Example #8
0
    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
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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)
Example #12
0
    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")
Example #16
0
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()
 def getImageDirectory():
     return ImageManager.instance().getDirectoryForType("QEMU")