diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 3e49d6749..e712ddd49 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -1131,7 +1131,6 @@ class QemuVM(BaseNode): await cancellable_wait_run_in_executor(md5sum, self._hdb_disk_image, self.working_dir) await cancellable_wait_run_in_executor(md5sum, self._hdc_disk_image, self.working_dir) await cancellable_wait_run_in_executor(md5sum, self._hdd_disk_image, self.working_dir) - super().create() async def start(self): @@ -2700,18 +2699,19 @@ class QemuVM(BaseNode): if not disk_image: continue answer[f"hd{drive}_disk_image"] = self.manager.get_relative_image_path(disk_image, self.working_dir) - answer[f"hd{drive}_disk_image_md5sum"] = md5sum(disk_image, self.working_dir) local_disk = os.path.join(self.working_dir, f"hd{drive}_disk.qcow2") if os.path.exists(local_disk): try: qcow2 = Qcow2(local_disk) if qcow2.backing_file: - answer[f"hd{drive}_disk_image"] = os.path.basename(local_disk) - answer[f"hd{drive}_disk_image_md5sum"] = md5sum(local_disk, self.working_dir) + # update disk image path to the local disk image and add the backing file name in the answer answer[f"hd{drive}_disk_image_backing_file"] = os.path.basename(qcow2.backing_file) + answer[f"hd{drive}_disk_image"] = os.path.basename(local_disk) except (Qcow2Error, OSError) as e: log.error(f"Could not read qcow2 disk image '{local_disk}': {e}") continue + # only compute the md5sum if the disk exists to avoid computing one for a backing file + answer[f"hd{drive}_disk_image_md5sum"] = md5sum(local_disk, self.working_dir) answer["cdrom_image"] = self.manager.get_relative_image_path(self._cdrom_image, self.working_dir) answer["cdrom_image_md5sum"] = md5sum(self._cdrom_image, self.working_dir) diff --git a/gns3server/controller/drawing.py b/gns3server/controller/drawing.py index ce8581475..daf072983 100644 --- a/gns3server/controller/drawing.py +++ b/gns3server/controller/drawing.py @@ -115,7 +115,7 @@ class Drawing: data = base64.decodebytes(data.split(",", 1)[1].encode()) - # We compute an hash of the image file to avoid duplication + # We compute a hash of the image file to avoid duplication filename = hashlib.md5(data).hexdigest() + "." + extension elem.set(href, filename) diff --git a/gns3server/schemas/compute/qemu_nodes.py b/gns3server/schemas/compute/qemu_nodes.py index 8d7e23dd3..60a37eb9f 100644 --- a/gns3server/schemas/compute/qemu_nodes.py +++ b/gns3server/schemas/compute/qemu_nodes.py @@ -167,19 +167,19 @@ class QemuBase(BaseModel): aux: Optional[int] = Field(None, gt=0, le=65535, description="Auxiliary console TCP port") aux_type: Optional[QemuConsoleType] = Field(None, description="Auxiliary console type") hda_disk_image: Optional[str] = Field(None, description="QEMU hda disk image path") - hda_disk_image_backed: Optional[str] = Field(None, description="QEMU hda backed disk image path") + hda_disk_image_backing_file: Optional[str] = Field(None, description="QEMU hda backing file disk image path") hda_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hda disk image checksum") hda_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hda interface") hdb_disk_image: Optional[str] = Field(None, description="QEMU hdb disk image path") - hdb_disk_image_backed: Optional[str] = Field(None, description="QEMU hdb backed disk image path") + hdb_disk_image_backing_file: Optional[str] = Field(None, description="QEMU hdb backing file disk image path") hdb_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdb disk image checksum") hdb_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hdb interface") hdc_disk_image: Optional[str] = Field(None, description="QEMU hdc disk image path") - hdc_disk_image_backed: Optional[str] = Field(None, description="QEMU hdc backed disk image path") + hdc_disk_image_backing_file: Optional[str] = Field(None, description="QEMU hdc backing file disk image path") hdc_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdc disk image checksum") hdc_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hdc interface") hdd_disk_image: Optional[str] = Field(None, description="QEMU hdd disk image path") - hdd_disk_image_backed: Optional[str] = Field(None, description="QEMU hdd backed disk image path") + hdd_disk_image_backing_file: Optional[str] = Field(None, description="QEMU hdd backing file disk image path") hdd_disk_image_md5sum: Optional[str] = Field(None, description="QEMU hdd disk image checksum") hdd_disk_interface: Optional[QemuDiskInterfaceType] = Field(None, description="QEMU hdd interface") cdrom_image: Optional[str] = Field(None, description="QEMU cdrom image path") diff --git a/gns3server/utils/images.py b/gns3server/utils/images.py index 794abf6ad..beba1a5c2 100644 --- a/gns3server/utils/images.py +++ b/gns3server/utils/images.py @@ -259,14 +259,15 @@ def md5sum(path, working_dir=None, stopped_event=None, cache_to_md5file=True): else: md5sum_file = path + ".md5sum" - try: - with open(md5sum_file) as f: - md5 = f.read().strip() - if len(md5) == 32: - return md5 - # Unicode error is when user rename an image to .md5sum .... - except (OSError, UnicodeDecodeError): - pass + if os.path.exists(md5sum_file): + try: + with open(md5sum_file) as f: + md5 = f.read().strip() + if len(md5) == 32: + return md5 + # Unicode error is when user rename an image to .md5sum .... + except (OSError, UnicodeDecodeError): + pass try: m = hashlib.md5() diff --git a/tests/api/routes/compute/test_qemu_nodes.py b/tests/api/routes/compute/test_qemu_nodes.py index 6edcbec3a..688adf9c2 100644 --- a/tests/api/routes/compute/test_qemu_nodes.py +++ b/tests/api/routes/compute/test_qemu_nodes.py @@ -144,7 +144,6 @@ class TestQemuNodesRoutes: assert response.json()["project_id"] == compute_project.id assert response.json()["ram"] == 1024 assert response.json()["hda_disk_image"] == "linuxè½½.img" - assert response.json()["hda_disk_image_md5sum"] == "fcea920f7412b5da7be0cf42b8c93759" @pytest.mark.parametrize(