mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
fix(instances): a clone's quota and automatic disk names follow the disks it copies
A clone copies the disks of the VM's persistent definition, but its disk quota and the disk names chosen with automatic naming came from the running VM's disks, which differ after a disk is attached or detached on the running VM only.
This commit is contained in:
parent
be00b1cf8e
commit
cbc8b22f98
2 changed files with 57 additions and 2 deletions
54
instances/test_clone_disks.py
Normal file
54
instances/test_clone_disks.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"""A clone copies the disks of the VM's persistent definition: its quota and
|
||||
disk names come from those, not from the running VM's disks."""
|
||||
from unittest.mock import PropertyMock, patch
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from accounts.models import UserInstance
|
||||
from appsettings.models import AppSettings
|
||||
from computes.models import Compute
|
||||
from instances.models import Instance
|
||||
|
||||
LIVE = [{"dev": "vda", "path": "/pool/live.qcow2", "storage": "pool", "image": "live.qcow2", "size": 1 << 30}]
|
||||
SAVED = [{"dev": "vdb", "path": "/pool/saved.qcow2", "storage": "pool", "image": "saved.qcow2", "size": 20 << 30}]
|
||||
|
||||
|
||||
class CloneDisksTestCase(TestCase):
|
||||
def setUp(self):
|
||||
compute = Compute.objects.create(name="cd", hostname="192.0.2.5", login="root", password="", type=1)
|
||||
self.vm = Instance.objects.create(compute=compute, name="cd-vm", uuid="12345678-aaaa-bbbb-cccc-1234567890ab")
|
||||
|
||||
def clone(self, user, **post):
|
||||
self.client.force_login(user)
|
||||
with patch("instances.models.wvmInstance") as wvm, patch.object(
|
||||
Compute, "status", new_callable=PropertyMock, return_value=True
|
||||
), patch("instances.views.utils.check_user_quota", return_value="") as quota:
|
||||
wvm.return_value.get_disk_devices.side_effect = lambda config=False: SAVED if config else LIVE
|
||||
wvm.return_value.get_vcpu.return_value = 1
|
||||
wvm.return_value.get_memory.return_value = 512
|
||||
wvm.return_value.get_net_devices.return_value = []
|
||||
wvm.return_value.clone_instance.return_value = "abcdefab-0000-1111-2222-333333333333"
|
||||
response = self.client.post(reverse("instances:clone", args=[self.vm.id]), post)
|
||||
self.messages = [str(m) for m in response.wsgi_request._messages]
|
||||
return quota, wvm.return_value.clone_instance
|
||||
|
||||
def test_the_quota_counts_the_disks_the_clone_copies(self):
|
||||
owner = get_user_model().objects.create_user("cd_owner", password="x")
|
||||
owner.user_permissions.add(Permission.objects.get(codename="clone_instances"))
|
||||
UserInstance.objects.create(instance=self.vm, user=owner, is_change=True)
|
||||
quota, _ = self.clone(owner, name="cd-clone")
|
||||
self.assertEqual(quota.call_args.args[4], 20)
|
||||
|
||||
def test_automatic_disk_names_are_for_the_disks_the_clone_copies(self):
|
||||
admin = get_user_model().objects.create_superuser("cd_admin", "cd@example.com", "x")
|
||||
AppSettings.objects.filter(key="CLONE_INSTANCE_AUTO_NAME").update(value="True")
|
||||
with patch("instances.views.utils.get_clone_free_names", return_value=["auto-1"]), patch(
|
||||
"instances.views.utils.get_dhcp_mac_address", return_value="52:54:00:00:00:01"
|
||||
):
|
||||
_, clone_instance = self.clone(admin)
|
||||
data = clone_instance.call_args.args[0]
|
||||
self.assertIn("disk-vdb", data)
|
||||
self.assertNotIn("disk-vda", data)
|
||||
|
|
@ -1784,7 +1784,8 @@ def _clone_plan(request, instance):
|
|||
clone_data["clone-title"] = request.POST.get("clone-title", "").strip()
|
||||
clone_data["clone-description"] = request.POST.get("clone-description", "").strip()
|
||||
|
||||
disk_sum = sum(int(disk.get("size") or 0) >> 30 for disk in instance.disks)
|
||||
# the clone copies the disks of the persistent definition
|
||||
disk_sum = sum(int(disk.get("size") or 0) >> 30 for disk in instance.config_disks)
|
||||
quota_msg = utils.check_user_quota(
|
||||
request.user, 1, instance.vcpu, instance.memory, disk_sum
|
||||
)
|
||||
|
|
@ -1803,7 +1804,7 @@ def _clone_plan(request, instance):
|
|||
auto_vname = utils.get_clone_free_names()[0]
|
||||
clone_data["name"] = auto_vname
|
||||
clone_data["clone-net-mac-0"] = utils.get_dhcp_mac_address(auto_vname)
|
||||
for disk in instance.disks:
|
||||
for disk in instance.config_disks:
|
||||
disk_dev = f"disk-{disk['dev']}"
|
||||
disk_name = utils.get_clone_disk_name(disk, instance.name, auto_vname)
|
||||
clone_data[disk_dev] = disk_name
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue