mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 04:36:48 +00:00
fix(instances): the quota counts every VM and refuses what it cannot verify
check_user_quota added up the vCPUs, memory and disks of the user's VMs, but skipped a VM whose host failed a TCP probe. A host that was down therefore let users exceed their quota, and the probe always failed for ssh computes named by an ssh_config alias or reached through ProxyJump, so their VMs were never counted. A VM that could not be read turned the page into the error page instead. - Hosts are checked with Compute.status, the connection WebVirtCloud uses, once per host. A VM that cannot be read (host down, VM gone) makes the usage unknown: clone and resize up are refused with their own message (fail closed). - A request that adds nothing is not checked, so a user over quota can still shrink a VM. Users without limits, and an exceeded instance count (from the database), need no host either. - Memory resize of a running VM changes only the current memory, but the quota was charged with the submitted maximum. It is now charged with no change, and resize_mem gets the current maximum, so a VM that shuts down meanwhile cannot take an unchecked one. - The VM page no longer computes the quota on every load (it read every VM of the user on every host for a "quota reached" banner). The limit is reported when a change is refused. The test that expected a down host to pass the quota now expects it to be refused. Checked against the test hosts: with a VM behind an ssh_config alias the previous code counted 29 vCPUs, the new one 31; with a VM on an unreachable host the previous code allowed +1 vCPU, the new one refuses it after 5.1 s and allows -1 at once. The new tests fail on the previous code, except the ones guarding unchanged behaviour.
This commit is contained in:
parent
a3d3cca477
commit
fb3f686532
5 changed files with 245 additions and 35 deletions
|
|
@ -6,11 +6,12 @@ from computes.models import Compute
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from instances.models import Instance
|
||||
from instances.utils import check_user_quota
|
||||
from instances.utils import QUOTA_UNVERIFIED, check_user_quota
|
||||
|
||||
|
||||
class QuotaWithDownHostTestCase(TestCase):
|
||||
def test_vm_on_an_unreachable_host_does_not_break_the_quota_check(self):
|
||||
def test_vm_on_an_unreachable_host_makes_the_quota_unverified(self):
|
||||
# its usage is unknown, so an increase is refused (fail closed), without an error page
|
||||
sock = socket.socket()
|
||||
sock.bind(("127.0.0.1", 0))
|
||||
port = sock.getsockname()[1]
|
||||
|
|
@ -22,4 +23,4 @@ class QuotaWithDownHostTestCase(TestCase):
|
|||
UserInstance.objects.create(user=user, instance=vm)
|
||||
get_settings() # app settings are normally loaded by middleware
|
||||
|
||||
self.assertEqual(check_user_quota(user, 1, 1, 128, 1), "")
|
||||
self.assertEqual(check_user_quota(user, 1, 1, 128, 1), QUOTA_UNVERIFIED)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue