diff --git a/gns3/dialogs/appliance_wizard.py b/gns3/dialogs/appliance_wizard.py index 08b298797..405d75dd9 100644 --- a/gns3/dialogs/appliance_wizard.py +++ b/gns3/dialogs/appliance_wizard.py @@ -85,6 +85,8 @@ def __init__(self, parent, path): QtWidgets.QMessageBox.warning(self.parent(), "Can't copy {} to {}".format(path, destination), str(e)) self.uiServerWizardPage.isComplete = self._uiServerWizardPage_isComplete + self.allowCustomFiles.clicked.connect(self._allowCustomFilesChangedSlot) + def initializePage(self, page_id): """ @@ -327,7 +329,10 @@ def _refreshDialogWorker(self): for version in self._appliance["versions"]: for image in version["images"].values(): - img = self._registry.search_image_file(self._appliance.emulator(), image["filename"], image.get("md5sum"), image.get("filesize")) + img = self._registry.search_image_file( + self._appliance.emulator(), image["filename"], image.get("md5sum"), image.get("filesize"), + strict_md5_check=not self.allowCustomFiles.isChecked() + ) if img: image["status"] = "Found" image["md5sum"] = img.md5sum @@ -413,8 +418,10 @@ def _importPushButtonClickedSlot(self, *args): return image = Image(self._appliance.emulator(), path, filename=disk["filename"]) + disallow_custom_images = not self.allowCustomFiles.isChecked() + try: - if "md5sum" in disk and image.md5sum != disk["md5sum"]: + if disallow_custom_images and ("md5sum" in disk and image.md5sum != disk["md5sum"]): QtWidgets.QMessageBox.warning(self.parent(), "Add appliance", "This is not the correct file. The MD5 sum is {} and should be {}.".format(image.md5sum, disk["md5sum"])) return except OSError as e: @@ -623,3 +630,23 @@ def _localToggledSlot(self, checked): if checked: self.uiRemoteServersGroupBox.setEnabled(False) self.uiRemoteServersGroupBox.hide() + + @qslot + def _allowCustomFilesChangedSlot(self, checked): + """ + Slot for when user want to upload images which don't match md5 + + :param checked: if allows or doesn't allow custom files + :return: + """ + if checked: + are_you_sure = QtWidgets.QMessageBox.question( + self, "Custom files", + "This option allows files with custom MD5 checksum. This feature is only for advance users and can lead " + "to serious unexpected problems. Are you sure you would like to enable it?", + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No + ) + + if are_you_sure == QtWidgets.QMessageBox.No: + self.allowCustomFiles.setChecked(False) + return False diff --git a/gns3/registry/appliance.py b/gns3/registry/appliance.py index 96724d756..15eb10be2 100644 --- a/gns3/registry/appliance.py +++ b/gns3/registry/appliance.py @@ -150,7 +150,9 @@ def search_images_for_version(self, version_name): for image_type, image in version["images"].items(): image["type"] = image_type - img = self._registry.search_image_file(self.emulator(), image["filename"], image.get("md5sum"), image.get("filesize")) + img = self._registry.search_image_file( + self.emulator(), image["filename"], image.get("md5sum"), image.get("filesize") + ) if img is None: if "md5sum" in image: raise ApplianceError("File {} with checksum {} not found for {}".format(image["filename"], image["md5sum"], appliance["name"])) diff --git a/gns3/registry/registry.py b/gns3/registry/registry.py index b2d090eb5..c12868201 100644 --- a/gns3/registry/registry.py +++ b/gns3/registry/registry.py @@ -67,7 +67,7 @@ def _getRemoteListCallback(self, result, error=False, **kwargs): self._remote_images.append(image) self.image_list_changed_signal.emit() - def search_image_file(self, emulator, filename, md5sum, size): + def search_image_file(self, emulator, filename, md5sum, size, strict_md5_check=True): """ Search an image based on its MD5 checksum @@ -75,13 +75,14 @@ def search_image_file(self, emulator, filename, md5sum, size): :param filename: Image filename (used for ova in order to return the correct file in the archive) :param md5sum: Hash of the image :param size: File size + :param strict_md5_check: If `True` then performs MD5 checksum checks, otherwise ignores them :returns: Image object or None """ for remote_image in list(self._remote_images): if remote_image.md5sum == md5sum: return remote_image - elif md5sum is None: # We create a new version + elif md5sum is None or strict_md5_check is False: # We create a new version or allow custom files if filename == remote_image.filename: return remote_image @@ -93,7 +94,7 @@ def search_image_file(self, emulator, filename, md5sum, size): path = os.path.join(directory, file) try: if os.path.isfile(path): - if md5sum is None: + if md5sum is None or strict_md5_check is False: if filename == os.path.basename(path): return Image(emulator, path) else: diff --git a/gns3/ui/appliance_wizard.ui b/gns3/ui/appliance_wizard.ui index 245359c1c..69760404c 100644 --- a/gns3/ui/appliance_wizard.ui +++ b/gns3/ui/appliance_wizard.ui @@ -434,6 +434,16 @@ + + + + + + + Allow custom files + + + @@ -613,8 +623,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The default username/password is admin/admin. A default configuration is present.</p></body></html> +</style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">The default username/password is admin/admin. A default configuration is present.</span></p></body></html> diff --git a/gns3/ui/appliance_wizard_ui.py b/gns3/ui/appliance_wizard_ui.py index 3e7c0c117..c63fdfd5f 100644 --- a/gns3/ui/appliance_wizard_ui.py +++ b/gns3/ui/appliance_wizard_ui.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/appliance_wizard.ui' +# Form implementation generated from reading ui file '/home/dominik/projects/gns3-gui-2.2/gns3/ui/appliance_wizard.ui' # -# Created: Tue Mar 7 08:40:14 2017 -# by: PyQt5 UI code generator 5.2.1 +# Created by: PyQt5 UI code generator 5.10 # # WARNING! All changes made in this file will be lost! @@ -174,6 +173,10 @@ def setupUi(self, ApplianceWizard): self.horizontalLayout.addWidget(self.uiDownloadPushButton) spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem1) + self.allowCustomFiles = QtWidgets.QCheckBox(self.uiFilesWizardPage) + self.allowCustomFiles.setToolTip("") + self.allowCustomFiles.setObjectName("allowCustomFiles") + self.horizontalLayout.addWidget(self.allowCustomFiles) self.uiCreateVersionPushButton = QtWidgets.QPushButton(self.uiFilesWizardPage) self.uiCreateVersionPushButton.setObjectName("uiCreateVersionPushButton") self.horizontalLayout.addWidget(self.uiCreateVersionPushButton) @@ -288,6 +291,7 @@ def retranslateUi(self, ApplianceWizard): self.uiExplainDownloadLabel.setText(_translate("ApplianceWizard", "Click on a the download button to access to a location where you can download the file.")) self.uiImportPushButton.setText(_translate("ApplianceWizard", "&Import")) self.uiDownloadPushButton.setText(_translate("ApplianceWizard", "&Download")) + self.allowCustomFiles.setText(_translate("ApplianceWizard", "Allow custom files")) self.uiCreateVersionPushButton.setText(_translate("ApplianceWizard", "Create a new version")) self.uiRefreshPushButton.setText(_translate("ApplianceWizard", "Refresh")) self.uiQemuWizardPage.setTitle(_translate("ApplianceWizard", "Qemu settings")) @@ -317,7 +321,7 @@ def retranslateUi(self, ApplianceWizard): self.uiUsageTextEdit.setHtml(_translate("ApplianceWizard", "\n" "\n" -"

The default username/password is admin/admin. A default configuration is present.

")) +"\n" +"

The default username/password is admin/admin. A default configuration is present.

")) from . import resources_rc