1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 19:56:48 +00:00

feat(instances): a running migration can be cancelled; its time limit goes

This commit is contained in:
catborise 2026-10-15 20:42:50 +03:00
parent 31cbe60aa4
commit c2d3285e0f
7 changed files with 69 additions and 127 deletions

View file

@ -5,7 +5,6 @@ import logging
import os.path
import re
import string
import threading
import time
logger = logging.getLogger(__name__)
@ -77,7 +76,7 @@ def _rate(before, after, seconds, scale=1):
class wvmInstances(wvmConnect):
def moveto(self, conn, name, live, unsafe, offline, autoconverge=False, compress=False, uri=None, timeout=None):
def moveto(self, conn, name, live, unsafe, offline, autoconverge=False, compress=False, uri=None):
"""Migrates the VM of conn (a wvmInstance on the source) here.
The mode follows the VM's state, read once: a running VM migrates
@ -86,9 +85,8 @@ class wvmInstances(wvmConnect):
fit the state is refused. unsafe, autoconverge (live only) and
compress apply to a running VM. uri: the native migration URI
(tcp://address) on the destination; None lets libvirt use the
destination's own hostname. timeout: seconds after which a migration
that has not finished is cancelled (None: no limit). Returns the mode
and options used, for the log."""
destination's own hostname. Returns the mode and options used, for
the log."""
state = conn.get_status()
if state == 5:
if live:
@ -150,7 +148,7 @@ class wvmInstances(wvmConnect):
# dom.migrate.
self.move_definition(dom)
else:
self.migrate_within(dom, flags, uri, timeout)
dom.migrate(self.wvm, flags, None, uri, 0)
return ", ".join(mode)
@staticmethod
@ -172,40 +170,6 @@ class wvmInstances(wvmConnect):
"host. Start the VM and migrate it live."
)
def migrate_within(self, dom, flags, uri, timeout):
"""dom.migrate, cancelled when it has not finished after timeout
seconds: a VM that changes its memory faster than the network carries
it never finishes, and the request would be ended by the web server
with no word. Cancelled, the VM stays on the source."""
cancelled = threading.Event()
def cancel():
with contextlib.suppress(libvirtError): # finished meanwhile
dom.abortJob()
cancelled.set()
timer = threading.Timer(timeout, cancel) if timeout else None
if timer:
timer.daemon = True
timer.start()
try:
dom.migrate(self.wvm, flags, None, uri, 0)
except libvirtError as error:
if timer:
timer.cancel()
timer.join() # a cancel under way ends before the locks go
if cancelled.is_set():
raise util.OperationError(
f"The migration did not finish within {timeout} s and was cancelled ({error}); the VM stays on "
"the source host. A VM that changes its memory faster than the network carries it needs auto "
"converge."
) from error
raise
finally:
if timer:
timer.cancel()
timer.join()
def missing_disks(self, definitions):
"""(target, source) of the disks in the VM definitions (XML) that are
not volumes of this host's active storage pools: the VM's own files,