mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
fix(vrtManager): a request back from other hosts counts on its own host again
A request counts on the host it connected to last. A quota check reads every host of the user's VMs, and a VM's destruction the other hosts' files, in the middle of a request that then goes on with the VM's own host through the objects it kept: it was counted on the last host it read while it used its own, so a host that does not answer could take more requests than its limit, and the last host read was charged. Both checks now give the request back to the host it counted on before.
This commit is contained in:
parent
491819ed64
commit
fb45445492
3 changed files with 33 additions and 1 deletions
|
|
@ -12,7 +12,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from libvirt import libvirtError
|
||||
from logs.audit import reason, write
|
||||
from operations.models import Operation
|
||||
from vrtManager.connection import wvmConnect
|
||||
from vrtManager.connection import other_hosts, wvmConnect
|
||||
from vrtManager.instance import wvmInstance, wvmInstances
|
||||
from vrtManager.util import OperationError
|
||||
|
||||
|
|
@ -46,6 +46,7 @@ def get_clone_free_names(size=10):
|
|||
return free_names
|
||||
|
||||
|
||||
@other_hosts()
|
||||
def paths_used_on_other_computes(compute, own):
|
||||
"""The paths in own that the VMs and volumes of the panel's other computes
|
||||
use (paths_in_use): shared storage holds a file at the same path on every
|
||||
|
|
@ -74,6 +75,7 @@ def disk_gib(disks):
|
|||
QUOTA_UNVERIFIED = "unverified"
|
||||
|
||||
|
||||
@other_hosts()
|
||||
def check_user_quota(user, instance, cpu, memory, disk_size):
|
||||
"""
|
||||
Which quota the user would exceed by adding these amounts (instances,
|
||||
|
|
|
|||
|
|
@ -135,6 +135,17 @@ def _count_on(connection):
|
|||
_request.held = connection
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def other_hosts():
|
||||
"""For code that reads other hosts in the middle of a web request, which
|
||||
then goes on with the host it used before, through the objects it kept:
|
||||
the request counts on that host again after the block (HOST_REQUESTS)."""
|
||||
held = getattr(_request, "held", None)
|
||||
yield
|
||||
if held is not None:
|
||||
_count_on(held)
|
||||
|
||||
|
||||
request_started.connect(_request_started, dispatch_uid="vrtManager.connection.request_started")
|
||||
request_finished.connect(_request_finished, dispatch_uid="vrtManager.connection.request_finished")
|
||||
|
||||
|
|
|
|||
|
|
@ -295,6 +295,25 @@ class HostRequestsTestCase(unittest.TestCase):
|
|||
self.end_requests()
|
||||
self.assertEqual(self.request("h") + self.request("h"), [])
|
||||
|
||||
def test_a_request_back_from_other_hosts_counts_on_its_own_again(self):
|
||||
def run():
|
||||
request_started.send(sender=None)
|
||||
self.manager.get_connection("h", "u", "p", CONN_TCP)
|
||||
with connection.other_hosts():
|
||||
self.manager.get_connection("g", "u", "p", CONN_TCP)
|
||||
back.set()
|
||||
self.done.wait(5)
|
||||
request_finished.send(sender=None)
|
||||
|
||||
back = threading.Event()
|
||||
thread = threading.Thread(target=run)
|
||||
thread.start()
|
||||
self.threads.append(thread)
|
||||
back.wait(5)
|
||||
# it holds h again (one of two) and left g
|
||||
self.assertEqual(self.request("h") + self.request("g") + self.request("g"), [])
|
||||
self.assertEqual(len(self.request("h")), 1)
|
||||
|
||||
def test_threads_outside_a_request_are_not_counted(self):
|
||||
self.assertEqual(self.request("h") + self.request("h"), [])
|
||||
self.manager.get_connection("h", "u", "p", CONN_TCP)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue