mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 12:46:49 +00:00
fix(instances): recording a migration holds the ownership lock
record_migration moved or merged a VM's owners without lock_ownership(), which every other step that moves owners takes; on PostgreSQL a sync of a third compute with the same UUID could move them at the same time, and owners moved onto the source record went with its delete.
This commit is contained in:
parent
1a8edafd14
commit
c8fb778d08
2 changed files with 13 additions and 0 deletions
|
|
@ -228,3 +228,13 @@ class MigrateJobTestCase(TransactionTestCase):
|
||||||
resource_label="mig-src/mig-vm")
|
resource_label="mig-src/mig-vm")
|
||||||
self.assertEqual(MigrateInstance().log_entry(queued, Operation.CANCELLED),
|
self.assertEqual(MigrateInstance().log_entry(queued, Operation.CANCELLED),
|
||||||
("mig-src", "mig-vm", UUID, "VM mig-vm: migrate to mig-dst (cancelled)"))
|
("mig-src", "mig-vm", UUID, "VM mig-vm: migrate to mig-dst (cancelled)"))
|
||||||
|
|
||||||
|
def test_recording_a_migration_holds_the_ownership_lock(self):
|
||||||
|
# a sync of a third compute must not move the owners at the same time
|
||||||
|
from instances import utils
|
||||||
|
|
||||||
|
with patch.object(utils, "lock_ownership") as lock:
|
||||||
|
utils.record_migration(self.vm, self.dest)
|
||||||
|
lock.assert_called_once_with()
|
||||||
|
self.vm.refresh_from_db()
|
||||||
|
self.assertEqual(self.vm.compute, self.dest)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from collections import namedtuple
|
||||||
from accounts.models import UserInstance, UserAttributes
|
from accounts.models import UserInstance, UserAttributes
|
||||||
from appsettings.settings import app_settings
|
from appsettings.settings import app_settings
|
||||||
from computes.models import Compute
|
from computes.models import Compute
|
||||||
|
from computes.utils import lock_ownership
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
@ -321,6 +322,8 @@ def record_migration(instance, new_compute):
|
||||||
"""Moves instance to new_compute in the database. A record the list of
|
"""Moves instance to new_compute in the database. A record the list of
|
||||||
new_compute made for it meanwhile takes its owners and template mark."""
|
new_compute made for it meanwhile takes its owners and template mark."""
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
|
# owners are moved here: not while a sync of a third compute moves them too
|
||||||
|
lock_ownership()
|
||||||
target_inst = Instance.objects.filter(compute=new_compute, uuid=instance.uuid).first()
|
target_inst = Instance.objects.filter(compute=new_compute, uuid=instance.uuid).first()
|
||||||
if target_inst and target_inst.id != instance.id:
|
if target_inst and target_inst.id != instance.id:
|
||||||
for ui in UserInstance.objects.filter(instance=instance):
|
for ui in UserInstance.objects.filter(instance=instance):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue