mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 12:46:49 +00:00
fix(instances): an empty panel says what to do next
- The VM list with no VMs no longer also says that no VM matches the search and the state. - The New VM dialog with no compute yet says to add the first host, with a link to the Computes page (and links there when none is reachable). - The new VM page on a host without a running storage pool or a network says what to add or start and where, instead of "You haven't defined any storage pools" (also when pools exist but are stopped) and "network pools".
This commit is contained in:
parent
0b4a601ecb
commit
129327358d
10 changed files with 278 additions and 225 deletions
|
|
@ -63,11 +63,13 @@
|
|||
{% else %}
|
||||
{% include 'allinstances_index_nongrouped.html' %}
|
||||
{% endif %}
|
||||
{% if instances %}
|
||||
{# table_filter.js shows it while no row matches #}
|
||||
<div id="no-match" class="text-center text-body-secondary py-4" hidden>
|
||||
{% trans "No VM matches the search and the state." %}
|
||||
<button type="button" class="btn btn-link" id="clear-filters">{% trans "Clear the filters" %}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="modal fade" id="find-address" tabindex="-1" aria-labelledby="find-address-title" aria-hidden="true"
|
||||
data-url="{% url 'instances:find_address' %}" data-failed="{% trans "The search did not go through. Try again." %}"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,12 @@
|
|||
</div>
|
||||
</a>
|
||||
{% empty %}
|
||||
<p>{% trans "No compute is reachable." %}</p>
|
||||
{% url 'computes' as computes_url %}
|
||||
{% if computes %}
|
||||
<p>{% blocktrans %}No compute is reachable: see the <a href="{{ computes_url }}">Computes</a> page.{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
<p>{% blocktrans %}There is no compute yet: add the first host on the <a href="{{ computes_url }}">Computes</a> page.{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -142,9 +142,19 @@ class CreateDialogHostsTestCase(TestCase):
|
|||
def test_only_reachable_computes_are_listed(self):
|
||||
dialog = self.dialog({"cd2"})
|
||||
self.assertEqual([e.text for e in dialog.xpath(".//a/div/div[1]")], ["cd2"])
|
||||
self.assertNotIn("No compute is reachable.", dialog.text_content())
|
||||
self.assertNotIn("No compute is reachable", dialog.text_content())
|
||||
|
||||
def test_no_reachable_compute_is_said(self):
|
||||
dialog = self.dialog(set())
|
||||
self.assertEqual(dialog.xpath(".//a"), [])
|
||||
self.assertIn("No compute is reachable.", dialog.text_content())
|
||||
self.assertEqual(dialog.xpath(".//a[contains(@class, 'list-group-item')]"), [])
|
||||
self.assertIn("No compute is reachable: see the Computes page.", dialog.text_content())
|
||||
|
||||
def test_a_panel_without_computes_says_to_add_one(self):
|
||||
# the first visit: the dialog and the list lead to the Computes page, and no filter is said to hide VMs
|
||||
Compute.objects.all().delete()
|
||||
response = self.client.get(reverse("instances:index"))
|
||||
dialog = html.fromstring(response.content).get_element_by_id("AddInstance")
|
||||
self.assertIn("There is no compute yet: add the first host on the Computes page.", dialog.text_content())
|
||||
self.assertEqual(dialog.xpath(".//p/a/@href"), [reverse("computes")])
|
||||
self.assertContains(response, "There are no VMs here yet.")
|
||||
self.assertNotContains(response, "No VM matches the search")
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class CreateFormInputTests(TestCase):
|
|||
_, response = render_create_page(self)
|
||||
self.assertIsNone(response.context["vm_form"])
|
||||
self.assertEqual(html.fromstring(response.content).xpath("//button[@name='create']"), [])
|
||||
self.assertTrue(any("storage pools" in str(m) for m in response.context["messages"]))
|
||||
self.assertTrue(any("no running storage pool" in str(m) for m in response.context["messages"]))
|
||||
|
||||
def test_a_host_that_cannot_be_read_is_a_message(self):
|
||||
import libvirt
|
||||
|
|
|
|||
|
|
@ -162,6 +162,11 @@ class CreateInstanceViewTests(TestCase):
|
|||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
conn.get_firmwares.assert_called_once_with("x86_64", "q35")
|
||||
# a fresh host: what to do, not that the user defined nothing
|
||||
self.assertContains(response, "This host has no running storage pool for the VM's disks: add or start one on its Storage page.")
|
||||
conn.get_storages.return_value = ["default"]
|
||||
response = self.client.get(reverse("instances:create_instance", args=[compute.id, "x86_64", "q35"]))
|
||||
self.assertContains(response, "This host has no network for the VM: add one on its Networks page.")
|
||||
|
||||
|
||||
class NicMacsTestCase(SimpleTestCase):
|
||||
|
|
|
|||
|
|
@ -2581,9 +2581,9 @@ def create_instance(request, compute_id, arch, machine):
|
|||
tpm_support = bool(conn.get_tpm_model(arch, machine))
|
||||
|
||||
if not storages:
|
||||
raise util.OperationError(_("You haven't defined any storage pools"))
|
||||
raise util.OperationError(_("This host has no running storage pool for the VM's disks: add or start one on its Storage page."))
|
||||
if not networks:
|
||||
raise util.OperationError(_("You haven't defined any network pools"))
|
||||
raise util.OperationError(_("This host has no network for the VM: add one on its Networks page."))
|
||||
|
||||
vm_form = NewVMForm(initial={
|
||||
# a default this host does not offer is no choice: the select asks for one
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue