1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/computes/tests/test_migration_address.py
catborise cf991adad5 fix(computes): a VM migrates to its host's panel address when it has no migration address
Without a migration address libvirt sends a migrating VM to the
destination's own host name, which the source host often cannot resolve:
a live migration to a host added without one failed ("Unable to resolve
address ..."), also when the other host had one. The destination's
address on the Computes page, which the panel reaches it at, is now the
default; the migration address stays for another network. A host the
panel reaches on its loopback keeps libvirt's default.
2026-11-01 18:41:07 +03:00

66 lines
3.8 KiB
Python

"""A compute's migration address: where other hosts send a migrating VM's
memory. Empty means libvirt's default (the destination's own hostname)."""
from unittest.mock import MagicMock, patch
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.test import TestCase
from django.urls import reverse
from computes.models import Compute
from computes.validators import validate_migration_address
from instances.models import Instance
from instances.utils import migrate_instance
class MigrationAddressTests(TestCase):
def test_accepted_and_refused_values(self):
for value in ("192.0.2.12", "kvm102.example.org", "kvm-102", "2001:db8::12",
"kvm102.example.org."):
with self.subTest(value=value):
validate_migration_address(value)
for value in ("tcp://10.0.0.1", "10.0.0.1:49152", "[2001:db8::12]", "host name", "-bad", "a..b", "10.0.0.1/24", "x;y",
"2001:db8::12%eth0", "2001:db8::12%bad]:49152", "a.."):
with self.subTest(value=value), self.assertRaises(ValidationError):
validate_migration_address(value)
def test_migration_uri(self):
cases = {"192.0.2.12": "tcp://192.0.2.12", "kvm102.example.org": "tcp://kvm102.example.org",
"2001:db8::12": "tcp://[2001:db8::12]"}
for address, uri in cases.items():
with self.subTest(address=address):
self.assertEqual(Compute(hostname="192.0.2.40", migration_address=address).migration_uri, uri)
def test_without_a_migration_address_the_panel_s_address_of_the_host_is_used(self):
# no DNS name of the host's own; a host the panel reaches on its loopback: libvirt's default
cases = {"192.0.2.40": "tcp://192.0.2.40", "kvm103.example.org": "tcp://kvm103.example.org",
"localhost": None, "LOCALHOST": None, "localhost.": None, "127.0.0.1": None}
for hostname, uri in cases.items():
with self.subTest(hostname=hostname):
self.assertEqual(Compute(hostname=hostname, migration_address="").migration_uri, uri)
def test_the_compute_form_saves_it(self):
self.client.force_login(get_user_model().objects.create_superuser("ma-admin", "ma@example.com", "pw"))
compute = Compute.objects.create(name="ma", hostname="10.0.0.9", login="root", password="", type=2)
data = {"name": "ma", "hostname": "10.0.0.9", "login": "root", "type": 2, "details": "", "migration_address": "198.51.100.9"}
self.client.post(reverse("compute_update", args=[compute.id]), data)
compute.refresh_from_db()
self.assertEqual(compute.migration_address, "198.51.100.9")
self.client.post(reverse("compute_update", args=[compute.id]), {**data, "migration_address": "tcp://x"})
compute.refresh_from_db()
self.assertEqual(compute.migration_address, "198.51.100.9")
def test_a_migration_uses_the_destination_address(self):
source = Compute.objects.create(name="ma-src", hostname="10.0.0.8", login="root", password="", type=2)
dest = Compute.objects.create(name="ma-dst", hostname="kvm9", login="root", password="", type=2,
migration_address="198.51.100.9")
vm = Instance.objects.create(compute=source, name="vm", uuid="u-ma")
user = get_user_model().objects.create_superuser("ma-mig", "mm@example.com", "pw")
with patch.object(Compute, "status", True), \
patch("instances.utils.wvmInstances") as instances, \
patch("instances.utils.wvmInstance"), \
patch.object(Instance, "proxy", MagicMock()):
instances.return_value.moveto.return_value = ("live", [])
migrate_instance(dest, vm, user, live=True)
self.assertEqual(instances.return_value.moveto.call_args.kwargs["uri"], "tcp://198.51.100.9")