diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index b96e1f38..f93488aa 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -99,6 +99,7 @@ class QemuVM(BaseNode): self._hdc_disk_interface = "ide" self._hdd_disk_interface = "ide" self._cdrom_image = "" + self._bios_image = "" self._boot_priority = "c" self._mac_address = "" self._options = "" @@ -407,6 +408,28 @@ class QemuVM(BaseNode): id=self._id, cdrom_image=self._cdrom_image)) + @property + def bios_image(self): + """ + Returns the bios image path for this QEMU VM. + + :returns: QEMU bios image path + """ + + return self._bios_image + + @bios_image.setter + def bios_image(self, bios_image): + """ + Sets the bios image for this QEMU VM. + + :param bios_image: QEMU bios image path + """ + self._bios_image = self.manager.get_abs_image_path(bios_image) + log.info('QEMU VM "{name}" [{id}] has set the QEMU bios image path to {bios_image}'.format(name=self._name, + id=self._id, + bios_image=self._bios_image)) + @property def boot_priority(self): """ @@ -1361,6 +1384,18 @@ class QemuVM(BaseNode): options.extend(["-cdrom", self._cdrom_image]) return options + def _bios_option(self): + + options = [] + if self._bios_image: + 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]) + return options + def _linux_boot_options(self): options = [] @@ -1500,8 +1535,8 @@ class QemuVM(BaseNode): if version and parse_version(version) >= parse_version("2.4.0") and self.platform == "x86_64": command.extend(["-machine", "smm=off"]) command.extend(["-boot", "order={}".format(self._boot_priority)]) - cdrom_option = self._cdrom_option() - command.extend(cdrom_option) + command.extend(self._bios_option()) + command.extend(self._cdrom_option()) command.extend((yield from self._disk_options())) command.extend(self._linux_boot_options()) if "-uuid" not in additional_options: @@ -1545,6 +1580,8 @@ class QemuVM(BaseNode): answer["hdd_disk_image_md5sum"] = md5sum(self._hdd_disk_image) answer["cdrom_image"] = self.manager.get_relative_image_path(self._cdrom_image) answer["cdrom_image_md5sum"] = md5sum(self._cdrom_image) + answer["bios_image"] = self.manager.get_relative_image_path(self._bios_image) + answer["bios_image_md5sum"] = md5sum(self._bios_image) answer["initrd"] = self.manager.get_relative_image_path(self._initrd) answer["initrd_md5sum"] = md5sum(self._initrd) diff --git a/gns3server/schemas/qemu.py b/gns3server/schemas/qemu.py index 2623dbf6..36e2fa6b 100644 --- a/gns3server/schemas/qemu.py +++ b/gns3server/schemas/qemu.py @@ -121,6 +121,14 @@ QEMU_CREATE_SCHEMA = { "description": "QEMU cdrom image checksum", "type": ["string", "null"], }, + "bios_image": { + "description": "QEMU bios image path", + "type": "string", + }, + "bios_image_md5sum": { + "description": "QEMU bios image checksum", + "type": ["string", "null"], + }, "boot_priority": { "description": "QEMU boot priority", "enum": ["c", "d", "n", "cn", "cd"] @@ -290,6 +298,14 @@ QEMU_UPDATE_SCHEMA = { "description": "QEMU hdd disk image checksum", "type": ["string", "null"], }, + "bios_image": { + "description": "QEMU bios image path", + "type": "string", + }, + "bios_image_md5sum": { + "description": "QEMU bios image checksum", + "type": ["string", "null"], + }, "cdrom_image": { "description": "QEMU cdrom image path", "type": "string", @@ -466,6 +482,14 @@ QEMU_OBJECT_SCHEMA = { "description": "QEMU hdd disk image checksum", "type": ["string", "null"], }, + "bios_image": { + "description": "QEMU bios image path", + "type": "string", + }, + "bios_image_md5sum": { + "description": "QEMU bios image checksum", + "type": ["string", "null"], + }, "cdrom_image": { "description": "QEMU cdrom image path", "type": "string", @@ -593,6 +617,8 @@ QEMU_OBJECT_SCHEMA = { "hdd_disk_interface", "cdrom_image", "cdrom_image_md5sum", + "bios_image", + "bios_image_md5sum", "boot_priority", "ram", "cpus", diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py index 2a3ccbf8..8b01381d 100644 --- a/tests/compute/qemu/test_qemu_vm.py +++ b/tests/compute/qemu/test_qemu_vm.py @@ -338,6 +338,26 @@ def test_disk_options(vm, tmpdir, loop, fake_qemu_img_binary): assert options == ['-drive', 'file=' + os.path.join(vm.working_dir, "hda_disk.qcow2") + ',if=ide,index=0,media=disk'] +def test_cdrom_option(vm, tmpdir, loop, fake_qemu_img_binary): + + vm._cdrom_image = str(tmpdir / "test.iso") + open(vm._cdrom_image, "w+").close() + + options = loop.run_until_complete(asyncio.async(vm._build_command())) + + assert ' '.join(['-cdrom', str(tmpdir / "test.iso")]) in ' '.join(options) + + +def test_bios_option(vm, tmpdir, loop, fake_qemu_img_binary): + + vm._bios_image = str(tmpdir / "test.img") + open(vm._bios_image, "w+").close() + + options = loop.run_until_complete(asyncio.async(vm._build_command())) + + assert ' '.join(['-bios', str(tmpdir / "test.img")]) in ' '.join(options) + + def test_disk_options_multiple_disk(vm, tmpdir, loop, fake_qemu_img_binary): vm._hda_disk_image = str(tmpdir / "test0.qcow2")