diff -Nru gns3-gui-2.2.17~focal1/CHANGELOG gns3-gui-2.2.18~focal1/CHANGELOG --- gns3-gui-2.2.17~focal1/CHANGELOG 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/CHANGELOG 2021-02-16 08:45:07.000000000 +0000 @@ -1,5 +1,17 @@ # Change Log +## 2.2.18 16/02/2021 + +* SSL support. +* Remove the useless file "zoom-in (copy).svg". Fixes #3114 +* Use HDD disk image as startup QEMU config disk +* Edit only text mode config files +* Hide config import/export when configFiles attribute is empty +* Qemu disk interfaces must be set to "none" by default. Ref #3035 +* Do not allow image to be configured on Qemu VM secondary slave disk if create config disk option is enabled. +* Add explicit option to automatically create or not the config disk. Off by default. +* QEMU config disk support + ## 2.2.17 04/12/2020 * Remove "-nographic" option by default for Qemu VM. Fixes #3094 diff -Nru gns3-gui-2.2.17~focal1/debian/changelog gns3-gui-2.2.18~focal1/debian/changelog --- gns3-gui-2.2.17~focal1/debian/changelog 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/debian/changelog 2021-02-16 08:45:07.000000000 +0000 @@ -1,9 +1,15 @@ -gns3-gui (2.2.17~focal1) focal; urgency=low +gns3-gui (2.2.18~focal1) focal; urgency=low - * 2.2.17 + * 2.2.18 * Release for focal - -- Jeremy Grossmann Fri, 04 Dec 2020 06:03:42 -0000 + -- Jeremy Grossmann Tue, 16 Feb 2021 08:45:07 -0000 + +gns3-gui (2.2.17~focal1) xenial; urgency=low + + * 2.2.17 + + -- Jeremy Grossmann Fri, 04 Dec 2020 06:03:42 -0000 gns3-gui (2.2.16~focal1) xenial; urgency=low Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/certifi-2020.11.8-py2.py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/certifi-2020.11.8-py2.py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/certifi-2020.12.5-py2.py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/certifi-2020.12.5-py2.py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/sentry_sdk-0.19.4-py2.py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/sentry_sdk-0.19.4-py2.py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/sentry_sdk-0.20.2-py2.py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/sentry_sdk-0.20.2-py2.py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/setuptools-50.3.2-py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/setuptools-50.3.2-py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/setuptools-53.0.0-py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/setuptools-53.0.0-py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/urllib3-1.26.2-py2.py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/urllib3-1.26.2-py2.py3-none-any.whl differ Binary files /tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/debian/pypi/urllib3-1.26.3-py2.py3-none-any.whl and /tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/debian/pypi/urllib3-1.26.3-py2.py3-none-any.whl differ diff -Nru gns3-gui-2.2.17~focal1/gns3/controller.py gns3-gui-2.2.18~focal1/gns3/controller.py --- gns3-gui-2.2.17~focal1/gns3/controller.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/controller.py 2021-02-16 08:45:07.000000000 +0000 @@ -130,7 +130,7 @@ self._connected = False self._connecting = True - self.get('/version', self._versionGetSlot) + self.httpClient().getSynchronous('/version', self._versionGetSlot, timeout=60) def _httpClientDisconnectedSlot(self): if self._connected: @@ -423,6 +423,7 @@ self._notification_stream = self._http_client.connectWebSocket(self._websocket, "/notifications/ws") self._notification_stream.textMessageReceived.connect(self._websocket_event_received) self._notification_stream.error.connect(self._websocket_error) + self._notification_stream.sslErrors.connect(self._sslErrorsSlot) def stopListenNotifications(self): if self._notification_stream: @@ -448,6 +449,11 @@ self._startListenNotifications() @qslot + def _sslErrorsSlot(self, ssl_errors): + + self._http_client.handleSslError(self._notification_stream, ssl_errors) + + @qslot def _websocket_event_received(self, event): try: self._event_received(json.loads(event)) diff -Nru gns3-gui-2.2.17~focal1/gns3/crash_report.py gns3-gui-2.2.18~focal1/gns3/crash_report.py --- gns3-gui-2.2.17~focal1/gns3/crash_report.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/crash_report.py 2021-02-16 08:45:07.000000000 +0000 @@ -51,7 +51,7 @@ Report crash to a third party service """ - DSN = "https://32b3e599a2ea4172817ee1800d60bb42:a4e8b89f01124ce0b0508d59fdec690a@o19455.ingest.sentry.io/38506" + DSN = "https://4983a844616742629f6ff91f8cc2eb59:9a3f497bcd12445cb7769fda00921937@o19455.ingest.sentry.io/38506" _instance = None def __init__(self): diff -Nru gns3-gui-2.2.17~focal1/gns3/dialogs/edit_compute_dialog.py gns3-gui-2.2.18~focal1/gns3/dialogs/edit_compute_dialog.py --- gns3-gui-2.2.17~focal1/gns3/dialogs/edit_compute_dialog.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/dialogs/edit_compute_dialog.py 2021-02-16 08:45:07.000000000 +0000 @@ -41,6 +41,9 @@ self.uiServerHostLineEdit.setText(self._compute.host()) self.uiServerPortSpinBox.setValue(self._compute.port()) + index = self.uiServerProtocolComboBox.findText(self._compute.protocol().upper()) + self.uiServerProtocolComboBox.setCurrentIndex(index) + if self._compute.user(): self.uiEnableAuthenticationCheckBox.setChecked(True) self.uiServerUserLineEdit.setText(self._compute.user()) @@ -78,7 +81,7 @@ host = self.uiServerHostLineEdit.text().strip() name = self.uiServerNameLineEdit.text().strip() - protocol = "http" + protocol = self.uiServerProtocolComboBox.currentText().lower() port = self.uiServerPortSpinBox.value() user = self.uiServerUserLineEdit.text().strip() password = self.uiServerPasswordLineEdit.text().strip() diff -Nru gns3-gui-2.2.17~focal1/gns3/graphics_view.py gns3-gui-2.2.18~focal1/gns3/graphics_view.py --- gns3-gui-2.2.17~focal1/gns3/graphics_view.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/graphics_view.py 2021-02-16 08:45:07.000000000 +0000 @@ -861,19 +861,19 @@ bring_to_front_action.triggered.connect(self.bringToFrontSlot) menu.addAction(bring_to_front_action) - if True in list(map(lambda item: isinstance(item, NodeItem) and hasattr(item.node(), "configFiles"), items)): + if True in list(map(lambda item: isinstance(item, NodeItem) and bool(item.node().configFiles()), items)): import_config_action = QtWidgets.QAction("Import config", menu) import_config_action.setIcon(get_icon("import.svg")) import_config_action.triggered.connect(self.importConfigActionSlot) menu.addAction(import_config_action) - if True in list(map(lambda item: isinstance(item, NodeItem) and hasattr(item.node(), "configFiles"), items)): + if True in list(map(lambda item: isinstance(item, NodeItem) and bool(item.node().configFiles()), items)): export_config_action = QtWidgets.QAction("Export config", menu) export_config_action.setIcon(get_icon("export.svg")) export_config_action.triggered.connect(self.exportConfigActionSlot) menu.addAction(export_config_action) - if True in list(map(lambda item: isinstance(item, NodeItem) and hasattr(item.node(), "configFiles"), items)): + if True in list(map(lambda item: isinstance(item, NodeItem) and bool(item.node().configTextFiles()), items)): export_config_action = QtWidgets.QAction("Edit config", menu) export_config_action.setIcon(get_icon("edit.svg")) export_config_action.triggered.connect(self.editConfigActionSlot) @@ -1226,7 +1226,7 @@ items = [] for item in self.scene().selectedItems(): - if isinstance(item, NodeItem) and hasattr(item.node(), "configFiles") and item.node().initialized(): + if isinstance(item, NodeItem) and item.node().configFiles() and item.node().initialized(): items.append(item) if not items: @@ -1257,17 +1257,17 @@ items = [] for item in self.scene().selectedItems(): - if isinstance(item, NodeItem) and hasattr(item.node(), "configFiles") and item.node().initialized(): + if isinstance(item, NodeItem) and item.node().configTextFiles() and item.node().initialized(): items.append(item) if not items: return for item in items: - if len(item.node().configFiles()) == 1: - config_file = item.node().configFiles()[0] + if len(item.node().configTextFiles()) == 1: + config_file = item.node().configTextFiles()[0] else: - config_file, ok = QtWidgets.QInputDialog.getItem(self, "Edit file", "File to edit?", item.node().configFiles(), 0, False) + config_file, ok = QtWidgets.QInputDialog.getItem(self, "Edit file", "File to edit?", item.node().configTextFiles(), 0, False) if not ok: continue dialog = FileEditorDialog(item.node(), config_file, parent=self) @@ -1282,7 +1282,7 @@ items = [] for item in self.scene().selectedItems(): - if isinstance(item, NodeItem) and hasattr(item.node(), "configFiles") and item.node().initialized(): + if isinstance(item, NodeItem) and item.node().configFiles() and item.node().initialized(): items.append(item) if not items: diff -Nru gns3-gui-2.2.17~focal1/gns3/http_client.py gns3-gui-2.2.18~focal1/gns3/http_client.py --- gns3-gui-2.2.17~focal1/gns3/http_client.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/http_client.py 2021-02-16 08:45:07.000000000 +0000 @@ -18,18 +18,15 @@ from .qt import sip import json import copy -import http import uuid import pathlib import base64 -import datetime import ipaddress import urllib.request import urllib.parse - from .version import __version__, __version_info__ -from .qt import QtCore, QtNetwork, qpartial, sip_is_deleted +from .qt import QtCore, QtNetwork, QtWidgets, qpartial, sip_is_deleted from .utils import parse_version import logging @@ -79,6 +76,18 @@ self._shutdown = False # Shutdown in progress self._accept_insecure_certificate = settings.get("accept_insecure_certificate", None) + # Add custom CA + # ssl_config = QtNetwork.QSslConfiguration.defaultConfiguration() + # if ssl_config.addCaCertificates("/path/to/rootCA.crt"): + # log.debug("CA certificate added") + # QtNetwork.QSslConfiguration.setDefaultConfiguration(ssl_config) + + if self._protocol == "https": + if not QtNetwork.QSslSocket.supportsSsl(): + log.error("SSL is not supported") + else: + log.debug(f"SSL is supported, version: {QtNetwork.QSslSocket().sslLibraryBuildVersionString()}") + # In order to detect computer hibernation we detect the date of the last # query and disconnect if time is too long between two query self._last_query_timestamp = None @@ -93,6 +102,12 @@ # List of query waiting for the connection self._query_waiting_connections = [] + # To catch SSL errors + self._network_manager.sslErrors.connect(self._sslErrorsSlot) + + # Store SSL error exceptions + self._ssl_exceptions = {} + def setMaxTimeDifferenceBetweenQueries(self, value): self._max_time_difference_between_queries = value @@ -470,7 +485,14 @@ """ host = self._getHostForQuery() request = websocket.request() - ws_url = "ws://{host}:{port}{prefix}{path}".format(host=host, port=self._port, path=path, prefix=prefix) + ws_protocol = "ws" + if self._protocol == "https": + ws_protocol = "wss" + ws_url = "{protocol}://{host}:{port}{prefix}{path}".format(protocol=ws_protocol, + host=host, + port=self._port, + path=path, + prefix=prefix) log.debug("Connecting to WebSocket endpoint: {}".format(ws_url)) request.setUrl(QtCore.QUrl(ws_url)) self._addAuth(request) @@ -776,6 +798,55 @@ return status, json_data return status, None + def _sslErrorsSlot(self, response, ssl_errors): + + self.handleSslError(response, ssl_errors) + + def handleSslError(self, response, ssl_errors): + + if self._accept_insecure_certificate: + response.ignoreSslErrors() + return + + url = response.request().url() + host_port_key = f"{url.host()}:{url.port()}" + + # get the certificate digest + ssl_config = response.sslConfiguration() + peer_cert = ssl_config.peerCertificate() + digest = peer_cert.digest() + + if host_port_key in self._ssl_exceptions: + + if self._ssl_exceptions[host_port_key] == digest: + response.ignoreSslErrors() + return + + from gns3.main_window import MainWindow + main_window = MainWindow.instance() + + msgbox = QtWidgets.QMessageBox(main_window) + msgbox.setWindowTitle("SSL error detected") + msgbox.setText(f"This server could not prove that it is {url.host()}:{url.port()}. Please carefully examine the certificate to make sure the server can be trusted.") + msgbox.setInformativeText(f"{ssl_errors[0].errorString()}") + msgbox.setDetailedText(peer_cert.toText()) + msgbox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + connect_button = QtWidgets.QPushButton(f"&Connect to {url.host()}:{url.port()}", msgbox) + msgbox.addButton(connect_button, QtWidgets.QMessageBox.YesRole) + abort_button = QtWidgets.QPushButton("&Abort", msgbox) + msgbox.addButton(abort_button, QtWidgets.QMessageBox.RejectRole) + msgbox.setDefaultButton(abort_button) + msgbox.setIcon(QtWidgets.QMessageBox.Critical) + msgbox.exec_() + + if msgbox.clickedButton() == connect_button: + self._ssl_exceptions[host_port_key] = digest + response.ignoreSslErrors() + else: + for error in ssl_errors: + log.error(f"SSL error detected: {error.errorString()}") + main_window.close() + @classmethod def fromUrl(cls, url, network_manager=None, base_settings=None): """ diff -Nru gns3-gui-2.2.17~focal1/gns3/modules/qemu/pages/qemu_vm_configuration_page.py gns3-gui-2.2.18~focal1/gns3/modules/qemu/pages/qemu_vm_configuration_page.py --- gns3-gui-2.2.17~focal1/gns3/modules/qemu/pages/qemu_vm_configuration_page.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/modules/qemu/pages/qemu_vm_configuration_page.py 2021-02-16 08:45:07.000000000 +0000 @@ -90,6 +90,7 @@ self.uiActivateCPUThrottlingCheckBox.stateChanged.connect(self._cpuThrottlingChangedSlot) self.uiLegacyNetworkingCheckBox.stateChanged.connect(self._legacyNetworkingChangedSlot) self.uiCustomAdaptersConfigurationPushButton.clicked.connect(self._customAdaptersConfigurationSlot) + self.uiCreateConfigDiskCheckBox.stateChanged.connect(self._createConfigDiskChangedSlot) # add the categories for name, category in Node.defaultCategories().items(): @@ -366,6 +367,19 @@ else: self._refreshQemuNetworkDevices() + def _createConfigDiskChangedSlot(self, state): + """ + Slot to allow or not HDD disk to be configured based on the state of the config disk option. + """ + + _translate = QtCore.QCoreApplication.translate + if state: + self.uiHddDiskImageLabel.setText(_translate("QemuVMConfigPageWidget", "Startup-cfg:")) + else: + self.uiHddDiskImageLabel.setText(_translate("QemuVMConfigPageWidget", "Disk image:")) + self.uiHddDiskImageCreateToolButton.setEnabled(not state) + self.uiHddDiskImageResizeToolButton.setEnabled(not state) + def _customAdaptersConfigurationSlot(self): """ Slot to open the custom adapters configuration dialog @@ -453,6 +467,7 @@ self.uiHdbDiskInterfaceComboBox.setCurrentIndex(self.uiHdbDiskInterfaceComboBox.findText(settings["hdb_disk_interface"])) self.uiHdcDiskInterfaceComboBox.setCurrentIndex(self.uiHdcDiskInterfaceComboBox.findText(settings["hdc_disk_interface"])) self.uiHddDiskInterfaceComboBox.setCurrentIndex(self.uiHddDiskInterfaceComboBox.findText(settings["hdd_disk_interface"])) + self.uiCreateConfigDiskCheckBox.setChecked(settings["create_config_disk"]) self.uiCdromImageLineEdit.setText(settings["cdrom_image"]) self.uiBiosImageLineEdit.setText(settings["bios_image"]) self.uiInitrdLineEdit.setText(settings["initrd"]) @@ -588,6 +603,7 @@ settings["hdb_disk_interface"] = self.uiHdbDiskInterfaceComboBox.currentText() settings["hdc_disk_interface"] = self.uiHdcDiskInterfaceComboBox.currentText() settings["hdd_disk_interface"] = self.uiHddDiskInterfaceComboBox.currentText() + settings["create_config_disk"] = self.uiCreateConfigDiskCheckBox.isChecked() settings["cdrom_image"] = self.uiCdromImageLineEdit.text().strip() settings["bios_image"] = self.uiBiosImageLineEdit.text().strip() settings["initrd"] = self.uiInitrdLineEdit.text().strip() diff -Nru gns3-gui-2.2.17~focal1/gns3/modules/qemu/qemu_vm.py gns3-gui-2.2.18~focal1/gns3/modules/qemu/qemu_vm.py --- gns3-gui-2.2.17~focal1/gns3/modules/qemu/qemu_vm.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/modules/qemu/qemu_vm.py 2021-02-16 08:45:07.000000000 +0000 @@ -72,6 +72,7 @@ "mac_address": QEMU_VM_SETTINGS["mac_address"], "legacy_networking": QEMU_VM_SETTINGS["legacy_networking"], "replicate_network_connection_state": QEMU_VM_SETTINGS["replicate_network_connection_state"], + "create_config_disk": QEMU_VM_SETTINGS["create_config_disk"], "platform": QEMU_VM_SETTINGS["platform"], "on_close": QEMU_VM_SETTINGS["on_close"], "cpu_throttling": QEMU_VM_SETTINGS["cpu_throttling"], @@ -134,6 +135,24 @@ usage = "\n" + self._settings.get("usage") return info + port_info + usage + def configFiles(self): + """ + Name of the configuration files + """ + + if self._settings.get("create_config_disk"): + return ["config.zip"] + return None + + def configTextFiles(self): + """ + Name of the configuration files, which are plain text files + + :returns: List of configuration files, False if no files + """ + + return None + def configPage(self): """ Returns the configuration page widget to be used by the node properties dialog. diff -Nru gns3-gui-2.2.17~focal1/gns3/modules/qemu/settings.py gns3-gui-2.2.18~focal1/gns3/modules/qemu/settings.py --- gns3-gui-2.2.17~focal1/gns3/modules/qemu/settings.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/modules/qemu/settings.py 2021-02-16 08:45:07.000000000 +0000 @@ -41,10 +41,10 @@ "hdb_disk_image": "", "hdc_disk_image": "", "hdd_disk_image": "", - "hda_disk_interface": "ide", - "hdb_disk_interface": "ide", - "hdc_disk_interface": "ide", - "hdd_disk_interface": "ide", + "hda_disk_interface": "none", + "hdb_disk_interface": "none", + "hdc_disk_interface": "none", + "hdd_disk_interface": "none", "cdrom_image": "", "bios_image": "", "boot_priority": "c", @@ -57,6 +57,7 @@ "mac_address": "", "legacy_networking": False, "replicate_network_connection_state": True, + "create_config_disk": False, "on_close": "power_off", "platform": "", "cpu_throttling": 0, diff -Nru gns3-gui-2.2.17~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui gns3-gui-2.2.18~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui --- gns3-gui-2.2.17~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui 2021-02-16 08:45:07.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 941 - 877 + 939 @@ -399,14 +399,21 @@ HDD (Secondary Slave) - + + + + Automatically create a config disk on HDD + + + + Disk image: - + @@ -437,7 +444,7 @@ - + Disk interface: @@ -470,7 +477,16 @@ CD/DVD - + + 10 + + + 10 + + + 10 + + 10 diff -Nru gns3-gui-2.2.17~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page_ui.py gns3-gui-2.2.18~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page_ui.py --- gns3-gui-2.2.17~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page_ui.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/modules/qemu/ui/qemu_vm_configuration_page_ui.py 2021-02-16 08:45:07.000000000 +0000 @@ -13,7 +13,7 @@ class Ui_QemuVMConfigPageWidget(object): def setupUi(self, QemuVMConfigPageWidget): QemuVMConfigPageWidget.setObjectName("QemuVMConfigPageWidget") - QemuVMConfigPageWidget.resize(941, 877) + QemuVMConfigPageWidget.resize(941, 939) self.verticalLayout = QtWidgets.QVBoxLayout(QemuVMConfigPageWidget) self.verticalLayout.setObjectName("verticalLayout") self.uiQemutabWidget = QtWidgets.QTabWidget(QemuVMConfigPageWidget) @@ -211,9 +211,12 @@ self.uiHddGroupBox.setObjectName("uiHddGroupBox") self.gridLayout_9 = QtWidgets.QGridLayout(self.uiHddGroupBox) self.gridLayout_9.setObjectName("gridLayout_9") + self.uiCreateConfigDiskCheckBox = QtWidgets.QCheckBox(self.uiHddGroupBox) + self.uiCreateConfigDiskCheckBox.setObjectName("uiCreateConfigDiskCheckBox") + self.gridLayout_9.addWidget(self.uiCreateConfigDiskCheckBox, 0, 0, 1, 2) self.uiHddDiskImageLabel = QtWidgets.QLabel(self.uiHddGroupBox) self.uiHddDiskImageLabel.setObjectName("uiHddDiskImageLabel") - self.gridLayout_9.addWidget(self.uiHddDiskImageLabel, 0, 0, 1, 1) + self.gridLayout_9.addWidget(self.uiHddDiskImageLabel, 1, 0, 1, 1) self.horizontalLayout_10 = QtWidgets.QHBoxLayout() self.horizontalLayout_10.setObjectName("horizontalLayout_10") self.uiHddDiskImageLineEdit = QtWidgets.QLineEdit(self.uiHddGroupBox) @@ -229,10 +232,10 @@ self.uiHddDiskImageResizeToolButton = QtWidgets.QToolButton(self.uiHddGroupBox) self.uiHddDiskImageResizeToolButton.setObjectName("uiHddDiskImageResizeToolButton") self.horizontalLayout_10.addWidget(self.uiHddDiskImageResizeToolButton) - self.gridLayout_9.addLayout(self.horizontalLayout_10, 0, 1, 2, 1) + self.gridLayout_9.addLayout(self.horizontalLayout_10, 1, 1, 1, 1) self.uiHddDiskInterfaceLabel = QtWidgets.QLabel(self.uiHddGroupBox) self.uiHddDiskInterfaceLabel.setObjectName("uiHddDiskInterfaceLabel") - self.gridLayout_9.addWidget(self.uiHddDiskInterfaceLabel, 1, 0, 2, 1) + self.gridLayout_9.addWidget(self.uiHddDiskInterfaceLabel, 2, 0, 1, 1) self.uiHddDiskInterfaceComboBox = QtWidgets.QComboBox(self.uiHddGroupBox) self.uiHddDiskInterfaceComboBox.setObjectName("uiHddDiskInterfaceComboBox") self.gridLayout_9.addWidget(self.uiHddDiskInterfaceComboBox, 2, 1, 1, 1) @@ -497,6 +500,7 @@ self.uiHdcDiskImageResizeToolButton.setText(_translate("QemuVMConfigPageWidget", "Resize...")) self.uiHdcDiskInterfaceLabel.setText(_translate("QemuVMConfigPageWidget", "Disk interface:")) self.uiHddGroupBox.setTitle(_translate("QemuVMConfigPageWidget", "HDD (Secondary Slave)")) + self.uiCreateConfigDiskCheckBox.setText(_translate("QemuVMConfigPageWidget", "Automatically create a config disk on HDD")) self.uiHddDiskImageLabel.setText(_translate("QemuVMConfigPageWidget", "Disk image:")) self.uiHddDiskImageToolButton.setText(_translate("QemuVMConfigPageWidget", "&Browse...")) self.uiHddDiskImageCreateToolButton.setText(_translate("QemuVMConfigPageWidget", "Create...")) diff -Nru gns3-gui-2.2.17~focal1/gns3/node.py gns3-gui-2.2.18~focal1/gns3/node.py --- gns3-gui-2.2.17~focal1/gns3/node.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/node.py 2021-02-16 08:45:07.000000000 +0000 @@ -199,6 +199,26 @@ return self._always_on + def configFiles(self): + """ + Name of the configuration files + + This method should be overridden in derived classes + + :returns: List of configuration files, False if no files + """ + + return None + + def configTextFiles(self): + """ + Name of the configuration files, which are plain text files + + :returns: List of configuration files, False if no files + """ + + return self.configFiles() + def get(self, path, *args, **kwargs): """ GET on current server / project @@ -774,7 +794,7 @@ :param directory: destination directory path """ - if not hasattr(self, "configFiles"): + if not self.configFiles(): return False for file in self.configFiles(): self.get("/files/{file}".format(file=file), @@ -813,7 +833,7 @@ :param directory: source directory path """ - if not hasattr(self, "configFiles"): + if not self.configFiles(): return try: diff -Nru gns3-gui-2.2.17~focal1/gns3/pages/server_preferences_page.py gns3-gui-2.2.18~focal1/gns3/pages/server_preferences_page.py --- gns3-gui-2.2.17~focal1/gns3/pages/server_preferences_page.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/pages/server_preferences_page.py 2021-02-16 08:45:07.000000000 +0000 @@ -191,6 +191,7 @@ self.uiRemoteMainServerHostLineEdit.setText(servers_settings["host"]) self.uiRemoteMainServerPortSpinBox.setValue(servers_settings["port"]) + self.uiRemoteMainServerProtocolComboBox.setCurrentText(servers_settings["protocol"].upper()) self.uiRemoteMainServerUserLineEdit.setText(servers_settings["user"]) self.uiRemoteMainServerPasswordLineEdit.setText(servers_settings["password"]) self.uiRemoteMainServerAuthCheckBox.setChecked(servers_settings["auth"]) @@ -285,7 +286,7 @@ else: new_local_server_settings["host"] = self.uiRemoteMainServerHostLineEdit.text() new_local_server_settings["port"] = self.uiRemoteMainServerPortSpinBox.value() - new_local_server_settings["protocol"] = "http" + new_local_server_settings["protocol"] = self.uiRemoteMainServerProtocolComboBox.currentText().lower() new_local_server_settings["user"] = self.uiRemoteMainServerUserLineEdit.text() new_local_server_settings["password"] = self.uiRemoteMainServerPasswordLineEdit.text() new_local_server_settings["auth"] = self.uiRemoteMainServerAuthCheckBox.isChecked() diff -Nru gns3-gui-2.2.17~focal1/gns3/project.py gns3-gui-2.2.18~focal1/gns3/project.py --- gns3-gui-2.2.17~focal1/gns3/project.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/project.py 2021-02-16 08:45:07.000000000 +0000 @@ -632,6 +632,7 @@ self._notification_stream = Controller.instance().httpClient().connectWebSocket(self._websocket, path) self._notification_stream.textMessageReceived.connect(self._websocket_event_received) self._notification_stream.error.connect(self._websocket_error) + self._notification_stream.sslErrors.connect(self._sslErrorsSlot) def _endListenNotificationCallback(self, result, error=False, **kwargs): """ @@ -649,6 +650,11 @@ self._startListenNotifications() @qslot + def _sslErrorsSlot(self, ssl_errors): + + Controller.instance().httpClient().handleSslError(self._notification_stream, ssl_errors) + + @qslot def _websocket_event_received(self, event): try: self._event_received(json.loads(event)) diff -Nru gns3-gui-2.2.17~focal1/gns3/ui/edit_compute_dialog.ui gns3-gui-2.2.18~focal1/gns3/ui/edit_compute_dialog.ui --- gns3-gui-2.2.17~focal1/gns3/ui/edit_compute_dialog.ui 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/ui/edit_compute_dialog.ui 2021-02-16 08:45:07.000000000 +0000 @@ -9,8 +9,8 @@ 0 0 - 579 - 374 + 585 + 353 @@ -23,10 +23,31 @@ Server settings + + + + Port: + + + + + + 192.168.56.101 + + + + + + + Host: + + + + @@ -52,25 +73,25 @@ - - - - 192.168.56.101 - - - - + - Host: + Protocol: - - - - Port: - + + + + + HTTP + + + + + HTTPS + + diff -Nru gns3-gui-2.2.17~focal1/gns3/ui/edit_compute_dialog_ui.py gns3-gui-2.2.18~focal1/gns3/ui/edit_compute_dialog_ui.py --- gns3-gui-2.2.17~focal1/gns3/ui/edit_compute_dialog_ui.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/ui/edit_compute_dialog_ui.py 2021-02-16 08:45:07.000000000 +0000 @@ -1,29 +1,39 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file '/Users/noplay/code/gns3/gns3-gui/gns3/ui/edit_compute_dialog.ui' +# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/edit_compute_dialog.ui' # -# Created by: PyQt5 UI code generator 5.8 +# Created by: PyQt5 UI code generator 5.15.2 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + from PyQt5 import QtCore, QtGui, QtWidgets class Ui_EditComputeDialog(object): - def setupUi(self, EditComputeDialog): EditComputeDialog.setObjectName("EditComputeDialog") EditComputeDialog.setWindowModality(QtCore.Qt.WindowModal) - EditComputeDialog.resize(579, 374) + EditComputeDialog.resize(585, 353) self.verticalLayout = QtWidgets.QVBoxLayout(EditComputeDialog) self.verticalLayout.setObjectName("verticalLayout") self.groupBox = QtWidgets.QGroupBox(EditComputeDialog) self.groupBox.setObjectName("groupBox") self.gridLayout = QtWidgets.QGridLayout(self.groupBox) self.gridLayout.setObjectName("gridLayout") + self.uiServerPortLabel = QtWidgets.QLabel(self.groupBox) + self.uiServerPortLabel.setObjectName("uiServerPortLabel") + self.gridLayout.addWidget(self.uiServerPortLabel, 3, 0, 1, 1) self.uiServerNameLineEdit = QtWidgets.QLineEdit(self.groupBox) self.uiServerNameLineEdit.setObjectName("uiServerNameLineEdit") self.gridLayout.addWidget(self.uiServerNameLineEdit, 0, 1, 1, 1) + self.uiServerHostLineEdit = QtWidgets.QLineEdit(self.groupBox) + self.uiServerHostLineEdit.setObjectName("uiServerHostLineEdit") + self.gridLayout.addWidget(self.uiServerHostLineEdit, 2, 1, 1, 2) + self.uiServerHostLabel = QtWidgets.QLabel(self.groupBox) + self.uiServerHostLabel.setObjectName("uiServerHostLabel") + self.gridLayout.addWidget(self.uiServerHostLabel, 2, 0, 1, 1) self.uiServerPortSpinBox = QtWidgets.QSpinBox(self.groupBox) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -34,19 +44,18 @@ self.uiServerPortSpinBox.setMaximum(65535) self.uiServerPortSpinBox.setProperty("value", 3080) self.uiServerPortSpinBox.setObjectName("uiServerPortSpinBox") - self.gridLayout.addWidget(self.uiServerPortSpinBox, 2, 1, 1, 2) + self.gridLayout.addWidget(self.uiServerPortSpinBox, 3, 1, 1, 2) self.label = QtWidgets.QLabel(self.groupBox) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) - self.uiServerHostLineEdit = QtWidgets.QLineEdit(self.groupBox) - self.uiServerHostLineEdit.setObjectName("uiServerHostLineEdit") - self.gridLayout.addWidget(self.uiServerHostLineEdit, 1, 1, 1, 2) - self.uiServerHostLabel = QtWidgets.QLabel(self.groupBox) - self.uiServerHostLabel.setObjectName("uiServerHostLabel") - self.gridLayout.addWidget(self.uiServerHostLabel, 1, 0, 1, 1) - self.uiServerPortLabel = QtWidgets.QLabel(self.groupBox) - self.uiServerPortLabel.setObjectName("uiServerPortLabel") - self.gridLayout.addWidget(self.uiServerPortLabel, 2, 0, 1, 1) + self.uiServerProtocolLabel = QtWidgets.QLabel(self.groupBox) + self.uiServerProtocolLabel.setObjectName("uiServerProtocolLabel") + self.gridLayout.addWidget(self.uiServerProtocolLabel, 1, 0, 1, 1) + self.uiServerProtocolComboBox = QtWidgets.QComboBox(self.groupBox) + self.uiServerProtocolComboBox.setObjectName("uiServerProtocolComboBox") + self.uiServerProtocolComboBox.addItem("") + self.uiServerProtocolComboBox.addItem("") + self.gridLayout.addWidget(self.uiServerProtocolComboBox, 1, 1, 1, 1) self.verticalLayout.addWidget(self.groupBox) self.uiEnableAuthenticationCheckBox = QtWidgets.QGroupBox(EditComputeDialog) self.uiEnableAuthenticationCheckBox.setCheckable(True) @@ -67,7 +76,7 @@ self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.uiServerPasswordLabel) self.uiServerPasswordLineEdit = QtWidgets.QLineEdit(self.uiEnableAuthenticationCheckBox) self.uiServerPasswordLineEdit.setEnabled(True) - self.uiServerPasswordLineEdit.setInputMethodHints(QtCore.Qt.ImhHiddenText | QtCore.Qt.ImhNoAutoUppercase | QtCore.Qt.ImhNoPredictiveText | QtCore.Qt.ImhSensitiveData) + self.uiServerPasswordLineEdit.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase|QtCore.Qt.ImhNoPredictiveText|QtCore.Qt.ImhSensitiveData) self.uiServerPasswordLineEdit.setEchoMode(QtWidgets.QLineEdit.Password) self.uiServerPasswordLineEdit.setObjectName("uiServerPasswordLineEdit") self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.uiServerPasswordLineEdit) @@ -80,7 +89,7 @@ self.verticalLayout.addItem(spacerItem) self.buttonBox = QtWidgets.QDialogButtonBox(EditComputeDialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.verticalLayout.addWidget(self.buttonBox) @@ -98,10 +107,13 @@ _translate = QtCore.QCoreApplication.translate EditComputeDialog.setWindowTitle(_translate("EditComputeDialog", "Edit server settings")) self.groupBox.setTitle(_translate("EditComputeDialog", "Server settings")) - self.label.setText(_translate("EditComputeDialog", "Name:")) + self.uiServerPortLabel.setText(_translate("EditComputeDialog", "Port:")) self.uiServerHostLineEdit.setText(_translate("EditComputeDialog", "192.168.56.101")) self.uiServerHostLabel.setText(_translate("EditComputeDialog", "Host:")) - self.uiServerPortLabel.setText(_translate("EditComputeDialog", "Port:")) + self.label.setText(_translate("EditComputeDialog", "Name:")) + self.uiServerProtocolLabel.setText(_translate("EditComputeDialog", "Protocol:")) + self.uiServerProtocolComboBox.setItemText(0, _translate("EditComputeDialog", "HTTP")) + self.uiServerProtocolComboBox.setItemText(1, _translate("EditComputeDialog", "HTTPS")) self.uiEnableAuthenticationCheckBox.setTitle(_translate("EditComputeDialog", "Enable authentication")) self.uiServerUserLabel.setText(_translate("EditComputeDialog", "User:")) self.uiServerPasswordLabel.setText(_translate("EditComputeDialog", "Password:")) diff -Nru gns3-gui-2.2.17~focal1/gns3/ui/server_preferences_page.ui gns3-gui-2.2.18~focal1/gns3/ui/server_preferences_page.ui --- gns3-gui-2.2.17~focal1/gns3/ui/server_preferences_page.ui 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/ui/server_preferences_page.ui 2021-02-16 08:45:07.000000000 +0000 @@ -6,8 +6,8 @@ 0 0 - 1273 - 1097 + 681 + 843 @@ -295,24 +295,14 @@ Remote main server - + Host: - - - - - - - Port: - - - - + @@ -331,44 +321,75 @@ - + Auth: - - + + + + + - + User: - - + + + + QLineEdit::Password + + + + + - User: + Port: - - + + - + Password: - - - - QLineEdit::Password + + + + + + + + + + + Protocol: + + + + + HTTP + + + + + HTTPS + + + + @@ -404,7 +425,16 @@ Remote servers - + + 10 + + + 10 + + + 10 + + 10 diff -Nru gns3-gui-2.2.17~focal1/gns3/ui/server_preferences_page_ui.py gns3-gui-2.2.18~focal1/gns3/ui/server_preferences_page_ui.py --- gns3-gui-2.2.17~focal1/gns3/ui/server_preferences_page_ui.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/ui/server_preferences_page_ui.py 2021-02-16 08:45:07.000000000 +0000 @@ -2,16 +2,19 @@ # Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/server_preferences_page.ui' # -# Created by: PyQt5 UI code generator 5.9 +# Created by: PyQt5 UI code generator 5.15.2 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + from PyQt5 import QtCore, QtGui, QtWidgets + class Ui_ServerPreferencesPageWidget(object): def setupUi(self, ServerPreferencesPageWidget): ServerPreferencesPageWidget.setObjectName("ServerPreferencesPageWidget") - ServerPreferencesPageWidget.resize(1273, 1097) + ServerPreferencesPageWidget.resize(681, 843) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -149,13 +152,7 @@ self.gridLayout_4.setObjectName("gridLayout_4") self.label_2 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) self.label_2.setObjectName("label_2") - self.gridLayout_4.addWidget(self.label_2, 0, 0, 1, 1) - self.uiRemoteMainServerHostLineEdit = QtWidgets.QLineEdit(self.uiRemoteMainServerGroupBox) - self.uiRemoteMainServerHostLineEdit.setObjectName("uiRemoteMainServerHostLineEdit") - self.gridLayout_4.addWidget(self.uiRemoteMainServerHostLineEdit, 0, 1, 1, 2) - self.label_3 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) - self.label_3.setObjectName("label_3") - self.gridLayout_4.addWidget(self.label_3, 1, 0, 1, 1) + self.gridLayout_4.addWidget(self.label_2, 1, 0, 1, 1) self.uiRemoteMainServerPortSpinBox = QtWidgets.QSpinBox(self.uiRemoteMainServerGroupBox) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) @@ -165,27 +162,41 @@ self.uiRemoteMainServerPortSpinBox.setMaximum(65535) self.uiRemoteMainServerPortSpinBox.setProperty("value", 3080) self.uiRemoteMainServerPortSpinBox.setObjectName("uiRemoteMainServerPortSpinBox") - self.gridLayout_4.addWidget(self.uiRemoteMainServerPortSpinBox, 1, 1, 1, 2) + self.gridLayout_4.addWidget(self.uiRemoteMainServerPortSpinBox, 2, 1, 1, 2) self.label = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) self.label.setObjectName("label") - self.gridLayout_4.addWidget(self.label, 2, 0, 1, 1) - self.uiRemoteMainServerAuthCheckBox = QtWidgets.QCheckBox(self.uiRemoteMainServerGroupBox) - self.uiRemoteMainServerAuthCheckBox.setText("") - self.uiRemoteMainServerAuthCheckBox.setObjectName("uiRemoteMainServerAuthCheckBox") - self.gridLayout_4.addWidget(self.uiRemoteMainServerAuthCheckBox, 2, 2, 1, 1) - self.label_4 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) - self.label_4.setObjectName("label_4") - self.gridLayout_4.addWidget(self.label_4, 3, 0, 1, 1) + self.gridLayout_4.addWidget(self.label, 3, 0, 1, 1) self.uiRemoteMainServerUserLineEdit = QtWidgets.QLineEdit(self.uiRemoteMainServerGroupBox) self.uiRemoteMainServerUserLineEdit.setObjectName("uiRemoteMainServerUserLineEdit") - self.gridLayout_4.addWidget(self.uiRemoteMainServerUserLineEdit, 3, 2, 1, 1) - self.label_5 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) - self.label_5.setObjectName("label_5") - self.gridLayout_4.addWidget(self.label_5, 4, 0, 1, 2) + self.gridLayout_4.addWidget(self.uiRemoteMainServerUserLineEdit, 4, 2, 1, 1) + self.label_4 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) + self.label_4.setObjectName("label_4") + self.gridLayout_4.addWidget(self.label_4, 4, 0, 1, 1) self.uiRemoteMainServerPasswordLineEdit = QtWidgets.QLineEdit(self.uiRemoteMainServerGroupBox) self.uiRemoteMainServerPasswordLineEdit.setEchoMode(QtWidgets.QLineEdit.Password) self.uiRemoteMainServerPasswordLineEdit.setObjectName("uiRemoteMainServerPasswordLineEdit") - self.gridLayout_4.addWidget(self.uiRemoteMainServerPasswordLineEdit, 4, 2, 1, 1) + self.gridLayout_4.addWidget(self.uiRemoteMainServerPasswordLineEdit, 5, 2, 1, 1) + self.label_3 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) + self.label_3.setObjectName("label_3") + self.gridLayout_4.addWidget(self.label_3, 2, 0, 1, 1) + self.uiRemoteMainServerHostLineEdit = QtWidgets.QLineEdit(self.uiRemoteMainServerGroupBox) + self.uiRemoteMainServerHostLineEdit.setObjectName("uiRemoteMainServerHostLineEdit") + self.gridLayout_4.addWidget(self.uiRemoteMainServerHostLineEdit, 1, 1, 1, 2) + self.label_5 = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) + self.label_5.setObjectName("label_5") + self.gridLayout_4.addWidget(self.label_5, 5, 0, 1, 2) + self.uiRemoteMainServerAuthCheckBox = QtWidgets.QCheckBox(self.uiRemoteMainServerGroupBox) + self.uiRemoteMainServerAuthCheckBox.setText("") + self.uiRemoteMainServerAuthCheckBox.setObjectName("uiRemoteMainServerAuthCheckBox") + self.gridLayout_4.addWidget(self.uiRemoteMainServerAuthCheckBox, 3, 2, 1, 1) + self.uiRemoteMainServerProtocolLabel = QtWidgets.QLabel(self.uiRemoteMainServerGroupBox) + self.uiRemoteMainServerProtocolLabel.setObjectName("uiRemoteMainServerProtocolLabel") + self.gridLayout_4.addWidget(self.uiRemoteMainServerProtocolLabel, 0, 0, 1, 1) + self.uiRemoteMainServerProtocolComboBox = QtWidgets.QComboBox(self.uiRemoteMainServerGroupBox) + self.uiRemoteMainServerProtocolComboBox.setObjectName("uiRemoteMainServerProtocolComboBox") + self.uiRemoteMainServerProtocolComboBox.addItem("") + self.uiRemoteMainServerProtocolComboBox.addItem("") + self.gridLayout_4.addWidget(self.uiRemoteMainServerProtocolComboBox, 0, 1, 1, 2) self.verticalLayout.addWidget(self.uiRemoteMainServerGroupBox) spacerItem2 = QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem2) @@ -290,11 +301,14 @@ self.uiUDPPortRangeLabel.setText(_translate("ServerPreferencesPageWidget", "to")) self.uiRemoteMainServerGroupBox.setTitle(_translate("ServerPreferencesPageWidget", "Remote main server")) self.label_2.setText(_translate("ServerPreferencesPageWidget", "Host:")) - self.label_3.setText(_translate("ServerPreferencesPageWidget", "Port:")) self.uiRemoteMainServerPortSpinBox.setSuffix(_translate("ServerPreferencesPageWidget", " TCP")) self.label.setText(_translate("ServerPreferencesPageWidget", "Auth:")) self.label_4.setText(_translate("ServerPreferencesPageWidget", "User:")) + self.label_3.setText(_translate("ServerPreferencesPageWidget", "Port:")) self.label_5.setText(_translate("ServerPreferencesPageWidget", "Password:")) + self.uiRemoteMainServerProtocolLabel.setText(_translate("ServerPreferencesPageWidget", "Protocol:")) + self.uiRemoteMainServerProtocolComboBox.setItemText(0, _translate("ServerPreferencesPageWidget", "HTTP")) + self.uiRemoteMainServerProtocolComboBox.setItemText(1, _translate("ServerPreferencesPageWidget", "HTTPS")) self.uiServerPreferenceTabWidget.setTabText(self.uiServerPreferenceTabWidget.indexOf(self.uiLocalTabWidget), _translate("ServerPreferencesPageWidget", "Main server")) self.uiRemoteServersTreeWidget.headerItem().setText(0, _translate("ServerPreferencesPageWidget", "Name")) self.uiRemoteServersTreeWidget.headerItem().setText(4, _translate("ServerPreferencesPageWidget", "User")) @@ -304,4 +318,3 @@ self.label_7.setText(_translate("ServerPreferencesPageWidget", "Note: Changes are not visible in other part of the settings or application until you apply them.")) self.uiServerPreferenceTabWidget.setTabText(self.uiServerPreferenceTabWidget.indexOf(self.uiRemoteTabWidget), _translate("ServerPreferencesPageWidget", "Remote servers")) self.uiRestoreDefaultsPushButton.setText(_translate("ServerPreferencesPageWidget", "Restore defaults")) - diff -Nru gns3-gui-2.2.17~focal1/gns3/version.py gns3-gui-2.2.18~focal1/gns3/version.py --- gns3-gui-2.2.17~focal1/gns3/version.py 2020-12-04 06:03:42.000000000 +0000 +++ gns3-gui-2.2.18~focal1/gns3/version.py 2021-02-16 08:45:07.000000000 +0000 @@ -23,8 +23,8 @@ # or negative for a release candidate or beta (after the base version # number has been incremented) -__version__ = "2.2.17" -__version_info__ = (2, 2, 17, 0) +__version__ = "2.2.18" +__version_info__ = (2, 2, 18, 0) if "dev" in __version__: try: diff -Nru "/tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/resources/charcoal_icons/zoom-in (copy).svg" "/tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/resources/charcoal_icons/zoom-in (copy).svg" --- "/tmp/tmpDHHVA0/HuL5WiGKy0/gns3-gui-2.2.17~focal1/resources/charcoal_icons/zoom-in (copy).svg" 2020-12-04 06:03:42.000000000 +0000 +++ "/tmp/tmpDHHVA0/Z7MBfYR4WG/gns3-gui-2.2.18~focal1/resources/charcoal_icons/zoom-in (copy).svg" 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - -