예제 #1
0
    def done(self, result):
        """
        This dialog is closed.

        :param result: ignored
        """

        Controller.instance().setDisplayError(True)
        settings = self.parentWidget().settings()
        if result:
            reply = QtWidgets.QMessageBox.question(
                self, "Wizard",
                "Do you want to run the wizard again when starting GNS3?",
                QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
            if reply == QtWidgets.QMessageBox.Yes:
                settings["hide_setup_wizard"] = False
            elif reply == QtWidgets.QMessageBox.No:
                settings["hide_setup_wizard"] = True
        else:
            local_server_settings = LocalServer.instance().localServerSettings(
            )
            if local_server_settings["host"] is None:
                local_server_settings["host"] = DEFAULT_LOCAL_SERVER_HOST
                LocalServer.instance().updateLocalServerSettings(
                    local_server_settings)
            settings["hide_setup_wizard"] = self.uiShowCheckBox.isChecked()

        self.parentWidget().setSettings(settings)
        super().done(result)
예제 #2
0
def test_killAlreadyRunningServer(local_server):
    with open(local_server._pid_path(), "w+") as f:
        f.write("42")

    mock_process = MagicMock()
    with patch("psutil.Process", return_value=mock_process) as mock:
        LocalServer.instance()._killAlreadyRunningServer()
        mock.assert_called_with(pid=42)
        assert mock_process.kill.called
예제 #3
0
def test_killAlreadyRunningServer(local_server):
    with open(local_server._pid_path(), "w+") as f:
        f.write("42")

    mock_process = MagicMock()
    with patch("psutil.Process", return_value=mock_process) as mock:
        LocalServer.instance()._killAlreadyRunningServer()
        mock.assert_called_with(pid=42)
        assert mock_process.kill.called
    def savePreferences(self):
        """
        Saves the general preferences.
        """

        additional_images_paths = set()
        for i in range(0, self.uiImageDirectoriesListWidget.count()):
            item = self.uiImageDirectoriesListWidget.item(i)
            additional_images_paths.add(item.text())

        new_local_server_settings = {"images_path": self.uiImagesPathLineEdit.text(),
                                     "projects_path": self.uiProjectsPathLineEdit.text(),
                                     "symbols_path": self.uiSymbolsPathLineEdit.text(),
                                     "configs_path": self.uiConfigsPathLineEdit.text(),
                                     "appliances_path": self.uiAppliancesPathLineEdit.text(),
                                     "report_errors": self.uiCrashReportCheckBox.isChecked(),
                                     "additional_images_paths": ":".join(additional_images_paths)}
        LocalServer.instance().updateLocalServerSettings(new_local_server_settings)

        new_general_settings = {
            "style": self.uiStyleComboBox.currentText(),
            "symbol_theme": self.uiSymbolThemeComboBox.currentText(),
            "experimental_features": self.uiExperimentalFeaturesCheckBox.isChecked(),
            "hdpi": self.uiHdpiCheckBox.isChecked(),
            "check_for_update": self.uiCheckForUpdateCheckBox.isChecked(),
            "overlay_notifications": self.uiOverlayNotificationsCheckBox.isChecked(),
            "telnet_console_command": self.uiTelnetConsoleCommandLineEdit.text(),
            "vnc_console_command": self.uiVNCConsoleCommandLineEdit.text(),
            "spice_console_command": self.uiSPICEConsoleCommandLineEdit.text(),
            "delay_console_all": self.uiDelayConsoleAllSpinBox.value(),
            "send_stats": self.uiStatsCheckBox.isChecked(),
            "multi_profiles": self.uiMultiProfilesCheckBox.isChecked(),
            "direct_file_upload": self.uiDirectFileUpload.isChecked()
        }

        from ..main_window import MainWindow
        MainWindow.instance().setSettings(new_general_settings)

        new_graphics_view_settings = {"scene_width": self.uiSceneWidthSpinBox.value(),
                                      "scene_height": self.uiSceneHeightSpinBox.value(),
                                      "grid_size": self.uiNodeGridSizeSpinBox.value(),
                                      "drawing_grid_size": self.uiDrawingGridSizeSpinBox.value(),
                                      "draw_rectangle_selected_item": self.uiRectangleSelectedItemCheckBox.isChecked(),
                                      "draw_link_status_points": self.uiDrawLinkStatusPointsCheckBox.isChecked(),
                                      "show_interface_labels_on_new_project": self.uiShowInterfaceLabelsOnNewProject.isChecked(),
                                      "limit_size_node_symbols": self.uiLimitSizeNodeSymbolCheckBox.isChecked(),
                                      "show_grid_on_new_project": self.uiShowGridOnNewProject.isChecked(),
                                      "snap_to_grid_on_new_project": self.uiSnapToGridOnNewProject.isChecked(),
                                      "default_label_font": self.uiDefaultLabelStylePlainTextEdit.font().toString(),
                                      "default_label_color": self._default_label_color.name(),
                                      "default_note_font": self.uiDefaultNoteStylePlainTextEdit.font().toString(),
                                      "default_note_color": self._default_note_color.name()}
        MainWindow.instance().uiGraphicsView.setSettings(new_graphics_view_settings)
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        self._widget_slots = {0: self.uiSlot0comboBox,
                              1: self.uiSlot1comboBox,
                              2: self.uiSlot2comboBox,
                              3: self.uiSlot3comboBox,
                              4: self.uiSlot4comboBox,
                              5: self.uiSlot5comboBox,
                              6: self.uiSlot6comboBox}

        self._widget_wics = {0: self.uiWic0comboBox,
                             1: self.uiWic1comboBox,
                             2: self.uiWic2comboBox}

        self.uiStartupConfigToolButton.clicked.connect(self._startupConfigBrowserSlot)
        self.uiPrivateConfigToolButton.clicked.connect(self._privateConfigBrowserSlot)
        self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot)
        self.uiIOSImageToolButton.clicked.connect(self._iosImageBrowserSlot)
        self._compute_id = None
        self._idle_valid = False
        idle_pc_rgx = QtCore.QRegExp("^(0x[0-9a-fA-F]{8})?$")
        validator = QtGui.QRegExpValidator(idle_pc_rgx, self)
        self.uiIdlepcLineEdit.setValidator(validator)
        self.uiIdlepcLineEdit.textChanged.connect(self._idlePCValidateSlot)
        self.uiIdlepcLineEdit.textChanged.emit(self.uiIdlepcLineEdit.text())
        self._default_configs_dir = LocalServer.instance().localServerSettings()["configs_path"]

        # add the categories
        for name, category in Node.defaultCategories().items():
            self.uiCategoryComboBox.addItem(name, category)
예제 #6
0
 def _configFileValid(self, path):
     """
     Return true if it's a valid configuration file
     """
     if not os.path.isabs(path):
         path = os.path.join(LocalServer.instance().localServerSettings()["configs_path"], path)
     return os.access(path, os.R_OK)
예제 #7
0
 def _configFileValid(self, path):
     """
     Return true if it's a valid configuration file
     """
     if not os.path.isabs(path):
         path = os.path.join(LocalServer.instance().localServerSettings()["configs_path"], path)
     return os.access(path, os.R_OK)
예제 #8
0
    def checkUbridgePermission(self):
        """Check if ubridge has the correct permission"""
        if not sys.platform.startswith("win") and os.geteuid() == 0:
            # we are root, so we should have privileged access.
            return (0, None)

        path = LocalServer.instance().localServerSettings().get("ubridge_path")
        if path is None:
            return (0, None)
        if not os.path.exists(path):
            return (2, "Ubridge path {path} doesn't exists".format(path=path))

        request_setuid = False
        if sys.platform.startswith("linux"):
            try:
                if "security.capability" in os.listxattr(path):
                    caps = os.getxattr(path, "security.capability")
                    # test the 2nd byte and check if the 13th bit (CAP_NET_RAW) is set
                    if not struct.unpack("<IIIII", caps)[1] & 1 << 13:
                        return (2, "Ubridge requires CAP_NET_RAW. Run sudo setcap cap_net_admin,cap_net_raw=ep {path}".format(path=path))
                else:
                    # capabilities not supported
                    request_setuid = True
            except AttributeError:
                # Due to a Python bug, os.listxattr could be missing: https://github.com/GNS3/gns3-gui/issues/2010
                return (1, "Could not determine if CAP_NET_RAW capability is set for uBridge (Python bug)".format(path=path))

        if sys.platform.startswith("darwin") or request_setuid:
            if os.stat(path).st_uid != 0 or not os.stat(path).st_mode & stat.S_ISUID:
                return (2, "Ubridge should be setuid. Run sudo chown root:admin {path} and sudo chmod 4750 {path}".format(path=path))
        return (0, None)
예제 #9
0
    def checkDynamipsPermission(self):
        """Check if dynamips has the correct permission"""
        if not sys.platform.startswith("win") and os.geteuid() == 0:
            # we are root, so we should have privileged access.
            return (0, None)

        path = LocalServer.instance().localServerSettings().get(
            "dynamips_path")
        if path is None:
            return (0, None)
        if not os.path.exists(path):
            return (2, "Dynamips path {path} doesn't exists".format(path=path))

        try:
            if sys.platform.startswith(
                    "linux") and "security.capability" in os.listxattr(path):
                caps = os.getxattr(path, "security.capability")
                # test the 2nd byte and check if the 13th bit (CAP_NET_RAW) is set
                if not struct.unpack("<IIIII", caps)[1] & 1 << 13:
                    return (
                        2,
                        "Dynamips requires CAP_NET_RAW. Run sudo setcap cap_net_raw,cap_net_admin+eip {path}"
                        .format(path=path))
        except AttributeError:
            # Due to a Python bug, os.listxattr could be missing: https://github.com/GNS3/gns3-gui/issues/2010
            return (
                1,
                "Could not determine if CAP_NET_RAW capability is set for Dynamips (Python bug)"
                .format(path=path))
        return (0, None)
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot)
        self.uiStartupConfigToolButton.clicked.connect(
            self._startupConfigBrowserSlot)
        self.uiPrivateConfigToolButton.clicked.connect(
            self._privateConfigBrowserSlot)
        self.uiIOUImageToolButton.clicked.connect(self._iouImageBrowserSlot)
        self.uiDefaultValuesCheckBox.stateChanged.connect(
            self._useDefaultValuesSlot)
        self._current_iou_image = ""
        self._compute_id = None

        # location of the base config templates
        self._base_iou_l2_config_template = get_resource(
            os.path.join("configs", "iou_l2_base_startup-config.txt"))
        self._base_iou_l3_config_template = get_resource(
            os.path.join("configs", "iou_l3_base_startup-config.txt"))
        self._default_configs_dir = LocalServer.instance().localServerSettings(
        )["configs_path"]

        # add the categories
        for name, category in Node.defaultCategories().items():
            self.uiCategoryComboBox.addItem(name, category)
예제 #11
0
파일: node.py 프로젝트: maherja/gns3-gui
    def _readBaseConfig(self, config_path):
        """
        Returns a base config content.

        :param config_path: path to the configuration file.

        :returns: config content
        """

        if config_path is None or len(config_path.strip()) == 0:
            return None

        if not os.path.isabs(config_path):
            config_path = os.path.join(LocalServer.instance().localServerSettings()["configs_path"], config_path)

        if not os.path.isfile(config_path):
            return None

        try:
            with open(config_path, "rb") as f:
                log.info("Opening configuration file: {}".format(config_path))
                config = f.read().decode("utf-8")
                config = config.replace('\r', "")
                return config
        except OSError as e:
            self.error_signal.emit(self.id(), "Could not read configuration file {}: {}".format(config_path, e))
            return None
        except UnicodeDecodeError as e:
            self.error_signal.emit(self.id(), "Invalid configuration file {}: {}".format(config_path, e))
            return None
예제 #12
0
def test_startLocalServer(tmpdir, local_server, local_server_path):
    logging.getLogger().setLevel(logging.DEBUG)  # Make sure we are using debug level in order to get the --debug

    process_mock = MagicMock()
    with patch("subprocess.Popen", return_value=process_mock) as mock:

        # If everything work fine the command is still running and a timeout is raised
        process_mock.communicate.side_effect = subprocess.TimeoutExpired("test", 1)

        LocalServer.instance().startLocalServer()
        mock.assert_called_with([unittest.mock.ANY,
                                 '--local',
                                 '--debug',
                                 '--log=' + str(tmpdir / "gns3_server.log"),
                                 '--pid=' + str(tmpdir / "gns3_server.pid")
                                 ], stderr=unittest.mock.ANY)
예제 #13
0
    def _populateGeneralSettingWidgets(self, settings):
        """
        Populates the widgets with the settings.

        :param settings: General settings
        """

        local_server = LocalServer.instance().localServerSettings()
        self.uiProjectsPathLineEdit.setText(local_server["projects_path"])
        self.uiSymbolsPathLineEdit.setText(local_server["symbols_path"])
        self.uiImagesPathLineEdit.setText(local_server["images_path"])
        self.uiConfigsPathLineEdit.setText(local_server["configs_path"])
        self.uiStatsCheckBox.setChecked(settings["send_stats"])
        self.uiCrashReportCheckBox.setChecked(local_server["report_errors"])
        self.uiCheckForUpdateCheckBox.setChecked(settings["check_for_update"])
        self.uiExperimentalFeaturesCheckBox.setChecked(settings["experimental_features"])
        self.uiHdpiCheckBox.setChecked(settings["hdpi"])
        self.uiTelnetConsoleCommandLineEdit.setText(settings["telnet_console_command"])
        self.uiTelnetConsoleCommandLineEdit.setCursorPosition(0)
        index = self.uiStyleComboBox.findText(settings["style"])
        if index != -1:
            self.uiStyleComboBox.setCurrentIndex(index)
        self.uiDelayConsoleAllSpinBox.setValue(settings["delay_console_all"])

        self.uiVNCConsoleCommandLineEdit.setText(settings["vnc_console_command"])
        self.uiVNCConsoleCommandLineEdit.setCursorPosition(0)

        self.uiMultiProfilesCheckBox.setChecked(settings["multi_profiles"])

        self.uiImageDirectoriesListWidget.clear()
        for path in local_server["additional_images_paths"].split(";"):
            if len(path) > 0:
                self.uiImageDirectoriesListWidget.addItem(path)
예제 #14
0
 def checkLocalServerEnabled(self):
     """Checking if the local server is enabled"""
     if LocalServer.instance().shouldLocalServerAutoStart() is False:
         return (
             2,
             "The local server is disabled. Go to Preferences -> Server -> Local Server and enable the local server."
         )
     return (0, None)
예제 #15
0
    def done(self, result):
        """
        This dialog is closed.

        :param result: ignored
        """

        Controller.instance().setDisplayError(True)
        settings = self.parentWidget().settings()
        if result:
            settings["hide_setup_wizard"] = True
        else:
            local_server_settings = LocalServer.instance().localServerSettings()
            LocalServer.instance().updateLocalServerSettings(local_server_settings)
            settings["hide_setup_wizard"] = not self.uiShowCheckBox.isChecked()
        self.parentWidget().setSettings(settings)
        super().done(result)
예제 #16
0
def test_startLocalServer(tmpdir, local_server, local_server_path):
    logging.getLogger().setLevel(
        logging.DEBUG
    )  # Make sure we are using debug level in order to get the --debug

    process_mock = MagicMock()
    with patch("subprocess.Popen", return_value=process_mock) as mock:

        # If everything work fine the command is still running and a timeout is raised
        process_mock.communicate.side_effect = subprocess.TimeoutExpired(
            "test", 1)

        LocalServer.instance().startLocalServer()
        mock.assert_called_with([
            unittest.mock.ANY, '--local', '--debug',
            '--log=' + str(tmpdir / "gns3_server.log"),
            '--pid=' + str(tmpdir / "gns3_server.pid")
        ],
                                stderr=unittest.mock.ANY)
    def _projectsPathSlot(self):
        """
        Slot to select the projects directory path.
        """

        local_server = LocalServer.instance().localServerSettings()
        directory = local_server["projects_path"]
        path = QtWidgets.QFileDialog.getExistingDirectory(self, "My projects directory", directory, QtWidgets.QFileDialog.ShowDirsOnly)
        if path:
            self.uiProjectsPathLineEdit.setText(path)
            self.uiProjectsPathLineEdit.setCursorPosition(0)
예제 #18
0
    def done(self, result):
        """
        This dialog is closed.

        :param result: ignored
        """

        Controller.instance().setDisplayError(True)
        settings = self.parentWidget().settings()
        if result:
            settings["hide_setup_wizard"] = True
        else:
            local_server_settings = LocalServer.instance().localServerSettings()
            if local_server_settings["host"] is None:
                local_server_settings["host"] = DEFAULT_LOCAL_SERVER_HOST
                LocalServer.instance().updateLocalServerSettings(local_server_settings)
            settings["hide_setup_wizard"] = self.uiShowCheckBox.isChecked()

        self.parentWidget().setSettings(settings)
        super().done(result)
예제 #19
0
    def _symbolsPathSlot(self):
        """
        Slot to select the symbols directory path.
        """

        local_server = LocalServer.instance().localServerSettings()
        directory = local_server["symbols_path"]
        path = QtWidgets.QFileDialog.getExistingDirectory(self, "My symbols directory", directory, QtWidgets.QFileDialog.ShowDirsOnly)
        if path:
            self.uiSymbolsPathLineEdit.setText(path)
            self.uiSymbolsPathLineEdit.setCursorPosition(0)
예제 #20
0
def local_server(local_server_path, tmpdir):
    with open(str(tmpdir / "test.cfg"), "w+") as f:
        f.write("""
[Server]
path={}""".format(local_server_path))

    LocalServerConfig.instance().setConfigFile(str(tmpdir / "test.cfg"))
    LocalServer._instance = None
    with patch("gns3.local_server.LocalServer.localServerAutoStartIfRequire"):
        local_server = LocalServer.instance()
        local_server._config_directory = str(tmpdir)
        yield local_server
예제 #21
0
 def _refreshLocalServerStatusSlot(self):
     """
     Refresh the local server status page
     """
     if Controller.instance().connected():
         self.uiLocalServerStatusLabel.setText("Connection to local server successful")
         Controller.instance().get("/gns3vm", self._getSettingsCallback)
     elif Controller.instance().connecting():
         self.uiLocalServerStatusLabel.setText("Please wait connection to the GNS3 server")
     else:
         local_server_settings = LocalServer.instance().localServerSettings()
         self.uiLocalServerStatusLabel.setText("Connection to local server failed.\n* Make sure GNS3 is allowed in your firewall.\n* Go back and try to change the server port\n* Please check with a browser if you can connect to {protocol}://{host}:{port}.\n* Try to run {path} in a terminal to see if you have an error if the above does not work.".format(protocol=local_server_settings["protocol"], host=local_server_settings["host"], port=local_server_settings["port"], path=local_server_settings["path"]))
예제 #22
0
def local_server(local_server_path, tmpdir):
    with open(str(tmpdir / "test.cfg"), "w+") as f:
        f.write("""
[Server]
path={}""".format(local_server_path))

    LocalServerConfig.instance().setConfigFile(str(tmpdir / "test.cfg"))
    LocalServer._instance = None
    with patch("gns3.local_server.LocalServer.localServerAutoStartIfRequire"):
        local_server = LocalServer.instance()
        local_server._config_directory = str(tmpdir)
        yield local_server
예제 #23
0
    def savePreferences(self):
        """
        Saves the general preferences.
        """

        additional_images_paths = set()
        for i in range(0, self.uiImageDirectoriesListWidget.count()):
            item = self.uiImageDirectoriesListWidget.item(i)
            additional_images_paths.add(item.text())

        new_local_server_settings = {"images_path": self.uiImagesPathLineEdit.text(),
                                     "projects_path": self.uiProjectsPathLineEdit.text(),
                                     "symbols_path": self.uiSymbolsPathLineEdit.text(),
                                     "configs_path": self.uiConfigsPathLineEdit.text(),
                                     "report_errors": self.uiCrashReportCheckBox.isChecked(),
                                     "additional_images_paths": ":".join(additional_images_paths)}
        LocalServer.instance().updateLocalServerSettings(new_local_server_settings)

        new_general_settings = {
            "style": self.uiStyleComboBox.currentText(),
            "experimental_features": self.uiExperimentalFeaturesCheckBox.isChecked(),
            "hdpi": self.uiHdpiCheckBox.isChecked(),
            "check_for_update": self.uiCheckForUpdateCheckBox.isChecked(),
            "telnet_console_command": self.uiTelnetConsoleCommandLineEdit.text(),
            "vnc_console_command": self.uiVNCConsoleCommandLineEdit.text(),
            "delay_console_all": self.uiDelayConsoleAllSpinBox.value(),
            "send_stats": self.uiStatsCheckBox.isChecked(),
            "multi_profiles": self.uiMultiProfilesCheckBox.isChecked()
        }

        from ..main_window import MainWindow
        MainWindow.instance().setSettings(new_general_settings)

        new_graphics_view_settings = {"scene_width": self.uiSceneWidthSpinBox.value(),
                                      "scene_height": self.uiSceneHeightSpinBox.value(),
                                      "draw_rectangle_selected_item": self.uiRectangleSelectedItemCheckBox.isChecked(),
                                      "draw_link_status_points": self.uiDrawLinkStatusPointsCheckBox.isChecked(),
                                      "default_label_font": self.uiDefaultLabelStylePlainTextEdit.font().toString(),
                                      "default_label_color": self._default_label_color.name()}
        MainWindow.instance().uiGraphicsView.setSettings(new_graphics_view_settings)
예제 #24
0
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot)
        self._default_configs_dir = LocalServer.instance().localServerSettings()["configs_path"]
        if Controller.instance().isRemote():
            self.uiScriptFileToolButton.hide()

        # add the categories
        for name, category in Node.defaultCategories().items():
            self.uiCategoryComboBox.addItem(name, category)
예제 #25
0
    def _populateGeneralSettingWidgets(self, settings):
        """
        Populates the widgets with the settings.

        :param settings: General settings
        """

        local_server = LocalServer.instance().localServerSettings()
        self.uiProjectsPathLineEdit.setText(local_server["projects_path"])
        self.uiSymbolsPathLineEdit.setText(local_server["symbols_path"])
        self.uiImagesPathLineEdit.setText(local_server["images_path"])
        self.uiConfigsPathLineEdit.setText(local_server["configs_path"])
        self.uiAppliancesPathLineEdit.setText(local_server["appliances_path"])
        self.uiStatsCheckBox.setChecked(settings["send_stats"])
        self.uiOverlayNotificationsCheckBox.setChecked(
            settings["overlay_notifications"])
        self.uiCrashReportCheckBox.setChecked(local_server["report_errors"])
        self.uiCheckForUpdateCheckBox.setChecked(settings["check_for_update"])
        self.uiExperimentalFeaturesCheckBox.setChecked(
            settings["experimental_features"])
        self.uiHdpiCheckBox.setChecked(settings["hdpi"])
        self.uiTelnetConsoleCommandLineEdit.setText(
            settings["telnet_console_command"])
        self.uiTelnetConsoleCommandLineEdit.setCursorPosition(0)

        index = self.uiStyleComboBox.findText(settings["style"])
        if index != -1:
            self.uiStyleComboBox.setCurrentIndex(index)

        index = self.uiSymbolThemeComboBox.findText(settings["symbol_theme"])
        if index != -1:
            self.uiSymbolThemeComboBox.setCurrentIndex(index)

        self.uiDelayConsoleAllSpinBox.setValue(settings["delay_console_all"])

        self.uiVNCConsoleCommandLineEdit.setText(
            settings["vnc_console_command"])
        self.uiVNCConsoleCommandLineEdit.setCursorPosition(0)

        self.uiSPICEConsoleCommandLineEdit.setText(
            settings["spice_console_command"])
        self.uiSPICEConsoleCommandLineEdit.setCursorPosition(0)

        self.uiMultiProfilesCheckBox.setChecked(settings["multi_profiles"])

        self.uiImageDirectoriesListWidget.clear()
        for path in local_server["additional_images_paths"].split(";"):
            if len(path) > 0:
                self.uiImageDirectoriesListWidget.addItem(path)

        self.uiDirectFileUpload.setChecked(settings["direct_file_upload"])
예제 #26
0
    def _refreshLocalServerStatusSlot(self):
        """
        Refresh the local server status page
        """

        self.uiLocalServerTextEdit.clear()
        if Controller.instance().connected():
            self.uiLocalServerTextEdit.setText("Connection to the local GNS3 server has been successful!")
            Controller.instance().get("/gns3vm", self._getSettingsCallback)
        elif Controller.instance().connecting():
            self.uiLocalServerTextEdit.setText("Please wait connection to the GNS3 server...")
        else:
            local_server_settings = LocalServer.instance().localServerSettings()
            self.uiLocalServerTextEdit.setText("Connection to local server failed. Please try one of the following:\n\n- Make sure GNS3 is allowed to run by your firewall.\n- Go back and try to change the server host binding and/or the port\n- Check with a browser if you can connect to {protocol}://{host}:{port}.\n- Try to run {path} in a terminal to see if you have an error.".format(protocol=local_server_settings["protocol"], host=local_server_settings["host"], port=local_server_settings["port"], path=local_server_settings["path"]))
예제 #27
0
    def _configFileValid(self, path):
        """
        Return true if it is a valid configuration file
        """

        if not os.path.isabs(path):
            path = os.path.join(LocalServer.instance().localServerSettings()["configs_path"], path)
        result = os.access(path, os.R_OK)
        if not result:
            if not os.path.exists(path):
                log.error("Cannot access config file '{}'".format(path))
            else:
                log.error("Cannot read config file '{}'".format(path))
        return result
예제 #28
0
    def _configFileValid(self, path):
        """
        Return true if it's a valid configuration file
        """

        if not os.path.isabs(path):
            path = os.path.join(LocalServer.instance().localServerSettings()["configs_path"], path)
        result = os.access(path, os.R_OK)
        if not result:
            if not os.path.exists(path):
                log.error("Cannot access config file '{}'".format(path))
            else:
                log.error("Cannot read config file '{}'".format(path))
        return result
예제 #29
0
    def _refreshLocalServerStatusSlot(self):
        """
        Refresh the local server status page
        """

        self.uiLocalServerTextEdit.clear()
        if Controller.instance().connected():
            self.uiLocalServerTextEdit.setText("Connection to the local GNS3 server has been successful!")
            Controller.instance().get("/gns3vm", self._getSettingsCallback)
        elif Controller.instance().connecting():
            self.uiLocalServerTextEdit.setText("Please wait connection to the GNS3 server...")
        else:
            local_server_settings = LocalServer.instance().localServerSettings()
            self.uiLocalServerTextEdit.setText("Connection to local server failed. Please try one of the following:\n\n- Make sure GNS3 is allowed to run by your firewall.\n- Go back and try to change the server host binding and/or the port\n- Check with a browser if you can connect to {protocol}://{host}:{port}.\n- Try to run {path} in a terminal to see if you have an error.".format(protocol=local_server_settings["protocol"], host=local_server_settings["host"], port=local_server_settings["port"], path=local_server_settings["path"]))
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        self._widget_slots = {
            0: self.uiSlot0comboBox,
            1: self.uiSlot1comboBox,
            2: self.uiSlot2comboBox,
            3: self.uiSlot3comboBox,
            4: self.uiSlot4comboBox,
            5: self.uiSlot5comboBox,
            6: self.uiSlot6comboBox
        }

        self._widget_wics = {
            0: self.uiWic0comboBox,
            1: self.uiWic1comboBox,
            2: self.uiWic2comboBox
        }

        self.uiStartupConfigToolButton.clicked.connect(
            self._startupConfigBrowserSlot)
        self.uiPrivateConfigToolButton.clicked.connect(
            self._privateConfigBrowserSlot)
        self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot)
        self.uiIOSImageToolButton.clicked.connect(self._iosImageBrowserSlot)
        self._compute_id = None
        self._idle_valid = False
        idle_pc_rgx = QtCore.QRegExp("^(0x[0-9a-fA-F]{8})?$")
        validator = QtGui.QRegExpValidator(idle_pc_rgx, self)
        self.uiIdlepcLineEdit.setValidator(validator)
        self.uiIdlepcLineEdit.textChanged.connect(self._idlePCValidateSlot)
        self.uiIdlepcLineEdit.textChanged.emit(self.uiIdlepcLineEdit.text())
        self._default_configs_dir = LocalServer.instance().localServerSettings(
        )["configs_path"]

        # add the categories
        for name, category in Node.defaultCategories().items():
            self.uiCategoryComboBox.addItem(name, category)

        if Controller.instance().isRemote():
            self.uiStartupConfigToolButton.hide()
            self.uiPrivateConfigToolButton.hide()
예제 #31
0
 def _refreshLocalServerStatusSlot(self):
     """
     Refresh the local server status page
     """
     if Controller.instance().connected():
         self.uiLocalServerStatusLabel.setText(
             "Connection to local server successful")
         Controller.instance().get("/gns3vm", self._getSettingsCallback)
     elif Controller.instance().connecting():
         self.uiLocalServerStatusLabel.setText(
             "Please wait connection to the GNS3 server")
     else:
         local_server_settings = LocalServer.instance().localServerSettings(
         )
         self.uiLocalServerStatusLabel.setText(
             "Connection to local server failed.\n* Make sure GNS3 is allowed in your firewall.\n* Go back and try to change the server port\n* Please check with a browser if you can connect to {protocol}://{host}:{port}.\n* Try to run {path} in a terminal to see if you have an error if the above does not work."
             .format(protocol=local_server_settings["protocol"],
                     host=local_server_settings["host"],
                     port=local_server_settings["port"],
                     path=local_server_settings["path"]))
예제 #32
0
    def checkUbridgePermission(self):
        """Check if ubridge has the correct permission"""
        if not sys.platform.startswith("win") and os.geteuid() == 0:
            # we are root, so we should have privileged access.
            return (0, None)

        path = LocalServer.instance().localServerSettings().get("ubridge_path")
        if path is None:
            return (0, None)
        if not os.path.exists(path):
            return (2, "Ubridge path {path} doesn't exists".format(path=path))

        request_setuid = False
        if sys.platform.startswith("linux"):
            try:
                if "security.capability" in os.listxattr(path):
                    caps = os.getxattr(path, "security.capability")
                    # test the 2nd byte and check if the 13th bit (CAP_NET_RAW) is set
                    if not struct.unpack("<IIIII", caps)[1] & 1 << 13:
                        return (
                            2,
                            "Ubridge requires CAP_NET_RAW. Run sudo setcap cap_net_admin,cap_net_raw=ep {path}"
                            .format(path=path))
                else:
                    # capabilities not supported
                    request_setuid = True
            except AttributeError:
                # Due to a Python bug, os.listxattr could be missing: https://github.com/GNS3/gns3-gui/issues/2010
                return (
                    1,
                    "Could not determine if CAP_NET_RAW capability is set for uBridge (Python bug)"
                    .format(path=path))

        if sys.platform.startswith("darwin") or request_setuid:
            if os.stat(path).st_uid != 0 or not os.stat(
                    path).st_mode & stat.S_ISUID:
                return (
                    2,
                    "Ubridge should be setuid. Run sudo chown root:admin {path} and sudo chmod 4750 {path}"
                    .format(path=path))
        return (0, None)
    def __init__(self):

        super().__init__()
        self.setupUi(self)

        self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot)
        self.uiStartupConfigToolButton.clicked.connect(self._startupConfigBrowserSlot)
        self.uiPrivateConfigToolButton.clicked.connect(self._privateConfigBrowserSlot)
        self.uiIOUImageToolButton.clicked.connect(self._iouImageBrowserSlot)
        self.uiDefaultValuesCheckBox.stateChanged.connect(self._useDefaultValuesSlot)
        self._current_iou_image = ""
        self._compute_id = None

        # location of the base config templates
        self._base_iou_l2_config_template = get_resource(os.path.join("configs", "iou_l2_base_startup-config.txt"))
        self._base_iou_l3_config_template = get_resource(os.path.join("configs", "iou_l3_base_startup-config.txt"))
        self._default_configs_dir = LocalServer.instance().localServerSettings()["configs_path"]

        # add the categories
        for name, category in Node.defaultCategories().items():
            self.uiCategoryComboBox.addItem(name, category)
예제 #34
0
    def checkDynamipsPermission(self):
        """Check if dynamips has the correct permission"""
        if not sys.platform.startswith("win") and os.geteuid() == 0:
            # we are root, so we should have privileged access.
            return (0, None)

        path = LocalServer.instance().localServerSettings().get("dynamips_path")
        if path is None:
            return (0, None)
        if not os.path.exists(path):
            return (2, "Dynamips path {path} doesn't exists".format(path=path))

        try:
            if sys.platform.startswith("linux") and "security.capability" in os.listxattr(path):
                caps = os.getxattr(path, "security.capability")
                # test the 2nd byte and check if the 13th bit (CAP_NET_RAW) is set
                if not struct.unpack("<IIIII", caps)[1] & 1 << 13:
                    return (2, "Dynamips requires CAP_NET_RAW. Run sudo setcap cap_net_raw,cap_net_admin+eip {path}".format(path=path))
        except AttributeError:
            # Due to a Python bug, os.listxattr could be missing: https://github.com/GNS3/gns3-gui/issues/2010
            return (1, "Could not determine if CAP_NET_RAW capability is set for Dynamips (Python bug)".format(path=path))
        return (0, None)
예제 #35
0
def get_default_base_config(base_config_template_path):
    """
    Copy the default base config template to settings directory (if not already present) and returns the path.

    :param base_config_template_path: path to the base config template

    :return: path to the base config
    """

    config_dir = LocalServer.instance().localServerSettings()["configs_path"]
    if base_config_template_path:
        try:
            os.makedirs(config_dir, exist_ok=True)
        except OSError as e:
            log.error("could not create the base configs directory {}: {}".format(config_dir, e))
            return ""
        try:
            base_config_path = os.path.join(config_dir, os.path.basename(base_config_template_path))
            if not os.path.isfile(base_config_path):
                shutil.copyfile(base_config_template_path, base_config_path)
            return os.path.normpath(base_config_path)
        except OSError as e:
            log.error("could not copy {} to {}: {}".format(base_config_template_path, base_config_path, e))
    return ""
예제 #36
0
    def _readBaseConfig(self, config_path):
        """
        Returns a base config content.

        :param config_path: path to the configuration file.

        :returns: config content
        """

        if config_path is None or len(config_path.strip()) == 0:
            return None

        if not os.path.isabs(config_path):
            config_path = os.path.join(
                LocalServer.instance().localServerSettings()["configs_path"],
                config_path)

        if not os.path.isfile(config_path):
            return None

        try:
            with open(config_path, "rb") as f:
                log.info("Opening configuration file: {}".format(config_path))
                config = f.read().decode("utf-8")
                config = config.replace('\r', "")
                return config
        except OSError as e:
            self.error_signal.emit(
                self.id(), "Could not read configuration file {}: {}".format(
                    config_path, e))
            return None
        except UnicodeDecodeError as e:
            self.error_signal.emit(
                self.id(),
                "Invalid configuration file {}: {}".format(config_path, e))
            return None
예제 #37
0
    def initializePage(self, page_id):
        """
        Initialize Wizard pages.

        :param page_id: page identifier
        """

        super().initializePage(page_id)
        if self.page(page_id) == self.uiServerWizardPage:
            Controller.instance().setDisplayError(False)
            Controller.instance().get("/gns3vm", self._getSettingsCallback)
        elif self.page(page_id) == self.uiVMWizardPage:
            if self._GNS3VMSettings()["engine"] == "vmware":
                self.uiVmwareRadioButton.setChecked(True)
                self._listVMwareVMsSlot()
            elif self._GNS3VMSettings()["engine"] == "virtualbox":
                self.uiVirtualBoxRadioButton.setChecked(True)
                self._listVirtualBoxVMsSlot()
            self.uiCPUSpinBox.setValue(self._GNS3VMSettings()["vcpus"])
            self.uiRAMSpinBox.setValue(self._GNS3VMSettings()["ram"])

        elif self.page(page_id) == self.uiLocalServerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings(
            )
            self.uiLocalServerPathLineEdit.setText(
                local_server_settings["path"])
            index = self.uiLocalServerHostComboBox.findData(
                local_server_settings["host"])
            if index != -1:
                self.uiLocalServerHostComboBox.setCurrentIndex(index)
            self.uiLocalServerPortSpinBox.setValue(
                local_server_settings["port"])

        elif self.page(page_id) == self.uiRemoteControllerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings(
            )
            if local_server_settings["host"] is None:
                self.uiRemoteMainServerHostLineEdit.setText(
                    DEFAULT_LOCAL_SERVER_HOST)
                self.uiRemoteMainServerAuthCheckBox.setChecked(False)
                self.uiRemoteMainServerUserLineEdit.setText("")
                self.uiRemoteMainServerPasswordLineEdit.setText("")
            else:
                self.uiRemoteMainServerHostLineEdit.setText(
                    local_server_settings["host"])
                self.uiRemoteMainServerAuthCheckBox.setChecked(
                    local_server_settings["auth"])
                self.uiRemoteMainServerUserLineEdit.setText(
                    local_server_settings["user"])
                self.uiRemoteMainServerPasswordLineEdit.setText(
                    local_server_settings["password"])
            self.uiRemoteMainServerPortSpinBox.setValue(
                local_server_settings["port"])
        elif self.page(page_id) == self.uiLocalServerStatusWizardPage:
            self._refreshLocalServerStatusSlot()

        elif self.page(page_id) == self.uiSummaryWizardPage:
            self.uiSummaryTreeWidget.clear()
            if self.uiLocalRadioButton.isChecked():
                local_server_settings = LocalServer.instance(
                ).localServerSettings()
                self._addSummaryEntry("Server type:", "Local")
                self._addSummaryEntry("Path:", local_server_settings["path"])
                self._addSummaryEntry("Host:", local_server_settings["host"])
                self._addSummaryEntry("Port:",
                                      str(local_server_settings["port"]))
            elif self.uiRemoteControllerRadioButton.isChecked():
                local_server_settings = LocalServer.instance(
                ).localServerSettings()
                self._addSummaryEntry("Server type:", "Remote")
                self._addSummaryEntry("Host:", local_server_settings["host"])
                self._addSummaryEntry("Port:",
                                      str(local_server_settings["port"]))
                self._addSummaryEntry("User:"******"user"])
            else:
                self._addSummaryEntry("Server type:", "GNS3 Virtual Machine")
                self._addSummaryEntry(
                    "VM engine:",
                    self._GNS3VMSettings()["engine"].capitalize())
                self._addSummaryEntry("VM name:",
                                      self._GNS3VMSettings()["vmname"])
                self._addSummaryEntry("VM vCPUs:",
                                      str(self._GNS3VMSettings()["vcpus"]))
                self._addSummaryEntry(
                    "VM RAM:",
                    str(self._GNS3VMSettings()["ram"]) + " MB")
예제 #38
0
    def validateCurrentPage(self):
        """
        Validates the settings.
        """

        Controller.instance().setDisplayError(True)
        if self.currentPage() == self.uiVMWizardPage:
            vmname = self.uiVMListComboBox.currentText()
            if vmname:
                # save the GNS3 VM settings
                vm_settings = self._GNS3VMSettings()
                vm_settings["enable"] = True
                vm_settings["vmname"] = vmname

                if self.uiVmwareRadioButton.isChecked():
                    vm_settings["engine"] = "vmware"
                elif self.uiVirtualBoxRadioButton.isChecked():
                    vm_settings["engine"] = "virtualbox"

                # set the vCPU count and RAM
                vpcus = self.uiCPUSpinBox.value()
                ram = self.uiRAMSpinBox.value()
                if ram < 1024:
                    QtWidgets.QMessageBox.warning(self, "GNS3 VM memory", "It is recommended to allocate a minimum of 1024 MB of memory to the GNS3 VM")
                vm_settings["vcpus"] = vpcus
                vm_settings["ram"] = ram

                self._setGNS3VMSettings(vm_settings)
            else:
                if not self.uiVmwareRadioButton.isChecked() and not self.uiVirtualBoxRadioButton.isChecked():
                    QtWidgets.QMessageBox.warning(self, "GNS3 VM", "Please select VMware or VirtualBox")
                else:
                    QtWidgets.QMessageBox.warning(self, "GNS3 VM", "Please select a VM. If no VM is listed, check if the GNS3 VM is correctly imported and press refresh.")
                return False
        elif self.currentPage() == self.uiLocalServerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings()
            local_server_settings["auto_start"] = True
            local_server_settings["path"] = self.uiLocalServerPathLineEdit.text().strip()
            local_server_settings["host"] = self.uiLocalServerHostComboBox.itemData(self.uiLocalServerHostComboBox.currentIndex())
            local_server_settings["port"] = self.uiLocalServerPortSpinBox.value()

            if not os.path.isfile(local_server_settings["path"]):
                QtWidgets.QMessageBox.critical(self, "Local server", "Could not find local server {}".format(local_server_settings["path"]))
                return False
            if not os.access(local_server_settings["path"], os.X_OK):
                QtWidgets.QMessageBox.critical(self, "Local server", "{} is not an executable".format(local_server_settings["path"]))
                return False

            LocalServer.instance().updateLocalServerSettings(local_server_settings)
            LocalServer.instance().localServerAutoStartIfRequire()

        elif self.currentPage() == self.uiRemoteControllerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings()
            local_server_settings["auto_start"] = False
            local_server_settings["host"] = self.uiRemoteMainServerHostLineEdit.text()
            local_server_settings["port"] = self.uiRemoteMainServerPortSpinBox.value()
            local_server_settings["protocol"] = "http"
            local_server_settings["user"] = self.uiRemoteMainServerUserLineEdit.text()
            local_server_settings["password"] = self.uiRemoteMainServerPasswordLineEdit.text()
            local_server_settings["auth"] = self.uiRemoteMainServerAuthCheckBox.isChecked()
            LocalServer.instance().updateLocalServerSettings(local_server_settings)

        elif self.currentPage() == self.uiSummaryWizardPage:
            if self.uiLocalRadioButton.isChecked():
                # deactivate the GNS3 VM if using the local server
                vm_settings = self._GNS3VMSettings()
                vm_settings["enable"] = False
                self._setGNS3VMSettings(vm_settings)

        elif self.currentPage() == self.uiLocalServerStatusWizardPage:
            if not Controller.instance().connected():
                return False

        return True
예제 #39
0
 def checkLocalServerEnabled(self):
     """Checking if the local server is enabled"""
     if LocalServer.instance().shouldLocalServerAutoStart() is False:
         return (2, "The local server is disabled. Go to Preferences -> Server -> Local Server and enable the local server.")
     return (0, None)
예제 #40
0
    def initializePage(self, page_id):
        """
        Initialize Wizard pages.

        :param page_id: page identifier
        """

        super().initializePage(page_id)
        if self.page(page_id) == self.uiServerWizardPage:
            Controller.instance().setDisplayError(False)
            Controller.instance().get("/gns3vm", self._getSettingsCallback)
        elif self.page(page_id) == self.uiVMWizardPage:
            if self._GNS3VMSettings()["engine"] == "vmware":
                self.uiVmwareRadioButton.setChecked(True)
                self._listVMwareVMsSlot()
            elif self._GNS3VMSettings()["engine"] == "virtualbox":
                self.uiVirtualBoxRadioButton.setChecked(True)
                self._listVirtualBoxVMsSlot()
            self.uiCPUSpinBox.setValue(self._GNS3VMSettings()["vcpus"])
            self.uiRAMSpinBox.setValue(self._GNS3VMSettings()["ram"])

        elif self.page(page_id) == self.uiLocalServerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings()
            self.uiLocalServerPathLineEdit.setText(local_server_settings["path"])
            index = self.uiLocalServerHostComboBox.findData(local_server_settings["host"])
            if index != -1:
                self.uiLocalServerHostComboBox.setCurrentIndex(index)
            self.uiLocalServerPortSpinBox.setValue(local_server_settings["port"])

        elif self.page(page_id) == self.uiRemoteControllerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings()
            if local_server_settings["host"] is None:
                self.uiRemoteMainServerHostLineEdit.setText(DEFAULT_LOCAL_SERVER_HOST)
                self.uiRemoteMainServerAuthCheckBox.setChecked(False)
                self.uiRemoteMainServerUserLineEdit.setText("")
                self.uiRemoteMainServerPasswordLineEdit.setText("")
            else:
                self.uiRemoteMainServerHostLineEdit.setText(local_server_settings["host"])
                self.uiRemoteMainServerAuthCheckBox.setChecked(local_server_settings["auth"])
                self.uiRemoteMainServerUserLineEdit.setText(local_server_settings["user"])
                self.uiRemoteMainServerPasswordLineEdit.setText(local_server_settings["password"])
            self.uiRemoteMainServerPortSpinBox.setValue(local_server_settings["port"])
        elif self.page(page_id) == self.uiLocalServerStatusWizardPage:
            self._refreshLocalServerStatusSlot()

        elif self.page(page_id) == self.uiSummaryWizardPage:
            self.uiSummaryTreeWidget.clear()
            if self.uiLocalRadioButton.isChecked():
                local_server_settings = LocalServer.instance().localServerSettings()
                self._addSummaryEntry("Server type:", "Local")
                self._addSummaryEntry("Path:", local_server_settings["path"])
                self._addSummaryEntry("Host:", local_server_settings["host"])
                self._addSummaryEntry("Port:", str(local_server_settings["port"]))
            elif self.uiRemoteControllerRadioButton.isChecked():
                local_server_settings = LocalServer.instance().localServerSettings()
                self._addSummaryEntry("Server type:", "Remote")
                self._addSummaryEntry("Host:", local_server_settings["host"])
                self._addSummaryEntry("Port:", str(local_server_settings["port"]))
                self._addSummaryEntry("User:"******"user"])
            else:
                self._addSummaryEntry("Server type:", "GNS3 Virtual Machine")
                self._addSummaryEntry("VM engine:", self._GNS3VMSettings()["engine"].capitalize())
                self._addSummaryEntry("VM name:", self._GNS3VMSettings()["vmname"])
                self._addSummaryEntry("VM vCPUs:", str(self._GNS3VMSettings()["vcpus"]))
                self._addSummaryEntry("VM RAM:", str(self._GNS3VMSettings()["ram"]) + " MB")
예제 #41
0
    def validateCurrentPage(self):
        """
        Validates the settings.
        """

        Controller.instance().setDisplayError(True)
        if self.currentPage() == self.uiVMWizardPage:
            vmname = self.uiVMListComboBox.currentText()
            if vmname:
                # save the GNS3 VM settings
                vm_settings = self._GNS3VMSettings()
                vm_settings["enable"] = True
                vm_settings["vmname"] = vmname

                if self.uiVmwareRadioButton.isChecked():
                    vm_settings["engine"] = "vmware"
                elif self.uiVirtualBoxRadioButton.isChecked():
                    vm_settings["engine"] = "virtualbox"

                # set the vCPU count and RAM
                vpcus = self.uiCPUSpinBox.value()
                ram = self.uiRAMSpinBox.value()
                if ram < 1024:
                    QtWidgets.QMessageBox.warning(
                        self, "GNS3 VM memory",
                        "It is recommended to allocate a minimum of 1024 MB of memory to the GNS3 VM"
                    )
                vm_settings["vcpus"] = vpcus
                vm_settings["ram"] = ram

                self._setGNS3VMSettings(vm_settings)
            else:
                if not self.uiVmwareRadioButton.isChecked(
                ) and not self.uiVirtualBoxRadioButton.isChecked():
                    QtWidgets.QMessageBox.warning(
                        self, "GNS3 VM", "Please select VMware or VirtualBox")
                else:
                    QtWidgets.QMessageBox.warning(
                        self, "GNS3 VM",
                        "Please select a VM. If no VM is listed, check if the GNS3 VM is correctly imported and press refresh."
                    )
                return False
        elif self.currentPage() == self.uiLocalServerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings(
            )
            local_server_settings["auto_start"] = True
            local_server_settings[
                "path"] = self.uiLocalServerPathLineEdit.text().strip()
            local_server_settings[
                "host"] = self.uiLocalServerHostComboBox.itemData(
                    self.uiLocalServerHostComboBox.currentIndex())
            local_server_settings[
                "port"] = self.uiLocalServerPortSpinBox.value()

            if not os.path.isfile(local_server_settings["path"]):
                QtWidgets.QMessageBox.critical(
                    self, "Local server",
                    "Could not find local server {}".format(
                        local_server_settings["path"]))
                return False
            if not os.access(local_server_settings["path"], os.X_OK):
                QtWidgets.QMessageBox.critical(
                    self, "Local server", "{} is not an executable".format(
                        local_server_settings["path"]))
                return False

            LocalServer.instance().updateLocalServerSettings(
                local_server_settings)
            LocalServer.instance().localServerAutoStartIfRequire()

        elif self.currentPage() == self.uiRemoteControllerWizardPage:
            local_server_settings = LocalServer.instance().localServerSettings(
            )
            local_server_settings["auto_start"] = False
            local_server_settings[
                "host"] = self.uiRemoteMainServerHostLineEdit.text()
            local_server_settings[
                "port"] = self.uiRemoteMainServerPortSpinBox.value()
            local_server_settings["protocol"] = "http"
            local_server_settings[
                "user"] = self.uiRemoteMainServerUserLineEdit.text()
            local_server_settings[
                "password"] = self.uiRemoteMainServerPasswordLineEdit.text()
            local_server_settings[
                "auth"] = self.uiRemoteMainServerAuthCheckBox.isChecked()
            LocalServer.instance().updateLocalServerSettings(
                local_server_settings)

        elif self.currentPage() == self.uiSummaryWizardPage:
            if self.uiLocalRadioButton.isChecked():
                # deactivate the GNS3 VM if using the local server
                vm_settings = self._GNS3VMSettings()
                vm_settings["enable"] = False
                self._setGNS3VMSettings(vm_settings)

        elif self.currentPage() == self.uiLocalServerStatusWizardPage:
            if not Controller.instance().connected():
                return False

        return True
    def savePreferences(self):
        """
        Saves the general preferences.
        """

        additional_images_paths = set()
        for i in range(0, self.uiImageDirectoriesListWidget.count()):
            item = self.uiImageDirectoriesListWidget.item(i)
            additional_images_paths.add(item.text())

        new_local_server_settings = {
            "images_path": self.uiImagesPathLineEdit.text(),
            "projects_path": self.uiProjectsPathLineEdit.text(),
            "symbols_path": self.uiSymbolsPathLineEdit.text(),
            "configs_path": self.uiConfigsPathLineEdit.text(),
            "report_errors": self.uiCrashReportCheckBox.isChecked(),
            "additional_images_paths": ":".join(additional_images_paths)
        }
        LocalServer.instance().updateLocalServerSettings(
            new_local_server_settings)

        new_general_settings = {
            "style":
            self.uiStyleComboBox.currentText(),
            "experimental_features":
            self.uiExperimentalFeaturesCheckBox.isChecked(),
            "hdpi":
            self.uiHdpiCheckBox.isChecked(),
            "check_for_update":
            self.uiCheckForUpdateCheckBox.isChecked(),
            "telnet_console_command":
            self.uiTelnetConsoleCommandLineEdit.text(),
            "vnc_console_command":
            self.uiVNCConsoleCommandLineEdit.text(),
            "delay_console_all":
            self.uiDelayConsoleAllSpinBox.value(),
            "send_stats":
            self.uiStatsCheckBox.isChecked(),
            "multi_profiles":
            self.uiMultiProfilesCheckBox.isChecked()
        }

        from ..main_window import MainWindow
        MainWindow.instance().setSettings(new_general_settings)

        new_graphics_view_settings = {
            "scene_width":
            self.uiSceneWidthSpinBox.value(),
            "scene_height":
            self.uiSceneHeightSpinBox.value(),
            "draw_rectangle_selected_item":
            self.uiRectangleSelectedItemCheckBox.isChecked(),
            "draw_link_status_points":
            self.uiDrawLinkStatusPointsCheckBox.isChecked(),
            "default_label_font":
            self.uiDefaultLabelStylePlainTextEdit.font().toString(),
            "default_label_color":
            self._default_label_color.name()
        }
        MainWindow.instance().uiGraphicsView.setSettings(
            new_graphics_view_settings)