diff --git a/instances/test_create_instance.py b/instances/test_create_instance.py index c981a2d9..6f9bd273 100644 --- a/instances/test_create_instance.py +++ b/instances/test_create_instance.py @@ -62,3 +62,30 @@ class CreateInstanceViewTests(TestCase): fetch_redirect_response=False, ) conn.create_instance.assert_called_once() + + @patch("instances.views.wvmCreate") + def test_firmware_list_uses_the_chosen_machine_type(self, connection_class): + user = get_user_model().objects.create_superuser( + username="create-fw-admin", password="password", email="fw@example.com" + ) + self.client.force_login(user) + compute = Compute.objects.create( + name="create-fw-compute", hostname="localhost", type=4, login="", password="", + ) + conn = connection_class.return_value + conn.get_instances.return_value = [] + conn.get_storages.return_value = [] + conn.get_networks.return_value = [] + conn.get_nwfilters.return_value = [] + conn.get_cache_modes.return_value = {} + # A host without loader support has no "loaders"/"loader_enums" keys + conn.get_dom_capabilities.return_value = {"loader_support": "no"} + conn.get_capabilities.return_value = {} + conn.label_for_firmware_path.return_value = None + conn.find_uefi_path_for_arch.return_value = None + + response = self.client.get(reverse("instances:create_instance", args=[compute.id, "x86_64", "q35"])) + + self.assertEqual(response.status_code, 200) + conn.find_uefi_path_for_arch.assert_called_once_with("x86_64", "q35") + diff --git a/instances/test_live_create.py b/instances/test_live_create.py index ae1167e0..96a91233 100644 --- a/instances/test_live_create.py +++ b/instances/test_live_create.py @@ -11,6 +11,7 @@ from computes.models import Compute from django.contrib.auth import get_user_model from django.test import TestCase from django.urls import reverse +from lxml import etree from vrtManager.connection import connection_manager from . import livetest @@ -111,6 +112,22 @@ class LiveCreateTestCase(TestCase): self.assertTrue(self.domain_exists(P + "cr-ok")) self.assertEqual(len(self.volumes()), 1) + def test_offered_uefi_firmware_boots_on_q35(self): + page = self.client.get(reverse("instances:create_instance", args=[self.compute.id, "x86_64", "q35"])) + uefi = [f for f in page.context["firmwares"] if f.startswith("UEFI")] + self.assertTrue(uefi, "no UEFI firmware offered for q35") + + self.create("cr-uefi-ok", firmware=uefi[0]) + + dom = self.conn.lookupByName(P + "cr-uefi-ok") + loader = etree.fromstring(dom.XMLDesc(0)).findtext("os/loader") + self.assertEqual(loader, uefi[0].split(":", 1)[1].strip()) + # Listed by libvirt for q35, so the domain starts with it + caps = etree.fromstring(self.conn.getDomainCapabilities(None, "x86_64", "q35", "kvm")) + self.assertIn(loader, caps.xpath("os/loader/value/text()")) + dom.create() + self.assertTrue(dom.isActive()) + def test_api_rejected_definition_removes_the_new_disk(self): response = self.client.post( f"/api/v1/computes/{self.compute.id}/instances/create/x86_64/q35/", diff --git a/instances/views.py b/instances/views.py index 53ce3e21..759a3cf7 100755 --- a/instances/views.py +++ b/instances/views.py @@ -2085,13 +2085,12 @@ def create_instance(request, compute_id, arch, machine): caps = conn.get_capabilities(arch) virtio_support = conn.is_supports_virtio(arch, machine) - hv_supports_uefi = conn.supports_uefi_xml(dom_caps["loader_enums"]) # Add BIOS label = conn.label_for_firmware_path(arch, None) if label: firmwares.append(label) # Add UEFI - loader_path = conn.find_uefi_path_for_arch(arch, dom_caps["loaders"]) + loader_path = conn.find_uefi_path_for_arch(arch, machine) label = conn.label_for_firmware_path(arch, loader_path) if label: firmwares.append(label)