From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Different kinds of vm elements will be added through different
libvirt apis, this patch abstract a framework for this update.
Wrap correspondent libvirt api in vm element class,
and format their own libvirt call parameters in each class.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/model.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 63 insertions(+), 2 deletions(-)
diff --git a/src/kimchi/model.py b/src/kimchi/model.py
index 2c6d3a1..0f82b61 100644
--- a/src/kimchi/model.py
+++ b/src/kimchi/model.py
@@ -78,7 +78,6 @@ ISO_POOL_NAME = u'kimchi_isos'
GUESTS_STATS_INTERVAL = 5
HOST_STATS_INTERVAL = 1
VM_STATIC_UPDATE_PARAMS = {'name': './name'}
-VM_LIVE_UPDATE_PARAMS = {}
STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
'path': '/pool/source/dir/@path'}}
@@ -490,7 +489,13 @@ class Model(object):
return dom
def _live_vm_update(self, dom, params):
- pass
+ try:
+ for key, val in params.items():
+ element = VMElementDef.create(key, val, dom)
+ element.add_to_vm()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("Cannot apply change on vm: %s",
+ e.get_error_message())
def vm_update(self, name, params):
dom = self._get_vm(name)
@@ -1510,6 +1515,62 @@ class LibvirtVMScreenshot(VMScreenshot):
os.close(fd)
+class VMElementDef(object):
+ @classmethod
+ def create(cls, elem_type, elemArgs, dom):
+ for klass in cls.__subclasses__():
+ if elem_type == klass.elemType:
+ return klass(elemArgs, dom)
+ raise OperationFailed('Unsupported vm element type: %s' %
elemArgs['type'])
+
+ def __init__(self, elemArgs, dom):
+ self.dom = dom
+ self.elemArgs = elemArgs
+
+ def add_to_vm(self):
+ """Live update domain with correspondant libvirt API.
+ This should be paired with cancel() operation to cancel failed
update."""
+ pass
+
+ def delete_from_vm(self):
+ """Revert operation of live update vm."""
+ pass
+
+ @property
+ def _update_param(self):
+ ''' Subclasses have to override this method to actually generate the
+ update param.'''
+ raise OperationFailed('Update param generater is not implemented: %s' %
self)
+
+
+class VMDiskDef(VMElementDef):
+ elemType = 'disk'
+
+ def __init__(self, elemArgs, dom):
+ super(VMDiskDef, self).__init__(elemArgs, dom)
+
+ def add_to_vm(self):
+ self.dom.attachDeviceFlags(xml=self._update_param['xml'],
+ flags=libvirt.VIR_DOMAIN_AFFECT_CURRENT|libvirt.VIR_DOMAIN_AFFECT_CONFIG)
+
+ def delete_from_vm(self):
+ self.dom.detachDeviceFlags(xml=self._update_param['xml'],
+ flags=libvirt.VIR_DOMAIN_AFFECT_CURRENT|libvirt.VIR_DOMAIN_AFFECT_CONFIG)
+
+ @property
+ def _update_param(self):
+ self.elemArgs['readonly'] = "<readonly/>" \
+ if self.elemArgs['target']['type'] == 'cdrom' else
None
+ xml = """
+ <disk type='{source[type]}' device='{target[type]}'>
+ <source file='{source[path]}'/>
+ <target dev='{target[name]}' bus='{target[bus]}'/>
+ {readonly}
+ </disk>
+ """.format(**self.elemArgs)
+ return dict(xml=xml)
+
+
class StoragePoolDef(object):
@classmethod
def create(cls, poolArgs):
--
1.8.1.2