mirror of
https://github.com/GNS3/gns3-gui.git
synced 2026-06-01 16:22:04 +03:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dfc8b7714 | ||
|
|
8c6fa9433f | ||
|
|
63837578c5 | ||
|
|
b719703dbe | ||
|
|
084d14c17e | ||
|
|
8c0fca1dd7 | ||
|
|
863d05c923 | ||
|
|
3ebaac8a2c | ||
|
|
16878c9dfa | ||
|
|
45da18bb7c | ||
|
|
7a6d06ea0c | ||
|
|
d371042647 |
11
CHANGELOG
11
CHANGELOG
@@ -1,5 +1,16 @@
|
||||
# Change Log
|
||||
|
||||
## 2.2.33 20/06/2022
|
||||
|
||||
* Upgrade sentry-sdk and psutil
|
||||
* Check that node names for Qemu and Docker are valid
|
||||
* Backport reset all console connections. Fixes #2072
|
||||
* Add more video resolutions to Docker containers using VNC. Fixes #3329
|
||||
* Add python_requires=">=3.4" in setup.py. Fixes #3326
|
||||
* Only allow post release corrective versions of GUI and server to interact
|
||||
* Allow minor versions of GUI and server to interact
|
||||
* Update VirtViewer path. Fixes #3334
|
||||
|
||||
## 2.2.32 27/04/2022
|
||||
|
||||
* Use public DSNs for Sentry
|
||||
|
||||
@@ -51,7 +51,7 @@ class CrashReport:
|
||||
Report crash to a third party service
|
||||
"""
|
||||
|
||||
DSN = "https://8aa9e09917494af7b7def60f0aed8512@o19455.ingest.sentry.io/38506"
|
||||
DSN = "https://6d2fd9dad4d3498698b0bc5c2af01996@o19455.ingest.sentry.io/38506"
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -406,15 +406,10 @@ class HTTPClient(QtCore.QObject):
|
||||
|
||||
if params["version"].split("-")[0] != __version__.split("-")[0]:
|
||||
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)
|
||||
for request, callback in self._query_waiting_connections:
|
||||
if callback is not None:
|
||||
callback({"message": msg}, error=True, server=server)
|
||||
return
|
||||
# We don't allow different major version to interact even with dev build
|
||||
elif parse_version(__version__)[:2] != parse_version(params["version"])[:2]:
|
||||
# We don't allow different versions to interact even with dev build
|
||||
# (excepting post release corrections e.g 2.2.32.1, occassionally done when fixing a packaging problem)
|
||||
# TODO: we should probably follow this standard starting with v3.0: https://semver.org/
|
||||
if parse_version(__version__)[:3] != parse_version(params["version"])[:3]:
|
||||
log.error(msg)
|
||||
for request, callback in self._query_waiting_connections:
|
||||
if callback is not None:
|
||||
|
||||
@@ -246,6 +246,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
self.uiReloadAllAction.triggered.connect(self._reloadAllActionSlot)
|
||||
self.uiAuxConsoleAllAction.triggered.connect(self._auxConsoleAllActionSlot)
|
||||
self.uiConsoleAllAction.triggered.connect(self._consoleAllActionSlot)
|
||||
self.uiResetConsoleAllAction.triggered.connect(self._consoleResetAllActionSlot)
|
||||
|
||||
# device menu is contextual and is build on-the-fly
|
||||
self.uiDeviceMenu.aboutToShow.connect(self._deviceMenuActionSlot)
|
||||
@@ -870,6 +871,15 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
if project is not None:
|
||||
project.reload_all_nodes()
|
||||
|
||||
def _consoleResetAllActionSlot(self):
|
||||
"""
|
||||
Slot called when reset all console connections.
|
||||
"""
|
||||
|
||||
project = Topology.instance().project()
|
||||
if project is not None:
|
||||
project.reset_console_all_nodes()
|
||||
|
||||
def _deviceMenuActionSlot(self):
|
||||
"""
|
||||
Slot to contextually show the device menu.
|
||||
|
||||
@@ -116,6 +116,18 @@ class DockerVM(Node):
|
||||
from .pages.docker_vm_configuration_page import DockerVMConfigurationPage
|
||||
return DockerVMConfigurationPage
|
||||
|
||||
@staticmethod
|
||||
def validateHostname(hostname):
|
||||
"""
|
||||
Checks if the hostname is valid.
|
||||
|
||||
:param hostname: hostname to check
|
||||
|
||||
:returns: boolean
|
||||
"""
|
||||
|
||||
return DockerVM.isValidRfc1123Hostname(hostname)
|
||||
|
||||
@staticmethod
|
||||
def defaultSymbol():
|
||||
"""
|
||||
|
||||
@@ -175,11 +175,26 @@
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="uiConsoleResolutionComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2560 x 1440</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1920x1080</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1680x1050</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1440x900</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1366x768</string>
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/docker/ui/docker_vm_configuration_page.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.11.3
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_dockerVMConfigPageWidget(object):
|
||||
def setupUi(self, dockerVMConfigPageWidget):
|
||||
dockerVMConfigPageWidget.setObjectName("dockerVMConfigPageWidget")
|
||||
@@ -100,6 +102,9 @@ class Ui_dockerVMConfigPageWidget(object):
|
||||
self.uiConsoleResolutionComboBox.addItem("")
|
||||
self.uiConsoleResolutionComboBox.addItem("")
|
||||
self.uiConsoleResolutionComboBox.addItem("")
|
||||
self.uiConsoleResolutionComboBox.addItem("")
|
||||
self.uiConsoleResolutionComboBox.addItem("")
|
||||
self.uiConsoleResolutionComboBox.addItem("")
|
||||
self.gridLayout.addWidget(self.uiConsoleResolutionComboBox, 8, 1, 1, 1)
|
||||
self.label = QtWidgets.QLabel(self.tab)
|
||||
self.label.setObjectName("label")
|
||||
@@ -190,13 +195,16 @@ class Ui_dockerVMConfigPageWidget(object):
|
||||
self.uiConsoleTypeComboBox.setItemText(4, _translate("dockerVMConfigPageWidget", "none"))
|
||||
self.uiConsoleAutoStartCheckBox.setText(_translate("dockerVMConfigPageWidget", "Auto start console"))
|
||||
self.uiConsoleResolutionLabel.setText(_translate("dockerVMConfigPageWidget", "VNC console resolution:"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(0, _translate("dockerVMConfigPageWidget", "1920x1080"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(1, _translate("dockerVMConfigPageWidget", "1366x768"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(2, _translate("dockerVMConfigPageWidget", "1280x1024"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(3, _translate("dockerVMConfigPageWidget", "1280x800"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(4, _translate("dockerVMConfigPageWidget", "1024x768"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(5, _translate("dockerVMConfigPageWidget", "800x600"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(6, _translate("dockerVMConfigPageWidget", "640x480"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(0, _translate("dockerVMConfigPageWidget", "2560 x 1440"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(1, _translate("dockerVMConfigPageWidget", "1920x1080"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(2, _translate("dockerVMConfigPageWidget", "1680x1050"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(3, _translate("dockerVMConfigPageWidget", "1440x900"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(4, _translate("dockerVMConfigPageWidget", "1366x768"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(5, _translate("dockerVMConfigPageWidget", "1280x1024"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(6, _translate("dockerVMConfigPageWidget", "1280x800"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(7, _translate("dockerVMConfigPageWidget", "1024x768"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(8, _translate("dockerVMConfigPageWidget", "800x600"))
|
||||
self.uiConsoleResolutionComboBox.setItemText(9, _translate("dockerVMConfigPageWidget", "640x480"))
|
||||
self.label.setText(_translate("dockerVMConfigPageWidget", "HTTP port in the container:"))
|
||||
self.label_2.setText(_translate("dockerVMConfigPageWidget", "HTTP path:"))
|
||||
self.uiEnvironmentLabel.setText(_translate("dockerVMConfigPageWidget", "Environment variables:\n"
|
||||
@@ -217,4 +225,3 @@ class Ui_dockerVMConfigPageWidget(object):
|
||||
self.uiExtraVolumeTextEdit.setPlaceholderText(_translate("dockerVMConfigPageWidget", "e.g. /etc/sysctl.d"))
|
||||
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_2), _translate("dockerVMConfigPageWidget", "Advanced"))
|
||||
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_3), _translate("dockerVMConfigPageWidget", "Usage"))
|
||||
|
||||
|
||||
@@ -310,8 +310,8 @@ class Router(Node):
|
||||
|
||||
# IOS names must start with a letter, end with a letter or digit, and
|
||||
# have as interior characters only letters, digits, and hyphens.
|
||||
# They must be 63 characters or fewer.
|
||||
if re.search(r"""^[\-\w]+$""", hostname) and len(hostname) <= 63:
|
||||
# They must be 63 characters or fewer (ARPANET rules).
|
||||
if re.search(r"""^(?!-|[0-9])[a-zA-Z0-9-]{1,63}(?<!-)$""", hostname):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -131,8 +131,8 @@ class IOUDevice(Node):
|
||||
|
||||
# IOS names must start with a letter, end with a letter or digit, and
|
||||
# have as interior characters only letters, digits, and hyphens.
|
||||
# They must be 63 characters or fewer.
|
||||
if re.search(r"""^[\-\w]+$""", hostname) and len(hostname) <= 63:
|
||||
# They must be 63 characters or fewer (ARPANET rules).
|
||||
if re.search(r"""^(?!-|[0-9])[a-zA-Z0-9-]{1,63}(?<!-)$""", hostname):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
QEMU VM implementation.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from gns3.node import Node
|
||||
from .settings import QEMU_VM_SETTINGS
|
||||
|
||||
@@ -163,6 +165,18 @@ class QemuVM(Node):
|
||||
from .pages.qemu_vm_configuration_page import QemuVMConfigurationPage
|
||||
return QemuVMConfigurationPage
|
||||
|
||||
@staticmethod
|
||||
def validateHostname(hostname):
|
||||
"""
|
||||
Checks if the hostname is valid.
|
||||
|
||||
:param hostname: hostname to check
|
||||
|
||||
:returns: boolean
|
||||
"""
|
||||
|
||||
return QemuVM.isValidRfc1123Hostname(hostname)
|
||||
|
||||
@staticmethod
|
||||
def defaultSymbol():
|
||||
"""
|
||||
|
||||
28
gns3/node.py
28
gns3/node.py
@@ -17,6 +17,7 @@
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
from gns3.controller import Controller
|
||||
from gns3.ports.ethernet_port import EthernetPort
|
||||
@@ -864,6 +865,33 @@ class Node(BaseNode):
|
||||
if error and "message" in result:
|
||||
log.error("Error while import config: {}".format(result["message"]))
|
||||
|
||||
@staticmethod
|
||||
def isValidRfc1123Hostname(hostname):
|
||||
"""
|
||||
Validate a hostname according to RFC 1123
|
||||
|
||||
Each element of the hostname must be from 1 to 63 characters long
|
||||
and the entire hostname, including the dots, can be at most 253
|
||||
characters long. Valid characters for hostnames are ASCII
|
||||
letters from a to z, the digits from 0 to 9, and the hyphen (-).
|
||||
A hostname may not start with a hyphen.
|
||||
"""
|
||||
|
||||
if hostname[-1] == ".":
|
||||
hostname = hostname[:-1] # strip exactly one dot from the right, if present
|
||||
|
||||
if len(hostname) > 253:
|
||||
return False
|
||||
|
||||
labels = hostname.split(".")
|
||||
|
||||
# the TLD must be not all-numeric
|
||||
if re.match(r"[0-9]+$", labels[-1]):
|
||||
return False
|
||||
|
||||
allowed = re.compile(r"(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$")
|
||||
return all(allowed.match(label) for label in labels)
|
||||
|
||||
@staticmethod
|
||||
def onCloseOptions():
|
||||
"""
|
||||
|
||||
@@ -365,6 +365,15 @@ class Project(QtCore.QObject):
|
||||
|
||||
Controller.instance().post("/projects/{project_id}/nodes/reload".format(project_id=self._id), None, body={}, timeout=None)
|
||||
|
||||
def reset_console_all_nodes(self):
|
||||
"""Reset console for all nodes belonging to this project"""
|
||||
|
||||
# Don't do anything if the project doesn't exist on the server
|
||||
if self._id is None:
|
||||
return
|
||||
|
||||
Controller.instance().post("/projects/{project_id}/nodes/console/reset".format(project_id=self._id), None, body={}, timeout=None)
|
||||
|
||||
def get(self, path, callback, **kwargs):
|
||||
"""
|
||||
HTTP GET on the remote server
|
||||
|
||||
@@ -213,7 +213,7 @@ else:
|
||||
if sys.platform.startswith("win"):
|
||||
# Windows
|
||||
PRECONFIGURED_SPICE_CONSOLE_COMMANDS = {
|
||||
'Remote Viewer': r'"{}\VirtViewer v7.0-256\bin\remote-viewer.exe" spice://%h:%p'.format(program_files),
|
||||
'Remote Viewer': r'"{}\VirtViewer v11.0-256\bin\remote-viewer.exe" spice://%h:%p'.format(program_files),
|
||||
}
|
||||
|
||||
# default Windows SPICE console command
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>986</width>
|
||||
<height>716</height>
|
||||
<height>719</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
@@ -151,6 +151,7 @@ background-none;
|
||||
<addaction name="uiReloadAllAction"/>
|
||||
<addaction name="uiAuxConsoleAllAction"/>
|
||||
<addaction name="uiConsoleAllAction"/>
|
||||
<addaction name="uiResetConsoleAllAction"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="uiAnnotateMenu">
|
||||
<property name="title">
|
||||
@@ -1294,6 +1295,11 @@ background-none;
|
||||
<string>Reset docks</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="uiResetConsoleAllAction">
|
||||
<property name="text">
|
||||
<string>Reset all console connections</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
@@ -450,6 +450,11 @@ class Ui_MainWindow(object):
|
||||
self.uiNewTemplateAction.setObjectName("uiNewTemplateAction")
|
||||
self.uiResetDocksAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiResetDocksAction.setObjectName("uiResetDocksAction")
|
||||
self.uiEditReadmeAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiEditReadmeAction.setIcon(icon31)
|
||||
self.uiEditReadmeAction.setObjectName("uiEditReadmeAction")
|
||||
self.uiResetConsoleAllAction = QtWidgets.QAction(MainWindow)
|
||||
self.uiResetConsoleAllAction.setObjectName("uiResetConsoleAllAction")
|
||||
self.uiEditMenu.addAction(self.uiSelectAllAction)
|
||||
self.uiEditMenu.addAction(self.uiSelectNoneAction)
|
||||
self.uiEditMenu.addSeparator()
|
||||
@@ -498,6 +503,7 @@ class Ui_MainWindow(object):
|
||||
self.uiControlMenu.addAction(self.uiReloadAllAction)
|
||||
self.uiControlMenu.addAction(self.uiAuxConsoleAllAction)
|
||||
self.uiControlMenu.addAction(self.uiConsoleAllAction)
|
||||
self.uiControlMenu.addAction(self.uiResetConsoleAllAction)
|
||||
self.uiAnnotateMenu.addAction(self.uiAddNoteAction)
|
||||
self.uiAnnotateMenu.addAction(self.uiInsertImageAction)
|
||||
self.uiAnnotateMenu.addAction(self.uiDrawRectangleAction)
|
||||
@@ -715,6 +721,9 @@ class Ui_MainWindow(object):
|
||||
self.uiWebUIAction.setText(_translate("MainWindow", "Web UI - beta"))
|
||||
self.uiNewTemplateAction.setText(_translate("MainWindow", "New template"))
|
||||
self.uiResetDocksAction.setText(_translate("MainWindow", "Reset docks"))
|
||||
self.uiEditReadmeAction.setText(_translate("MainWindow", "Edit readme"))
|
||||
self.uiEditReadmeAction.setToolTip(_translate("MainWindow", "Edit readme"))
|
||||
self.uiResetConsoleAllAction.setText(_translate("MainWindow", "Reset all console connections"))
|
||||
from ..compute_summary_view import ComputeSummaryView
|
||||
from ..console_view import ConsoleView
|
||||
from ..graphics_view import GraphicsView
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
# or negative for a release candidate or beta (after the base version
|
||||
# number has been incremented)
|
||||
|
||||
__version__ = "2.2.32"
|
||||
__version_info__ = (2, 2, 32, 0)
|
||||
__version__ = "2.2.33"
|
||||
__version_info__ = (2, 2, 33, 0)
|
||||
|
||||
if "dev" in __version__:
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
jsonschema==3.2.0
|
||||
sentry-sdk==1.5.10
|
||||
psutil==5.9.0
|
||||
distro==1.6.0
|
||||
sentry-sdk==1.5.12
|
||||
psutil==5.9.1
|
||||
distro==1.7.0
|
||||
setuptools==60.6.0; python_version >= '3.7' # don't upgrade because of https://github.com/pypa/setuptools/issues/3084
|
||||
setuptools==59.6.0; python_version < '3.7' # v59.7.0 dropped support for Python 3.6
|
||||
Reference in New Issue
Block a user