diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 2a111021..f2b8b7c9 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -122,6 +122,7 @@ class QemuVM(BaseNode): self._kernel_image = "" self._kernel_command_line = "" self._tpm = False + self._uefi = False self._legacy_networking = False self._replicate_network_connection_state = True self._create_config_disk = False @@ -833,6 +834,30 @@ class QemuVM(BaseNode): log.info('QEMU VM "{name}" [{id}] has disabled the Trusted Platform Module (TPM)'.format(name=self._name, id=self._id)) self._tpm = tpm + @property + def uefi(self): + """ + Returns whether UEFI boot mode is activated for this QEMU VM. + + :returns: boolean + """ + + return self._uefi + + @uefi.setter + def uefi(self, uefi): + """ + Sets whether UEFI boot mode is activated for this QEMU VM. + + :param uefi: boolean + """ + + if uefi: + log.info(f'QEMU VM "{self._name}" [{self._id}] has enabled the UEFI boot mode') + else: + log.info(f'QEMU VM "{self._name}" [{self._id}] has disabled the UEFI boot mode') + self._uefi = uefi + @property def options(self): """ @@ -1994,12 +2019,16 @@ class QemuVM(BaseNode): options = [] if self._bios_image: + if self._uefi: + raise QemuError("Cannot use a bios image and the UEFI boot mode at the same time") if not os.path.isfile(self._bios_image) or not os.path.exists(self._bios_image): if os.path.islink(self._bios_image): raise QemuError("bios image '{}' linked to '{}' is not accessible".format(self._bios_image, os.path.realpath(self._bios_image))) else: raise QemuError("bios image '{}' is not accessible".format(self._bios_image)) options.extend(["-bios", self._bios_image.replace(",", ",,")]) + elif self._uefi: + options.extend(["-bios", "OVMF.fd"]) # the OVMF bios image should be in the image directory return options def _linux_boot_options(self): diff --git a/gns3server/disks/OVMF.fd b/gns3server/disks/OVMF.fd new file mode 100644 index 00000000..d05e10cb Binary files /dev/null and b/gns3server/disks/OVMF.fd differ diff --git a/gns3server/schemas/qemu.py b/gns3server/schemas/qemu.py index 07cca4f8..3fb75f30 100644 --- a/gns3server/schemas/qemu.py +++ b/gns3server/schemas/qemu.py @@ -194,6 +194,10 @@ QEMU_CREATE_SCHEMA = { "description": "Enable the Trusted Platform Module (TPM) in Qemu", "type": ["boolean", "null"], }, + "uefi": { + "description": "Enable the UEFI boot mode in Qemu", + "type": ["boolean", "null"], + }, "create_config_disk": { "description": "Automatically create a config disk on HDD disk interface (secondary slave)", "type": ["boolean", "null"], @@ -392,6 +396,10 @@ QEMU_UPDATE_SCHEMA = { "description": "Enable the Trusted Platform Module (TPM) in Qemu", "type": ["boolean", "null"], }, + "uefi": { + "description": "Enable the UEFI boot mode in Qemu", + "type": ["boolean", "null"], + }, "create_config_disk": { "description": "Automatically create a config disk on HDD disk interface (secondary slave)", "type": ["boolean", "null"], @@ -603,6 +611,10 @@ QEMU_OBJECT_SCHEMA = { "description": "Enable the Trusted Platform Module (TPM) in Qemu", "type": "boolean", }, + "uefi": { + "description": "Enable the UEFI boot mode in Qemu", + "type": "boolean", + }, "create_config_disk": { "description": "Automatically create a config disk on HDD disk interface (secondary slave)", "type": ["boolean", "null"], @@ -678,6 +690,7 @@ QEMU_OBJECT_SCHEMA = { "legacy_networking", "replicate_network_connection_state", "tpm", + "uefi", "create_config_disk", "on_close", "cpu_throttling", diff --git a/gns3server/schemas/qemu_template.py b/gns3server/schemas/qemu_template.py index a84a3da9..89bc55b2 100644 --- a/gns3server/schemas/qemu_template.py +++ b/gns3server/schemas/qemu_template.py @@ -188,6 +188,11 @@ QEMU_TEMPLATE_PROPERTIES = { "type": "boolean", "default": False }, + "uefi": { + "description": "Enable the UEFI boot mode in Qemu", + "type": "boolean", + "default": False + }, "create_config_disk": { "description": "Automatically create a config disk on HDD disk interface (secondary slave)", "type": "boolean", diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py index 8e67e8b7..2d504732 100644 --- a/tests/compute/qemu/test_qemu_vm.py +++ b/tests/compute/qemu/test_qemu_vm.py @@ -387,6 +387,23 @@ async def test_bios_option(vm, tmpdir, fake_qemu_img_binary): assert ' '.join(['-bios', str(tmpdir / "test.img")]) in ' '.join(options) +async def test_uefi_boot_mode_option(vm, tmpdir, fake_qemu_img_binary): + + vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0") + vm._uefi = True + options = await vm._build_command() + assert ' '.join(['-bios', 'OVMF.fd']) in ' '.join(options) + + +async def test_uefi_with_bios_image_already_configured(vm, tmpdir, fake_qemu_img_binary): + + vm.manager.get_qemu_version = AsyncioMagicMock(return_value="3.1.0") + vm._bios_image = str(tmpdir / "test.img") + vm._uefi = True + with pytest.raises(QemuError): + await vm._build_command() + + async def test_vnc_option(vm, fake_qemu_img_binary): vm._console_type = 'vnc'