From c1f6620c4b5197a0dba783594e577f233600c8c1 Mon Sep 17 00:00:00 2001 From: catborise Date: Sun, 11 Oct 2026 15:00:47 +0300 Subject: [PATCH] feat(instances): a running VM's settings tab says most settings apply at the next start On an active VM most edits in the settings tab change the persistent definition only. The tab now says so above its panes. --- README.md | 2 +- instances/templates/instances/settings_tab.html | 3 +++ instances/test_pending_edits.py | 9 +++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4ddc3d63..13047729 100644 --- a/README.md +++ b/README.md @@ -540,7 +540,7 @@ A rollback leaves the clone on a detached HEAD at the restored commit; the updat - A VM's stats are polled every 5 s like the host graph, the first point as soon as the tab opens; each point is the average since the previous one, disk rates in MB/s (they were MiB/s labelled Mb/s); a counter the host does not report shows a gap instead of 0. - An ISO uploads to an SSH compute about 3.5 times faster (SFTP writes no longer wait for each 32 KiB); a failed write still fails the upload. - On a host whose libvirt cannot change network interfaces (the udev backend: RHEL 9 and later, Debian 12), the interface pages offer no create, start, stop or delete; they only failed there. -- On a running VM the disk list, its edit form, the QoS table, the title, description, CPU, boot order, video and console fields show the settings as they will be at the next start, so saving an edit no longer reverts another pending change. A boot order that names a device missing from that definition is refused instead of clearing the order. A QoS edit keeps the inbound floor. Buttons shown as disabled while the VM runs can no longer be submitted with Enter. +- On a running VM the disk list, its edit form, the QoS table, the title, description, CPU, boot order, video and console fields show the settings as they will be at the next start, so saving an edit no longer reverts another pending change. A boot order that names a device missing from that definition is refused instead of clearing the order. The settings tab of a running VM says so. A QoS edit keeps the inbound floor. Buttons shown as disabled while the VM runs can no longer be submitted with Enter. - The VM page shows each NIC's own QoS and each CD-ROM's own pool (they showed the previous device's), and a NIC without a source or model no longer breaks it. - A volume of an LVM or iSCSI pool can be attached to a VM, and bridge and direct NICs can be boot devices. The NIC model `default` lets libvirt choose, and `rt18139` is `rtl8139`: a VM with either did not start; a migration corrects the default NIC type setting. - A paused VM's memory is resized as a running VM's: the current memory changes and the guest takes it once resumed, the maximum stays (both only reached the VM at its next boot). diff --git a/instances/templates/instances/settings_tab.html b/instances/templates/instances/settings_tab.html index 58e00cea..70f561b5 100644 --- a/instances/templates/instances/settings_tab.html +++ b/instances/templates/instances/settings_tab.html @@ -71,6 +71,9 @@ {% endif %} + {% if instance.status != 5 %} +

{% trans "While the VM runs, most settings here apply at its next start." %}

+ {% endif %}
{% if instance.guest_agent_ready %} diff --git a/instances/test_pending_edits.py b/instances/test_pending_edits.py index 5237b0b4..56e93e44 100644 --- a/instances/test_pending_edits.py +++ b/instances/test_pending_edits.py @@ -28,14 +28,14 @@ class PendingEditsTestCase(TestCase): compute = Compute.objects.create(name="pe", hostname="127.0.0.1:1", login="root", password="", type=1) self.instance = Instance.objects.create(compute=compute, name="pe-vm", uuid="aaaaaaaa-1111-2222-3333-444444444444") - def page(self, live=(), config=(), qos=({}, {}), **getters): + def page(self, live=(), config=(), qos=({}, {}), status=1, **getters): """live and config: disks; qos and getters (get_vcpu=(2, 4)): values of the live and the persistent definition.""" with patch("instances.models.wvmInstance") as wvm, patch.object( Compute, "status", new_callable=PropertyMock, return_value=True ): proxy = wvm.return_value - proxy.get_status.return_value = 1 + proxy.get_status.return_value = status proxy.get_memory.return_value = proxy.get_cur_memory.return_value = 1024 proxy.get_max_memory.return_value = 4096 getters = {"get_vcpu": (1, 1), "get_cur_vcpu": (1, 1), "get_title": ("", ""), @@ -130,3 +130,8 @@ class PendingEditsTestCase(TestCase): response = self.client.post(reverse("instances:set_bootorder", args=[self.instance.id]), {"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_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): + self.assertEqual(bool(self.page(status=status).xpath("//p[@id='next-start-note']")), shown)