mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 04:36:48 +00:00
feat(instances): a VM's boot settings as switches and its boot order as one list
The Boot pane shows Autostart and the boot menu as switches that save on change, and the boot order as one list of the VM's disks, CD-ROM drives and NICs: the devices in the order first, checked and numbered, the others below. Up and Down move the checked devices; Apply order saves. - The boot menu can be changed while the VM runs: it is in the persistent definition, so it applies at the next start, as the boot order does. - The boot order editor no longer needs the boot menu enabled. - A VM that boots by device type (<os><boot dev='hd'/>) names those types; checking devices replaces that order. - An order is refused while a device the list does not show (a host device, a floppy) has a boot place, so Apply does not drop it; the message points to the XML editor. - An empty order is refused with a message instead of being ignored. - get_bootorder gives a NIC's full MAC as its target. - The unused jQuery multiselect plugin is removed.
This commit is contained in:
parent
a8f445d580
commit
20cfc25367
10 changed files with 168 additions and 163 deletions
|
|
@ -493,7 +493,7 @@ class LiveDataLossTestCase(TestCase):
|
|||
|
||||
page = html.fromstring(self.client.get(reverse("instances:instance", args=[inst.id])).content)
|
||||
(boot,) = page.xpath("//form[@action=$a]", a=reverse("instances:set_bootorder", args=[inst.id]))
|
||||
self.assertEqual(boot.xpath(".//input[@type='checkbox']/@value"), ["disk:vda", "network:52:54:00:aa:05:21"])
|
||||
self.assertEqual(boot.xpath(".//input[@type='checkbox']/@value"), ["network:52:54:00:aa:05:21", "disk:vda"])
|
||||
self.assertEqual(page.xpath("//select[@name='video_model']/option[@selected]/@value"), [video])
|
||||
|
||||
self.post("set_bootorder", inst, {"bootorder": "network:52:54:00:aa:05:22,disk:vda"})
|
||||
|
|
|
|||
|
|
@ -147,13 +147,24 @@ class PendingEditsTestCase(TestCase):
|
|||
get_console_passwd=("live-pw", "pending-pw"),
|
||||
)
|
||||
(boot,) = doc.xpath("//form[@action=$a]", a=reverse("instances:set_bootorder", args=[self.instance.id]))
|
||||
self.assertEqual(boot.xpath(".//input[@type='checkbox']/@value"), ["disk:vda", "disk:vdb", "cdrom:sda"])
|
||||
self.assertIn("1:sda", doc.xpath("string(//div[label[contains(., ':')]])"))
|
||||
# the devices in the order first, checked
|
||||
self.assertEqual(boot.xpath(".//input[@type='checkbox']/@value"), ["cdrom:sda", "disk:vda", "disk:vdb"])
|
||||
self.assertEqual(boot.xpath(".//input[@checked]/@value"), ["cdrom:sda"])
|
||||
# the pending boot menu is on: its switch turns it off, also while the VM runs
|
||||
self.assertEqual(doc.xpath("//input[@id='bootmenu']/ancestor::form/@action"),
|
||||
[reverse("instances:unset_bootmenu", args=[self.instance.id])])
|
||||
self.assertEqual(doc.xpath("//select[@name='video_model']/option[@selected]/@value"), ["virtio"])
|
||||
self.assertEqual(doc.xpath("//select[@name='keymap']/option[@selected]/@value"), ["de"])
|
||||
self.assertEqual(doc.xpath("//select[@name='listen_on']/option[@selected]/@value"), ["0.0.0.0"])
|
||||
self.assertEqual(doc.xpath("//input[@name='password']/@value"), ["pending-pw"])
|
||||
|
||||
def test_a_boot_order_by_device_type_is_named_and_no_device_is_checked(self):
|
||||
doc = self.page(live=[disk("vda", "default", "")], config=[disk("vda", "default", "")],
|
||||
get_bootorder=({}, {0: {"type": "file", "dev": "hd", "target": "disk"},
|
||||
1: {"type": "file", "dev": "cdrom", "target": "cdrom"}}))
|
||||
self.assertIn("disk, cdrom.", " ".join(doc.xpath("string(//p[@id='boot-by-type'])").split()))
|
||||
self.assertEqual(doc.xpath("//div[@id='b_order']//input[@checked]"), [])
|
||||
|
||||
def test_a_boot_order_choice_not_in_the_definition_is_refused(self):
|
||||
with patch("instances.models.wvmInstance") as wvm:
|
||||
wvm.return_value.set_bootorder.side_effect = util.OperationError("Boot device vdz is not in the definition")
|
||||
|
|
@ -161,6 +172,12 @@ class PendingEditsTestCase(TestCase):
|
|||
{"bootorder": "disk:vda,disk:vdz"})
|
||||
self.assertEqual([str(m) for m in get_messages(response.wsgi_request)], ["Boot device vdz is not in the definition"])
|
||||
|
||||
def test_an_empty_boot_order_is_refused(self):
|
||||
with patch("instances.models.wvmInstance") as wvm:
|
||||
response = self.client.post(reverse("instances:set_bootorder", args=[self.instance.id]), {"bootorder": ""})
|
||||
wvm.return_value.set_bootorder.assert_not_called()
|
||||
self.assertEqual([str(m) for m in get_messages(response.wsgi_request)], ["Check at least one device to boot from."])
|
||||
|
||||
def test_an_active_vm_says_its_settings_apply_at_the_next_start(self):
|
||||
for status, shown in ((1, True), (3, True), (5, False)):
|
||||
with self.subTest(status=status):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue