mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-10 20:26:48 +00:00
fix(logs): failures name their job, VM and user; the new VM form shows a list it could not load
- A failed cancel hook logged "worker task cancel failed": it now names
the job, its kind, resource and user, with the traceback for a fault
of the panel.
- novncd logged "Console connection failed" without the VM or the user.
- django-axes wrote four INFO lines a login ("Reset 0 access
attempts"...); logins are on the Logs page, so it logs warnings only.
- The new VM form's machine types and disk buses answered 200 with an
empty object when libvirt failed, and nothing was logged: the list
stayed empty, the form could not go on and said nothing. They answer
400 with the error, as the pool's volume list does, the warning is
logged with the compute, and the form's lists show an error they get
with the page's messages.
This commit is contained in:
parent
432b1505b3
commit
6abea495f1
14 changed files with 155 additions and 40 deletions
|
|
@ -71,7 +71,7 @@ class GraphTestCase(TestCase):
|
|||
self.assertEqual((data["cpudata"], data["memdata"]["total"]), (None, None))
|
||||
self.assertNotIn("cpu_sample", data)
|
||||
|
||||
def test_a_host_that_cannot_be_connected_to_answers_without_values(self):
|
||||
def test_a_host_that_cannot_be_connected_to_answers_without_values_or_with_its_error(self):
|
||||
down = ConnectionFailed("192.0.2.1 is down")
|
||||
with patch("computes.views.wvmHostDetails", side_effect=down), patch(
|
||||
"computes.models.wvmHostDetails", side_effect=down
|
||||
|
|
@ -79,7 +79,9 @@ class GraphTestCase(TestCase):
|
|||
self.assertIsNone(self.graph()["cpudata"])
|
||||
for url in (reverse("machines", args=[self.compute.id, "x86_64"]),
|
||||
reverse("buses", args=[self.compute.id, "x86_64", "q35", "disk"])):
|
||||
self.assertEqual(json.loads(self.client.get(url).content), {})
|
||||
# a list the new VM form waits for: the error, not an empty answer
|
||||
response = self.client.get(url)
|
||||
self.assertEqual((response.status_code, json.loads(response.content)), (400, {"error": "192.0.2.1 is down"}))
|
||||
|
||||
|
||||
@unittest.skipUnless(shutil.which("node"), "node is not installed")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from django.contrib.auth import get_user_model
|
|||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase
|
||||
from libvirt import libvirtError
|
||||
|
||||
from vrtManager.connection import CONN_SOCKET, connection_manager
|
||||
from computes.models import Compute
|
||||
|
|
@ -190,6 +191,17 @@ class ComputesTestCase(TestCase):
|
|||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_a_list_the_host_does_not_give_is_an_error_not_an_empty_list(self):
|
||||
# the new VM form showed nothing and could not go on; the error was nowhere
|
||||
for url, method in ((reverse("machines", args=[self.compute.id, "x86_64"]), "get_machine_types"),
|
||||
(reverse("buses", args=[self.compute.id, "x86_64", "q35", "disk"]), "get_disk_device_types")):
|
||||
with self.subTest(method), patch("computes.models.wvmHostDetails") as conn, \
|
||||
self.assertLogs("computes.views", "WARNING") as logs:
|
||||
getattr(conn.return_value, method).side_effect = libvirtError("Cannot recv data")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual((response.status_code, json.loads(response.content)), (400, {"error": "Cannot recv data"}))
|
||||
self.assertIn(f"of compute {self.compute.name} failed: Cannot recv data", logs.output[0])
|
||||
|
||||
def test_a_disk_is_offered_the_hosts_disk_buses(self):
|
||||
with patch("computes.models.wvmHostDetails") as conn:
|
||||
conn.return_value.get_disk_device_types.return_value = ["disk", "cdrom", "lun"]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import json
|
||||
import logging
|
||||
|
||||
from admin.decorators import superuser_only
|
||||
from django.conf import settings
|
||||
from django.core import signing
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
|
@ -28,6 +29,8 @@ from computes.models import Compute
|
|||
|
||||
from . import utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# The host CPU graph sends back the CPU sample of its previous answer; usage
|
||||
# is taken since then when it is this recent, otherwise over one second.
|
||||
CPU_SAMPLE_MAX_AGE = 15
|
||||
|
|
@ -227,7 +230,10 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
|
|||
:return:
|
||||
"""
|
||||
comp_mgr = ComputeManager(compute_id)
|
||||
return HttpResponse(comp_mgr.get_disk_buses(arch, machine, disk), content_type="application/json")
|
||||
try:
|
||||
return HttpResponse(comp_mgr.get_disk_buses(arch, machine, disk), content_type="application/json")
|
||||
except libvirtError as err:
|
||||
return read_failed(comp_mgr.compute, "disk buses", err)
|
||||
|
||||
|
||||
def get_compute_machine_types(request, compute_id, arch):
|
||||
|
|
@ -238,7 +244,17 @@ def get_compute_machine_types(request, compute_id, arch):
|
|||
:return:
|
||||
"""
|
||||
comp_mgr = ComputeManager(compute_id)
|
||||
return HttpResponse(comp_mgr.get_machine_types(arch), content_type="application/json")
|
||||
try:
|
||||
return HttpResponse(comp_mgr.get_machine_types(arch), content_type="application/json")
|
||||
except libvirtError as err:
|
||||
return read_failed(comp_mgr.compute, "machine types", err)
|
||||
|
||||
|
||||
def read_failed(compute, what, err):
|
||||
"""A list the new VM form loads that the host did not give: not 200 with
|
||||
an empty list, which the form cannot tell from none."""
|
||||
logger.warning("Reading the %s of compute %s failed: %s", what, compute.name, err)
|
||||
return JsonResponse({"error": str(err)}, status=400)
|
||||
|
||||
|
||||
class ComputeManager:
|
||||
|
|
@ -246,30 +262,21 @@ class ComputeManager:
|
|||
self.compute = get_object_or_404(Compute, pk=compute_id)
|
||||
|
||||
def get_machine_types(self, arch):
|
||||
data = dict()
|
||||
try:
|
||||
data["machines"] = self.compute.proxy.get_machine_types(arch)
|
||||
except libvirtError:
|
||||
pass
|
||||
|
||||
return json.dumps(data)
|
||||
return json.dumps({"machines": self.compute.proxy.get_machine_types(arch)})
|
||||
|
||||
def get_disk_buses(self, arch, machine, disk):
|
||||
data = dict()
|
||||
try:
|
||||
disk_device_types = self.compute.proxy.get_disk_device_types(arch, machine)
|
||||
disk_device_types = self.compute.proxy.get_disk_device_types(arch, machine)
|
||||
|
||||
if disk in disk_device_types:
|
||||
if disk == "disk":
|
||||
data["bus"] = sorted(self.compute.proxy.get_disk_bus_types(arch, machine))
|
||||
elif disk == "cdrom":
|
||||
data["bus"] = ["ide", "sata", "scsi"]
|
||||
elif disk == "floppy":
|
||||
data["bus"] = ["fdc"]
|
||||
elif disk == "lun":
|
||||
data["bus"] = ["scsi"]
|
||||
except libvirtError:
|
||||
pass
|
||||
if disk in disk_device_types:
|
||||
if disk == "disk":
|
||||
data["bus"] = sorted(self.compute.proxy.get_disk_bus_types(arch, machine))
|
||||
elif disk == "cdrom":
|
||||
data["bus"] = ["ide", "sata", "scsi"]
|
||||
elif disk == "floppy":
|
||||
data["bus"] = ["fdc"]
|
||||
elif disk == "lun":
|
||||
data["bus"] = ["scsi"]
|
||||
|
||||
return json.dumps(data)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue