Compare commits

...

12 Commits

Author SHA1 Message Date
grossmj
8dfc8b7714 Release v2.2.33 2022-06-20 20:53:21 +02:00
grossmj
8c6fa9433f Upgrade sentry-sdk and psutil 2022-06-20 20:05:34 +02:00
Jeremy Grossmann
63837578c5 Merge pull request #3340 from GNS3/node-name-checks
Check node names
2022-06-20 19:02:37 +02:00
grossmj
b719703dbe Check that node names for Qemu and Docker are valid 2022-06-18 16:59:14 +02:00
grossmj
084d14c17e Backport reset all console connections. Fixes #2072 2022-06-15 15:58:15 +02:00
grossmj
8c0fca1dd7 Add more video resolutions to Docker containers using VNC. Fixes #3329 2022-06-09 00:26:39 +08:00
grossmj
863d05c923 Add python_requires=">=3.4" in setup.py. Fixes #3326 2022-06-07 18:27:01 +08:00
grossmj
3ebaac8a2c Only allow post release corrective versions of GUI and server to interact 2022-06-07 18:22:06 +08:00
grossmj
16878c9dfa Allow minor versions of GUI and server to interact 2022-06-07 18:06:53 +08:00
grossmj
45da18bb7c Update VirtViewer path. Fixes #3334 2022-06-07 17:35:55 +08:00
grossmj
7a6d06ea0c Development on 2.2.33dev1 2022-04-27 19:51:24 +07:00
grossmj
d371042647 Upgrade distro package to v1.7.0 2022-04-27 19:48:50 +07:00
18 changed files with 147 additions and 30 deletions

View File

@@ -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

View File

@@ -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):

View File

@@ -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:

View File

@@ -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.

View File

@@ -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():
"""

View File

@@ -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>

View File

@@ -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"))

View File

@@ -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

View File

@@ -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

View File

@@ -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():
"""

View File

@@ -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():
"""

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -78,6 +78,7 @@ setup(
include_package_data=True,
package_data={"gns3": ["configs/*.txt", "schemas/*.json"]},
platforms="any",
python_requires=">=3.4",
setup_requires=["setuptools>=17.1"],
classifiers=[
"Development Status :: 5 - Production/Stable",