[PATCH 1/3] probe that libvirt support to change a live VM network source

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> This is a good feature to user, but it is not supported by low version libvirt. So we need to probe it. Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- src/kimchi/featuretests.py | 43 ++++++++++++++++++++++++++++++++++++++++++- src/kimchi/model/config.py | 3 +++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/kimchi/featuretests.py b/src/kimchi/featuretests.py index 5192361..6eb29f4 100644 --- a/src/kimchi/featuretests.py +++ b/src/kimchi/featuretests.py @@ -62,8 +62,25 @@ SIMPLE_VM_XML = """ <type arch='x86_64' machine='pc'>hvm</type> <boot dev='hd'/> </os> + <devices> + %s + </devices> </domain>""" +SIMPLE_NETWORK_XML = """ +<network> + <name>%s</name> +</network> +""" + +VM_IFACE_XML = """ +<interface type='network'> + <mac address='52:54:00:12:34:56'/> + <source network='%s'/> + <model type='rtl8139'/> +</interface> +""" + SCSI_FC_XML = """ <pool type='scsi'> <name>TEST_SCSI_FC_POOL</name> @@ -196,7 +213,7 @@ class FeatureTests(object): rollback.prependDefer(FeatureTests.enable_screen_error_logging) conn = libvirt.open('qemu:///system') rollback.prependDefer(conn.close) - dom = conn.defineXML(SIMPLE_VM_XML) + dom = conn.defineXML(SIMPLE_VM_XML % "") rollback.prependDefer(dom.undefine) try: dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, @@ -206,3 +223,27 @@ class FeatureTests(object): return True except libvirt.libvirtError: return False + + @staticmethod + def change_live_vm_network(): + with RollbackContext() as rollback: + FeatureTests.disable_screen_error_logging() + rollback.prependDefer(FeatureTests.enable_screen_error_logging) + conn = libvirt.open('qemu:///system') + rollback.prependDefer(conn.close) + net1_name = "isolated_test_net1" + net2_name = "isolated_test_net2" + net1 = conn.networkCreateXML(SIMPLE_NETWORK_XML % net1_name) + rollback.prependDefer(net1.destroy) + net2 = conn.networkCreateXML(SIMPLE_NETWORK_XML % net2_name) + rollback.prependDefer(net2.destroy) + iface1_xml = VM_IFACE_XML % net1_name + iface2_xml = VM_IFACE_XML % net2_name + dom = conn.createXML(SIMPLE_VM_XML % iface1_xml, flags=0) + rollback.prependDefer(dom.destroy) + try: + dom.updateDeviceFlags(iface2_xml, + libvirt.VIR_DOMAIN_AFFECT_LIVE) + return True + except libvirt.libvirtError: + return False diff --git a/src/kimchi/model/config.py b/src/kimchi/model/config.py index 0ef0855..88ab681 100644 --- a/src/kimchi/model/config.py +++ b/src/kimchi/model/config.py @@ -54,6 +54,7 @@ class CapabilitiesModel(object): self.libvirt_stream_protocols = [] self.fc_host_support = False self.metadata_support = False + self.change_live_vm_network = False # Subscribe function to set host capabilities to be run when cherrypy # server is up @@ -67,6 +68,8 @@ class CapabilitiesModel(object): self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe() self.fc_host_support = FeatureTests.libvirt_support_fc_host() self.metadata_support = FeatureTests.has_metadata_support() + self.change_live_vm_network = FeatureTests.change_live_vm_network() + self.libvirt_stream_protocols = [] for p in ['http', 'https', 'ftp', 'ftps', 'tftp']: -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> This is a good feature to user. Probe this feature, if libvirt support it then let kimchi support it. Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- src/kimchi/model/vmifaces.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py index e377477..101dab1 100644 --- a/src/kimchi/model/vmifaces.py +++ b/src/kimchi/model/vmifaces.py @@ -24,6 +24,7 @@ from lxml import etree, objectify from lxml.builder import E from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError +from kimchi.model.config import CapabilitiesModel from kimchi.model.vms import DOM_STATE_MAP, VMModel @@ -137,11 +138,18 @@ class VMIfaceModel(object): if iface is None: raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac}) - # FIXME we will support to change the live VM configuration later. + # change on the active VM instance and persisted VM configuration. if iface.attrib['type'] == 'network' and 'network' in params: iface.source.attrib['network'] = params['network'] xml = etree.tostring(iface) - dom.updateDeviceFlags(xml, flags=libvirt.VIR_DOMAIN_AFFECT_CONFIG) + if CapabilitiesModel().change_live_vm_network: + conf_flag = (libvirt.VIR_DOMAIN_AFFECT_CONFIG + + libvirt.VIR_DOMAIN_AFFECT_LIVE if dom.isActive() + and dom.isPersistent() else + libvirt.VIR_DOMAIN_AFFECT_CURRENT) + else: + conf_flag = libvirt.VIR_DOMAIN_AFFECT_CONFIG + dom.updateDeviceFlags(xml, flags=conf_flag) # change on the persisted VM configuration only. if 'model' in params and dom.isPersistent(): -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> update test case Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- tests/test_model.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_model.py b/tests/test_model.py index e3dff95..ab927f0 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -39,6 +39,7 @@ from kimchi.exception import InvalidOperation, InvalidParameter from kimchi.exception import NotFoundError, OperationFailed from kimchi.iscsi import TargetClient from kimchi.model import model +from kimchi.model.config import CapabilitiesModel from kimchi.rollbackcontext import RollbackContext from kimchi.utils import add_task @@ -182,6 +183,18 @@ class ModelTests(unittest.TestCase): self.assertEquals("default", iface['network']) self.assertEquals("e1000", iface["model"]) + # update vm interface when vm is running + if CapabilitiesModel().change_live_vm_network: + print ".change_live_vm_network:" + inst.vm_start("kimchi-ifaces") + rollback.prependDefer(inst.vm_poweroff, 'kimchi-ifaces') + iface_args = {"network": "test-network", + "model": "virtio"} + inst.vmiface_update('kimchi-ifaces', mac, iface_args) + iface = inst.vmiface_lookup('kimchi-ifaces', mac) + self.assertEquals("e1000", iface["model"]) + self.assertEquals("test-network", iface['network']) + @unittest.skipUnless(utils.running_as_root(), 'Must be run as root') def test_vm_disk(self): def _attach_disk(bus_type=None): -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com>
This is a good feature to user, but it is not supported by low version libvirt.
So we need to probe it.
Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- src/kimchi/featuretests.py | 43 ++++++++++++++++++++++++++++++++++++++++++- src/kimchi/model/config.py | 3 +++ 2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/kimchi/featuretests.py b/src/kimchi/featuretests.py index 5192361..6eb29f4 100644 --- a/src/kimchi/featuretests.py +++ b/src/kimchi/featuretests.py @@ -62,8 +62,25 @@ SIMPLE_VM_XML = """ <type arch='x86_64' machine='pc'>hvm</type> <boot dev='hd'/> </os> + <devices> + %s + </devices> </domain>"""
+SIMPLE_NETWORK_XML = """ +<network> + <name>%s</name> +</network> +""" + +VM_IFACE_XML = """ +<interface type='network'> + <mac address='52:54:00:12:34:56'/> + <source network='%s'/> + <model type='rtl8139'/> +</interface> +""" + SCSI_FC_XML = """ <pool type='scsi'> <name>TEST_SCSI_FC_POOL</name> @@ -196,7 +213,7 @@ class FeatureTests(object): rollback.prependDefer(FeatureTests.enable_screen_error_logging) conn = libvirt.open('qemu:///system') rollback.prependDefer(conn.close) - dom = conn.defineXML(SIMPLE_VM_XML) + dom = conn.defineXML(SIMPLE_VM_XML % "") rollback.prependDefer(dom.undefine) try: dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, @@ -206,3 +223,27 @@ class FeatureTests(object): return True except libvirt.libvirtError: return False + + @staticmethod + def change_live_vm_network(): + with RollbackContext() as rollback: + FeatureTests.disable_screen_error_logging() + rollback.prependDefer(FeatureTests.enable_screen_error_logging) + conn = libvirt.open('qemu:///system') + rollback.prependDefer(conn.close) + net1_name = "isolated_test_net1" + net2_name = "isolated_test_net2" + net1 = conn.networkCreateXML(SIMPLE_NETWORK_XML % net1_name) + rollback.prependDefer(net1.destroy) + net2 = conn.networkCreateXML(SIMPLE_NETWORK_XML % net2_name) + rollback.prependDefer(net2.destroy) + iface1_xml = VM_IFACE_XML % net1_name + iface2_xml = VM_IFACE_XML % net2_name + dom = conn.createXML(SIMPLE_VM_XML % iface1_xml, flags=0) + rollback.prependDefer(dom.destroy) + try: + dom.updateDeviceFlags(iface2_xml, + libvirt.VIR_DOMAIN_AFFECT_LIVE) + return True + except libvirt.libvirtError: + return False diff --git a/src/kimchi/model/config.py b/src/kimchi/model/config.py index 0ef0855..88ab681 100644 --- a/src/kimchi/model/config.py +++ b/src/kimchi/model/config.py @@ -54,6 +54,7 @@ class CapabilitiesModel(object): self.libvirt_stream_protocols = [] self.fc_host_support = False self.metadata_support = False + self.change_live_vm_network = False
# Subscribe function to set host capabilities to be run when cherrypy # server is up @@ -67,6 +68,8 @@ class CapabilitiesModel(object): self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe() self.fc_host_support = FeatureTests.libvirt_support_fc_host() self.metadata_support = FeatureTests.has_metadata_support() + self.change_live_vm_network = FeatureTests.change_live_vm_network() +
On 05/09/2014 11:41 PM, shaohef@linux.vnet.ibm.com wrote: please remove this line.
self.libvirt_stream_protocols = [] for p in ['http', 'https', 'ftp', 'ftps', 'tftp']:
-- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center
participants (2)
-
shaohef@linux.vnet.ibm.com
-
Sheldon