1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00

fix(instances): a VM's DRBD status counts only its own resources

The resource pattern was not anchored and took any letters after the VM's
name, so VM "web" also counted "webserver" and "myweb"; a VM with no
resource of its own got "Secondary/OK", stored on every page view. A
VM's resources are now its name or name_SUFFIX at the start of a line,
and a VM without one is "None DRBD".
This commit is contained in:
catborise 2026-10-26 12:13:08 +03:00
parent 11348b2c37
commit d696820120
2 changed files with 33 additions and 7 deletions

View file

@ -26,3 +26,29 @@ class DrbdTargetTestCase(unittest.TestCase):
) as run:
self.assertEqual(drbd_status(SimpleNamespace(user=None), 1), "None DRBD")
self.assertEqual(run.call_args.kwargs["timeout"], DRBD_STATUS_TIMEOUT)
STATUS = """webserver role:Primary
disk:UpToDate
web role:Secondary
disk:UpToDate
web_data role:Secondary
disk:Outdated
"""
class DrbdStatusTestCase(unittest.TestCase):
def status(self, name, stdout=STATUS):
vm = SimpleNamespace(name=name, compute=SimpleNamespace(type=2, login="root", hostname="192.0.2.1"))
with patch("instances.views.get_instance", return_value=vm), patch(
"instances.views.subprocess.run", return_value=SimpleNamespace(stdout=stdout)
):
return drbd_status(SimpleNamespace(user=None), 1)
def test_a_vm_counts_only_its_own_resources(self):
# "webserver" is another VM's resource; "web_data" is web's second disk
self.assertEqual(self.status("web"), "Secondary/NOK")
self.assertEqual(self.status("webserver"), "Primary/OK")
def test_a_vm_without_a_resource_has_no_drbd(self):
self.assertEqual(self.status("db"), "None DRBD")

View file

@ -341,13 +341,13 @@ def drbd_status(request, pk):
except subprocess.TimeoutExpired:
return result
if remoteDrbdStatus.stdout:
instanceFindDrbd = re.compile(
re.escape(instance.name) + "[_]*[A-Z]* role:(.+?)\n disk:(.+?)\n",
re.IGNORECASE,
)
instanceDrbd = instanceFindDrbd.findall(remoteDrbdStatus.stdout)
# the VM's resources are its name or its name_SUFFIX, at the start of a line
instanceFindDrbd = re.compile(
"^" + re.escape(instance.name) + "(?:_[A-Z]+)? role:(.+?)\n disk:(.+?)\n",
re.IGNORECASE | re.MULTILINE,
)
instanceDrbd = instanceFindDrbd.findall(remoteDrbdStatus.stdout or "")
if instanceDrbd:
primaryCount = 0
secondaryCount = 0
statusDisk = "OK"