diff --git a/CHANGELOG b/CHANGELOG
index 4f8dccbf1..002098669 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,13 @@
# Change Log
+## 2.2.48 08/07/2024
+
+* Use "experimental features" to allow bypassing hostname validation. Ref #3524
+* Update appliance_v8.json. Ref https://github.com/GNS3/gns3-registry/pull/897
+* Option to keep the compute IDs unchanged when exporting a project
+* Upgrade sentry-sdk and psutil packages
+* Switch to PyQt5 5.15.10 for macOS build
+
## 2.2.47 15/05/2024
* Remove maximum size for capture dialog. Ref #3576
diff --git a/gns3/crash_report.py b/gns3/crash_report.py
index 2cd34b7ea..458792681 100644
--- a/gns3/crash_report.py
+++ b/gns3/crash_report.py
@@ -50,7 +50,7 @@ class CrashReport:
Report crash to a third party service
"""
- DSN = "https://235ecbc961abe34327a4a397d8ce427a@o19455.ingest.us.sentry.io/38506"
+ DSN = "https://a9154d40d27d0cecfdbf5943b2ea68d5@o19455.ingest.us.sentry.io/38506"
_instance = None
def __init__(self):
diff --git a/gns3/dialogs/project_export_wizard.py b/gns3/dialogs/project_export_wizard.py
index 3446247f5..dc810128f 100644
--- a/gns3/dialogs/project_export_wizard.py
+++ b/gns3/dialogs/project_export_wizard.py
@@ -126,20 +126,18 @@ def done(self, result):
"""
if result:
+ include_images = include_snapshots = reset_mac_addresses = keep_compute_ids = "no"
if self.uiIncludeImagesCheckBox.isChecked():
include_images = "yes"
- else:
- include_images = "no"
if self.uiIncludeSnapshotsCheckBox.isChecked():
include_snapshots = "yes"
- else:
- include_snapshots = "no"
if self.uiResetMacAddressesCheckBox.isChecked():
reset_mac_addresses = "yes"
- else:
- reset_mac_addresses = "no"
+ if self.uiKeepComputeIdsCheckBox.isChecked():
+ keep_compute_ids = "yes"
+
compression = self.uiCompressionComboBox.currentData()
- export_worker = ExportProjectWorker(self._project, self._path, include_images, include_snapshots, reset_mac_addresses, compression)
+ export_worker = ExportProjectWorker(self._project, self._path, include_images, include_snapshots, reset_mac_addresses, keep_compute_ids, compression)
progress_dialog = ProgressDialog(export_worker, "Exporting project", "Exporting portable project files...", "Cancel", parent=self, create_thread=False)
progress_dialog.show()
progress_dialog.exec_()
diff --git a/gns3/graphics_view.py b/gns3/graphics_view.py
index 668ea8451..6481a6c6e 100644
--- a/gns3/graphics_view.py
+++ b/gns3/graphics_view.py
@@ -1032,7 +1032,7 @@ def changeHostnameActionSlot(self):
if not new_hostname.strip():
QtWidgets.QMessageBox.critical(self, "Change hostname", "Hostname cannot be blank")
continue
- if hasattr(item.node(), "validateHostname"):
+ if hasattr(item.node(), "validateHostname") and not LocalConfig.instance().experimental():
if not item.node().validateHostname(new_hostname):
QtWidgets.QMessageBox.critical(self, "Change hostname", "Invalid name detected for this node: {}".format(new_hostname))
continue
diff --git a/gns3/modules/dynamips/pages/ios_router_configuration_page.py b/gns3/modules/dynamips/pages/ios_router_configuration_page.py
index 112d15bd5..12fccab6f 100644
--- a/gns3/modules/dynamips/pages/ios_router_configuration_page.py
+++ b/gns3/modules/dynamips/pages/ios_router_configuration_page.py
@@ -24,6 +24,7 @@
from gns3.qt import QtCore, QtGui, QtWidgets
from gns3.local_server import LocalServer
+from gns3.local_config import LocalConfig
from gns3.dialogs.node_properties_dialog import ConfigurationError
from gns3.dialogs.symbol_selection_dialog import SymbolSelectionDialog
from gns3.controller import Controller
@@ -488,7 +489,7 @@ def saveSettings(self, settings, node=None, group=False):
name = self.uiNameLineEdit.text()
if not name:
QtWidgets.QMessageBox.critical(self, "Name", "IOS router name cannot be empty!")
- elif node and not node.validateHostname(name):
+ elif node and not node.validateHostname(name) and not LocalConfig.instance().experimental():
QtWidgets.QMessageBox.critical(self, "Name", "Invalid name detected for IOS router: {}".format(name))
else:
settings["name"] = name
diff --git a/gns3/modules/iou/pages/iou_device_configuration_page.py b/gns3/modules/iou/pages/iou_device_configuration_page.py
index 4a712056d..eee9a94ca 100644
--- a/gns3/modules/iou/pages/iou_device_configuration_page.py
+++ b/gns3/modules/iou/pages/iou_device_configuration_page.py
@@ -23,6 +23,7 @@
from gns3.qt import QtWidgets
from gns3.local_server import LocalServer
+from gns3.local_config import LocalConfig
from gns3.dialogs.node_properties_dialog import ConfigurationError
from gns3.dialogs.symbol_selection_dialog import SymbolSelectionDialog
from gns3.node import Node
@@ -245,7 +246,7 @@ def saveSettings(self, settings, node=None, group=False):
name = self.uiNameLineEdit.text()
if not name:
QtWidgets.QMessageBox.critical(self, "Name", "IOU device name cannot be empty!")
- elif node and not node.validateHostname(name):
+ elif node and not node.validateHostname(name) and not LocalConfig.instance().experimental():
QtWidgets.QMessageBox.critical(self, "Name", "Invalid name detected for IOU device: {}".format(name))
else:
settings["name"] = name
diff --git a/gns3/schemas/appliance_v8.json b/gns3/schemas/appliance_v8.json
index 043ef26ec..4b0e23ed4 100644
--- a/gns3/schemas/appliance_v8.json
+++ b/gns3/schemas/appliance_v8.json
@@ -720,174 +720,174 @@
"template_properties"
]
}
- }
- },
- "images": {
- "type": "array",
- "title": "Images for this appliance",
- "items": {
- "type": "object",
- "title": "An image file",
- "properties": {
- "filename": {
- "type": "string",
- "title": "Filename"
- },
- "version": {
- "type": "string",
- "title": "Version of the image file"
- },
- "md5sum": {
- "type": "string",
- "title": "MD5 cheksum of the image file",
- "pattern": "^[a-f0-9]{32}$"
- },
- "checksum": {
- "type": "string",
- "title": "checksum of the image file"
- },
- "checksum_type": {
- "title": "checksum type of the image file",
- "enum": [
- "md5"
- ]
- },
- "filesize": {
- "type": "integer",
- "title": "File size in bytes of the image file"
- },
- "download_url": {
- "type": "string",
- "format": "uri",
- "title": "Download URL where you can download the image file from a browser"
- },
- "direct_download_url": {
- "type": "string",
- "format": "uri",
- "title": "Optional. Non authenticated URL to the image file where you can download the image directly"
- },
- "compression": {
- "enum": [
- "bzip2",
- "gzip",
- "lzma",
- "xz",
- "rar",
- "zip",
- "7z"
- ],
- "title": "Optional, compression type of direct download URL image."
- },
- "compression_target": {
- "type": "string",
- "title": "Optional, file name of the image file inside the compressed file."
- }
- },
- "anyOf": [
- {
- "required": [
- "filename",
- "version",
- "md5sum",
- "filesize"
- ]
- },
- {
- "required": [
- "filename",
- "version",
- "checksum",
- "filesize"
- ]
- }
- ]
- }
- },
- "versions": {
- "type": "array",
- "title": "Versions of the appliance",
- "items": {
- "type": "object",
- "title": "A version of the appliance",
- "properties": {
- "name": {
- "type": "string",
- "title": "Name of the version"
- },
- "settings": {
- "type": "string",
- "title": "Template settings to use to run the version"
- },
- "category": {
- "$ref": "#/definitions/categories",
- "title": "Category of the version"
- },
- "installation_instructions": {
- "type": "string",
- "title": "Optional installation instructions for the version"
- },
- "usage": {
- "type": "string",
- "title": "Optional instructions about using the version"
- },
- "default_username": {
- "type": "string",
- "title": "Default username for the version"
- },
- "default_password": {
- "type": "string",
- "title": "Default password for the version"
+ },
+ "images": {
+ "type": "array",
+ "title": "Images for this appliance",
+ "items": {
+ "type": "object",
+ "title": "An image file",
+ "properties": {
+ "filename": {
+ "type": "string",
+ "title": "Filename"
+ },
+ "version": {
+ "type": "string",
+ "title": "Version of the image file"
+ },
+ "md5sum": {
+ "type": "string",
+ "title": "MD5 cheksum of the image file",
+ "pattern": "^[a-f0-9]{32}$"
+ },
+ "checksum": {
+ "type": "string",
+ "title": "checksum of the image file"
+ },
+ "checksum_type": {
+ "title": "checksum type of the image file",
+ "enum": [
+ "md5"
+ ]
+ },
+ "filesize": {
+ "type": "integer",
+ "title": "File size in bytes of the image file"
+ },
+ "download_url": {
+ "type": "string",
+ "format": "uri",
+ "title": "Download URL where you can download the image file from a browser"
+ },
+ "direct_download_url": {
+ "type": "string",
+ "format": "uri",
+ "title": "Optional. Non authenticated URL to the image file where you can download the image directly"
+ },
+ "compression": {
+ "enum": [
+ "bzip2",
+ "gzip",
+ "lzma",
+ "xz",
+ "rar",
+ "zip",
+ "7z"
+ ],
+ "title": "Optional, compression type of direct download URL image."
+ },
+ "compression_target": {
+ "type": "string",
+ "title": "Optional, file name of the image file inside the compressed file."
+ }
},
- "symbol": {
- "type": "string",
- "title": "An optional symbol for the version"
- },
- "images": {
- "type": "object",
- "title": "Images used for this version",
- "properties": {
- "kernel_image": {
- "type": "string",
- "title": "Kernel image (Qemu only)"
- },
- "initrd": {
- "type": "string",
- "title": "Initrd disk image (Qemu only)"
- },
- "image": {
- "type": "string",
- "title": "OS image (IOU and Dynamips only)"
- },
- "bios_image": {
- "type": "string",
- "title": "Bios image (Qemu only)"
- },
- "hda_disk_image": {
- "type": "string",
- "title": "Hda disk image (Qemu only)"
- },
- "hdb_disk_image": {
- "type": "string",
- "title": "Hdc disk image (Qemu only)"
- },
- "hdc_disk_image": {
- "type": "string",
- "title": "Hdd disk image (Qemu only)"
- },
- "hdd_disk_image": {
- "type": "string",
- "title": "Hdd disk image (Qemu only)"
- },
- "cdrom_image": {
- "type": "string",
- "title": "cdrom image (Qemu only)"
+ "anyOf": [
+ {
+ "required": [
+ "filename",
+ "version",
+ "md5sum",
+ "filesize"
+ ]
+ },
+ {
+ "required": [
+ "filename",
+ "version",
+ "checksum",
+ "filesize"
+ ]
+ }
+ ]
+ }
+ },
+ "versions": {
+ "type": "array",
+ "title": "Versions of the appliance",
+ "items": {
+ "type": "object",
+ "title": "A version of the appliance",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name of the version"
+ },
+ "settings": {
+ "type": "string",
+ "title": "Template settings to use to run the version"
+ },
+ "category": {
+ "$ref": "#/definitions/categories",
+ "title": "Category of the version"
+ },
+ "installation_instructions": {
+ "type": "string",
+ "title": "Optional installation instructions for the version"
+ },
+ "usage": {
+ "type": "string",
+ "title": "Optional instructions about using the version"
+ },
+ "default_username": {
+ "type": "string",
+ "title": "Default username for the version"
+ },
+ "default_password": {
+ "type": "string",
+ "title": "Default password for the version"
+ },
+ "symbol": {
+ "type": "string",
+ "title": "An optional symbol for the version"
+ },
+ "images": {
+ "type": "object",
+ "title": "Images used for this version",
+ "properties": {
+ "kernel_image": {
+ "type": "string",
+ "title": "Kernel image (Qemu only)"
+ },
+ "initrd": {
+ "type": "string",
+ "title": "Initrd disk image (Qemu only)"
+ },
+ "image": {
+ "type": "string",
+ "title": "OS image (IOU and Dynamips only)"
+ },
+ "bios_image": {
+ "type": "string",
+ "title": "Bios image (Qemu only)"
+ },
+ "hda_disk_image": {
+ "type": "string",
+ "title": "Hda disk image (Qemu only)"
+ },
+ "hdb_disk_image": {
+ "type": "string",
+ "title": "Hdc disk image (Qemu only)"
+ },
+ "hdc_disk_image": {
+ "type": "string",
+ "title": "Hdd disk image (Qemu only)"
+ },
+ "hdd_disk_image": {
+ "type": "string",
+ "title": "Hdd disk image (Qemu only)"
+ },
+ "cdrom_image": {
+ "type": "string",
+ "title": "cdrom image (Qemu only)"
+ }
}
}
- }
- },
- "required": [
- "name"
- ]
+ },
+ "required": [
+ "name"
+ ]
+ }
}
},
"required": [
diff --git a/gns3/settings.py b/gns3/settings.py
index 47fecb3d2..2ec438dfa 100644
--- a/gns3/settings.py
+++ b/gns3/settings.py
@@ -287,7 +287,6 @@
"check_for_update": True,
"overlay_notifications": True,
"experimental_features": False,
- "stats_visitor_id": str(uuid.uuid4()), # An anonymous id for stats
"last_check_for_update": 0,
"telnet_console_command": DEFAULT_TELNET_CONSOLE_COMMAND,
"vnc_console_command": DEFAULT_VNC_CONSOLE_COMMAND,
diff --git a/gns3/ui/export_project_wizard.ui b/gns3/ui/export_project_wizard.ui
index 95ff6bba7..0046b2de4 100644
--- a/gns3/ui/export_project_wizard.ui
+++ b/gns3/ui/export_project_wizard.ui
@@ -9,8 +9,8 @@
0
0
- 900
- 600
+ 602
+ 367
@@ -27,19 +27,6 @@
Please select the location, whether to include base images or not and the compression type.
- -
-
-
-
- 0
- 0
-
-
-
- Path:
-
-
-
-
-
@@ -54,31 +41,34 @@
- -
-
+
-
+
- Compression:
+ &Reset MAC addresses
- -
-
-
- -
-
+
-
+
+
+
+ 0
+ 0
+
+
- &Include base images
+ Path:
- -
-
+
-
+
- &Include snapshots
+ Compression:
- -
+
-
Qt::Vertical
@@ -91,10 +81,27 @@
- -
-
+
-
+
+
+ -
+
- &Reset MAC addresses
+ &Include base images
+
+
+
+ -
+
+
+ &Include snapshots
+
+
+
+ -
+
+
+ &Keep the original compute IDs
diff --git a/gns3/ui/export_project_wizard_ui.py b/gns3/ui/export_project_wizard_ui.py
index 2311bc915..1f5c6dbc4 100644
--- a/gns3/ui/export_project_wizard_ui.py
+++ b/gns3/ui/export_project_wizard_ui.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/export_project_wizard.ui'
#
-# Created by: PyQt5 UI code generator 5.13.2
+# Created by: PyQt5 UI code generator 5.15.6
#
-# 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
@@ -14,20 +15,12 @@ class Ui_ExportProjectWizard(object):
def setupUi(self, ExportProjectWizard):
ExportProjectWizard.setObjectName("ExportProjectWizard")
ExportProjectWizard.setWindowModality(QtCore.Qt.ApplicationModal)
- ExportProjectWizard.resize(900, 600)
+ ExportProjectWizard.resize(602, 367)
ExportProjectWizard.setOptions(QtWidgets.QWizard.HaveHelpButton)
self.uiExportOptionsWizardPage = QtWidgets.QWizardPage()
self.uiExportOptionsWizardPage.setObjectName("uiExportOptionsWizardPage")
self.gridLayout = QtWidgets.QGridLayout(self.uiExportOptionsWizardPage)
self.gridLayout.setObjectName("gridLayout")
- self.uiPathLabel = QtWidgets.QLabel(self.uiExportOptionsWizardPage)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.uiPathLabel.sizePolicy().hasHeightForWidth())
- self.uiPathLabel.setSizePolicy(sizePolicy)
- self.uiPathLabel.setObjectName("uiPathLabel")
- self.gridLayout.addWidget(self.uiPathLabel, 0, 0, 1, 1)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.uiPathLineEdit = QtWidgets.QLineEdit(self.uiExportOptionsWizardPage)
@@ -37,9 +30,22 @@ def setupUi(self, ExportProjectWizard):
self.uiPathBrowserToolButton.setObjectName("uiPathBrowserToolButton")
self.horizontalLayout_3.addWidget(self.uiPathBrowserToolButton)
self.gridLayout.addLayout(self.horizontalLayout_3, 0, 1, 1, 2)
+ self.uiResetMacAddressesCheckBox = QtWidgets.QCheckBox(self.uiExportOptionsWizardPage)
+ self.uiResetMacAddressesCheckBox.setObjectName("uiResetMacAddressesCheckBox")
+ self.gridLayout.addWidget(self.uiResetMacAddressesCheckBox, 5, 0, 1, 2)
+ self.uiPathLabel = QtWidgets.QLabel(self.uiExportOptionsWizardPage)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.uiPathLabel.sizePolicy().hasHeightForWidth())
+ self.uiPathLabel.setSizePolicy(sizePolicy)
+ self.uiPathLabel.setObjectName("uiPathLabel")
+ self.gridLayout.addWidget(self.uiPathLabel, 0, 0, 1, 1)
self.uiCompressionLabel = QtWidgets.QLabel(self.uiExportOptionsWizardPage)
self.uiCompressionLabel.setObjectName("uiCompressionLabel")
self.gridLayout.addWidget(self.uiCompressionLabel, 1, 0, 1, 1)
+ spacerItem = QtWidgets.QSpacerItem(20, 247, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ self.gridLayout.addItem(spacerItem, 7, 2, 1, 1)
self.uiCompressionComboBox = QtWidgets.QComboBox(self.uiExportOptionsWizardPage)
self.uiCompressionComboBox.setObjectName("uiCompressionComboBox")
self.gridLayout.addWidget(self.uiCompressionComboBox, 1, 1, 1, 2)
@@ -49,11 +55,9 @@ def setupUi(self, ExportProjectWizard):
self.uiIncludeSnapshotsCheckBox = QtWidgets.QCheckBox(self.uiExportOptionsWizardPage)
self.uiIncludeSnapshotsCheckBox.setObjectName("uiIncludeSnapshotsCheckBox")
self.gridLayout.addWidget(self.uiIncludeSnapshotsCheckBox, 4, 0, 1, 2)
- spacerItem = QtWidgets.QSpacerItem(20, 247, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout.addItem(spacerItem, 6, 2, 1, 1)
- self.uiResetMacAddressesCheckBox = QtWidgets.QCheckBox(self.uiExportOptionsWizardPage)
- self.uiResetMacAddressesCheckBox.setObjectName("uiResetMacAddressesCheckBox")
- self.gridLayout.addWidget(self.uiResetMacAddressesCheckBox, 5, 0, 1, 2)
+ self.uiKeepComputeIdsCheckBox = QtWidgets.QCheckBox(self.uiExportOptionsWizardPage)
+ self.uiKeepComputeIdsCheckBox.setObjectName("uiKeepComputeIdsCheckBox")
+ self.gridLayout.addWidget(self.uiKeepComputeIdsCheckBox, 6, 0, 1, 3)
ExportProjectWizard.addPage(self.uiExportOptionsWizardPage)
self.uiProjectReadmeWizardPage = QtWidgets.QWizardPage()
self.uiProjectReadmeWizardPage.setObjectName("uiProjectReadmeWizardPage")
@@ -72,12 +76,13 @@ def retranslateUi(self, ExportProjectWizard):
ExportProjectWizard.setWindowTitle(_translate("ExportProjectWizard", "Export project"))
self.uiExportOptionsWizardPage.setTitle(_translate("ExportProjectWizard", "Export project"))
self.uiExportOptionsWizardPage.setSubTitle(_translate("ExportProjectWizard", "Please select the location, whether to include base images or not and the compression type."))
- self.uiPathLabel.setText(_translate("ExportProjectWizard", "Path:"))
self.uiPathBrowserToolButton.setText(_translate("ExportProjectWizard", "Browse..."))
+ self.uiResetMacAddressesCheckBox.setText(_translate("ExportProjectWizard", "&Reset MAC addresses"))
+ self.uiPathLabel.setText(_translate("ExportProjectWizard", "Path:"))
self.uiCompressionLabel.setText(_translate("ExportProjectWizard", "Compression:"))
self.uiIncludeImagesCheckBox.setText(_translate("ExportProjectWizard", "&Include base images"))
self.uiIncludeSnapshotsCheckBox.setText(_translate("ExportProjectWizard", "&Include snapshots"))
- self.uiResetMacAddressesCheckBox.setText(_translate("ExportProjectWizard", "&Reset MAC addresses"))
+ self.uiKeepComputeIdsCheckBox.setText(_translate("ExportProjectWizard", "&Keep the original compute IDs"))
self.uiProjectReadmeWizardPage.setTitle(_translate("ExportProjectWizard", "Readme file"))
self.uiProjectReadmeWizardPage.setSubTitle(_translate("ExportProjectWizard", "Write a summary of the project."))
self.uiReadmeTextEdit.setHtml(_translate("ExportProjectWizard", "\n"
diff --git a/gns3/ui/general_preferences_page.ui b/gns3/ui/general_preferences_page.ui
index f5ec5ab69..b7226e3d8 100755
--- a/gns3/ui/general_preferences_page.ui
+++ b/gns3/ui/general_preferences_page.ui
@@ -1012,7 +1012,7 @@
-
- Enable experimental features (dangerous, restart required)
+ Enable experimental features
diff --git a/gns3/ui/general_preferences_page_ui.py b/gns3/ui/general_preferences_page_ui.py
index fc3bd1a0b..c6f2fb2d8 100644
--- a/gns3/ui/general_preferences_page_ui.py
+++ b/gns3/ui/general_preferences_page_ui.py
@@ -598,7 +598,7 @@ def retranslateUi(self, GeneralPreferencesPageWidget):
self.uiCheckForUpdateCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Automatically check for update"))
self.uiCrashReportCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Send anonymous crash reports"))
self.uiOverlayNotificationsCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Display error, warning and info in an overlay popup"))
- self.uiExperimentalFeaturesCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Enable experimental features (dangerous, restart required)"))
+ self.uiExperimentalFeaturesCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Enable experimental features"))
self.uiHdpiCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Enable HDPI mode (this may crash on Linux, restart required)"))
self.uiMultiProfilesCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Request for profile settings at application startup"))
self.uiDirectFileUpload.setToolTip(_translate("GeneralPreferencesPageWidget", "Experimental, requires computes visibility from GUI network"))
diff --git a/gns3/utils/export_project_worker.py b/gns3/utils/export_project_worker.py
index 70d5003b0..05552bbd3 100644
--- a/gns3/utils/export_project_worker.py
+++ b/gns3/utils/export_project_worker.py
@@ -28,21 +28,24 @@ class ExportProjectWorker(QtCore.QObject):
finished = QtCore.pyqtSignal()
updated = QtCore.pyqtSignal(int)
- def __init__(self, project, path, include_images, include_snapshots, reset_mac_addresses, compression):
+ def __init__(self, project, path, include_images, include_snapshots, reset_mac_addresses, keep_compute_ids, compression):
super().__init__()
self._project = project
+ self._path = path
self._include_images = include_images
self._include_snapshots = include_snapshots
self._reset_mac_addresses = reset_mac_addresses
- self._path = path
+ self._keep_compute_ids = keep_compute_ids
self._compression = compression
def run(self):
if self._project:
- self._project.get("/export?include_images={}&include_snapshots={}&reset_mac_addresses={}&compression={}".format(self._include_images, self._include_snapshots, self._reset_mac_addresses, self._compression),
- self._exportReceived,
- downloadProgressCallback=self._downloadFileProgress,
- timeout=None)
+ self._project.get(
+ "/export?include_images={}&include_snapshots={}&reset_mac_addresses={}&keep_compute_ids={}&compression={}".format(self._include_images, self._include_snapshots, self._reset_mac_addresses, self._keep_compute_ids, self._compression),
+ self._exportReceived,
+ downloadProgressCallback=self._downloadFileProgress,
+ timeout=None
+ )
def _exportReceived(self, content, error=False, server=None, context={}, **kwargs):
if error:
diff --git a/gns3/version.py b/gns3/version.py
index 59f956837..bd0baa5c3 100644
--- a/gns3/version.py
+++ b/gns3/version.py
@@ -23,8 +23,8 @@
# or negative for a release candidate or beta (after the base version
# number has been incremented)
-__version__ = "2.2.47"
-__version_info__ = (2, 2, 47, 0)
+__version__ = "2.2.48"
+__version_info__ = (2, 2, 48, 0)
if "dev" in __version__:
try:
diff --git a/mac-requirements.txt b/mac-requirements.txt
index fa6d90645..def2481a2 100644
--- a/mac-requirements.txt
+++ b/mac-requirements.txt
@@ -1,5 +1,3 @@
-rrequirements.txt
-PyQt5-Qt5==5.15.2
-PyQt5-sip==12.12.2
-PyQt5==5.15.9
+PyQt5==5.15.10
diff --git a/requirements.txt b/requirements.txt
index 21e540235..ef6131e48 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
jsonschema>=4.22.0,<4.23
-sentry-sdk==2.1.1,<2.2
-psutil==5.9.8
+sentry-sdk==2.7.1,<2.8
+psutil==6.0.0
distro>=1.9.0
truststore>=0.9.1; python_version >= '3.10'
importlib-resources>=1.3; python_version < '3.9'