Merge branch '2.1' into 2.2

# Conflicts:
#	gns3/compute.py
#	gns3/nodes_view.py
#	gns3/version.py
This commit is contained in:
grossmj
2018-08-29 15:35:31 +07:00
13 changed files with 62 additions and 15 deletions

View File

@@ -1,5 +1,16 @@
# Change Log
## 2.1.9 13/08/2018
* Fix incorrect short port names in topology summary. Fixes https://github.com/GNS3/gns3-gui/issues/2562
* Add compute version in server summary tooltip.
* Fix test for Qemu boot priority. Fixes #2548.
* Fix boot priority missing when installing an appliance. Fixes #2548.
* Support PATH with UTF-8 characters in OSX telnet console, fixes #2537
* Allow users to accept different MD5 hashes for preconfigured appliances. Fixes #2526.
* Do not try to update drawing if it is being deleted. Ref #2483.
* Catch exception when loading invalid appliance file.
## 2.1.8 14/06/2018
* Add error information when cannot access/read IOS/IOU config file. Ref #2501

View File

@@ -38,6 +38,7 @@ class Compute:
self._cpu_usage_percent = None
self._memory_usage_percent = None
self._capabilities = {"node_types": []}
self._last_error = None
def id(self):
"""
@@ -219,6 +220,12 @@ class Compute:
self._capabilities = value
def setLastError(self, last_error):
self._last_error = last_error
def lastError(self):
return self._last_error
def __str__(self):
return self._compute_id

View File

@@ -121,6 +121,7 @@ class ComputeManager(QtCore.QObject):
self._computes[compute_id].setCpuUsagePercent(compute["cpu_usage_percent"])
self._computes[compute_id].setMemoryUsagePercent(compute["memory_usage_percent"])
self._computes[compute_id].setCapabilities(compute["capabilities"])
self._computes[compute_id].setLastError(compute.get("last_error"))
if new_node:
self.created_signal.emit(compute_id)

View File

@@ -61,21 +61,26 @@ class ComputeItem(QtWidgets.QTreeWidgetItem):
text = "{} CPU {}%, RAM {}%".format(text, self._compute.cpuUsagePercent(), self._compute.memoryUsagePercent())
self.setText(0, text)
self.setToolTip(0, "{} version {} running on {}".format(self._compute.name(),
self._compute.capabilities().get("version", "n/a"),
self._compute.capabilities().get("platform", "")))
if self._compute.connected():
self._status = "connected"
self.setToolTip(0, "Server {} version {} running on {}".format(self._compute.name(),
self._compute.capabilities().get("version", "n/a"),
self._compute.capabilities().get("platform", "")))
if usage is None or (self._compute.cpuUsagePercent() < 90 and self._compute.memoryUsagePercent() < 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":
last_error = self._compute.lastError()
if last_error:
self.setToolTip(0, "Failed to connect to {}: {}".format(self._compute.name(), last_error))
self.setIcon(0, QtGui.QIcon(':/icons/led_red.svg'))
elif self._status == "unknown":
self.setToolTip(0, "Discovering or connecting to {}...".format(self._compute.name()))
self.setIcon(0, QtGui.QIcon(':/icons/led_gray.svg'))
else:
self._status = "stopped"
self.setToolTip(0, "{} is stopped or cannot be reached".format(self._compute.name()))
self.setIcon(0, QtGui.QIcon(':/icons/led_red.svg'))
self._parent.sortItems(0, QtCore.Qt.AscendingOrder)

View File

@@ -45,6 +45,7 @@ class Controller(QtCore.QObject):
super().__init__()
self._connected = False
self._connecting = False
self._version = None
self._cache_directory = tempfile.mkdtemp()
self._http_client = None
self._first_error = True
@@ -59,6 +60,9 @@ class Controller(QtCore.QObject):
return self._http_client.host()
def version(self):
return self._version
def isRemote(self):
"""
:returns Boolean: True if the controller is remote
@@ -156,6 +160,7 @@ class Controller(QtCore.QObject):
if self._error_dialog:
self._error_dialog.reject()
self._error_dialog = None
self._version = result.get("version")
def _httpClientConnectedSlot(self):

View File

@@ -51,7 +51,7 @@ class CrashReport:
Report crash to a third party service
"""
DSN = "sync+https://08a47076d6cf4eebb455e8e79ef1e78d:ee721159025d4e2ea044e119a8789ece@sentry.io/38506"
DSN = "sync+https://4d0138fdd3e642628228ed99c08a76d6:f51fa98dfa3c45b29de6637d176a3132@sentry.io/38506"
if hasattr(sys, "frozen"):
cacert = get_resource("cacert.pem")
if cacert is not None and os.path.isfile(cacert):
@@ -71,6 +71,8 @@ class CrashReport:
def captureException(self, exception, value, tb):
from .local_server import LocalServer
from .local_config import LocalConfig
from .controller import Controller
from .compute_manager import ComputeManager
local_server = LocalServer.instance().localServerSettings()
if local_server["report_errors"]:
@@ -102,8 +104,14 @@ class CrashReport:
sys.version_info[2]),
"python:bit": struct.calcsize("P") * 8,
"python:encoding": sys.getdefaultencoding(),
"python:frozen": "{}".format(hasattr(sys, "frozen"))
"python:frozen": "{}".format(hasattr(sys, "frozen")),
"controller:version": Controller.instance().version()
}
for index, compute in enumerate(ComputeManager.instance().computes()):
context["compute{}:version".format(index)] = compute.capabilities().get("version", "n/a")
context["compute{}:platform".format(index)] = compute.capabilities().get("platform", "n/a")
context = self._add_qt_information(context)
client.tags_context(context)
try:

View File

@@ -263,7 +263,7 @@ class SetupWizard(QtWidgets.QWizard, Ui_SetupWizard):
def _saveSettingsCallback(self, result, error=False, **kwargs):
if error:
if "message" in result:
QtWidgets.QMessageBox.critical(self, "Save settings", "Error while save settings: {}".format(result["message"]))
QtWidgets.QMessageBox.critical(self, "Save settings", "Error while saving settings: {}".format(result["message"]))
return
def _addSummaryEntry(self, name, value):

View File

@@ -391,7 +391,7 @@ class HTTPClient(QtCore.QObject):
return
if params["version"].split("-")[0] != __version__.split("-")[0]:
msg = "Client version {} is not the same as server version {}".format(__version__, params["version"])
msg = "Client version {} is not the same as server (controller) version {}".format(__version__, params["version"])
# Stable release
if __version_info__[3] == 0:
log.error(msg)

View File

@@ -56,6 +56,10 @@ class QemuVMConfigurationPage(QtWidgets.QWidget, Ui_QemuVMConfigPageWidget):
self.uiBootPriorityComboBox.addItem("Network", "n")
self.uiBootPriorityComboBox.addItem("HDD or Network", "cn")
self.uiBootPriorityComboBox.addItem("HDD or CD/DVD-ROM", "cd")
self.uiBootPriorityComboBox.addItem("CD/DVD-ROM or Network", "dn")
self.uiBootPriorityComboBox.addItem("CD/DVD-ROM or HDD", "dc")
self.uiBootPriorityComboBox.addItem("Network or HDD", "nc")
self.uiBootPriorityComboBox.addItem("Network or CD/DVD-ROM", "nd")
self.uiHdaDiskImageToolButton.clicked.connect(self._hdaDiskImageBrowserSlot)
self.uiHdbDiskImageToolButton.clicked.connect(self._hdbDiskImageBrowserSlot)

View File

@@ -162,5 +162,5 @@ class GNS3VMPreferencesPage(QtWidgets.QWidget, Ui_GNS3VMPreferencesPageWidget):
def _saveSettingsCallback(self, result, error=False, **kwargs):
if error:
if "message" in result:
QtWidgets.QMessageBox.critical(self, "Save settings", "Error while save settings: {}".format(result["message"]))
QtWidgets.QMessageBox.critical(self, "Save settings", "Error while saving settings: {}".format(result["message"]))
return

View File

@@ -22,6 +22,7 @@
"enum": [
"router",
"multilayer_switch",
"switch",
"firewall",
"guest"
],
@@ -287,8 +288,8 @@
"title": "Type of console connection for the administration of the appliance"
},
"boot_priority": {
"enum": ["d", "c", "dc", "cd", "n", "nc", "nd", "cn", "dn"],
"title": "Optional define the disk boot priory. Refer to -boot option in qemu manual for more details."
"enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"],
"title": "Disk boot priority. Refer to -boot option in qemu manual for more details."
},
"kernel_command_line": {
"type": "string",

View File

@@ -23,6 +23,7 @@ import os
import sys
import uuid
import platform
import shutil
# Default projects directory location
DEFAULT_PROJECTS_PATH = os.path.normpath(os.path.expanduser("~/GNS3/projects"))
@@ -67,7 +68,11 @@ if sys.platform.startswith("win"):
'ZOC 6': r'"{}\ZOC6\zoc.exe" "/TELNET:%h:%p" /TABBED "/TITLE:%d"'.format(program_files_x86)}
# default on Windows
DEFAULT_TELNET_CONSOLE_COMMAND = PRECONFIGURED_TELNET_CONSOLE_COMMANDS["Putty (included with GNS3)"]
if shutil.which("Solar-PuTTY.exe"):
# Solar-Putty is the default if it is installed.
DEFAULT_TELNET_CONSOLE_COMMAND = PRECONFIGURED_TELNET_CONSOLE_COMMANDS["Solar-Putty (included with GNS3)"]
else:
DEFAULT_TELNET_CONSOLE_COMMAND = PRECONFIGURED_TELNET_CONSOLE_COMMANDS["Putty (included with GNS3)"]
elif sys.platform.startswith("darwin"):
# Mac OS X

View File

@@ -306,7 +306,7 @@ def test_callbackConnect_major_version_invalid(http_client):
http_client._query_waiting_connections.append((None, mock))
http_client._callbackConnect(params)
assert http_client._connected is False
mock.assert_called_with({"message": "Client version {} is not the same as server version 1.2.3".format(__version__)}, error=True, server=None)
mock.assert_called_with({"message": "Client version {} is not the same as server (controller) version 1.2.3".format(__version__)}, error=True, server=None)
def test_callbackConnect_minor_version_invalid(http_client):
@@ -323,7 +323,7 @@ def test_callbackConnect_minor_version_invalid(http_client):
if __version_info__[3] == 0:
http_client._callbackConnect(params)
assert http_client._connected is False
mock.assert_called_with({"message": "Client version {} is not the same as server version {}".format(__version__, new_version)}, error=True, server=None)
mock.assert_called_with({"message": "Client version {} is not the same as server (controller) version {}".format(__version__, new_version)}, error=True, server=None)
else:
http_client._callbackConnect(params)
assert http_client._connected is True