mirror of
https://github.com/GNS3/gns3-gui.git
synced 2026-05-17 00:46:01 +03:00
Merge branch 'master' into 1.5
This commit is contained in:
@@ -42,7 +42,9 @@ class ConsoleView(PyCutExt, ConsoleCmd):
|
||||
bitness = struct.calcsize("P") * 8
|
||||
current_year = datetime.date.today().year
|
||||
self.intro = "GNS3 management console.\nRunning GNS3 version {} on {} ({}-bit) with Python {} Qt {}.\n" \
|
||||
"Copyright (c) 2006-{} GNS3 Technologies.".format(__version__, platform.system(), bitness, platform.python_version(), QtCore.QT_VERSION_STR, current_year)
|
||||
"Copyright (c) 2006-{} GNS3 Technologies.\n" \
|
||||
"Use Help -> GNS3 Doctor to detect common issues." \
|
||||
"".format(__version__, platform.system(), bitness, platform.python_version(), QtCore.QT_VERSION_STR, current_year)
|
||||
|
||||
if LocalConfig.instance().experimental():
|
||||
self.intro += "\nWARNING: Experimental features enable. You can use some unfinished features and lost data."
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import psutil
|
||||
import os
|
||||
import platform
|
||||
import struct
|
||||
@@ -109,6 +110,7 @@ class CrashReport:
|
||||
import sip
|
||||
except ImportError:
|
||||
return context
|
||||
context["psutil:version"] = psutil.__version__
|
||||
context["pyqt:version"] = QtCore.PYQT_VERSION_STR
|
||||
context["qt:version"] = QtCore.QT_VERSION_STR
|
||||
context["sip:version"] = sip.SIP_VERSION_STR
|
||||
|
||||
173
gns3/dialogs/doctor_dialog.py
Normal file
173
gns3/dialogs/doctor_dialog.py
Normal file
@@ -0,0 +1,173 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2016 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import psutil
|
||||
import platform
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
import struct
|
||||
|
||||
from gns3.qt import QtWidgets
|
||||
from gns3.ui.doctor_dialog_ui import Ui_DoctorDialog
|
||||
from gns3.servers import Servers
|
||||
from gns3.local_config import LocalConfig
|
||||
from gns3 import version
|
||||
from gns3.modules.vmware import VMware
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DoctorDialog(QtWidgets.QDialog, Ui_DoctorDialog):
|
||||
"""
|
||||
This dialog allow user to detect error in his GNS3 installation.
|
||||
|
||||
If you want to add a test add a method starting by check. The
|
||||
check return a tuple result and a message in case of failure.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, console=False):
|
||||
|
||||
super().__init__(parent)
|
||||
self._console = console
|
||||
self.setupUi(self)
|
||||
self.uiOkButton.clicked.connect(self._okButtonClickedSlot)
|
||||
for method in sorted(dir(self)):
|
||||
if method.startswith('check'):
|
||||
self.write(getattr(self, method).__doc__ + "...")
|
||||
(res, msg) = getattr(self, method)()
|
||||
if res == 0:
|
||||
self.write('<span style="color: green"><strong>OK</strong></span>')
|
||||
elif res == 1:
|
||||
self.write('<span style="color: orange"><strong>WARNING</strong> {}</span>'.format(msg))
|
||||
elif res == 2:
|
||||
self.write('<span style="color: red"><strong>ERROR</strong> {}</span>'.format(msg))
|
||||
self.write("<br/>")
|
||||
|
||||
def write(self, text):
|
||||
"""
|
||||
Add text to the text windows
|
||||
"""
|
||||
if self._console:
|
||||
print(text)
|
||||
self.uiDoctorResultTextEdit.setHtml(self.uiDoctorResultTextEdit.toHtml() + text)
|
||||
|
||||
def _okButtonClickedSlot(self):
|
||||
self.accept()
|
||||
|
||||
def checkLocalServerEnabled(self):
|
||||
"""Checking if the local server is enabled"""
|
||||
if Servers.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 checkDevVersionOfGNS3(self):
|
||||
"""Checking for stable GNS3 version"""
|
||||
if version.__version_info__[3] != 0:
|
||||
return (1, "You are using a unstable version of GNS3.")
|
||||
return (0, None)
|
||||
|
||||
def checkExperimentalFeaturesEnabled(self):
|
||||
"""Checking if experimental features are not enabled"""
|
||||
if LocalConfig.instance().experimental():
|
||||
return (1, "Experimental features are enabled. Turn them off by going to Preferences -> General -> Miscellaneous.")
|
||||
return (0, None)
|
||||
|
||||
def checkAVGInstalled(self):
|
||||
"""Checking if AVG software is not installed"""
|
||||
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
psinfo = proc.as_dict(["exe"])
|
||||
if psinfo["exe"] and "AVG\\" in psinfo["exe"]:
|
||||
return (2, "AVG has known issues with GNS3, even after you disable it. You must whitelist dynamips.exe in the AVG preferences.")
|
||||
except psutil.NoSuchProcess:
|
||||
pass
|
||||
return (0, None)
|
||||
|
||||
def checkFreeRam(self):
|
||||
"""Checking for amount of free virtual memory"""
|
||||
|
||||
if int(psutil.virtual_memory().available / (1024 * 1024)) < 600:
|
||||
return (2, "You have less than 600MB of available virtual memory, this could prevent nodes to start")
|
||||
return (0, None)
|
||||
|
||||
def checkVmrun(self):
|
||||
"""Checking if vmrun is installed"""
|
||||
vmrun = VMware.instance().findVmrun()
|
||||
if len(vmrun) == 0:
|
||||
return (1, "The vmrun executable could not be found, VMware VMs cannot be used")
|
||||
return (0, None)
|
||||
|
||||
def check64Bit(self):
|
||||
"""Check if processor is 64 bit"""
|
||||
if platform.architecture()[0] != "64bit":
|
||||
return (2, "The architecture {} is not supported.".format(platform.architecture()[0]))
|
||||
return (0, None)
|
||||
|
||||
def checkUbridgePermission(self):
|
||||
"""Check if ubridge has the correct permission"""
|
||||
if os.geteuid() == 0:
|
||||
# we are root, so we should have privileged access.
|
||||
return (0, None)
|
||||
|
||||
path = Servers.instance().localServerSettings().get("ubridge_path")
|
||||
if path is None:
|
||||
return (0, None)
|
||||
|
||||
request_setuid = False
|
||||
if sys.platform.startswith("linux"):
|
||||
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 require CAP_NET_RAW. Run sudo setcap cap_net_admin,cap_net_raw=ep {path}".format(path=path))
|
||||
else:
|
||||
# capabilities not supported
|
||||
request_setuid = True
|
||||
|
||||
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 {path} and sudo chmod 4755 {path}".format(path=path))
|
||||
return (0, None)
|
||||
|
||||
def checkDynamipsPermission(self):
|
||||
"""Check if dynamips has the correct permission"""
|
||||
if os.geteuid() == 0:
|
||||
# we are root, so we should have privileged access.
|
||||
return (0, None)
|
||||
|
||||
path = Servers.instance().localServerSettings().get("dynamips_path")
|
||||
if path is None:
|
||||
return (0, None)
|
||||
|
||||
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 require CAP_NET_RAW. Run sudo setcap cap_net_raw,cap_net_admin+eip {path}".format(path=path))
|
||||
return (0, None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
main = QtWidgets.QMainWindow()
|
||||
dialog = DoctorDialog(main, console=True)
|
||||
#dialog.show()
|
||||
#exit_code = app.exec_()
|
||||
@@ -80,7 +80,7 @@ class SetupWizard(QtWidgets.QWizard, Ui_SetupWizard):
|
||||
from gns3.modules import VMware
|
||||
settings = VMware.instance().settings()
|
||||
if not os.path.exists(settings["vmrun_path"]):
|
||||
QtWidgets.QMessageBox.critical(self, "VMware", "VMware vmrun tool could not be found, VMware or the VIX API (required for VMware player) is probably not installed")
|
||||
QtWidgets.QMessageBox.critical(self, "VMware", "VMware vmrun tool could not be found, VMware or the VIX API (required for VMware player) is probably not installed. You can download it from https://www.vmware.com/support/developer/vix-api/")
|
||||
return
|
||||
self._refreshVMListSlot()
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@ class TextEditorDialog(QtWidgets.QDialog, Ui_TextEditorDialog):
|
||||
self.uiPlainTextEdit.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
|
||||
|
||||
if len(self._items) == 1:
|
||||
self.uiApplyColorToAllItemsCheckBox.setChecked(True)
|
||||
self.uiApplyColorToAllItemsCheckBox.hide()
|
||||
self.uiApplyRotationToAllItemsCheckBox.setChecked(True)
|
||||
self.uiApplyRotationToAllItemsCheckBox.hide()
|
||||
self.uiApplyTextToAllItemsCheckBox.setChecked(True)
|
||||
self.uiApplyTextToAllItemsCheckBox.hide()
|
||||
|
||||
@@ -90,9 +94,11 @@ class TextEditorDialog(QtWidgets.QDialog, Ui_TextEditorDialog):
|
||||
"""
|
||||
|
||||
for item in self._items:
|
||||
item.setDefaultTextColor(self._color)
|
||||
item.setFont(self.uiPlainTextEdit.font())
|
||||
item.setRotation(self.uiRotationSpinBox.value())
|
||||
if self.uiApplyColorToAllItemsCheckBox.isChecked():
|
||||
item.setDefaultTextColor(self._color)
|
||||
if self.uiApplyRotationToAllItemsCheckBox.isChecked():
|
||||
item.setRotation(self.uiRotationSpinBox.value())
|
||||
if item.editable() and self.uiApplyTextToAllItemsCheckBox.isChecked():
|
||||
item.setPlainText(self.uiPlainTextEdit.toPlainText())
|
||||
|
||||
|
||||
@@ -293,36 +293,36 @@ class GraphicsView(QtWidgets.QGraphicsView):
|
||||
self.deleteLinkSlot(link_id)
|
||||
return
|
||||
|
||||
# ugly multi-link management
|
||||
# FIXME: taken from old GNS3 and has a bug!
|
||||
multi = 0
|
||||
d1 = 0
|
||||
d2 = 1
|
||||
link_items = source_item.links()
|
||||
for link_item in link_items:
|
||||
if link_item.destinationItem().node().id() == destination_item.node().id():
|
||||
d1 += 1
|
||||
if link_item.sourceItem().node().id() == destination_item.node().id():
|
||||
d2 += 1
|
||||
|
||||
if len(link_items) > 0:
|
||||
if d2 - d1 == 2:
|
||||
source_port, destination_port = destination_port, source_port
|
||||
source_item, destination_item = destination_item, source_item
|
||||
multi = d1 + 1
|
||||
elif d1 >= d2:
|
||||
source_port, destination_port = destination_port, source_port
|
||||
source_item, destination_item = destination_item, source_item
|
||||
multi = d2
|
||||
else:
|
||||
multi = d1
|
||||
|
||||
# MAX 7 links on the scene between 2 nodes
|
||||
if multi > 3:
|
||||
multi = 0
|
||||
# Multi-link management
|
||||
#
|
||||
# multi is the offset of the link
|
||||
# +------+ multi = -1 Link 2 +-------+
|
||||
# | +-----------------------------+ |
|
||||
# | R1 | | R2 |
|
||||
# | | multi = 0 Link 1 | |
|
||||
# | +-----------------------------+ |
|
||||
# | | multi = 1 Link 3 | |
|
||||
# +------+-----------------------------+-------+
|
||||
|
||||
if source_item == destination_item:
|
||||
multi = 0
|
||||
else:
|
||||
multi = 0
|
||||
link_items = source_item.links()
|
||||
for link_item in link_items:
|
||||
if link_item.destinationItem().node().id() == destination_item.node().id():
|
||||
multi += 1
|
||||
if link_item.sourceItem().node().id() == destination_item.node().id():
|
||||
multi += 1
|
||||
|
||||
# MAX 7 links on the scene between 2 nodes
|
||||
if multi > 7:
|
||||
multi = 0
|
||||
# Pair item represent the bottom links
|
||||
elif multi % 2 == 0:
|
||||
multi = multi // 2
|
||||
else:
|
||||
multi = -multi // 2
|
||||
|
||||
if link.sourcePort().linkType() == "Serial" or (source_port.isStub() and link.destinationPort().linkType() == "Serial"):
|
||||
link_item = SerialLinkItem(source_item, source_port, destination_item, destination_port, link, multilink=multi)
|
||||
|
||||
@@ -54,7 +54,9 @@ class HTTPClient(QtCore.QObject):
|
||||
# Callback class used for displaying progress
|
||||
_progress_callback = None
|
||||
|
||||
connected_signal = QtCore.Signal()
|
||||
connection_connected_signal = QtCore.Signal()
|
||||
connection_closed_signal = QtCore.Signal()
|
||||
system_usage_updated_signal = QtCore.Signal()
|
||||
connection_error_signal = QtCore.Signal(str)
|
||||
|
||||
def __init__(self, settings, network_manager):
|
||||
@@ -79,6 +81,7 @@ class HTTPClient(QtCore.QObject):
|
||||
self._ram_limit = settings.get("ram_limit", 0)
|
||||
self._allocated_ram = 0
|
||||
self._accept_insecure_certificate = settings.get("accept_insecure_certificate", None)
|
||||
self._usage = None
|
||||
|
||||
self._network_manager = network_manager
|
||||
|
||||
@@ -89,25 +92,6 @@ class HTTPClient(QtCore.QObject):
|
||||
self._id = HTTPClient._instance_count
|
||||
HTTPClient._instance_count += 1
|
||||
|
||||
def getTunnel(self, port):
|
||||
"""
|
||||
Get a tunnel to the remote port.
|
||||
For HTTP standard client it's the same port. For SSH it will create a new tunnel.
|
||||
|
||||
:param port: Remote port
|
||||
:returns: Tuple host, port to connect
|
||||
"""
|
||||
return self._host, port
|
||||
|
||||
def releaseTunnel(self, port):
|
||||
"""
|
||||
Release a tunnel to the remote port.
|
||||
For HTTP standard client it's do nothing
|
||||
|
||||
:param port: Allocated remote port
|
||||
"""
|
||||
pass
|
||||
|
||||
def settings(self):
|
||||
"""
|
||||
Return a dictionnary with server settings
|
||||
@@ -286,6 +270,7 @@ class HTTPClient(QtCore.QObject):
|
||||
"""
|
||||
log.info("Connection to %s closed", self.url())
|
||||
self._connected = False
|
||||
self.connection_closed_signal.emit()
|
||||
|
||||
def isLocalServerRunning(self):
|
||||
"""
|
||||
@@ -507,6 +492,7 @@ class HTTPClient(QtCore.QObject):
|
||||
return
|
||||
|
||||
self._connected = True
|
||||
self.connection_connected_signal.emit()
|
||||
kwargs["context"] = original_context
|
||||
self.executeHTTPQuery(method, path, callback, body, **kwargs)
|
||||
self._version = params["version"]
|
||||
@@ -787,5 +773,14 @@ class HTTPClient(QtCore.QObject):
|
||||
server["accept_insecure_certificate"] = self._accept_insecure_certificate
|
||||
return server
|
||||
|
||||
def isCloud(self):
|
||||
return False
|
||||
def systemUsage(self):
|
||||
"""
|
||||
Get information about current system usage
|
||||
|
||||
:returns: None or dict
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
def setSystemUsage(self, usage):
|
||||
self._usage = usage
|
||||
self.system_usage_updated_signal.emit()
|
||||
|
||||
@@ -172,6 +172,20 @@ class LinkItem(QtWidgets.QGraphicsPathItem):
|
||||
|
||||
cls._draw_port_labels = state
|
||||
|
||||
def resetPortLabels(self):
|
||||
"""
|
||||
Resets the port label positions.
|
||||
"""
|
||||
|
||||
source_port_label = self._source_port.label()
|
||||
destination_port_label = self._destination_port.label()
|
||||
if source_port_label is not None:
|
||||
source_port_label.delete()
|
||||
self._source_port.setLabel(None)
|
||||
if destination_port_label is not None:
|
||||
destination_port_label.delete()
|
||||
self._destination_port.setLabel(None)
|
||||
|
||||
def populateLinkContextualMenu(self, menu):
|
||||
"""
|
||||
Adds device actions to the link contextual menu.
|
||||
|
||||
@@ -27,7 +27,6 @@ from .qt import QtCore
|
||||
from .version import __version__
|
||||
from .utils import parse_version
|
||||
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -147,6 +146,15 @@ class LocalConfig(QtCore.QObject):
|
||||
main_window["hide_getting_started_dialog"] = self._settings["GUI"].get("hide_getting_started_dialog", False)
|
||||
self._settings["MainWindow"] = main_window
|
||||
|
||||
if "version" not in self._settings or parse_version(self._settings["version"]) < parse_version("1.4.1dev2"):
|
||||
if sys.platform.startswith("darwin"):
|
||||
from .settings import PRECONFIGURED_TELNET_CONSOLE_COMMANDS, DEFAULT_TELNET_CONSOLE_COMMAND
|
||||
|
||||
if "MainWindow" in self._settings:
|
||||
if self._settings["MainWindow"]["telnet_console_command"] not in PRECONFIGURED_TELNET_CONSOLE_COMMANDS.values():
|
||||
self._settings["MainWindow"]["telnet_console_command"] = DEFAULT_TELNET_CONSOLE_COMMAND
|
||||
|
||||
|
||||
def _readConfig(self, config_path):
|
||||
"""
|
||||
Read the configuration file.
|
||||
|
||||
@@ -198,6 +198,10 @@ def main():
|
||||
if DEFAULT_BINDING == "PyQt5" and version(QtCore.BINDING_VERSION_STR) < version("5.0.0"):
|
||||
raise SystemExit("Requirement is PyQt5 version 5.0.0 or higher, got version {}".format(QtCore.BINDING_VERSION_STR))
|
||||
|
||||
import psutil
|
||||
if version(psutil.__version__) < version("2.2.1"):
|
||||
raise SystemExit("Requirement is psutil version 2.2.1 or higher, got version {}".format(psutil.__version__))
|
||||
|
||||
# check for the correct locale
|
||||
# (UNIX/Linux only)
|
||||
locale_check()
|
||||
|
||||
@@ -43,6 +43,7 @@ from .dialogs.new_project_dialog import NewProjectDialog
|
||||
from .dialogs.preferences_dialog import PreferencesDialog
|
||||
from .dialogs.snapshots_dialog import SnapshotsDialog
|
||||
from .dialogs.export_debug_dialog import ExportDebugDialog
|
||||
from .dialogs.doctor_dialog import DoctorDialog
|
||||
from .dialogs.setup_wizard import SetupWizard
|
||||
from .settings import GENERAL_SETTINGS
|
||||
from .utils.progress_dialog import ProgressDialog
|
||||
@@ -119,6 +120,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
|
||||
# populate the view -> docks menu
|
||||
self.uiDocksMenu.addAction(self.uiTopologySummaryDockWidget.toggleViewAction())
|
||||
self.uiDocksMenu.addAction(self.uiServerSummaryDockWidget.toggleViewAction())
|
||||
self.uiDocksMenu.addAction(self.uiConsoleDockWidget.toggleViewAction())
|
||||
self.uiDocksMenu.addAction(self.uiNodesDockWidget.toggleViewAction())
|
||||
|
||||
@@ -218,7 +220,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
self.uiFitInViewAction.triggered.connect(self._fitInViewActionSlot)
|
||||
self.uiShowLayersAction.triggered.connect(self._showLayersActionSlot)
|
||||
self.uiResetPortLabelsAction.triggered.connect(self._resetPortLabelsActionSlot)
|
||||
self.uiShowNamesAction.triggered.connect(self._showNamesActionSlot)
|
||||
self.uiShowPortNamesAction.triggered.connect(self._showPortNamesActionSlot)
|
||||
|
||||
# control menu connections
|
||||
@@ -249,6 +250,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
self.uiAboutQtAction.triggered.connect(self._aboutQtActionSlot)
|
||||
self.uiAboutAction.triggered.connect(self._aboutActionSlot)
|
||||
self.uiExportDebugInformationAction.triggered.connect(self._exportDebugInformationSlot)
|
||||
self.uiDoctorAction.triggered.connect(self._doctorSlot)
|
||||
self.uiIOUVMConverterAction.triggered.connect(self._IOUVMConverterActionSlot)
|
||||
|
||||
# browsers tool bar connections
|
||||
@@ -674,16 +676,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
Slot called to reset the port labels on the scene.
|
||||
"""
|
||||
|
||||
# TODO: reset port labels
|
||||
pass
|
||||
|
||||
def _showNamesActionSlot(self):
|
||||
"""
|
||||
Slot called to show the node names on the scene.
|
||||
"""
|
||||
|
||||
# TODO: show/hide node names
|
||||
pass
|
||||
for item in self.uiGraphicsView.scene().items():
|
||||
if isinstance(item, LinkItem):
|
||||
item.resetPortLabels()
|
||||
item.adjust()
|
||||
|
||||
def _showPortNamesActionSlot(self):
|
||||
"""
|
||||
@@ -923,6 +919,15 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
dialog.show()
|
||||
dialog.exec_()
|
||||
|
||||
def _doctorSlot(self):
|
||||
"""
|
||||
Slot to display a window for exporting debug information
|
||||
"""
|
||||
|
||||
dialog = DoctorDialog(self)
|
||||
dialog.show()
|
||||
dialog.exec_()
|
||||
|
||||
def _showNodesDockWidget(self, title, category):
|
||||
"""
|
||||
Makes the NodesDockWidget appear with the appropriate title and the devices
|
||||
|
||||
@@ -74,7 +74,7 @@ class VMware(Module):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _findVmrun(self):
|
||||
def findVmrun():
|
||||
"""
|
||||
Finds the vmrun path.
|
||||
|
||||
@@ -91,7 +91,7 @@ class VMware(Module):
|
||||
vmrun_path = vmrun_ws
|
||||
else:
|
||||
# look for vmrun.exe using the directory listed in the registry
|
||||
vmrun_path = self._findVmrunRegistry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation")
|
||||
vmrun_path = VMware._findVmrunRegistry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation")
|
||||
if vmrun_path is None:
|
||||
# look for vmrun.exe in default VMware VIX directory
|
||||
vmrun_vix = os.path.expandvars(r"%PROGRAMFILES(X86)%\VMware\VMware VIX\vmrun.exe")
|
||||
@@ -99,7 +99,7 @@ class VMware(Module):
|
||||
vmrun_path = vmrun_vix
|
||||
else:
|
||||
# look for vmrun.exe using the directory listed in the registry
|
||||
vmrun_path = self._findVmrunRegistry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware VIX")
|
||||
vmrun_path = VMware._findVmrunRegistry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware VIX")
|
||||
elif sys.platform.startswith("darwin"):
|
||||
vmware_fusion_vmrun_path = "/Applications/VMware Fusion.app/Contents/Library/vmrun"
|
||||
if os.path.exists(vmware_fusion_vmrun_path):
|
||||
@@ -120,6 +120,10 @@ class VMware(Module):
|
||||
return "fusion"
|
||||
else:
|
||||
vmware_path = shutil.which("vmware")
|
||||
if vmware_path is None:
|
||||
vmware_path = shutil.which("vmplayer")
|
||||
if vmware_path is not None:
|
||||
return "player"
|
||||
if vmware_path:
|
||||
command = [vmware_path, "-v"]
|
||||
log.debug("Executing vmware with command: {}".format(command))
|
||||
@@ -144,7 +148,7 @@ class VMware(Module):
|
||||
local_config = LocalConfig.instance()
|
||||
self._settings = local_config.loadSectionSettings(self.__class__.__name__, VMWARE_SETTINGS)
|
||||
if not os.path.exists(self._settings["vmrun_path"]):
|
||||
self._settings["vmrun_path"] = self._findVmrun(self)
|
||||
self._settings["vmrun_path"] = self.findVmrun()
|
||||
self._settings["host_type"] = self._determineHostType(self)
|
||||
self._loadVMwareVMs()
|
||||
|
||||
|
||||
@@ -18,34 +18,19 @@
|
||||
import ipaddress
|
||||
|
||||
|
||||
def getNetworkClientInstance(settings, network_manager):
|
||||
"""
|
||||
Based on url return a network client instance
|
||||
"""
|
||||
|
||||
if settings.get("protocol", "http") == "ssh":
|
||||
from gns3.ssh_client import SSHClient
|
||||
return SSHClient(settings, network_manager)
|
||||
else:
|
||||
from gns3.http_client import HTTPClient
|
||||
return HTTPClient(settings, network_manager)
|
||||
|
||||
|
||||
def getNetworkUrl(protocol, host, port, user=None, settings={}):
|
||||
"""
|
||||
Return a network url from settings
|
||||
|
||||
:param protocol: server protocol (http/ssh)
|
||||
:param protocol: server protocol (http/https)
|
||||
:param host: host address
|
||||
:param port: port
|
||||
:param user: the username
|
||||
:param settings: Additional settings
|
||||
"""
|
||||
|
||||
if protocol == "ssh":
|
||||
return "{protocol}://{user}@{host}:{ssh_port}:{port}".format(protocol=protocol, user=user, host=host, port=port, ssh_port=settings["ssh_port"])
|
||||
# 64 character autogenerated user name, we hide it, it's more user friendly
|
||||
elif user and len(user) != 64:
|
||||
if user and len(user) != 64:
|
||||
|
||||
try:
|
||||
ipaddress.IPv6Address(host.rsplit('%', 1)[0]) # remove any scope ID
|
||||
|
||||
@@ -59,8 +59,6 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
self.uiRemoteServersTreeWidget.itemSelectionChanged.connect(self._remoteServerChangedSlot)
|
||||
self.uiRestoreDefaultsPushButton.clicked.connect(self._restoreDefaultsSlot)
|
||||
self.uiLocalServerAutoStartCheckBox.stateChanged.connect(self._useLocalServerAutoStartSlot)
|
||||
self.uiRemoteServerProtocolComboBox.currentIndexChanged.connect(self._remoteServerProtocolCurrentIndexSlot)
|
||||
self.uiRemoteServerSSHKeyPushButton.clicked.connect(self._remoteServerSSHKeyPushButtonSlot)
|
||||
self.uiEnableVMCheckBox.stateChanged.connect(self._enableGNS3VMSlot)
|
||||
self.uiRefreshPushButton.clicked.connect(self._refreshVMListSlot)
|
||||
self.uiVmwareRadioButton.clicked.connect(self._listVMwareVMsSlot)
|
||||
@@ -79,8 +77,6 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
if index != -1:
|
||||
self.uiLocalServerHostComboBox.setCurrentIndex(index)
|
||||
|
||||
self._remoteServerProtocolCurrentIndexSlot(0)
|
||||
|
||||
def _tabChangedSlot(self, index):
|
||||
if index == 1:
|
||||
self._refreshVMListSlot()
|
||||
@@ -151,36 +147,6 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
else:
|
||||
self.uiGNS3VMSettingsGroupBox.setEnabled(False)
|
||||
|
||||
def _remoteServerSSHKeyPushButtonSlot(self):
|
||||
"""
|
||||
Slot to open a file browser and select an ssh key.
|
||||
"""
|
||||
|
||||
filter = ""
|
||||
ssh_dir = os.path.join(os.path.expanduser("~"), ".ssh")
|
||||
path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select the SSH key", ssh_dir, filter)
|
||||
if not path:
|
||||
return
|
||||
|
||||
self.uiRemoteServerSSHKeyLineEdit.setText(path)
|
||||
|
||||
def _remoteServerProtocolCurrentIndexSlot(self, index):
|
||||
if self.uiRemoteServerProtocolComboBox.currentText() == "SSH":
|
||||
self.uiRemoteServerPasswordLabel.hide()
|
||||
self.uiRemoteServerPasswordLineEdit.hide()
|
||||
self.uiRemoteServerSSHPortLabel.show()
|
||||
self.uiRemoteServerSSHPortSpinBox.show()
|
||||
self.uiRemoteServerSSHKeyLabel.show()
|
||||
self.uiRemoteServerSSHKeyLineEdit.show()
|
||||
self.uiRemoteServerSSHKeyPushButton.show()
|
||||
else:
|
||||
self.uiRemoteServerPasswordLabel.show()
|
||||
self.uiRemoteServerPasswordLineEdit.show()
|
||||
self.uiRemoteServerSSHPortLabel.hide()
|
||||
self.uiRemoteServerSSHPortSpinBox.hide()
|
||||
self.uiRemoteServerSSHKeyLabel.hide()
|
||||
self.uiRemoteServerSSHKeyLineEdit.hide()
|
||||
self.uiRemoteServerSSHKeyPushButton.hide()
|
||||
|
||||
def _useLocalServerAutoStartSlot(self, state):
|
||||
"""
|
||||
@@ -258,8 +224,6 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
self.uiRemoteServerPortSpinBox.setValue(port)
|
||||
self.uiRAMLimitSpinBox.setValue(settings["ram_limit"])
|
||||
self.uiRemoteServerUserLineEdit.setText(settings["user"])
|
||||
self.uiRemoteServerSSHKeyLineEdit.setText(settings.get("ssh_key", None))
|
||||
self.uiRemoteServerSSHPortSpinBox.setValue(settings.get("ssh_port", 22))
|
||||
|
||||
def _remoteServerChangedSlot(self):
|
||||
"""
|
||||
@@ -283,8 +247,6 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
ram_limit = self.uiRAMLimitSpinBox.value()
|
||||
user = self.uiRemoteServerUserLineEdit.text().strip()
|
||||
password = self.uiRemoteServerPasswordLineEdit.text().strip()
|
||||
ssh_port = self.uiRemoteServerSSHPortSpinBox.value()
|
||||
ssh_key = self.uiRemoteServerSSHKeyLineEdit.text().strip()
|
||||
|
||||
if not re.match(r"^[a-zA-Z0-9\.{}-]+$".format("\u0370-\u1CDF\u2C00-\u30FF\u4E00-\u9FBF"), host):
|
||||
QtWidgets.QMessageBox.critical(self, "Remote server", "Invalid remote server hostname {}".format(host))
|
||||
@@ -293,14 +255,6 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
QtWidgets.QMessageBox.critical(self, "Remote server", "Invalid remote server port {}".format(port))
|
||||
return
|
||||
|
||||
if protocol == "ssh" and len(user) == 0:
|
||||
QtWidgets.QMessageBox.critical(self, "Remote server", "Missing user login")
|
||||
return
|
||||
|
||||
if protocol == "ssh" and len(ssh_key) == 0:
|
||||
QtWidgets.QMessageBox.critical(self, "Remote server", "Missing SSH key")
|
||||
return
|
||||
|
||||
# check if the remote server is already defined
|
||||
for server in self._remote_servers.values():
|
||||
if server["protocol"] == protocol and server["host"] == host and server["port"] == port and server["user"] == user:
|
||||
@@ -312,9 +266,7 @@ class ServerPreferencesPage(QtWidgets.QWidget, Ui_ServerPreferencesPageWidget):
|
||||
"port": port,
|
||||
"ram_limit": ram_limit,
|
||||
"user": user,
|
||||
"password": password,
|
||||
"ssh_port": ssh_port,
|
||||
"ssh_key": ssh_key}
|
||||
"password": password}
|
||||
|
||||
# add a new entry in the tree widget
|
||||
item = QtWidgets.QTreeWidgetItem(self.uiRemoteServersTreeWidget)
|
||||
|
||||
@@ -369,7 +369,7 @@ class Project(QtCore.QObject):
|
||||
path = "/projects/{project_id}/notifications".format(project_id=self._id)
|
||||
self._notifications_stream.add(server.createHTTPQuery("GET", path, None, downloadProgressCallback=self._event_received, showProgress=False, ignoreErrors=True))
|
||||
|
||||
def _event_received(self, result, **kwargs):
|
||||
def _event_received(self, result, server=None, **kwargs):
|
||||
|
||||
log.debug("Event received: %s", result)
|
||||
if result["action"] in ["vm.started", "vm.stopped"]:
|
||||
@@ -390,4 +390,7 @@ class Project(QtCore.QObject):
|
||||
elif result["action"] == "log.info":
|
||||
log.info(result["event"]["message"])
|
||||
print("Info: " + result["event"]["message"])
|
||||
|
||||
elif result["action"] == "ping":
|
||||
# Compatible with 1.4.0 server
|
||||
if "event" in result:
|
||||
server.setSystemUsage(result["event"])
|
||||
|
||||
@@ -228,36 +228,6 @@
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"server_ssh": {
|
||||
"properties": {
|
||||
"protocol": { "enum": ["ssh"] },
|
||||
"cloud": { "type": "boolean" },
|
||||
"vm": { "type": "boolean" },
|
||||
"host": { "$ref": "#/definitions/mandatory_string" },
|
||||
"id": { "$ref": "#/definitions/numeric_id" },
|
||||
"local": { "type": "boolean" },
|
||||
"ram_limit": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"port": { "$ref": "#/definitions/network_port" },
|
||||
"ssh_key": { "$ref": "#/definitions/mandatory_string" },
|
||||
"ssh_port": { "$ref": "#/definitions/network_port" },
|
||||
"user": { "$ref": "#/definitions/mandatory_string" }
|
||||
},
|
||||
"required": [
|
||||
"protocol",
|
||||
"host",
|
||||
"id",
|
||||
"local",
|
||||
"port",
|
||||
"ssh_key",
|
||||
"ssh_port",
|
||||
"user"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"node": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -692,13 +662,7 @@
|
||||
},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{ "$ref": "#/definitions/server_http" },
|
||||
{ "$ref": "#/definitions/server_ssh" }
|
||||
]
|
||||
}
|
||||
"items": { "$ref": "#/definitions/server_http" }
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -20,6 +20,7 @@ Functions to start external serial console terminals.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
from .main_window import MainWindow
|
||||
@@ -54,7 +55,7 @@ def serialConsole(vmname, pipe_path):
|
||||
else:
|
||||
# use arguments on other platforms
|
||||
args = shlex.split(command)
|
||||
subprocess.Popen(args)
|
||||
subprocess.Popen(args, env=os.environ)
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
log.warning('could not start serial console "{}": {}'.format(command, e))
|
||||
raise
|
||||
|
||||
108
gns3/server_summary_view.py
Normal file
108
gns3/server_summary_view.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2014 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Server summary view that list all the server, their status.
|
||||
"""
|
||||
|
||||
import sip
|
||||
|
||||
from .qt import QtGui, QtCore, QtWidgets
|
||||
from .servers import Servers
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ServerItem(QtWidgets.QTreeWidgetItem):
|
||||
|
||||
"""
|
||||
Custom item for the QTreeWidget instance
|
||||
(topology summary view).
|
||||
|
||||
:param parent: parent widget
|
||||
:param server: Server instance
|
||||
"""
|
||||
|
||||
def __init__(self, parent, server):
|
||||
|
||||
super().__init__(parent)
|
||||
self._server = server
|
||||
self._parent = parent
|
||||
self._status = "unknown"
|
||||
|
||||
self._server.connection_connected_signal.connect(self._refreshStatusSlot)
|
||||
self._server.connection_closed_signal.connect(self._refreshStatusSlot)
|
||||
self._server.system_usage_updated_signal.connect(self._refreshStatusSlot)
|
||||
self._refreshStatusSlot()
|
||||
|
||||
def _refreshStatusSlot(self):
|
||||
"""
|
||||
Changes the icon to show the node status (started, stopped etc.)
|
||||
"""
|
||||
|
||||
usage = self._server.systemUsage()
|
||||
|
||||
if self._server.isLocal():
|
||||
text = "Local"
|
||||
elif self._server.isGNS3VM():
|
||||
text = "GNS3 VM"
|
||||
else:
|
||||
text = self._server.url()
|
||||
|
||||
if usage is not None and usage["cpu_usage_percent"] > 0.0:
|
||||
text = "{} CPU {}%, RAM {}%".format(text, usage["cpu_usage_percent"], usage["memory_usage_percent"])
|
||||
|
||||
self.setText(0, text)
|
||||
if self._server.connected():
|
||||
self._status = "connected"
|
||||
if usage is None or (usage["cpu_usage_percent"] < 90 and usage["memory_usage_percent"] < 90):
|
||||
self.setIcon(0, QtGui.QIcon(':/icons/led_green.svg'))
|
||||
else:
|
||||
self.setIcon(0, QtGui.QIcon(':/icons/led_yellow.svg'))
|
||||
else:
|
||||
if self._status == "unknown":
|
||||
self.setIcon(0, QtGui.QIcon(':/icons/led_gray.svg'))
|
||||
else:
|
||||
self._status = "stopped"
|
||||
self.setIcon(0, QtGui.QIcon(':/icons/led_red.svg'))
|
||||
|
||||
|
||||
class ServerSummaryView(QtWidgets.QTreeWidget):
|
||||
|
||||
"""
|
||||
Server summary view implementation.
|
||||
|
||||
:param parent: parent widget
|
||||
"""
|
||||
|
||||
def __init__(self, parent):
|
||||
|
||||
super().__init__(parent)
|
||||
Servers.instance().server_added_signal.connect(self._serverAddedSlot)
|
||||
for server in Servers.instance().servers():
|
||||
self._serverAddedSlot(server.url())
|
||||
|
||||
def _serverAddedSlot(self, url):
|
||||
"""
|
||||
Called when a server is added to the list of servers
|
||||
|
||||
:params url: URL of the server
|
||||
"""
|
||||
server = Servers.instance().getServerFromString(url)
|
||||
ServerItem(self, server)
|
||||
|
||||
@@ -34,8 +34,8 @@ import stat
|
||||
import struct
|
||||
import psutil
|
||||
|
||||
from .qt import QtNetwork, QtWidgets
|
||||
from .network_client import getNetworkClientInstance, getNetworkUrl
|
||||
from .qt import QtNetwork, QtWidgets, QtCore
|
||||
from .network_client import getNetworkUrl
|
||||
from .local_config import LocalConfig
|
||||
from .settings import SERVERS_SETTINGS
|
||||
from .local_server_config import LocalServerConfig
|
||||
@@ -48,14 +48,17 @@ import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Servers():
|
||||
class Servers(QtCore.QObject):
|
||||
|
||||
"""
|
||||
Server management class.
|
||||
"""
|
||||
|
||||
server_added_signal = QtCore.Signal(str)
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super().__init__()
|
||||
self._settings = {}
|
||||
self._local_server = None
|
||||
self._vm_server = None
|
||||
@@ -71,6 +74,17 @@ class Servers():
|
||||
self._pid_path = os.path.join(LocalConfig.configDirectory(), "gns3_server.pid")
|
||||
self.registerLocalServer()
|
||||
|
||||
def servers(self):
|
||||
"""
|
||||
Return the list of all servers, remote, vm and local
|
||||
"""
|
||||
servers = list(self._remote_servers.values())
|
||||
if self._local_server:
|
||||
servers.append(self._local_server)
|
||||
if self._vm_server:
|
||||
servers.append(self._vm_server)
|
||||
return servers
|
||||
|
||||
def registerLocalServer(self):
|
||||
"""
|
||||
Register a new local server.
|
||||
@@ -81,11 +95,13 @@ class Servers():
|
||||
port = local_server_settings["port"]
|
||||
user = local_server_settings["user"]
|
||||
password = local_server_settings["password"]
|
||||
self._local_server = getNetworkClientInstance({"host": host, "port": port, "user": user, "password": password},
|
||||
self._local_server = self.getNetworkClientInstance({"host": host, "port": port, "user": user, "password": password},
|
||||
self._network_manager)
|
||||
self._local_server.setLocal(True)
|
||||
self.server_added_signal.emit("local")
|
||||
log.info("New local server connection {} registered".format(self._local_server.url()))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _findLocalServer(self):
|
||||
"""
|
||||
@@ -231,8 +247,6 @@ class Servers():
|
||||
ram_limit=remote_server.get("ram_limit", 0),
|
||||
user=remote_server.get("user", None),
|
||||
password=remote_server.get("password", None),
|
||||
ssh_key=remote_server.get("ssh_key", None),
|
||||
ssh_port=remote_server.get("ssh_port", None),
|
||||
accept_insecure_certificate=remote_server.get("accept_insecure_certificate", False))
|
||||
|
||||
changed = False
|
||||
@@ -559,15 +573,15 @@ class Servers():
|
||||
self._local_server_process.wait(timeout=2)
|
||||
except subprocess.TimeoutExpired:
|
||||
# the local server couldn't be stopped with the normal procedure
|
||||
if sys.platform.startswith("win"):
|
||||
try:
|
||||
try:
|
||||
if sys.platform.startswith("win"):
|
||||
self._local_server_process.send_signal(signal.CTRL_BREAK_EVENT)
|
||||
# If the process is already dead we received a permission error
|
||||
# it's a race condition between the timeout and send signal
|
||||
except PermissionError:
|
||||
pass
|
||||
else:
|
||||
self._local_server_process.send_signal(signal.SIGINT)
|
||||
else:
|
||||
self._local_server_process.send_signal(signal.SIGINT)
|
||||
# If the process is already dead we received a permission error
|
||||
# it's a race condition between the timeout and send signal
|
||||
except PermissionError:
|
||||
pass
|
||||
try:
|
||||
# wait for the server to stop for maximum 2 seconds
|
||||
self._local_server_process.wait(timeout=2)
|
||||
@@ -605,10 +619,11 @@ class Servers():
|
||||
"user": gns3_vm_settings["user"],
|
||||
"password": gns3_vm_settings["password"]
|
||||
}
|
||||
server = getNetworkClientInstance(server_info, self._network_manager)
|
||||
server = self.getNetworkClientInstance(server_info, self._network_manager)
|
||||
server.setLocal(False)
|
||||
server.setGNS3VM(True)
|
||||
self._vm_server = server
|
||||
self.server_added_signal.emit("vm")
|
||||
log.info("GNS3 VM server initialized {}".format(server.url()))
|
||||
|
||||
def vmServer(self):
|
||||
@@ -620,7 +635,7 @@ class Servers():
|
||||
|
||||
return self._vm_server
|
||||
|
||||
def _addRemoteServer(self, protocol="http", host="localhost", port=8000, ram_limit=0, user=None, password=None, ssh_port=None, ssh_key=None, accept_insecure_certificate=False, id=None):
|
||||
def _addRemoteServer(self, protocol="http", host="localhost", port=8000, ram_limit=0, user=None, password=None, accept_insecure_certificate=False, id=None):
|
||||
"""
|
||||
Adds a new remote server.
|
||||
|
||||
@@ -630,8 +645,6 @@ class Servers():
|
||||
:param ram_limit: maximum RAM to be used (integer)
|
||||
:param user: user login or None
|
||||
:param password: user password or None
|
||||
:param ssh_port: ssh port or None
|
||||
:param ssh_key: ssh key
|
||||
:param accept_insecure_certificate: Accept invalid SSL certificate
|
||||
|
||||
:returns: the new remote server
|
||||
@@ -642,23 +655,31 @@ class Servers():
|
||||
"ram_limit": ram_limit,
|
||||
"protocol": protocol,
|
||||
"user": user,
|
||||
"password": password,
|
||||
"ssh_port": ssh_port,
|
||||
"ssh_key": ssh_key}
|
||||
"password": password}
|
||||
if accept_insecure_certificate:
|
||||
server["accept_insecure_certificate"] = accept_insecure_certificate
|
||||
server = getNetworkClientInstance(server, self._network_manager)
|
||||
server = self.getNetworkClientInstance(server, self._network_manager)
|
||||
server.setLocal(False)
|
||||
self._remote_servers[server.url()] = server
|
||||
self.server_added_signal.emit(server.url())
|
||||
log.info("New remote server connection {} registered".format(server.url()))
|
||||
|
||||
return server
|
||||
|
||||
def getNetworkClientInstance(self, settings, network_manager):
|
||||
"""
|
||||
Based on url return a network client instance
|
||||
"""
|
||||
|
||||
from gns3.http_client import HTTPClient
|
||||
client = HTTPClient(settings, network_manager)
|
||||
return client
|
||||
|
||||
def getRemoteServer(self, protocol, host, port, user, settings={}):
|
||||
"""
|
||||
Gets a remote server.
|
||||
|
||||
:param protocol: server protocol (http/ssh)
|
||||
:param protocol: server protocol (http/https)
|
||||
:param host: host address
|
||||
:param port: port
|
||||
:param user: the username
|
||||
@@ -691,13 +712,12 @@ class Servers():
|
||||
return self.anyRemoteServer()
|
||||
|
||||
if "://" in server_name:
|
||||
for server in self.servers():
|
||||
if server.url() == server_name:
|
||||
return server
|
||||
url_settings = urllib.parse.urlparse(server_name)
|
||||
if url_settings.scheme == "ssh":
|
||||
_, ssh_port, port = url_settings.netloc.split(":")
|
||||
settings = {"ssh_port": int(ssh_port)}
|
||||
else:
|
||||
settings = {}
|
||||
port = url_settings.port
|
||||
settings = {}
|
||||
port = url_settings.port
|
||||
return self.getRemoteServer(url_settings.scheme, url_settings.hostname, port, url_settings.username, settings=settings)
|
||||
else:
|
||||
(host, port) = server_name.split(":")
|
||||
@@ -742,9 +762,10 @@ class Servers():
|
||||
if server_id in self._remote_servers:
|
||||
continue
|
||||
|
||||
new_server = getNetworkClientInstance(server, self._network_manager)
|
||||
new_server = self.getNetworkClientInstance(server, self._network_manager)
|
||||
new_server.setLocal(False)
|
||||
self._remote_servers[server_id] = new_server
|
||||
self.server_added_signal.emit(new_server.url())
|
||||
log.info("New remote server connection {} registered".format(new_server.url()))
|
||||
|
||||
def remoteServers(self):
|
||||
@@ -801,6 +822,8 @@ class Servers():
|
||||
|
||||
if self._local_server.connected():
|
||||
self._local_server.close()
|
||||
if self._vm_server is not None and self._vm_server.connected():
|
||||
self._vm_server.close()
|
||||
for server in self._remote_servers.values():
|
||||
if server.connected():
|
||||
server.close()
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import paramiko
|
||||
|
||||
from gns3.http_client import HTTPClient
|
||||
from gns3.tunnel.endpoint import Endpoint
|
||||
from gns3.qt import QtCore
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SSHConnectionThread(QtCore.QThread):
|
||||
error_signal = QtCore.pyqtSignal(str)
|
||||
connected_signal = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, ssh_client, parent=None):
|
||||
self._ssh_client = ssh_client
|
||||
super().__init__(parent)
|
||||
|
||||
def run(self):
|
||||
port = Endpoint.find_unused_port(1000, 10000)
|
||||
if port is None:
|
||||
self.error_signal.emit("No port available in order to create SSH tunnel")
|
||||
return
|
||||
|
||||
try:
|
||||
self._ssh_client.transport = paramiko.Transport((self._ssh_client.host(), self._ssh_client.ssh_port(), ))
|
||||
self._ssh_client.transport.set_keepalive(30)
|
||||
with open(self._ssh_client.ssh_key()) as f:
|
||||
self._ssh_client.transport.connect(username=self._ssh_client.user(), pkey=paramiko.RSAKey.from_private_key(f))
|
||||
|
||||
endpoint = Endpoint(("127.0.0.1", port), ("127.0.0.1", self._ssh_client._http_port), self._ssh_client.transport)
|
||||
endpoint.enable()
|
||||
self._ssh_client._endpoints[port] = endpoint
|
||||
except (paramiko.ssh_exception.SSHException, OSError) as e:
|
||||
self.error_signal.emit(str(e))
|
||||
return
|
||||
|
||||
self._ssh_client._http_port = port
|
||||
|
||||
self.connected_signal.emit()
|
||||
|
||||
|
||||
class SSHClient(HTTPClient):
|
||||
|
||||
"""
|
||||
SSH client.
|
||||
|
||||
It's create an SSH tunnel and run HTTP query inside the tunnel
|
||||
|
||||
:param settings: Settings to connect to the server
|
||||
:param network_manager: A QT network manager
|
||||
"""
|
||||
|
||||
def __init__(self, settings, network_manager):
|
||||
|
||||
settings["protocol"] = "http"
|
||||
settings["http_host"] = "127.0.0.1"
|
||||
self._ssh_port = settings["ssh_port"]
|
||||
self._ssh_key = settings["ssh_key"]
|
||||
self._endpoints = {}
|
||||
assert settings["ssh_port"] is not None
|
||||
assert settings["ssh_key"] is not None
|
||||
super().__init__(settings, network_manager)
|
||||
|
||||
def _connect(self, query):
|
||||
"""
|
||||
Initialize the connection
|
||||
|
||||
:param query: The query to execute when all network stack is ready
|
||||
:param callback: User callback when connection is finish
|
||||
"""
|
||||
|
||||
log.info("SSH connection to %s with key %s", self.url(), self.ssh_key())
|
||||
thread = SSHConnectionThread(self, parent=self)
|
||||
thread.error_signal.connect(lambda msg: self._connectionError(None, msg))
|
||||
thread.connected_signal.connect(lambda: super(SSHClient, self)._connect(query ))
|
||||
thread.start()
|
||||
|
||||
def getTunnel(self, port):
|
||||
"""
|
||||
Get a tunnel to the remote port.
|
||||
For HTTP standard client it's the same port. For SSH it will be different
|
||||
|
||||
:param port: Remote port
|
||||
:returns: Tuple host, port to connect
|
||||
"""
|
||||
|
||||
new_port = Endpoint.find_unused_port(1000, 10000)
|
||||
|
||||
endpoint = Endpoint(("127.0.0.1", new_port), ("127.0.0.1", port), self.transport)
|
||||
endpoint.enable()
|
||||
self._endpoints[new_port] = endpoint
|
||||
|
||||
return ("127.0.0.1", new_port)
|
||||
|
||||
def releaseTunnel(self, port):
|
||||
"""
|
||||
Release a tunnel
|
||||
|
||||
:param port: The previously allocated port
|
||||
"""
|
||||
endpoint = self._endpoints[port]
|
||||
endpoint.disable()
|
||||
del self._endpoints[port]
|
||||
|
||||
def settings(self):
|
||||
settings = super().settings()
|
||||
settings["ssh_port"] = self.ssh_port()
|
||||
settings["ssh_key"] = self.ssh_key()
|
||||
return settings
|
||||
|
||||
def ssh_port(self):
|
||||
return self._ssh_port
|
||||
|
||||
def ssh_key(self):
|
||||
return self._ssh_key
|
||||
|
||||
def protocol(self):
|
||||
return "ssh"
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close all remote connection
|
||||
"""
|
||||
for endpoint in self._endpoints.values():
|
||||
endpoint.disable()
|
||||
super().close()
|
||||
@@ -60,7 +60,8 @@ class ConsoleThread(QtCore.QThread):
|
||||
|
||||
def run(self):
|
||||
|
||||
(host, port) = self._server.getTunnel(self._port)
|
||||
host = self._server.host()
|
||||
port = self._port
|
||||
|
||||
# replace the place-holders by the actual values
|
||||
command = self._command.replace("%h", host)
|
||||
@@ -81,9 +82,6 @@ class ConsoleThread(QtCore.QThread):
|
||||
log.info('Telnet console {}:{} closed'.format(host, port))
|
||||
if sys.platform.startswith("darwin") and "osascript" in command:
|
||||
console_mutex.unlock()
|
||||
else:
|
||||
#TODO: For apple script we can't detect when the console is closed. This mean we leak a port each time you close the console
|
||||
self._server.releaseTunnel(port)
|
||||
|
||||
|
||||
def nodeTelnetConsole(name, server, port):
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
Topology summary view that list all the nodes, their status and connections.
|
||||
"""
|
||||
|
||||
import sip
|
||||
|
||||
from .qt import QtGui, QtCore, QtWidgets
|
||||
from .node import Node
|
||||
from .topology import Topology
|
||||
@@ -59,7 +61,8 @@ class TopologyNodeItem(QtWidgets.QTreeWidgetItem):
|
||||
"""
|
||||
Changes the icon to show the node status (started, stopped etc.)
|
||||
"""
|
||||
|
||||
if self is None or sip.isdeleted(self):
|
||||
return
|
||||
self.setText(0, self._node.name())
|
||||
if self._node.status() == Node.started:
|
||||
self.setIcon(0, QtGui.QIcon(':/icons/led_green.svg'))
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
import socket
|
||||
import select
|
||||
import socketserver
|
||||
import threading
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
allow_reuse_address = True
|
||||
daemon_threads = True # Kill the threads when server is closing
|
||||
|
||||
|
||||
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
chan = self.ssh_transport.open_channel('direct-tcpip',
|
||||
self.remote_address,
|
||||
self.request.getpeername())
|
||||
except Exception as e:
|
||||
log.critical('Incoming request to %s failed: %s' % (
|
||||
self.remote_address,
|
||||
str(e)
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
if chan is None:
|
||||
log.critical('Incoming request to %s:%s was rejected by the SSH server.' %
|
||||
(self.remote_address))
|
||||
return
|
||||
|
||||
log.debug('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
|
||||
chan.getpeername(), self.remote_address))
|
||||
|
||||
while True:
|
||||
r, w, x = select.select([self.request, chan], [], [])
|
||||
if self.request in r:
|
||||
data = self.request.recv(1024)
|
||||
if len(data) == 0:
|
||||
break
|
||||
chan.send(data)
|
||||
if chan in r:
|
||||
data = chan.recv(1024)
|
||||
if len(data) == 0:
|
||||
break
|
||||
self.request.send(data)
|
||||
|
||||
peername = self.request.getpeername()
|
||||
chan.close()
|
||||
self.request.close()
|
||||
log.debug('Tunnel closed from %r' % (peername,))
|
||||
|
||||
|
||||
class Endpoint:
|
||||
|
||||
def __init__(self, local_address, remote_address, transport):
|
||||
"""
|
||||
Store local and remote tunnel address information in the format:
|
||||
(ip, port) format.
|
||||
"""
|
||||
|
||||
self.local_address = local_address
|
||||
self.remote_address = remote_address
|
||||
self.transport = transport
|
||||
self.thread = None
|
||||
self.server = None
|
||||
|
||||
def get(self):
|
||||
return (self.local_address, self.remote_address)
|
||||
|
||||
def log_msg(self, msg):
|
||||
if self.thread:
|
||||
thread_name = self.thread.name
|
||||
else:
|
||||
thread_name = "Creating ID"
|
||||
|
||||
log.info("%s: local %s:%s for remote %s:%s - %s" % (
|
||||
thread_name,
|
||||
self.local_address[0],
|
||||
self.local_address[1],
|
||||
self.remote_address[0],
|
||||
self.remote_address[1],
|
||||
msg,
|
||||
))
|
||||
|
||||
def _enable(self, local_address, remote_address, ssh_transport):
|
||||
# https://github.com/paramiko/paramiko/blob/master/demos/forward.py
|
||||
# This is a little convoluted, but lets me configure things for the Handler
|
||||
# object. (SocketServer doesn't give Handlers any way to access the outer
|
||||
# server normally.)
|
||||
class EndPointHandler(ThreadedTCPRequestHandler):
|
||||
remote_address = self.remote_address
|
||||
local_address = self.local_address
|
||||
ssh_transport = self.transport
|
||||
|
||||
server = ThreadedTCPServer(self.local_address, EndPointHandler)
|
||||
|
||||
# https://docs.python.org/3.4/library/socketserver.html
|
||||
# Start a thread with the server -- that thread will then start one
|
||||
# more thread for each request
|
||||
server_thread = threading.Thread(target=server.serve_forever)
|
||||
# Exit the server thread when the main thread terminates
|
||||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
self.thread = server_thread
|
||||
self.server = server
|
||||
self.log_msg("Server thread running")
|
||||
|
||||
def getId(self):
|
||||
return self.thread.name
|
||||
|
||||
def enable(self):
|
||||
self.log_msg("Starting server thread")
|
||||
self._enable(self.local_address, self.remote_address, self.transport)
|
||||
|
||||
def disable(self):
|
||||
if self.server:
|
||||
self.log_msg("Stopping server thread")
|
||||
self.server.shutdown()
|
||||
else:
|
||||
self.log_msg("No server thread running to stop")
|
||||
|
||||
@staticmethod
|
||||
def find_unused_port(start_port, end_port, host="127.0.0.1", socket_type="TCP", ignore_ports=[]):
|
||||
"""
|
||||
Finds an unused port in a range.
|
||||
|
||||
:param start_port: first port in the range
|
||||
:param end_port: last port in the range
|
||||
:param host: host/address for bind()
|
||||
:param socket_type: TCP (default) or UDP
|
||||
:param ignore_ports: list of port to ignore within the range
|
||||
"""
|
||||
|
||||
if socket_type == "UDP":
|
||||
socket_type = socket.SOCK_DGRAM
|
||||
else:
|
||||
socket_type = socket.SOCK_STREAM
|
||||
|
||||
last_exception = None
|
||||
for port in range(start_port, end_port + 1):
|
||||
if port in ignore_ports:
|
||||
continue
|
||||
try:
|
||||
for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket_type, 0, socket.AI_PASSIVE):
|
||||
af, socktype, proto, _, sa = res
|
||||
with socket.socket(af, socktype, proto) as s:
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
s.bind(sa) # the port is available if bind is a success
|
||||
return port
|
||||
except OSError as e:
|
||||
last_exception = e
|
||||
if port + 1 == end_port:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
raise Exception("Could not find a free port between {} and {} on host {}, last exception: {}".format(start_port,
|
||||
end_port,
|
||||
host,
|
||||
last_exception))
|
||||
98
gns3/ui/doctor_dialog.ui
Executable file
98
gns3/ui/doctor_dialog.ui
Executable file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DoctorDialog</class>
|
||||
<widget class="QDialog" name="DoctorDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>607</width>
|
||||
<height>390</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>GNS3 Doctor</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>This will list potential problem in your GNS3 installation:</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="uiDoctorResultTextEdit">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'.SF NS Text'; font-size:13pt; font-weight:600; font-style:italic;">Starting checks...</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="uiOkButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
61
gns3/ui/doctor_dialog_ui.py
Normal file
61
gns3/ui/doctor_dialog_ui.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/doctor_dialog.ui'
|
||||
#
|
||||
# Created: Tue Jan 26 16:05:25 2016
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_DoctorDialog(object):
|
||||
def setupUi(self, DoctorDialog):
|
||||
DoctorDialog.setObjectName("DoctorDialog")
|
||||
DoctorDialog.setWindowModality(QtCore.Qt.WindowModal)
|
||||
DoctorDialog.resize(607, 390)
|
||||
DoctorDialog.setModal(True)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(DoctorDialog)
|
||||
self.verticalLayout.setContentsMargins(-1, -1, 12, -1)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label = QtWidgets.QLabel(DoctorDialog)
|
||||
self.label.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label.setScaledContents(False)
|
||||
self.label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
||||
self.label.setWordWrap(True)
|
||||
self.label.setObjectName("label")
|
||||
self.verticalLayout.addWidget(self.label)
|
||||
self.uiDoctorResultTextEdit = QtWidgets.QTextEdit(DoctorDialog)
|
||||
self.uiDoctorResultTextEdit.setObjectName("uiDoctorResultTextEdit")
|
||||
self.verticalLayout.addWidget(self.uiDoctorResultTextEdit)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setSpacing(20)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.uiOkButton = QtWidgets.QDialogButtonBox(DoctorDialog)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiOkButton.sizePolicy().hasHeightForWidth())
|
||||
self.uiOkButton.setSizePolicy(sizePolicy)
|
||||
self.uiOkButton.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.uiOkButton.setStandardButtons(QtWidgets.QDialogButtonBox.Ok)
|
||||
self.uiOkButton.setObjectName("uiOkButton")
|
||||
self.horizontalLayout.addWidget(self.uiOkButton)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
|
||||
self.retranslateUi(DoctorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(DoctorDialog)
|
||||
|
||||
def retranslateUi(self, DoctorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
DoctorDialog.setWindowTitle(_translate("DoctorDialog", "GNS3 Doctor"))
|
||||
self.label.setText(_translate("DoctorDialog", "<html><head/><body><p>This will list potential problem in your GNS3 installation:</p></body></html>"))
|
||||
self.uiDoctorResultTextEdit.setHtml(_translate("DoctorDialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'Ubuntu\'; font-size:11pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'.SF NS Text\'; font-size:13pt; font-weight:600; font-style:italic;\">Starting checks...</span></p></body></html>"))
|
||||
|
||||
from . import resources_rc
|
||||
@@ -113,7 +113,8 @@ background-none;
|
||||
<addaction name="uiCheckForUpdateAction"/>
|
||||
<addaction name="uiSetupWizard"/>
|
||||
<addaction name="uiLabInstructionsAction"/>
|
||||
<addaction name="uiExportDebugInformationsAction"/>
|
||||
<addaction name="uiDoctorAction"/>
|
||||
<addaction name="uiExportDebugInformationAction"/>
|
||||
<addaction name="uiAboutQtAction"/>
|
||||
<addaction name="uiAboutAction"/>
|
||||
</widget>
|
||||
@@ -420,7 +421,7 @@ background-none;
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="allowedAreas">
|
||||
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
|
||||
<set>Qt::AllDockWidgetAreas</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Topology Summary</string>
|
||||
@@ -472,6 +473,48 @@ background-none;
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="uiServerSummaryDockWidget">
|
||||
<property name="allowedAreas">
|
||||
<set>Qt::AllDockWidgetAreas</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Servers Summary</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="ServerSummaryView" name="uiServerSummaryTreeWidget">
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<action name="uiAboutAction">
|
||||
<property name="text">
|
||||
<string>&About</string>
|
||||
@@ -603,24 +646,6 @@ background-none;
|
||||
<string>Stop all devices</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="uiShowNamesAction">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../resources/resources.qrc">
|
||||
<normaloff>:/icons/show-hostname.svg</normaloff>:/icons/show-hostname.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show hostnames</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Show hostnames</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show hostnames</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="uiConsoleAllAction">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@@ -970,7 +995,7 @@ background-none;
|
||||
</action>
|
||||
<action name="uiCheckForUpdateAction">
|
||||
<property name="text">
|
||||
<string>Check for Update</string>
|
||||
<string>Check for &Update</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Check for Update</string>
|
||||
@@ -1121,7 +1146,7 @@ background-none;
|
||||
</action>
|
||||
<action name="uiLabInstructionsAction">
|
||||
<property name="text">
|
||||
<string>Lab instructions</string>
|
||||
<string>&Lab instructions</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="uiFitInViewAction">
|
||||
@@ -1219,9 +1244,17 @@ background-none;
|
||||
<string>Import appliance</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="uiExportDebugInformationsAction">
|
||||
<action name="uiExportDebugInformationAction">
|
||||
<property name="text">
|
||||
<string>Export debug informations</string>
|
||||
<string>Export debug information</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>&Export debug information</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="uiDoctorAction">
|
||||
<property name="text">
|
||||
<string>GNS3 &Doctor</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
@@ -1246,6 +1279,11 @@ background-none;
|
||||
<extends>QTreeWidget</extends>
|
||||
<header>..topology_summary_view.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ServerSummaryView</class>
|
||||
<extends>QTreeWidget</extends>
|
||||
<header>..server_summary_view.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>uiGraphicsView</tabstop>
|
||||
|
||||
@@ -8,30 +8,28 @@
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.setWindowModality(QtCore.Qt.NonModal)
|
||||
MainWindow.resize(984, 715)
|
||||
MainWindow.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
|
||||
MainWindow.setStyleSheet("#toolBar_Devices QToolButton {\n"
|
||||
"width: 50px;\n"
|
||||
"height: 55px;\n"
|
||||
"border:solid 1px black opacity 0.4;\n"
|
||||
"background-none;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"#toolBar_General QToolButton {\n"
|
||||
"width: 36px;\n"
|
||||
"height: 36px;\n"
|
||||
"border:solid 1px black opacity 0.4;\n"
|
||||
"background-none;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"")
|
||||
MainWindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks | QtWidgets.QMainWindow.AnimatedDocks)
|
||||
"width: 50px;\n"
|
||||
"height: 55px;\n"
|
||||
"border:solid 1px black opacity 0.4;\n"
|
||||
"background-none;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"#toolBar_General QToolButton {\n"
|
||||
"width: 36px;\n"
|
||||
"height: 36px;\n"
|
||||
"border:solid 1px black opacity 0.4;\n"
|
||||
"background-none;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"")
|
||||
MainWindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks|QtWidgets.QMainWindow.AnimatedDocks)
|
||||
self.uiCentralWidget = QtWidgets.QWidget(MainWindow)
|
||||
self.uiCentralWidget.setObjectName("uiCentralWidget")
|
||||
self.gridlayout = QtWidgets.QGridLayout(self.uiCentralWidget)
|
||||
@@ -83,7 +81,7 @@ class Ui_MainWindow(object):
|
||||
self.uiNodesDockWidget.setEnabled(True)
|
||||
self.uiNodesDockWidget.setVisible(True)
|
||||
self.uiNodesDockWidget.setFloating(False)
|
||||
self.uiNodesDockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea)
|
||||
self.uiNodesDockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
|
||||
self.uiNodesDockWidget.setObjectName("uiNodesDockWidget")
|
||||
self.uiNodesDockWidgetContents = QtWidgets.QWidget()
|
||||
self.uiNodesDockWidgetContents.setObjectName("uiNodesDockWidgetContents")
|
||||
@@ -145,7 +143,7 @@ class Ui_MainWindow(object):
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiTopologySummaryDockWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiTopologySummaryDockWidget.setSizePolicy(sizePolicy)
|
||||
self.uiTopologySummaryDockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea)
|
||||
self.uiTopologySummaryDockWidget.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas)
|
||||
self.uiTopologySummaryDockWidget.setObjectName("uiTopologySummaryDockWidget")
|
||||
self.uiTopologySummaryDockWidgetContents = QtWidgets.QWidget()
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
@@ -169,6 +167,22 @@ class Ui_MainWindow(object):
|
||||
self.gridlayout1.addWidget(self.uiTopologySummaryTreeWidget, 0, 0, 1, 1)
|
||||
self.uiTopologySummaryDockWidget.setWidget(self.uiTopologySummaryDockWidgetContents)
|
||||
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.uiTopologySummaryDockWidget)
|
||||
self.uiServerSummaryDockWidget = QtWidgets.QDockWidget(MainWindow)
|
||||
self.uiServerSummaryDockWidget.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas)
|
||||
self.uiServerSummaryDockWidget.setObjectName("uiServerSummaryDockWidget")
|
||||
self.dockWidgetContents = QtWidgets.QWidget()
|
||||
self.dockWidgetContents.setObjectName("dockWidgetContents")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.dockWidgetContents)
|
||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout.setSpacing(0)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.uiServerSummaryTreeWidget = ServerSummaryView(self.dockWidgetContents)
|
||||
self.uiServerSummaryTreeWidget.setObjectName("uiServerSummaryTreeWidget")
|
||||
self.uiServerSummaryTreeWidget.headerItem().setText(0, "1")
|
||||
self.uiServerSummaryTreeWidget.header().setVisible(False)
|
||||
self.gridLayout.addWidget(self.uiServerSummaryTreeWidget, 0, 0, 1, 1)
|
||||
self.uiServerSummaryDockWidget.setWidget(self.dockWidgetContents)
|
||||
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.uiServerSummaryDockWidget)
|
||||
self.uiAboutAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiAboutAction.setMenuRole(QtWidgets.QAction.AboutRole)
|
||||
self.uiAboutAction.setObjectName("uiAboutAction")
|
||||
@@ -212,32 +226,26 @@ class Ui_MainWindow(object):
|
||||
icon6.addPixmap(QtGui.QPixmap(":/icons/stop-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiStopAllAction.setIcon(icon6)
|
||||
self.uiStopAllAction.setObjectName("uiStopAllAction")
|
||||
self.uiShowNamesAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiShowNamesAction.setCheckable(True)
|
||||
icon7 = QtGui.QIcon()
|
||||
icon7.addPixmap(QtGui.QPixmap(":/icons/show-hostname.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiShowNamesAction.setIcon(icon7)
|
||||
self.uiShowNamesAction.setObjectName("uiShowNamesAction")
|
||||
self.uiConsoleAllAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiConsoleAllAction.setEnabled(True)
|
||||
icon8 = QtGui.QIcon()
|
||||
icon8.addPixmap(QtGui.QPixmap(":/icons/console.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiConsoleAllAction.setIcon(icon8)
|
||||
icon7 = QtGui.QIcon()
|
||||
icon7.addPixmap(QtGui.QPixmap(":/icons/console.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiConsoleAllAction.setIcon(icon7)
|
||||
self.uiConsoleAllAction.setObjectName("uiConsoleAllAction")
|
||||
self.uiAboutQtAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiAboutQtAction.setMenuRole(QtWidgets.QAction.AboutQtRole)
|
||||
self.uiAboutQtAction.setObjectName("uiAboutQtAction")
|
||||
self.uiZoomInAction = QtWidgets.QAction(MainWindow)
|
||||
icon9 = QtGui.QIcon()
|
||||
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-in.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-in-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiZoomInAction.setIcon(icon9)
|
||||
icon8 = QtGui.QIcon()
|
||||
icon8.addPixmap(QtGui.QPixmap(":/icons/zoom-in.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon8.addPixmap(QtGui.QPixmap(":/icons/zoom-in-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiZoomInAction.setIcon(icon8)
|
||||
self.uiZoomInAction.setObjectName("uiZoomInAction")
|
||||
self.uiZoomOutAction = QtWidgets.QAction(MainWindow)
|
||||
icon10 = QtGui.QIcon()
|
||||
icon10.addPixmap(QtGui.QPixmap(":/icons/zoom-out.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon10.addPixmap(QtGui.QPixmap(":/icons/zoom-out-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiZoomOutAction.setIcon(icon10)
|
||||
icon9 = QtGui.QIcon()
|
||||
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-out.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-out-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiZoomOutAction.setIcon(icon9)
|
||||
self.uiZoomOutAction.setObjectName("uiZoomOutAction")
|
||||
self.uiZoomResetAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiZoomResetAction.setObjectName("uiZoomResetAction")
|
||||
@@ -246,82 +254,82 @@ class Ui_MainWindow(object):
|
||||
self.uiSelectNoneAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiSelectNoneAction.setObjectName("uiSelectNoneAction")
|
||||
self.uiPreferencesAction = QtWidgets.QAction(MainWindow)
|
||||
icon11 = QtGui.QIcon()
|
||||
icon11.addPixmap(QtGui.QPixmap(":/icons/applications.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiPreferencesAction.setIcon(icon11)
|
||||
icon10 = QtGui.QIcon()
|
||||
icon10.addPixmap(QtGui.QPixmap(":/icons/applications.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiPreferencesAction.setIcon(icon10)
|
||||
self.uiPreferencesAction.setMenuRole(QtWidgets.QAction.PreferencesRole)
|
||||
self.uiPreferencesAction.setObjectName("uiPreferencesAction")
|
||||
self.uiSuspendAllAction = QtWidgets.QAction(MainWindow)
|
||||
icon12 = QtGui.QIcon()
|
||||
icon12.addPixmap(QtGui.QPixmap(":/icons/pause.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon12.addPixmap(QtGui.QPixmap(":/icons/pause-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiSuspendAllAction.setIcon(icon12)
|
||||
icon11 = QtGui.QIcon()
|
||||
icon11.addPixmap(QtGui.QPixmap(":/icons/pause.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon11.addPixmap(QtGui.QPixmap(":/icons/pause-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiSuspendAllAction.setIcon(icon11)
|
||||
self.uiSuspendAllAction.setObjectName("uiSuspendAllAction")
|
||||
self.uiAddNoteAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiAddNoteAction.setCheckable(True)
|
||||
icon13 = QtGui.QIcon()
|
||||
icon13.addPixmap(QtGui.QPixmap(":/icons/add-note.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiAddNoteAction.setIcon(icon13)
|
||||
icon12 = QtGui.QIcon()
|
||||
icon12.addPixmap(QtGui.QPixmap(":/icons/add-note.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiAddNoteAction.setIcon(icon12)
|
||||
self.uiAddNoteAction.setObjectName("uiAddNoteAction")
|
||||
self.uiNewProjectAction = QtWidgets.QAction(MainWindow)
|
||||
icon14 = QtGui.QIcon()
|
||||
icon14.addPixmap(QtGui.QPixmap(":/icons/new-project.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiNewProjectAction.setIcon(icon14)
|
||||
icon13 = QtGui.QIcon()
|
||||
icon13.addPixmap(QtGui.QPixmap(":/icons/new-project.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiNewProjectAction.setIcon(icon13)
|
||||
self.uiNewProjectAction.setObjectName("uiNewProjectAction")
|
||||
self.uiImportExportConfigsAction = QtWidgets.QAction(MainWindow)
|
||||
icon15 = QtGui.QIcon()
|
||||
icon15.addPixmap(QtGui.QPixmap(":/icons/import_export_configs.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiImportExportConfigsAction.setIcon(icon15)
|
||||
icon14 = QtGui.QIcon()
|
||||
icon14.addPixmap(QtGui.QPixmap(":/icons/import_export_configs.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiImportExportConfigsAction.setIcon(icon14)
|
||||
self.uiImportExportConfigsAction.setObjectName("uiImportExportConfigsAction")
|
||||
self.uiInsertImageAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiInsertImageAction.setCheckable(False)
|
||||
icon16 = QtGui.QIcon()
|
||||
icon16.addPixmap(QtGui.QPixmap(":/icons/image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiInsertImageAction.setIcon(icon16)
|
||||
icon15 = QtGui.QIcon()
|
||||
icon15.addPixmap(QtGui.QPixmap(":/icons/image.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiInsertImageAction.setIcon(icon15)
|
||||
self.uiInsertImageAction.setObjectName("uiInsertImageAction")
|
||||
self.uiDrawRectangleAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiDrawRectangleAction.setCheckable(True)
|
||||
icon17 = QtGui.QIcon()
|
||||
icon17.addPixmap(QtGui.QPixmap(":/icons/rectangle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon17.addPixmap(QtGui.QPixmap(":/icons/rectangle-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiDrawRectangleAction.setIcon(icon17)
|
||||
icon16 = QtGui.QIcon()
|
||||
icon16.addPixmap(QtGui.QPixmap(":/icons/rectangle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon16.addPixmap(QtGui.QPixmap(":/icons/rectangle-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiDrawRectangleAction.setIcon(icon16)
|
||||
self.uiDrawRectangleAction.setObjectName("uiDrawRectangleAction")
|
||||
self.uiDrawEllipseAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiDrawEllipseAction.setCheckable(True)
|
||||
icon18 = QtGui.QIcon()
|
||||
icon18.addPixmap(QtGui.QPixmap(":/icons/ellipse.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon18.addPixmap(QtGui.QPixmap(":/icons/ellipse-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiDrawEllipseAction.setIcon(icon18)
|
||||
icon17 = QtGui.QIcon()
|
||||
icon17.addPixmap(QtGui.QPixmap(":/icons/ellipse.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon17.addPixmap(QtGui.QPixmap(":/icons/ellipse-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiDrawEllipseAction.setIcon(icon17)
|
||||
self.uiDrawEllipseAction.setObjectName("uiDrawEllipseAction")
|
||||
self.uiShowPortNamesAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiShowPortNamesAction.setCheckable(True)
|
||||
icon19 = QtGui.QIcon()
|
||||
icon19.addPixmap(QtGui.QPixmap(":/icons/show-interface-names.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiShowPortNamesAction.setIcon(icon19)
|
||||
icon18 = QtGui.QIcon()
|
||||
icon18.addPixmap(QtGui.QPixmap(":/icons/show-interface-names.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiShowPortNamesAction.setIcon(icon18)
|
||||
self.uiShowPortNamesAction.setObjectName("uiShowPortNamesAction")
|
||||
self.uiSnapshotAction = QtWidgets.QAction(MainWindow)
|
||||
icon20 = QtGui.QIcon()
|
||||
icon20.addPixmap(QtGui.QPixmap(":/icons/snapshot.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiSnapshotAction.setIcon(icon20)
|
||||
icon19 = QtGui.QIcon()
|
||||
icon19.addPixmap(QtGui.QPixmap(":/icons/snapshot.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiSnapshotAction.setIcon(icon19)
|
||||
self.uiSnapshotAction.setObjectName("uiSnapshotAction")
|
||||
self.uiShowLayersAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiShowLayersAction.setCheckable(True)
|
||||
self.uiShowLayersAction.setObjectName("uiShowLayersAction")
|
||||
self.uiSaveProjectAsAction = QtWidgets.QAction(MainWindow)
|
||||
icon21 = QtGui.QIcon()
|
||||
icon21.addPixmap(QtGui.QPixmap(":/icons/save-as-project.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiSaveProjectAsAction.setIcon(icon21)
|
||||
icon20 = QtGui.QIcon()
|
||||
icon20.addPixmap(QtGui.QPixmap(":/icons/save-as-project.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiSaveProjectAsAction.setIcon(icon20)
|
||||
self.uiSaveProjectAsAction.setObjectName("uiSaveProjectAsAction")
|
||||
self.uiReloadAllAction = QtWidgets.QAction(MainWindow)
|
||||
icon22 = QtGui.QIcon()
|
||||
icon22.addPixmap(QtGui.QPixmap(":/icons/reload.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiReloadAllAction.setIcon(icon22)
|
||||
icon21 = QtGui.QIcon()
|
||||
icon21.addPixmap(QtGui.QPixmap(":/icons/reload.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiReloadAllAction.setIcon(icon21)
|
||||
self.uiReloadAllAction.setObjectName("uiReloadAllAction")
|
||||
self.uiAuxConsoleAllAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiAuxConsoleAllAction.setEnabled(True)
|
||||
icon23 = QtGui.QIcon()
|
||||
icon23.addPixmap(QtGui.QPixmap(":/icons/aux-console.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiAuxConsoleAllAction.setIcon(icon23)
|
||||
icon22 = QtGui.QIcon()
|
||||
icon22.addPixmap(QtGui.QPixmap(":/icons/aux-console.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiAuxConsoleAllAction.setIcon(icon22)
|
||||
self.uiAuxConsoleAllAction.setObjectName("uiAuxConsoleAllAction")
|
||||
self.uiResetPortLabelsAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiResetPortLabelsAction.setObjectName("uiResetPortLabelsAction")
|
||||
@@ -335,43 +343,43 @@ class Ui_MainWindow(object):
|
||||
self.uiDefaultStyleAction.setChecked(True)
|
||||
self.uiDefaultStyleAction.setObjectName("uiDefaultStyleAction")
|
||||
self.uiBrowseRoutersAction = QtWidgets.QAction(MainWindow)
|
||||
icon24 = QtGui.QIcon()
|
||||
icon24.addPixmap(QtGui.QPixmap(":/icons/router.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon24.addPixmap(QtGui.QPixmap(":/icons/router-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseRoutersAction.setIcon(icon24)
|
||||
icon23 = QtGui.QIcon()
|
||||
icon23.addPixmap(QtGui.QPixmap(":/icons/router.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon23.addPixmap(QtGui.QPixmap(":/icons/router-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseRoutersAction.setIcon(icon23)
|
||||
self.uiBrowseRoutersAction.setObjectName("uiBrowseRoutersAction")
|
||||
self.uiBrowseSwitchesAction = QtWidgets.QAction(MainWindow)
|
||||
icon25 = QtGui.QIcon()
|
||||
icon25.addPixmap(QtGui.QPixmap(":/icons/switch.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon25.addPixmap(QtGui.QPixmap(":/icons/switch-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseSwitchesAction.setIcon(icon25)
|
||||
icon24 = QtGui.QIcon()
|
||||
icon24.addPixmap(QtGui.QPixmap(":/icons/switch.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon24.addPixmap(QtGui.QPixmap(":/icons/switch-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseSwitchesAction.setIcon(icon24)
|
||||
self.uiBrowseSwitchesAction.setObjectName("uiBrowseSwitchesAction")
|
||||
self.uiBrowseEndDevicesAction = QtWidgets.QAction(MainWindow)
|
||||
icon26 = QtGui.QIcon()
|
||||
icon26.addPixmap(QtGui.QPixmap(":/icons/PC.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon26.addPixmap(QtGui.QPixmap(":/icons/PC-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseEndDevicesAction.setIcon(icon26)
|
||||
icon25 = QtGui.QIcon()
|
||||
icon25.addPixmap(QtGui.QPixmap(":/icons/PC.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon25.addPixmap(QtGui.QPixmap(":/icons/PC-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseEndDevicesAction.setIcon(icon25)
|
||||
self.uiBrowseEndDevicesAction.setObjectName("uiBrowseEndDevicesAction")
|
||||
self.uiBrowseSecurityDevicesAction = QtWidgets.QAction(MainWindow)
|
||||
icon27 = QtGui.QIcon()
|
||||
icon27.addPixmap(QtGui.QPixmap(":/icons/firewall.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon27.addPixmap(QtGui.QPixmap(":/icons/firewall-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseSecurityDevicesAction.setIcon(icon27)
|
||||
icon26 = QtGui.QIcon()
|
||||
icon26.addPixmap(QtGui.QPixmap(":/icons/firewall.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon26.addPixmap(QtGui.QPixmap(":/icons/firewall-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseSecurityDevicesAction.setIcon(icon26)
|
||||
self.uiBrowseSecurityDevicesAction.setObjectName("uiBrowseSecurityDevicesAction")
|
||||
self.uiBrowseAllDevicesAction = QtWidgets.QAction(MainWindow)
|
||||
icon28 = QtGui.QIcon()
|
||||
icon28.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon28.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseAllDevicesAction.setIcon(icon28)
|
||||
icon27 = QtGui.QIcon()
|
||||
icon27.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon27.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
self.uiBrowseAllDevicesAction.setIcon(icon27)
|
||||
self.uiBrowseAllDevicesAction.setObjectName("uiBrowseAllDevicesAction")
|
||||
self.uiAddLinkAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiAddLinkAction.setCheckable(True)
|
||||
icon29 = QtGui.QIcon()
|
||||
icon29.addPixmap(QtGui.QPixmap(":/icons/connection-new.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon29.addPixmap(QtGui.QPixmap(":/icons/cancel-connection.svg"), QtGui.QIcon.Normal, QtGui.QIcon.On)
|
||||
icon29.addPixmap(QtGui.QPixmap(":/icons/connection-new-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
icon29.addPixmap(QtGui.QPixmap(":/icons/cancel-connection.svg"), QtGui.QIcon.Active, QtGui.QIcon.On)
|
||||
self.uiAddLinkAction.setIcon(icon29)
|
||||
icon28 = QtGui.QIcon()
|
||||
icon28.addPixmap(QtGui.QPixmap(":/icons/connection-new.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
icon28.addPixmap(QtGui.QPixmap(":/icons/connection-new-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
|
||||
icon28.addPixmap(QtGui.QPixmap(":/icons/cancel-connection.svg"), QtGui.QIcon.Active, QtGui.QIcon.On)
|
||||
icon28.addPixmap(QtGui.QPixmap(":/icons/cancel-connection.svg"), QtGui.QIcon.Normal, QtGui.QIcon.On)
|
||||
self.uiAddLinkAction.setIcon(icon28)
|
||||
self.uiAddLinkAction.setObjectName("uiAddLinkAction")
|
||||
self.uiGettingStartedAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiGettingStartedAction.setObjectName("uiGettingStartedAction")
|
||||
@@ -398,14 +406,14 @@ class Ui_MainWindow(object):
|
||||
self.uiVPCSAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiVPCSAction.setObjectName("uiVPCSAction")
|
||||
self.uiDownloadRemoteProject = QtWidgets.QAction(MainWindow)
|
||||
icon30 = QtGui.QIcon()
|
||||
icon30.addPixmap(QtGui.QPixmap(":/classic_icons/save-as-project.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiDownloadRemoteProject.setIcon(icon30)
|
||||
icon29 = QtGui.QIcon()
|
||||
icon29.addPixmap(QtGui.QPixmap(":/classic_icons/save-as-project.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiDownloadRemoteProject.setIcon(icon29)
|
||||
self.uiDownloadRemoteProject.setObjectName("uiDownloadRemoteProject")
|
||||
self.uiQemuImgWizardAction = QtWidgets.QAction(MainWindow)
|
||||
icon31 = QtGui.QIcon()
|
||||
icon31.addPixmap(QtGui.QPixmap(":/icons/qemu.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiQemuImgWizardAction.setIcon(icon31)
|
||||
icon30 = QtGui.QIcon()
|
||||
icon30.addPixmap(QtGui.QPixmap(":/icons/qemu.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.uiQemuImgWizardAction.setIcon(icon30)
|
||||
self.uiQemuImgWizardAction.setObjectName("uiQemuImgWizardAction")
|
||||
self.uiSetupWizard = QtWidgets.QAction(MainWindow)
|
||||
self.uiSetupWizard.setMenuRole(QtWidgets.QAction.NoRole)
|
||||
@@ -417,6 +425,8 @@ class Ui_MainWindow(object):
|
||||
self.uiOpenApplianceAction.setObjectName("uiOpenApplianceAction")
|
||||
self.uiExportDebugInformationAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiExportDebugInformationAction.setObjectName("uiExportDebugInformationAction")
|
||||
self.uiDoctorAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiDoctorAction.setObjectName("uiDoctorAction")
|
||||
self.uiEditMenu.addAction(self.uiSelectAllAction)
|
||||
self.uiEditMenu.addAction(self.uiSelectNoneAction)
|
||||
self.uiEditMenu.addSeparator()
|
||||
@@ -442,6 +452,7 @@ class Ui_MainWindow(object):
|
||||
self.uiHelpMenu.addAction(self.uiCheckForUpdateAction)
|
||||
self.uiHelpMenu.addAction(self.uiSetupWizard)
|
||||
self.uiHelpMenu.addAction(self.uiLabInstructionsAction)
|
||||
self.uiHelpMenu.addAction(self.uiDoctorAction)
|
||||
self.uiHelpMenu.addAction(self.uiExportDebugInformationAction)
|
||||
self.uiHelpMenu.addAction(self.uiAboutQtAction)
|
||||
self.uiHelpMenu.addAction(self.uiAboutAction)
|
||||
@@ -536,6 +547,7 @@ class Ui_MainWindow(object):
|
||||
self.uiAnnotationToolBar.setWindowTitle(_translate("MainWindow", "Drawing"))
|
||||
self.uiTopologySummaryDockWidget.setWindowTitle(_translate("MainWindow", "Topology Summary"))
|
||||
self.uiTopologySummaryTreeWidget.headerItem().setText(0, _translate("MainWindow", "1"))
|
||||
self.uiServerSummaryDockWidget.setWindowTitle(_translate("MainWindow", "Servers Summary"))
|
||||
self.uiAboutAction.setText(_translate("MainWindow", "&About"))
|
||||
self.uiAboutAction.setStatusTip(_translate("MainWindow", "About"))
|
||||
self.uiQuitAction.setText(_translate("MainWindow", "&Quit"))
|
||||
@@ -561,9 +573,6 @@ class Ui_MainWindow(object):
|
||||
self.uiStopAllAction.setText(_translate("MainWindow", "Stop all devices"))
|
||||
self.uiStopAllAction.setToolTip(_translate("MainWindow", "Stop all devices"))
|
||||
self.uiStopAllAction.setStatusTip(_translate("MainWindow", "Stop all devices"))
|
||||
self.uiShowNamesAction.setText(_translate("MainWindow", "Show hostnames"))
|
||||
self.uiShowNamesAction.setToolTip(_translate("MainWindow", "Show hostnames"))
|
||||
self.uiShowNamesAction.setStatusTip(_translate("MainWindow", "Show hostnames"))
|
||||
self.uiConsoleAllAction.setText(_translate("MainWindow", "Console connect to all devices"))
|
||||
self.uiConsoleAllAction.setToolTip(_translate("MainWindow", "Console connect to all devices"))
|
||||
self.uiConsoleAllAction.setStatusTip(_translate("MainWindow", "Console to all devices"))
|
||||
@@ -632,7 +641,7 @@ class Ui_MainWindow(object):
|
||||
self.uiResetPortLabelsAction.setText(_translate("MainWindow", "Reset interface labels"))
|
||||
self.uiResetPortLabelsAction.setToolTip(_translate("MainWindow", "Reset interface labels"))
|
||||
self.uiResetPortLabelsAction.setStatusTip(_translate("MainWindow", "Reset Interface Labels"))
|
||||
self.uiCheckForUpdateAction.setText(_translate("MainWindow", "Check for Update"))
|
||||
self.uiCheckForUpdateAction.setText(_translate("MainWindow", "Check for &Update"))
|
||||
self.uiCheckForUpdateAction.setStatusTip(_translate("MainWindow", "Check for Update"))
|
||||
self.uiEnergySavingStyleAction.setText(_translate("MainWindow", "Energy Saving"))
|
||||
self.uiEnergySavingStyleAction.setStatusTip(_translate("MainWindow", "Energy Saving Mode"))
|
||||
@@ -661,7 +670,7 @@ class Ui_MainWindow(object):
|
||||
self.uiAddLinkAction.setStatusTip(_translate("MainWindow", "Add a link"))
|
||||
self.uiGettingStartedAction.setText(_translate("MainWindow", "Getting started"))
|
||||
self.uiGettingStartedAction.setToolTip(_translate("MainWindow", "Show GNS3 news"))
|
||||
self.uiLabInstructionsAction.setText(_translate("MainWindow", "Lab instructions"))
|
||||
self.uiLabInstructionsAction.setText(_translate("MainWindow", "&Lab instructions"))
|
||||
self.uiFitInViewAction.setText(_translate("MainWindow", "Fit in view"))
|
||||
self.uiExportProjectAction.setText(_translate("MainWindow", "Backup project to cloud"))
|
||||
self.uiImportProjectAction.setText(_translate("MainWindow", "Restore backup from cloud"))
|
||||
@@ -677,9 +686,12 @@ class Ui_MainWindow(object):
|
||||
self.uiIOUVMConverterAction.setText(_translate("MainWindow", "IOU VM Converter"))
|
||||
self.uiOpenApplianceAction.setText(_translate("MainWindow", "Import appliance"))
|
||||
self.uiExportDebugInformationAction.setText(_translate("MainWindow", "Export debug information"))
|
||||
self.uiExportDebugInformationAction.setToolTip(_translate("MainWindow", "&Export debug information"))
|
||||
self.uiDoctorAction.setText(_translate("MainWindow", "GNS3 &Doctor"))
|
||||
|
||||
from ..console_view import ConsoleView
|
||||
from ..graphics_view import GraphicsView
|
||||
from ..nodes_view import NodesView
|
||||
from ..server_summary_view import ServerSummaryView
|
||||
from ..topology_summary_view import TopologySummaryView
|
||||
from . import resources_rc
|
||||
|
||||
199194
gns3/ui/resources_rc.py
199194
gns3/ui/resources_rc.py
File diff suppressed because it is too large
Load Diff
@@ -6,10 +6,16 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>609</height>
|
||||
<width>529</width>
|
||||
<height>645</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
@@ -28,10 +34,22 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="uiLocalTabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Local server</string>
|
||||
</attribute>
|
||||
@@ -207,19 +225,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>363</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -262,24 +267,11 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>363</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@@ -295,10 +287,16 @@
|
||||
<zorder>uiGeneralSettingsGroupBox</zorder>
|
||||
<zorder>uiConsolePortRangeGroupBox</zorder>
|
||||
<zorder>uiUDPPortRangeGroupBox</zorder>
|
||||
<zorder>verticalSpacer</zorder>
|
||||
<zorder>uiLocalServerAutoStartCheckBox</zorder>
|
||||
<zorder>verticalSpacer_4</zorder>
|
||||
</widget>
|
||||
<widget class="QWidget" name="uiGNS3VMTabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Local GNS3 VM</string>
|
||||
</attribute>
|
||||
@@ -343,6 +341,19 @@
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="uiVmwareRadioButton">
|
||||
<property name="text">
|
||||
@@ -360,19 +371,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
@@ -460,14 +458,14 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>320</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -475,102 +473,23 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="uiRemoteTabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Remote servers</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerUserLabel">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerHostLabel">
|
||||
<property name="text">
|
||||
<string>User:</string>
|
||||
<string>Host:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="uiRemoteServerUserLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerSSHPortLabel">
|
||||
<property name="text">
|
||||
<string>SSH port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerSSHKeyLabel">
|
||||
<property name="text">
|
||||
<string>SSH key:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QHBoxLayout" name="uiRemoteServerSSHKeyHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="uiRemoteServerSSHKeyLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiRemoteServerSSHKeyPushButton">
|
||||
<property name="text">
|
||||
<string>Browse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiAddRemoteServerPushButton">
|
||||
<property name="text">
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiDeleteRemoteServerPushButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>206</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<spacer name="spacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>390</width>
|
||||
<height>12</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="uiRemoteServersTreeWidget">
|
||||
<property name="sizePolicy">
|
||||
@@ -632,18 +551,6 @@
|
||||
<string>HTTPS</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>SSH</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerHostLabel">
|
||||
<property name="text">
|
||||
<string>Host:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
@@ -653,6 +560,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="uiRemoteServerUserLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerPortLabel">
|
||||
<property name="text">
|
||||
@@ -660,6 +577,47 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerUserLabel">
|
||||
<property name="text">
|
||||
<string>User:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiAddRemoteServerPushButton">
|
||||
<property name="text">
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiDeleteRemoteServerPushButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="uiRemoteServerPortSpinBox">
|
||||
<property name="sizePolicy">
|
||||
@@ -699,22 +657,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="uiRemoteServerSSHPortSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> TCP</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>22</number>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerPasswordLabel">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -731,12 +677,18 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServerPasswordLabel">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>uiRemoteServerProtocolComboBox</zorder>
|
||||
@@ -748,16 +700,19 @@
|
||||
<zorder>uiRAMLimitSpinBox</zorder>
|
||||
<zorder>uiRemoteServerUserLabel</zorder>
|
||||
<zorder>uiRemoteServerUserLineEdit</zorder>
|
||||
<zorder>uiRemoteServerSSHPortLabel</zorder>
|
||||
<zorder>uiRemoteServerSSHPortSpinBox</zorder>
|
||||
<zorder>uiRemoteServerSSHKeyLabel</zorder>
|
||||
<zorder>spacer_2</zorder>
|
||||
<zorder>uiRemoteServersTreeWidget</zorder>
|
||||
<zorder>uiRemoteServerProtocolLabel</zorder>
|
||||
<zorder>uiRemoteServerPasswordLineEdit</zorder>
|
||||
<zorder>uiRemoteServerPasswordLabel</zorder>
|
||||
<zorder>verticalSpacer_3</zorder>
|
||||
</widget>
|
||||
<widget class="QWidget" name="uiLoadBalancingTabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Load Balancing</string>
|
||||
</attribute>
|
||||
@@ -799,14 +754,14 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>382</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -824,7 +779,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>164</width>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -872,9 +827,6 @@
|
||||
<tabstop>uiRemoteServerPortSpinBox</tabstop>
|
||||
<tabstop>uiRemoteServerUserLineEdit</tabstop>
|
||||
<tabstop>uiRemoteServerPasswordLineEdit</tabstop>
|
||||
<tabstop>uiRemoteServerSSHPortSpinBox</tabstop>
|
||||
<tabstop>uiRemoteServerSSHKeyLineEdit</tabstop>
|
||||
<tabstop>uiRemoteServerSSHKeyPushButton</tabstop>
|
||||
<tabstop>uiAddRemoteServerPushButton</tabstop>
|
||||
<tabstop>uiDeleteRemoteServerPushButton</tabstop>
|
||||
<tabstop>uiRAMLimitSpinBox</tabstop>
|
||||
|
||||
@@ -11,7 +11,12 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
class Ui_ServerPreferencesPageWidget(object):
|
||||
def setupUi(self, ServerPreferencesPageWidget):
|
||||
ServerPreferencesPageWidget.setObjectName("ServerPreferencesPageWidget")
|
||||
ServerPreferencesPageWidget.resize(500, 609)
|
||||
ServerPreferencesPageWidget.resize(529, 645)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(ServerPreferencesPageWidget.sizePolicy().hasHeightForWidth())
|
||||
ServerPreferencesPageWidget.setSizePolicy(sizePolicy)
|
||||
ServerPreferencesPageWidget.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(ServerPreferencesPageWidget)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
@@ -21,8 +26,14 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiServerPreferenceTabWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiServerPreferenceTabWidget.setSizePolicy(sizePolicy)
|
||||
self.uiServerPreferenceTabWidget.setMaximumSize(QtCore.QSize(16777215, 16777215))
|
||||
self.uiServerPreferenceTabWidget.setObjectName("uiServerPreferenceTabWidget")
|
||||
self.uiLocalTabWidget = QtWidgets.QWidget()
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiLocalTabWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiLocalTabWidget.setSizePolicy(sizePolicy)
|
||||
self.uiLocalTabWidget.setObjectName("uiLocalTabWidget")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.uiLocalTabWidget)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
@@ -113,8 +124,6 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiConsoleEndPortSpinBox.setProperty("value", 5000)
|
||||
self.uiConsoleEndPortSpinBox.setObjectName("uiConsoleEndPortSpinBox")
|
||||
self.horizontalLayout_7.addWidget(self.uiConsoleEndPortSpinBox)
|
||||
spacerItem = QtWidgets.QSpacerItem(363, 22, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_7.addItem(spacerItem)
|
||||
self.verticalLayout.addWidget(self.uiConsolePortRangeGroupBox)
|
||||
self.uiUDPPortRangeGroupBox = QtWidgets.QGroupBox(self.uiLocalTabWidget)
|
||||
self.uiUDPPortRangeGroupBox.setObjectName("uiUDPPortRangeGroupBox")
|
||||
@@ -135,17 +144,20 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiUDPEndPortSpinBox.setProperty("value", 20000)
|
||||
self.uiUDPEndPortSpinBox.setObjectName("uiUDPEndPortSpinBox")
|
||||
self.horizontalLayout_8.addWidget(self.uiUDPEndPortSpinBox)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(363, 22, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_8.addItem(spacerItem1)
|
||||
self.verticalLayout.addWidget(self.uiUDPPortRangeGroupBox)
|
||||
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem2)
|
||||
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem)
|
||||
self.uiGeneralSettingsGroupBox.raise_()
|
||||
self.uiConsolePortRangeGroupBox.raise_()
|
||||
self.uiUDPPortRangeGroupBox.raise_()
|
||||
self.uiLocalServerAutoStartCheckBox.raise_()
|
||||
self.uiServerPreferenceTabWidget.addTab(self.uiLocalTabWidget, "")
|
||||
self.uiGNS3VMTabWidget = QtWidgets.QWidget()
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiGNS3VMTabWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiGNS3VMTabWidget.setSizePolicy(sizePolicy)
|
||||
self.uiGNS3VMTabWidget.setObjectName("uiGNS3VMTabWidget")
|
||||
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.uiGNS3VMTabWidget)
|
||||
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||
@@ -169,6 +181,8 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.gridLayout_2.addWidget(self.uiVirtualizationSoftwarLabel, 0, 0, 1, 1)
|
||||
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_4.addItem(spacerItem1)
|
||||
self.uiVmwareRadioButton = QtWidgets.QRadioButton(self.uiGNS3VMSettingsGroupBox)
|
||||
self.uiVmwareRadioButton.setChecked(True)
|
||||
self.uiVmwareRadioButton.setObjectName("uiVmwareRadioButton")
|
||||
@@ -176,8 +190,6 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiVirtualBoxRadioButton = QtWidgets.QRadioButton(self.uiGNS3VMSettingsGroupBox)
|
||||
self.uiVirtualBoxRadioButton.setObjectName("uiVirtualBoxRadioButton")
|
||||
self.horizontalLayout_4.addWidget(self.uiVirtualBoxRadioButton)
|
||||
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_4.addItem(spacerItem3)
|
||||
self.gridLayout_2.addLayout(self.horizontalLayout_4, 1, 0, 1, 2)
|
||||
self.uiVMNameLabel = QtWidgets.QLabel(self.uiGNS3VMSettingsGroupBox)
|
||||
self.uiVMNameLabel.setObjectName("uiVMNameLabel")
|
||||
@@ -222,53 +234,21 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiVMPasswordLineEdit.setObjectName("uiVMPasswordLineEdit")
|
||||
self.gridLayout_3.addWidget(self.uiVMPasswordLineEdit, 1, 1, 1, 1)
|
||||
self.verticalLayout_3.addWidget(self.groupBox)
|
||||
spacerItem4 = QtWidgets.QSpacerItem(20, 320, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout_3.addItem(spacerItem4)
|
||||
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout_3.addItem(spacerItem2)
|
||||
self.uiServerPreferenceTabWidget.addTab(self.uiGNS3VMTabWidget, "")
|
||||
self.uiRemoteTabWidget = QtWidgets.QWidget()
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiRemoteTabWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiRemoteTabWidget.setSizePolicy(sizePolicy)
|
||||
self.uiRemoteTabWidget.setObjectName("uiRemoteTabWidget")
|
||||
self.gridLayout_5 = QtWidgets.QGridLayout(self.uiRemoteTabWidget)
|
||||
self.gridLayout_5.setObjectName("gridLayout_5")
|
||||
self.uiRemoteServerUserLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerUserLabel.setObjectName("uiRemoteServerUserLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerUserLabel, 5, 0, 1, 1)
|
||||
self.uiRemoteServerUserLineEdit = QtWidgets.QLineEdit(self.uiRemoteTabWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiRemoteServerUserLineEdit.sizePolicy().hasHeightForWidth())
|
||||
self.uiRemoteServerUserLineEdit.setSizePolicy(sizePolicy)
|
||||
self.uiRemoteServerUserLineEdit.setObjectName("uiRemoteServerUserLineEdit")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerUserLineEdit, 5, 1, 1, 1)
|
||||
self.uiRemoteServerSSHPortLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerSSHPortLabel.setObjectName("uiRemoteServerSSHPortLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerSSHPortLabel, 7, 0, 1, 1)
|
||||
self.uiRemoteServerSSHKeyLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerSSHKeyLabel.setObjectName("uiRemoteServerSSHKeyLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerSSHKeyLabel, 8, 0, 1, 1)
|
||||
self.uiRemoteServerSSHKeyHorizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.uiRemoteServerSSHKeyHorizontalLayout.setObjectName("uiRemoteServerSSHKeyHorizontalLayout")
|
||||
self.uiRemoteServerSSHKeyLineEdit = QtWidgets.QLineEdit(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerSSHKeyLineEdit.setObjectName("uiRemoteServerSSHKeyLineEdit")
|
||||
self.uiRemoteServerSSHKeyHorizontalLayout.addWidget(self.uiRemoteServerSSHKeyLineEdit)
|
||||
self.uiRemoteServerSSHKeyPushButton = QtWidgets.QPushButton(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerSSHKeyPushButton.setObjectName("uiRemoteServerSSHKeyPushButton")
|
||||
self.uiRemoteServerSSHKeyHorizontalLayout.addWidget(self.uiRemoteServerSSHKeyPushButton)
|
||||
self.gridLayout_5.addLayout(self.uiRemoteServerSSHKeyHorizontalLayout, 8, 1, 1, 1)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.uiAddRemoteServerPushButton = QtWidgets.QPushButton(self.uiRemoteTabWidget)
|
||||
self.uiAddRemoteServerPushButton.setObjectName("uiAddRemoteServerPushButton")
|
||||
self.horizontalLayout_3.addWidget(self.uiAddRemoteServerPushButton)
|
||||
self.uiDeleteRemoteServerPushButton = QtWidgets.QPushButton(self.uiRemoteTabWidget)
|
||||
self.uiDeleteRemoteServerPushButton.setEnabled(False)
|
||||
self.uiDeleteRemoteServerPushButton.setObjectName("uiDeleteRemoteServerPushButton")
|
||||
self.horizontalLayout_3.addWidget(self.uiDeleteRemoteServerPushButton)
|
||||
spacerItem5 = QtWidgets.QSpacerItem(206, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_3.addItem(spacerItem5)
|
||||
self.gridLayout_5.addLayout(self.horizontalLayout_3, 9, 0, 1, 2)
|
||||
spacerItem6 = QtWidgets.QSpacerItem(390, 12, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.gridLayout_5.addItem(spacerItem6, 10, 0, 1, 2)
|
||||
self.uiRemoteServerHostLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerHostLabel.setObjectName("uiRemoteServerHostLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerHostLabel, 2, 0, 1, 1)
|
||||
self.uiRemoteServersTreeWidget = QtWidgets.QTreeWidget(self.uiRemoteTabWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
@@ -293,17 +273,36 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiRemoteServerProtocolComboBox.setObjectName("uiRemoteServerProtocolComboBox")
|
||||
self.uiRemoteServerProtocolComboBox.addItem("")
|
||||
self.uiRemoteServerProtocolComboBox.addItem("")
|
||||
self.uiRemoteServerProtocolComboBox.addItem("")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerProtocolComboBox, 1, 1, 1, 1)
|
||||
self.uiRemoteServerHostLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerHostLabel.setObjectName("uiRemoteServerHostLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerHostLabel, 2, 0, 1, 1)
|
||||
self.uiRemoteServerPortLineEdit = QtWidgets.QLineEdit(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerPortLineEdit.setObjectName("uiRemoteServerPortLineEdit")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerPortLineEdit, 2, 1, 1, 1)
|
||||
self.uiRemoteServerUserLineEdit = QtWidgets.QLineEdit(self.uiRemoteTabWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiRemoteServerUserLineEdit.sizePolicy().hasHeightForWidth())
|
||||
self.uiRemoteServerUserLineEdit.setSizePolicy(sizePolicy)
|
||||
self.uiRemoteServerUserLineEdit.setObjectName("uiRemoteServerUserLineEdit")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerUserLineEdit, 5, 1, 1, 1)
|
||||
self.uiRemoteServerPortLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerPortLabel.setObjectName("uiRemoteServerPortLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerPortLabel, 3, 0, 1, 1)
|
||||
self.uiRemoteServerUserLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerUserLabel.setObjectName("uiRemoteServerUserLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerUserLabel, 5, 0, 1, 1)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.uiAddRemoteServerPushButton = QtWidgets.QPushButton(self.uiRemoteTabWidget)
|
||||
self.uiAddRemoteServerPushButton.setObjectName("uiAddRemoteServerPushButton")
|
||||
self.horizontalLayout_3.addWidget(self.uiAddRemoteServerPushButton)
|
||||
self.uiDeleteRemoteServerPushButton = QtWidgets.QPushButton(self.uiRemoteTabWidget)
|
||||
self.uiDeleteRemoteServerPushButton.setEnabled(False)
|
||||
self.uiDeleteRemoteServerPushButton.setObjectName("uiDeleteRemoteServerPushButton")
|
||||
self.horizontalLayout_3.addWidget(self.uiDeleteRemoteServerPushButton)
|
||||
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_3.addItem(spacerItem3)
|
||||
self.gridLayout_5.addLayout(self.horizontalLayout_3, 7, 0, 1, 2)
|
||||
self.uiRemoteServerPortSpinBox = QtWidgets.QSpinBox(self.uiRemoteTabWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
@@ -323,25 +322,17 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiRAMLimitSpinBox.setSingleStep(512)
|
||||
self.uiRAMLimitSpinBox.setObjectName("uiRAMLimitSpinBox")
|
||||
self.gridLayout_5.addWidget(self.uiRAMLimitSpinBox, 4, 1, 1, 1)
|
||||
self.uiRemoteServerSSHPortSpinBox = QtWidgets.QSpinBox(self.uiRemoteTabWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiRemoteServerSSHPortSpinBox.sizePolicy().hasHeightForWidth())
|
||||
self.uiRemoteServerSSHPortSpinBox.setSizePolicy(sizePolicy)
|
||||
self.uiRemoteServerSSHPortSpinBox.setMaximum(65535)
|
||||
self.uiRemoteServerSSHPortSpinBox.setProperty("value", 22)
|
||||
self.uiRemoteServerSSHPortSpinBox.setObjectName("uiRemoteServerSSHPortSpinBox")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerSSHPortSpinBox, 7, 1, 1, 1)
|
||||
self.uiRemoteServerPasswordLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerPasswordLabel.setObjectName("uiRemoteServerPasswordLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerPasswordLabel, 6, 0, 1, 1)
|
||||
self.uiRemoteServerPasswordLineEdit = QtWidgets.QLineEdit(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerPasswordLineEdit.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase|QtCore.Qt.ImhNoPredictiveText|QtCore.Qt.ImhSensitiveData)
|
||||
self.uiRemoteServerPasswordLineEdit.setText("")
|
||||
self.uiRemoteServerPasswordLineEdit.setEchoMode(QtWidgets.QLineEdit.Password)
|
||||
self.uiRemoteServerPasswordLineEdit.setObjectName("uiRemoteServerPasswordLineEdit")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerPasswordLineEdit, 6, 1, 1, 1)
|
||||
self.uiRemoteServerPasswordLabel = QtWidgets.QLabel(self.uiRemoteTabWidget)
|
||||
self.uiRemoteServerPasswordLabel.setObjectName("uiRemoteServerPasswordLabel")
|
||||
self.gridLayout_5.addWidget(self.uiRemoteServerPasswordLabel, 6, 0, 1, 1)
|
||||
spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.gridLayout_5.addItem(spacerItem4, 8, 0, 1, 1)
|
||||
self.uiRemoteServerProtocolComboBox.raise_()
|
||||
self.uiRemoteServerHostLabel.raise_()
|
||||
self.uiRemoteServerPortLineEdit.raise_()
|
||||
@@ -351,15 +342,17 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiRAMLimitSpinBox.raise_()
|
||||
self.uiRemoteServerUserLabel.raise_()
|
||||
self.uiRemoteServerUserLineEdit.raise_()
|
||||
self.uiRemoteServerSSHPortLabel.raise_()
|
||||
self.uiRemoteServerSSHPortSpinBox.raise_()
|
||||
self.uiRemoteServerSSHKeyLabel.raise_()
|
||||
self.uiRemoteServersTreeWidget.raise_()
|
||||
self.uiRemoteServerProtocolLabel.raise_()
|
||||
self.uiRemoteServerPasswordLineEdit.raise_()
|
||||
self.uiRemoteServerPasswordLabel.raise_()
|
||||
self.uiServerPreferenceTabWidget.addTab(self.uiRemoteTabWidget, "")
|
||||
self.uiLoadBalancingTabWidget = QtWidgets.QWidget()
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiLoadBalancingTabWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiLoadBalancingTabWidget.setSizePolicy(sizePolicy)
|
||||
self.uiLoadBalancingTabWidget.setObjectName("uiLoadBalancingTabWidget")
|
||||
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.uiLoadBalancingTabWidget)
|
||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||
@@ -379,14 +372,14 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiRendezVousHashingRadioButton.setObjectName("uiRendezVousHashingRadioButton")
|
||||
self.gridLayout_4.addWidget(self.uiRendezVousHashingRadioButton, 2, 0, 1, 1)
|
||||
self.verticalLayout_4.addWidget(self.uiMethodGroupBox)
|
||||
spacerItem7 = QtWidgets.QSpacerItem(20, 382, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout_4.addItem(spacerItem7)
|
||||
spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout_4.addItem(spacerItem5)
|
||||
self.uiServerPreferenceTabWidget.addTab(self.uiLoadBalancingTabWidget, "")
|
||||
self.verticalLayout_2.addWidget(self.uiServerPreferenceTabWidget)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
spacerItem8 = QtWidgets.QSpacerItem(164, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem8)
|
||||
spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem6)
|
||||
self.uiRestoreDefaultsPushButton = QtWidgets.QPushButton(ServerPreferencesPageWidget)
|
||||
self.uiRestoreDefaultsPushButton.setObjectName("uiRestoreDefaultsPushButton")
|
||||
self.horizontalLayout_2.addWidget(self.uiRestoreDefaultsPushButton)
|
||||
@@ -424,10 +417,7 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerPortLineEdit, self.uiRemoteServerPortSpinBox)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerPortSpinBox, self.uiRemoteServerUserLineEdit)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerUserLineEdit, self.uiRemoteServerPasswordLineEdit)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerPasswordLineEdit, self.uiRemoteServerSSHPortSpinBox)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerSSHPortSpinBox, self.uiRemoteServerSSHKeyLineEdit)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerSSHKeyLineEdit, self.uiRemoteServerSSHKeyPushButton)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerSSHKeyPushButton, self.uiAddRemoteServerPushButton)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRemoteServerPasswordLineEdit, self.uiAddRemoteServerPushButton)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiAddRemoteServerPushButton, self.uiDeleteRemoteServerPushButton)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiDeleteRemoteServerPushButton, self.uiRAMLimitSpinBox)
|
||||
ServerPreferencesPageWidget.setTabOrder(self.uiRAMLimitSpinBox, self.uiRAMUsageRadioButton)
|
||||
@@ -466,24 +456,19 @@ class Ui_ServerPreferencesPageWidget(object):
|
||||
self.uiVMUserLabel.setText(_translate("ServerPreferencesPageWidget", "User:"))
|
||||
self.uiVMPasswordLabel.setText(_translate("ServerPreferencesPageWidget", "Password:"))
|
||||
self.uiServerPreferenceTabWidget.setTabText(self.uiServerPreferenceTabWidget.indexOf(self.uiGNS3VMTabWidget), _translate("ServerPreferencesPageWidget", "Local GNS3 VM"))
|
||||
self.uiRemoteServerUserLabel.setText(_translate("ServerPreferencesPageWidget", "User:"))
|
||||
self.uiRemoteServerSSHPortLabel.setText(_translate("ServerPreferencesPageWidget", "SSH port:"))
|
||||
self.uiRemoteServerSSHKeyLabel.setText(_translate("ServerPreferencesPageWidget", "SSH key:"))
|
||||
self.uiRemoteServerSSHKeyPushButton.setText(_translate("ServerPreferencesPageWidget", "Browse"))
|
||||
self.uiAddRemoteServerPushButton.setText(_translate("ServerPreferencesPageWidget", "&Add"))
|
||||
self.uiDeleteRemoteServerPushButton.setText(_translate("ServerPreferencesPageWidget", "&Delete"))
|
||||
self.uiRemoteServerHostLabel.setText(_translate("ServerPreferencesPageWidget", "Host:"))
|
||||
self.uiRemoteServersTreeWidget.headerItem().setText(3, _translate("ServerPreferencesPageWidget", "User"))
|
||||
self.uiRemoteServerProtocolLabel.setText(_translate("ServerPreferencesPageWidget", "Protocol:"))
|
||||
self.uiRemoteServerProtocolComboBox.setCurrentText(_translate("ServerPreferencesPageWidget", "HTTP"))
|
||||
self.uiRemoteServerProtocolComboBox.setItemText(0, _translate("ServerPreferencesPageWidget", "HTTP"))
|
||||
self.uiRemoteServerProtocolComboBox.setItemText(1, _translate("ServerPreferencesPageWidget", "HTTPS"))
|
||||
self.uiRemoteServerProtocolComboBox.setItemText(2, _translate("ServerPreferencesPageWidget", "SSH"))
|
||||
self.uiRemoteServerHostLabel.setText(_translate("ServerPreferencesPageWidget", "Host:"))
|
||||
self.uiRemoteServerPortLineEdit.setText(_translate("ServerPreferencesPageWidget", "192.168.56.101"))
|
||||
self.uiRemoteServerPortLabel.setText(_translate("ServerPreferencesPageWidget", "Port:"))
|
||||
self.uiRemoteServerUserLabel.setText(_translate("ServerPreferencesPageWidget", "User:"))
|
||||
self.uiAddRemoteServerPushButton.setText(_translate("ServerPreferencesPageWidget", "&Add"))
|
||||
self.uiDeleteRemoteServerPushButton.setText(_translate("ServerPreferencesPageWidget", "&Delete"))
|
||||
self.uiRAMLimitLabel.setText(_translate("ServerPreferencesPageWidget", "RAM limit:"))
|
||||
self.uiRAMLimitSpinBox.setSuffix(_translate("ServerPreferencesPageWidget", " MB"))
|
||||
self.uiRemoteServerSSHPortSpinBox.setSuffix(_translate("ServerPreferencesPageWidget", " TCP"))
|
||||
self.uiRemoteServerPasswordLabel.setText(_translate("ServerPreferencesPageWidget", "Password:"))
|
||||
self.uiServerPreferenceTabWidget.setTabText(self.uiServerPreferenceTabWidget.indexOf(self.uiRemoteTabWidget), _translate("ServerPreferencesPageWidget", "Remote servers"))
|
||||
self.uiMethodGroupBox.setTitle(_translate("ServerPreferencesPageWidget", "Method"))
|
||||
|
||||
@@ -37,14 +37,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="uiRotationLabel">
|
||||
<property name="text">
|
||||
<string>Rotation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="uiRotationSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -70,6 +70,20 @@ editing (notes only) with ALT and '+' (or P) / ALT and '-' (or M)</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="uiApplyColorToAllItemsCheckBox">
|
||||
<property name="text">
|
||||
<string>Apply the color to all selected items</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="uiApplyRotationToAllItemsCheckBox">
|
||||
<property name="text">
|
||||
<string>Apply the rotation to all selected items</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="uiApplyTextToAllItemsCheckBox">
|
||||
<property name="text">
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
|
||||
# Form implementation generated from reading ui file '/Users/noplay/code/gns3/gns3-gui/gns3/ui/text_editor_dialog.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.4.2
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_TextEditorDialog(object):
|
||||
|
||||
def setupUi(self, TextEditorDialog):
|
||||
TextEditorDialog.setObjectName("TextEditorDialog")
|
||||
TextEditorDialog.resize(457, 333)
|
||||
@@ -30,7 +28,7 @@ class Ui_TextEditorDialog(object):
|
||||
self.gridLayout.addWidget(self.uiColorPushButton, 0, 1, 1, 1)
|
||||
self.uiRotationLabel = QtWidgets.QLabel(self.uiTextSettingsGroupBox)
|
||||
self.uiRotationLabel.setObjectName("uiRotationLabel")
|
||||
self.gridLayout.addWidget(self.uiRotationLabel, 1, 0, 1, 1)
|
||||
self.gridLayout.addWidget(self.uiRotationLabel, 2, 0, 1, 1)
|
||||
self.uiRotationSpinBox = QtWidgets.QSpinBox(self.uiTextSettingsGroupBox)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
@@ -40,8 +38,14 @@ class Ui_TextEditorDialog(object):
|
||||
self.uiRotationSpinBox.setMinimum(-360)
|
||||
self.uiRotationSpinBox.setMaximum(360)
|
||||
self.uiRotationSpinBox.setObjectName("uiRotationSpinBox")
|
||||
self.gridLayout.addWidget(self.uiRotationSpinBox, 1, 1, 1, 1)
|
||||
self.gridLayout.addWidget(self.uiRotationSpinBox, 2, 1, 1, 1)
|
||||
self.verticalLayout.addWidget(self.uiTextSettingsGroupBox)
|
||||
self.uiApplyColorToAllItemsCheckBox = QtWidgets.QCheckBox(TextEditorDialog)
|
||||
self.uiApplyColorToAllItemsCheckBox.setObjectName("uiApplyColorToAllItemsCheckBox")
|
||||
self.verticalLayout.addWidget(self.uiApplyColorToAllItemsCheckBox)
|
||||
self.uiApplyRotationToAllItemsCheckBox = QtWidgets.QCheckBox(TextEditorDialog)
|
||||
self.uiApplyRotationToAllItemsCheckBox.setObjectName("uiApplyRotationToAllItemsCheckBox")
|
||||
self.verticalLayout.addWidget(self.uiApplyRotationToAllItemsCheckBox)
|
||||
self.uiApplyTextToAllItemsCheckBox = QtWidgets.QCheckBox(TextEditorDialog)
|
||||
self.uiApplyTextToAllItemsCheckBox.setObjectName("uiApplyTextToAllItemsCheckBox")
|
||||
self.verticalLayout.addWidget(self.uiApplyTextToAllItemsCheckBox)
|
||||
@@ -57,7 +61,7 @@ class Ui_TextEditorDialog(object):
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.uiButtonBox = QtWidgets.QDialogButtonBox(TextEditorDialog)
|
||||
self.uiButtonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.uiButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Apply | QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok)
|
||||
self.uiButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Apply|QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||
self.uiButtonBox.setObjectName("uiButtonBox")
|
||||
self.horizontalLayout.addWidget(self.uiButtonBox)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
@@ -76,8 +80,10 @@ class Ui_TextEditorDialog(object):
|
||||
self.uiColorLabel.setText(_translate("TextEditorDialog", "Color:"))
|
||||
self.uiRotationLabel.setText(_translate("TextEditorDialog", "Rotation:"))
|
||||
self.uiRotationSpinBox.setToolTip(_translate("TextEditorDialog", "Rotation can be ajusted on the scene for a selected item while\n"
|
||||
"editing (notes only) with ALT and \'+\' (or P) / ALT and \'-\' (or M)"))
|
||||
"editing (notes only) with ALT and \'+\' (or P) / ALT and \'-\' (or M)"))
|
||||
self.uiRotationSpinBox.setSuffix(_translate("TextEditorDialog", "°"))
|
||||
self.uiApplyColorToAllItemsCheckBox.setText(_translate("TextEditorDialog", "Apply the color to all selected items"))
|
||||
self.uiApplyRotationToAllItemsCheckBox.setText(_translate("TextEditorDialog", "Apply the rotation to all selected items"))
|
||||
self.uiApplyTextToAllItemsCheckBox.setText(_translate("TextEditorDialog", "Apply the text below to all selected items"))
|
||||
self.uiFontPushButton.setText(_translate("TextEditorDialog", "&Select font"))
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ Functions to start VNC console programs.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
from .main_window import MainWindow
|
||||
@@ -52,7 +53,7 @@ def vncConsole(host, port):
|
||||
else:
|
||||
# use arguments on other platforms
|
||||
args = shlex.split(command)
|
||||
subprocess.Popen(args)
|
||||
subprocess.Popen(args, env=os.environ)
|
||||
except (OSError, ValueError, subprocess.SubprocessError) as e:
|
||||
log.warning('could not start VNC program "{}": {}'.format(command, e))
|
||||
raise
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
jsonschema>=2.4.0
|
||||
paramiko>=1.15.1
|
||||
raven>=5.2.0
|
||||
psutil>=2.2.1
|
||||
gns3-converter>=1.2.4
|
||||
|
||||
286
resources/icons/led_gray.svg
Normal file
286
resources/icons/led_gray.svg
Normal file
@@ -0,0 +1,286 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="32"
|
||||
id="svg9493"
|
||||
inkscape:export-filename="/datas/Projs/Cliparts Stocker/led/led_circle_red.png"
|
||||
inkscape:export-xdpi="90.000000"
|
||||
inkscape:export-ydpi="90.000000"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="led_gray.svg"
|
||||
sodipodi:version="0.32"
|
||||
width="32"
|
||||
version="1.0">
|
||||
<metadata
|
||||
id="metadata3">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title></dc:title>
|
||||
<dc:description>jean.victor.balin@gmail.com</dc:description>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>led</rdf:li>
|
||||
<rdf:li>shape</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:publisher>
|
||||
<cc:Agent
|
||||
rdf:about="http://www.openclipart.org/">
|
||||
<dc:title>Open Clip Art Library</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Jean-Victor Balin</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>Jean-Victor Balin</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:date>2005-08-21</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<cc:license
|
||||
rdf:resource="http://web.resource.org/cc/PublicDomain" />
|
||||
<dc:language>en</dc:language>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://web.resource.org/cc/PublicDomain">
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs9495">
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient6650"
|
||||
inkscape:collect="always"
|
||||
x1="23.402565"
|
||||
x2="23.389874"
|
||||
xlink:href="#linearGradient6506"
|
||||
y1="44.066776"
|
||||
y2="42.883698"
|
||||
gradientTransform="matrix(0.494844,0,0,0.38268,9.310292,26.12426)" />
|
||||
<linearGradient
|
||||
id="linearGradient6494">
|
||||
<stop
|
||||
id="stop6496"
|
||||
offset="0.0000000"
|
||||
style="stop-color:red;stop-opacity:1.0000000" />
|
||||
<stop
|
||||
id="stop6498"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#ff8ba4;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient6648"
|
||||
inkscape:collect="always"
|
||||
x1="23.194286"
|
||||
x2="23.20129"
|
||||
xlink:href="#linearGradient5756"
|
||||
y1="42.794029"
|
||||
y2="43.892632"
|
||||
gradientTransform="matrix(0.620206,0,0,0.620204,6.388612,15.9637)" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient6646"
|
||||
inkscape:collect="always"
|
||||
x1="23.349695"
|
||||
x2="23.44058"
|
||||
xlink:href="#linearGradient5756"
|
||||
y1="42.767944"
|
||||
y2="43.710873"
|
||||
gradientTransform="matrix(0.692782,0,0,0.692782,4.696832,12.82138)" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient6644"
|
||||
inkscape:collect="always"
|
||||
x1="23.193102"
|
||||
x2="23.200001"
|
||||
xlink:href="#linearGradient5742"
|
||||
y1="42.42923"
|
||||
y2="44"
|
||||
gradientTransform="matrix(0.64,0,0,0.64,5.997572,15.16826)" />
|
||||
<linearGradient
|
||||
id="linearGradient6506">
|
||||
<stop
|
||||
id="stop6508"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#ffffff;stop-opacity:0.0000000;" />
|
||||
<stop
|
||||
id="stop6510"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#ffffff;stop-opacity:0.87450981;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient7498"
|
||||
inkscape:collect="always"
|
||||
x1="23.402565"
|
||||
x2="23.389874"
|
||||
xlink:href="#linearGradient6506"
|
||||
y1="44.066776"
|
||||
y2="42.883698" />
|
||||
<linearGradient
|
||||
id="linearGradient7464">
|
||||
<stop
|
||||
id="stop7466"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#00039a;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop7468"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#afa5ff;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient7496"
|
||||
inkscape:collect="always"
|
||||
x1="23.21398"
|
||||
x2="23.20129"
|
||||
xlink:href="#linearGradient7464"
|
||||
y1="42.754631"
|
||||
y2="43.892632" />
|
||||
<linearGradient
|
||||
id="linearGradient5756">
|
||||
<stop
|
||||
id="stop5758"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#828282;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop5760"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#929292;stop-opacity:0.35294119;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient9321"
|
||||
inkscape:collect="always"
|
||||
x1="22.93503"
|
||||
x2="23.662106"
|
||||
xlink:href="#linearGradient5756"
|
||||
y1="42.699776"
|
||||
y2="43.892632" />
|
||||
<linearGradient
|
||||
id="linearGradient5742">
|
||||
<stop
|
||||
id="stop5744"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#adadad;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop5746"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#f0f0f0;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient7492"
|
||||
inkscape:collect="always"
|
||||
x1="23.193102"
|
||||
x2="23.200001"
|
||||
xlink:href="#linearGradient5742"
|
||||
y1="42.42923"
|
||||
y2="44" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient9527"
|
||||
inkscape:collect="always"
|
||||
x1="23.193102"
|
||||
x2="23.200001"
|
||||
xlink:href="#linearGradient5742"
|
||||
y1="42.42923"
|
||||
y2="44" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient9529"
|
||||
inkscape:collect="always"
|
||||
x1="22.93503"
|
||||
x2="23.662106"
|
||||
xlink:href="#linearGradient5756"
|
||||
y1="42.699776"
|
||||
y2="43.892632" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient9531"
|
||||
inkscape:collect="always"
|
||||
x1="23.21398"
|
||||
x2="23.20129"
|
||||
xlink:href="#linearGradient7464"
|
||||
y1="42.754631"
|
||||
y2="43.892632" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient9533"
|
||||
inkscape:collect="always"
|
||||
x1="23.402565"
|
||||
x2="23.389874"
|
||||
xlink:href="#linearGradient6506"
|
||||
y1="44.066776"
|
||||
y2="42.883698" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
id="base"
|
||||
inkscape:current-layer="g9447"
|
||||
inkscape:cx="8.9694656"
|
||||
inkscape:cy="13.454198"
|
||||
inkscape:document-units="px"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-height="970"
|
||||
inkscape:window-width="1390"
|
||||
inkscape:window-x="1372"
|
||||
inkscape:window-y="0"
|
||||
inkscape:zoom="10.48"
|
||||
pagecolor="#ffffff"
|
||||
showgrid="false"
|
||||
inkscape:window-maximized="0" />
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Calque 1"
|
||||
transform="translate(-10.4008,2.992344)">
|
||||
<g
|
||||
id="g9447"
|
||||
style="overflow:visible"
|
||||
transform="matrix(31.25,0,0,31.25,-625.0232,-1325)">
|
||||
<path
|
||||
d="M 21.357568,42.816245 C 21.357568,43.098869 21.128192,43.328245 20.845568,43.328245 C 20.562944,43.328245 20.333568,43.098869 20.333568,42.816245 C 20.333568,42.533621 20.562944,42.304245 20.845568,42.304245 C 21.128192,42.304245 21.357568,42.533621 21.357568,42.816245 z "
|
||||
id="path6596"
|
||||
style="fill:url(#linearGradient6644);fill-opacity:1;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;overflow:visible" />
|
||||
<path
|
||||
d="M 21.258764,42.816245 C 21.258764,43.044329 21.073652,43.229441 20.845568,43.229441 C 20.617482,43.229441 20.432372,43.044329 20.432372,42.816245 C 20.432372,42.588161 20.617482,42.403049 20.845568,42.403049 C 21.073652,42.403049 21.258764,42.588161 21.258764,42.816245 z "
|
||||
id="path6598"
|
||||
style="fill:url(#linearGradient6646);fill-opacity:1;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;overflow:visible" />
|
||||
<path
|
||||
d="M 21.215476,42.816245 C 21.215476,43.020435 21.049758,43.186153 20.845568,43.186153 C 20.641378,43.186153 20.475658,43.020435 20.475658,42.816245 C 20.475658,42.612055 20.641378,42.446335 20.845568,42.446335 C 21.049758,42.446335 21.215476,42.612055 21.215476,42.816245 z "
|
||||
id="path6600"
|
||||
style="fill:url(#linearGradient6648);fill-opacity:1.0;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;overflow:visible" />
|
||||
<path
|
||||
d="M 21.140232,42.692857 C 21.140232,42.818847 21.00801,42.921099 20.845092,42.921099 C 20.682174,42.921099 20.549952,42.818847 20.549952,42.692857 C 20.549952,42.566867 20.682174,42.464615 20.845092,42.464615 C 21.00801,42.464615 21.140232,42.566867 21.140232,42.692857 z "
|
||||
id="path6602"
|
||||
style="fill:url(#linearGradient6650);fill-opacity:1;stroke:none;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;overflow:visible" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.9 KiB |
@@ -52,6 +52,7 @@
|
||||
<file>icons/delete.svg</file>
|
||||
<file>icons/led_green.svg</file>
|
||||
<file>icons/led_red.svg</file>
|
||||
<file>icons/led_gray.svg</file>
|
||||
<file>icons/led_yellow.svg</file>
|
||||
<file>icons/open.svg</file>
|
||||
<file>icons/start.svg</file>
|
||||
|
||||
@@ -88,14 +88,6 @@ def gns3vm_server():
|
||||
return Servers.instance().vmServer()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ssh_server():
|
||||
|
||||
from gns3.servers import Servers
|
||||
|
||||
return Servers.instance().getRemoteServer("ssh", "127.0.0.1", 8001, "gns3", settings={"ssh_port": 22, "ssh_key": "/tmp/key.ssh"})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def vpcs_device(local_server, project):
|
||||
|
||||
|
||||
@@ -26,6 +26,3 @@ def test_getNetworkUrl():
|
||||
assert getNetworkUrl("http", "localhost", 8000, "rsWfk49a15KipT9o8tx4vKmGRo6NtwYJ3Q2Yff6imf6PplX1hJWHJQ6ayi0XfdoF") == "http://localhost:8000"
|
||||
|
||||
|
||||
def test_ssh_getNetworkUrl():
|
||||
settings = {"ssh_port": 22}
|
||||
assert getNetworkUrl("ssh", "localhost", 8000, "root", settings=settings) == "ssh://root@localhost:22:8000"
|
||||
|
||||
@@ -98,6 +98,10 @@ def test_loadSettingsWith13LocalServerSetting(tmpdir, local_config):
|
||||
assert local_server["user"] == "world"
|
||||
assert local_server["password"] == "hello"
|
||||
|
||||
def testServers():
|
||||
servers = Servers.instance()
|
||||
http_server = servers.getRemoteServer("http", "localhost", 8000, None)
|
||||
assert len(servers.servers()) == 2
|
||||
|
||||
def test_getRemoteServer():
|
||||
servers = Servers.instance()
|
||||
@@ -107,14 +111,6 @@ def test_getRemoteServer():
|
||||
assert http_server.port() == 8000
|
||||
assert http_server.user() is None
|
||||
|
||||
ssh_server = servers.getRemoteServer("ssh", "127.0.0.1", 4000, "gns3", settings={"ssh_port": 22, "ssh_key": "/tmp/test.ssh"})
|
||||
assert ssh_server.protocol() == "ssh"
|
||||
assert ssh_server.host() == "127.0.0.1"
|
||||
assert ssh_server.port() == 4000
|
||||
assert ssh_server.user() == "gns3"
|
||||
assert ssh_server.ssh_port() == 22
|
||||
assert ssh_server.ssh_key() == "/tmp/test.ssh"
|
||||
|
||||
|
||||
def test_getServerFromString():
|
||||
|
||||
@@ -136,19 +132,6 @@ def test_getServerFromString_with_user():
|
||||
assert server.user() == "root"
|
||||
|
||||
|
||||
def test_getServerFromString_with_ssh():
|
||||
|
||||
servers = Servers.instance()
|
||||
servers._addRemoteServer("ssh", "127.0.0.1", "4000", user="root", ssh_port=22, ssh_key="/tmp/test.ssh")
|
||||
server = servers.getServerFromString("ssh://root@127.0.0.1:22:4000")
|
||||
assert server.protocol() == "ssh"
|
||||
assert server.host() == "127.0.0.1"
|
||||
assert server.port() == 4000
|
||||
assert server.user() == "root"
|
||||
assert server.ssh_port() == 22
|
||||
assert server.ssh_key() == "/tmp/test.ssh"
|
||||
|
||||
|
||||
def test_is_non_local_server_configured():
|
||||
|
||||
servers = Servers.instance()
|
||||
@@ -159,9 +142,6 @@ def test_is_non_local_server_configured():
|
||||
servers._vm_server = None
|
||||
assert servers.isNonLocalServerConfigured() is False
|
||||
|
||||
servers._addRemoteServer("ssh", "127.0.0.1", "4000", user="root", ssh_port=22, ssh_key="/tmp/test.ssh")
|
||||
assert servers.isNonLocalServerConfigured() is True
|
||||
|
||||
|
||||
def test_handle_handleSslErrors():
|
||||
"""
|
||||
|
||||
@@ -149,67 +149,6 @@ def test_dump_http_auth(vpcs_device, project, remote_server):
|
||||
}
|
||||
|
||||
|
||||
def test_dump_ssh_server(project, ssh_server):
|
||||
|
||||
from gns3.modules.vpcs.vpcs_device import VPCSDevice
|
||||
from gns3.modules.vpcs import VPCS
|
||||
|
||||
vpcs_device = VPCSDevice(VPCS(), ssh_server, project)
|
||||
vpcs_device._vpcs_device_id = str(uuid.uuid4())
|
||||
vpcs_device._settings = {"name": "VPCS 1", "script_file": "", "console": None, "startup_script": None}
|
||||
vpcs_device.setInitialized(True)
|
||||
|
||||
topology = Topology()
|
||||
topology.project = project
|
||||
topology.addNode(vpcs_device)
|
||||
|
||||
dump = topology.dump(include_gui_data=False)
|
||||
assert dict(dump) == {
|
||||
"project_id": project.id(),
|
||||
"auto_start": False,
|
||||
"name": project.name(),
|
||||
"version": __version__,
|
||||
"revision": 4,
|
||||
"topology": {
|
||||
"nodes": [
|
||||
{
|
||||
"description": "VPCS device",
|
||||
"id": vpcs_device.id(),
|
||||
"ports": [
|
||||
{
|
||||
"id": vpcs_device.ports()[0].id(),
|
||||
"name": "Ethernet0",
|
||||
"port_number": 0,
|
||||
"adapter_number": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"name": vpcs_device.name()
|
||||
},
|
||||
"server_id": ssh_server.id(),
|
||||
"type": "VPCSDevice",
|
||||
"vm_id": None
|
||||
}
|
||||
],
|
||||
"servers": [
|
||||
{
|
||||
"vm": False,
|
||||
"host": "127.0.0.1",
|
||||
"id": ssh_server.id(),
|
||||
"local": False,
|
||||
"port": 8001,
|
||||
"protocol": "ssh",
|
||||
"ram_limit": 0,
|
||||
"user": "gns3",
|
||||
"ssh_port": 22,
|
||||
"ssh_key": "/tmp/key.ssh"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "topology"
|
||||
}
|
||||
|
||||
|
||||
def test_randomize_id(project, tmpdir):
|
||||
project.setTopologyFile(str(tmpdir / "test.gns3"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user