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:
parent
31cbe60aa4
commit
c2d3285e0f
7 changed files with 69 additions and 127 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue