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)
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 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)
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)
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)
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 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)
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
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 _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)
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)
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)
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)
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)
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)
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
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"]))
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
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)
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)
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"])
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 _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
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
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()
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"]))
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)
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 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 ""
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
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")
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 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)
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")
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)