mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
moveto read the VM state for each flag and dropped options that did
not fit it, so a request could run as something else than asked; the
log then named the mode from the form ("live" or "offline"), not the
one used. The API did not log at all and answered "instance migrate is
started" after the migration had finished.
- moveto reads the state once. A running VM migrates live, or without
live paused for the transfer (non-live); a paused VM stays paused; a
shut-off VM moves offline. Live for a shut-off VM, offline for a
running or paused one, and any other state are refused before
anything changes. unsafe, auto converge (live only) and compressed
apply to a running VM.
- migrate_instance logs the outcome for the VM page and the API: the
mode and options used, or the error. The API answers
"instance is migrated (<mode>)" and accepts requests that leave out
an optional option.
- Post copy is gone from the form, the view and the API: only the
flag was set, and without migrateStartPostCopy, which the app never
called, the migration never switched to post copy.
58 lines
3.3 KiB
Python
58 lines
3.3 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.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 = {"": None, "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(migration_address=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 = MagicMock(compute=source, autostart=False)
|
|
vm.name = "vm"
|
|
with patch("instances.utils.connection_manager.host_is_up", return_value=True), \
|
|
patch("instances.utils.wvmInstances") as instances, \
|
|
patch("instances.utils.wvmInstance"), \
|
|
patch("instances.utils.Instance") as model:
|
|
model.objects.filter.return_value.first.return_value = None
|
|
user = get_user_model().objects.create_superuser("ma-mig", "mm@example.com", "pw")
|
|
migrate_instance(dest, vm, user, live=True)
|
|
self.assertEqual(instances.return_value.moveto.call_args.kwargs["uri"], "tcp://198.51.100.9")
|