mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
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.
66 lines
3.8 KiB
Python
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")
|