mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-10-26 08:55:13 +03:00
migrate: Add XML editor support
Allows the user to tweak the XML at the destination, which is already something that libvirt supports Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
parent
16ebab2230
commit
5e495ebd46
@ -102,7 +102,6 @@ class VMMMigrate(uiutils.UITestCase):
|
|||||||
uiutils.check(lambda: not progwin.showing, timeout=5)
|
uiutils.check(lambda: not progwin.showing, timeout=5)
|
||||||
uiutils.check(lambda: not mig.showing)
|
uiutils.check(lambda: not mig.showing)
|
||||||
|
|
||||||
|
|
||||||
def testMigrateConnMismatch(self):
|
def testMigrateConnMismatch(self):
|
||||||
# Add a possible target but disconnect it
|
# Add a possible target but disconnect it
|
||||||
self.app.uri = utils.URIs.test_default
|
self.app.uri = utils.URIs.test_default
|
||||||
@ -120,3 +119,35 @@ class VMMMigrate(uiutils.UITestCase):
|
|||||||
mig.find("conn-combo").find("No usable", "menu item")
|
mig.find("conn-combo").find("No usable", "menu item")
|
||||||
mig.keyCombo("<alt>F4")
|
mig.keyCombo("<alt>F4")
|
||||||
uiutils.check(lambda: not mig.showing)
|
uiutils.check(lambda: not mig.showing)
|
||||||
|
|
||||||
|
def testMigrateXMLEditor(self):
|
||||||
|
self.app.open(xmleditor_enabled=True)
|
||||||
|
manager = self.app.topwin
|
||||||
|
|
||||||
|
# Add an additional connection
|
||||||
|
self._add_conn("test:///default")
|
||||||
|
|
||||||
|
# Run it and check some values
|
||||||
|
vmname = "test-many-devices"
|
||||||
|
win = self._open_migrate(vmname)
|
||||||
|
win.find("address-text").set_text("TESTSUITE-FAKE")
|
||||||
|
|
||||||
|
# Create a new obj with XML edited name, verify it worked
|
||||||
|
newname = "aafroofroo"
|
||||||
|
win.find("XML", "page tab").click()
|
||||||
|
xmleditor = win.find("XML editor")
|
||||||
|
newtext = xmleditor.text.replace(
|
||||||
|
">%s<" % vmname, ">%s<" % newname)
|
||||||
|
xmleditor.set_text(newtext)
|
||||||
|
win.find("Migrate", "push button").click()
|
||||||
|
uiutils.check(lambda: not win.showing, timeout=10)
|
||||||
|
|
||||||
|
manager.find(newname, "table cell")
|
||||||
|
|
||||||
|
# Do standard xmleditor tests
|
||||||
|
win = self._open_migrate(vmname)
|
||||||
|
win.find("address-text").set_text("TESTSUITE-FAKE")
|
||||||
|
finish = win.find("Migrate", "push button")
|
||||||
|
self._test_xmleditor_interactions(win, finish)
|
||||||
|
win.find("Cancel", "push button").click()
|
||||||
|
uiutils.check(lambda: not win.visible)
|
||||||
|
@ -265,7 +265,9 @@ def drag(win, x, y):
|
|||||||
"""
|
"""
|
||||||
Drag a window to the x/y coordinates
|
Drag a window to the x/y coordinates
|
||||||
"""
|
"""
|
||||||
win.click()
|
time.sleep(.5)
|
||||||
|
win.click_title()
|
||||||
|
time.sleep(.5)
|
||||||
clickX, clickY = _title_coordinates(win)
|
clickX, clickY = _title_coordinates(win)
|
||||||
dogtail.rawinput.drag((clickX, clickY), (x, y))
|
dogtail.rawinput.drag((clickX, clickY), (x, y))
|
||||||
|
|
||||||
|
964
ui/migrate.ui
964
ui/migrate.ui
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,7 @@ from .asyncjob import vmmAsyncJob
|
|||||||
from .baseclass import vmmGObjectUI
|
from .baseclass import vmmGObjectUI
|
||||||
from .connmanager import vmmConnectionManager
|
from .connmanager import vmmConnectionManager
|
||||||
from .object.domain import vmmDomain
|
from .object.domain import vmmDomain
|
||||||
|
from .xmleditor import vmmXMLEditor
|
||||||
|
|
||||||
|
|
||||||
NUM_COLS = 3
|
NUM_COLS = 3
|
||||||
@ -40,6 +41,12 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
vmmGObjectUI.__init__(self, "migrate.ui", "vmm-migrate")
|
vmmGObjectUI.__init__(self, "migrate.ui", "vmm-migrate")
|
||||||
self.vm = None
|
self.vm = None
|
||||||
|
|
||||||
|
self._xmleditor = vmmXMLEditor(self.builder, self.topwin,
|
||||||
|
self.widget("details-box-align"),
|
||||||
|
self.widget("details-box"))
|
||||||
|
self._xmleditor.connect("xml-requested",
|
||||||
|
self._xmleditor_xml_requested_cb)
|
||||||
|
|
||||||
self.builder.connect_signals({
|
self.builder.connect_signals({
|
||||||
"on_vmm_migrate_delete_event": self._delete_event,
|
"on_vmm_migrate_delete_event": self._delete_event,
|
||||||
"on_migrate_cancel_clicked": self._cancel_clicked,
|
"on_migrate_cancel_clicked": self._cancel_clicked,
|
||||||
@ -58,6 +65,8 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
self.vm = None
|
self.vm = None
|
||||||
|
self._xmleditor.cleanup()
|
||||||
|
self._xmleditor = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _connobjs(self):
|
def _connobjs(self):
|
||||||
@ -147,6 +156,8 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
self.widget("migrate-temporary-label").get_tooltip_text())
|
self.widget("migrate-temporary-label").get_tooltip_text())
|
||||||
|
|
||||||
def _reset_state(self):
|
def _reset_state(self):
|
||||||
|
self._xmleditor.reset_state()
|
||||||
|
|
||||||
title_str = _("<span size='large'>Migrate '%(vm)s'</span>") % {
|
title_str = _("<span size='large'>Migrate '%(vm)s'</span>") % {
|
||||||
"vm": xmlutil.xml_escape(self.vm.get_name()),
|
"vm": xmlutil.xml_escape(self.vm.get_name()),
|
||||||
}
|
}
|
||||||
@ -348,6 +359,11 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
|
|
||||||
def _finish(self):
|
def _finish(self):
|
||||||
try:
|
try:
|
||||||
|
xml = None
|
||||||
|
if self._xmleditor.is_xml_selected():
|
||||||
|
xml = self._xmleditor.get_xml()
|
||||||
|
log.debug("Using XML from xmleditor:\n%s", xml)
|
||||||
|
|
||||||
row = uiutil.get_list_selected_row(self.widget("migrate-dest"))
|
row = uiutil.get_list_selected_row(self.widget("migrate-dest"))
|
||||||
destlabel = row[COL_LABEL]
|
destlabel = row[COL_LABEL]
|
||||||
destconn = self._connobjs.get(row[COL_URI])
|
destconn = self._connobjs.get(row[COL_URI])
|
||||||
@ -378,7 +394,7 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
|
|
||||||
progWin = vmmAsyncJob(
|
progWin = vmmAsyncJob(
|
||||||
self._async_migrate,
|
self._async_migrate,
|
||||||
[self.vm, destconn, uri, tunnel, unsafe, temporary],
|
[self.vm, destconn, uri, tunnel, unsafe, temporary, xml],
|
||||||
self._finish_cb, [destconn],
|
self._finish_cb, [destconn],
|
||||||
_("Migrating VM '%s'") % self.vm.get_name(),
|
_("Migrating VM '%s'") % self.vm.get_name(),
|
||||||
(_("Migrating VM '%(name)s' to %(host)s. This may take a while.") %
|
(_("Migrating VM '%(name)s' to %(host)s. This may take a while.") %
|
||||||
@ -398,7 +414,7 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
asyncjob.job_canceled = True # pragma: no cover
|
asyncjob.job_canceled = True # pragma: no cover
|
||||||
|
|
||||||
def _async_migrate(self, asyncjob,
|
def _async_migrate(self, asyncjob,
|
||||||
origvm, origdconn, migrate_uri, tunnel, unsafe, temporary):
|
origvm, origdconn, migrate_uri, tunnel, unsafe, temporary, xml):
|
||||||
meter = asyncjob.get_meter()
|
meter = asyncjob.get_meter()
|
||||||
|
|
||||||
srcconn = origvm.conn
|
srcconn = origvm.conn
|
||||||
@ -410,5 +426,12 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||||||
log.debug("Migrating vm=%s from %s to %s", vm.get_name(),
|
log.debug("Migrating vm=%s from %s to %s", vm.get_name(),
|
||||||
srcconn.get_uri(), dstconn.get_uri())
|
srcconn.get_uri(), dstconn.get_uri())
|
||||||
|
|
||||||
vm.migrate(dstconn, migrate_uri, tunnel, unsafe, temporary,
|
vm.migrate(dstconn, migrate_uri, tunnel, unsafe, temporary, xml,
|
||||||
meter=meter)
|
meter=meter)
|
||||||
|
|
||||||
|
################
|
||||||
|
# UI listeners #
|
||||||
|
################
|
||||||
|
|
||||||
|
def _xmleditor_xml_requested_cb(self, src):
|
||||||
|
self._xmleditor.set_xml(self.vm.xmlobj.get_xml())
|
||||||
|
@ -1388,7 +1388,7 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
|
|
||||||
|
|
||||||
def migrate(self, destconn, dest_uri=None,
|
def migrate(self, destconn, dest_uri=None,
|
||||||
tunnel=False, unsafe=False, temporary=False, meter=None):
|
tunnel=False, unsafe=False, temporary=False, xml=None, meter=None):
|
||||||
self._cancel_set_time()
|
self._cancel_set_time()
|
||||||
self._install_abort = True
|
self._install_abort = True
|
||||||
|
|
||||||
@ -1417,12 +1417,15 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
params = {}
|
params = {}
|
||||||
if dest_uri and not tunnel:
|
if dest_uri and not tunnel:
|
||||||
params[libvirt.VIR_MIGRATE_PARAM_URI] = dest_uri
|
params[libvirt.VIR_MIGRATE_PARAM_URI] = dest_uri
|
||||||
|
if xml:
|
||||||
|
params[libvirt.VIR_MIGRATE_PARAM_DEST_XML] = xml
|
||||||
|
|
||||||
if self.conn.is_test() and "TESTSUITE-FAKE" in (dest_uri or ""):
|
if self.conn.is_test() and "TESTSUITE-FAKE" in (dest_uri or ""):
|
||||||
# If using the test driver and a special URI, fake successful
|
# If using the test driver and a special URI, fake successful
|
||||||
# migration so we can test more of the migration wizard
|
# migration so we can test more of the migration wizard
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
xml = self.get_xml_to_define()
|
if not xml:
|
||||||
|
xml = self.get_xml_to_define()
|
||||||
destconn.define_domain(xml).create()
|
destconn.define_domain(xml).create()
|
||||||
self.delete()
|
self.delete()
|
||||||
elif tunnel:
|
elif tunnel:
|
||||||
|
Loading…
Reference in New Issue
Block a user