1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

perf(instances): the VM page lists ISO images without reading every pool

The VM page refreshed every active storage pool to list the ISO images
for its CD-ROM drives. A pool holding large disk images took up to
seconds to refresh, most of the page's time, on every page load.

The page now lists the ISO images libvirt already knows. Images
uploaded through the panel are known at once. For an image copied to a
pool by hand, the Removable media section has a Refresh ISO list button
that refreshes the active pools and returns to the page.
This commit is contained in:
catborise 2026-11-02 13:51:20 +03:00
parent 37905a0b75
commit d5d054de71
6 changed files with 52 additions and 19 deletions

View file

@ -152,7 +152,13 @@
<section class="mb-4" aria-labelledby="media-heading">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-2">
<h2 class="h6 mb-0" id="media-heading">{% trans "Removable media" %}</h2>
{% include 'add_instance_cdrom.html' %}
<div class="d-flex gap-2">
{# the pools are read again: an ISO image copied to one by hand is listed then #}
<form method="post" action="{% url 'instances:refresh_iso' instance.id %}">{% csrf_token %}
<button type="submit" class="btn btn-sm btn-outline-secondary" title="{% trans "Read the storage pools again: an ISO image copied to a pool by hand is listed then" %}">{% bs_icon 'arrow-clockwise' %} {% trans "Refresh ISO list" %}</button>
</form>
{% include 'add_instance_cdrom.html' %}
</div>
</div>
{% for cd in instance.media %}
<div class="card mb-2">

View file

@ -23,6 +23,7 @@ DISK_ENDPOINTS = [
("detach_cdrom", ["hda"]),
("mount_iso", []),
("unmount_iso", []),
("refresh_iso", []),
]
VM_DISK = {
@ -86,6 +87,13 @@ class DiskViewsTenantIsolationTestCase(TestCase):
mock_storage.assert_not_called()
mock_create.assert_not_called()
def test_refresh_iso_reads_the_pools_again_and_returns_to_the_disks_tab(self):
self.client.force_login(self.superuser)
with patch("instances.models.wvmInstance") as mock_wvm:
res = self._post("refresh_iso", {})
self.assertRedirects(res, self.referer + "#disks", fetch_redirect_response=False)
mock_wvm.return_value.refresh_iso_pools.assert_called_once_with()
def test_delete_vol_deletes_the_volume_attached_to_dev_not_the_posted_one(self):
self.client.force_login(self.superuser)
with patch("instances.models.wvmInstance") as mock_wvm, patch(

View file

@ -40,6 +40,7 @@ urlpatterns = [
path("<int:pk>/detach_cdrom/<str:dev>/", views.detach_cdrom, name="detach_cdrom"),
path("<int:pk>/unmount_iso/", views.unmount_iso, name="unmount_iso"),
path("<int:pk>/mount_iso/", views.mount_iso, name="mount_iso"),
path("<int:pk>/refresh_iso/", views.refresh_iso, name="refresh_iso"),
path("<int:pk>/snapshot/", views.snapshot, name="snapshot"),
path("<int:pk>/delete_snapshot/", views.delete_snapshot, name="delete_snapshot"),
path("<int:pk>/revert_snapshot/", views.revert_snapshot, name="revert_snapshot"),

View file

@ -1685,6 +1685,14 @@ def mount_iso(request, pk):
return redirect(same_origin_referer(request, reverse("instances:instance", args=[pk])) + "#disks")
@require_POST
@superuser_only
def refresh_iso(request, pk):
instance = get_instance(request.user, pk, perm_type="change")
instance.proxy.refresh_iso_pools()
return _back(request, pk, "disks")
@require_POST
def snapshot(request, pk):
return _snapshot_job(request, pk, "snapshot.create",