Static and Live update functions were always called and VM
state was checked inside functions.
This patch makes functions be called separately and remove
unsed state checking. This separation is also important because
during live updates the static funtion is called and the guest
xml is updated. This might cause errors.
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
i18n.py | 1 -
model/vms.py | 47 +++++++++++++++++++++++++----------------------
tests/test_model.py | 2 +-
3 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/i18n.py b/i18n.py
index 0340303..b4f758e 100644
--- a/i18n.py
+++ b/i18n.py
@@ -59,7 +59,6 @@ messages = {
"KCHVM0001E": _("Virtual machine %(name)s already exists"),
"KCHVM0002E": _("Virtual machine %(name)s does not exist"),
- "KCHVM0003E": _("Unable to rename virtual machine %(name)s. The name
%(new_name)s is already in use or the virtual machine is not powered off."),
"KCHVM0004E": _("Unable to retrieve screenshot for stopped virtual
machine %(name)s"),
"KCHVM0005E": _("Remote ISO image is not supported by this
server."),
"KCHVM0006E": _("Screenshot is not supported on virtual machine
%(name)s"),
diff --git a/model/vms.py b/model/vms.py
index 48196dd..f5323ac 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -272,8 +272,20 @@ class VMModel(object):
raise InvalidParameter('KCHVM0074E',
{'params': ',
'.join(ext_params)})
- self._live_vm_update(dom, params)
- vm_name, dom = self._static_vm_update(name, dom, params)
+ # METADATA can be updated offline or online
+ self._vm_update_access_metadata(dom, params)
+
+ # GRAPHICS can be updated offline or online
+ if 'graphics' in params:
+ dom = self._update_graphics(dom, params)
+
+ # Live updates
+ if dom.isActive():
+ self._live_vm_update(dom, params)
+
+ vm_name = name
+ if (DOM_STATE_MAP[dom.info()[0]] == 'shutoff'):
+ vm_name, dom = self._static_vm_update(name, dom, params)
return vm_name
def clone(self, name):
@@ -650,11 +662,11 @@ class VMModel(object):
os_elem = ET.fromstring(os_xml)
return (os_elem.attrib.get("version"),
os_elem.attrib.get("distro"))
- def _update_graphics(self, dom, xml, params):
- root = objectify.fromstring(xml)
+ def _update_graphics(self, dom, params):
+ root = objectify.fromstring(dom.XMLDesc(0))
graphics = root.devices.find("graphics")
if graphics is None:
- return xml
+ return dom
password = params['graphics'].get("passwd")
if password is not None and len(password.strip()) == 0:
@@ -676,13 +688,14 @@ class VMModel(object):
valid_to = time.strftime('%Y-%m-%dT%H:%M:%S', expire_time)
graphics.attrib['passwdValidTo'] = valid_to
+ conn = self.conn.get()
if not dom.isActive():
- return ET.tostring(root, encoding="utf-8")
+ return conn.defineXML(ET.tostring(root, encoding="utf-8"))
xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
dom.updateDeviceFlags(etree.tostring(graphics),
libvirt.VIR_DOMAIN_AFFECT_LIVE)
- return xml
+ return conn.defineXML(xml)
def _backup_snapshots(self, snap, all_info):
""" Append "snap" and the children of "snap"
to the list "all_info".
@@ -724,19 +737,14 @@ class VMModel(object):
remove_metadata_node(dom, 'name')
def _static_vm_update(self, vm_name, dom, params):
- old_xml = new_xml = dom.XMLDesc(0)
+ old_xml = new_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
params = copy.deepcopy(params)
# Update name
name = params.get('name')
nonascii_name = None
- state = DOM_STATE_MAP[dom.info()[0]]
if name is not None:
- if state != 'shutoff':
- msg_args = {'name': vm_name, 'new_name':
params['name']}
- raise InvalidParameter("KCHVM0003E", msg_args)
-
params['name'], nonascii_name = get_ascii_nonascii_name(name)
new_xml = xml_item_update(new_xml, XPATH_NAME, name, None)
@@ -770,14 +778,10 @@ class VMModel(object):
# topology is being undefined: remove it
new_xml = xml_item_remove(new_xml, XPATH_TOPOLOGY)
- # Updating memory if vm is offline
- if (not dom.isActive() and 'memory' in params and
- params['memory'] != {}):
+ # Updating memory
+ if ('memory' in params and params['memory'] != {}):
new_xml = self._update_memory_config(new_xml, params, dom)
- if 'graphics' in params:
- new_xml = self._update_graphics(dom, new_xml, params)
-
snapshots_info = []
conn = self.conn.get()
try:
@@ -954,9 +958,8 @@ class VMModel(object):
return cpu_info
def _live_vm_update(self, dom, params):
- self._vm_update_access_metadata(dom, params)
- if (('memory' in params) and ('current' in
params['memory']) and
- dom.isActive()):
+ # Memory Hotplug/Unplug
+ if (('memory' in params) and ('current' in
params['memory'])):
self._update_memory_live(dom, params)
def _get_mem_dev_total_size(self, xml):
diff --git a/tests/test_model.py b/tests/test_model.py
index 6b72bd0..f4a145f 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -957,7 +957,7 @@ class ModelTests(unittest.TestCase):
# template disk format must be qcow2 because vmsnapshot
# only supports this format
orig_params = {
- 'name': 'test', 'memory': {'current': 1024},
+ 'name': 'test', 'memory': {'current': 1024,
'maxmemory': 2048},
'cpu_info': {'vcpus': 1},
'source_media': {'type': 'disk', 'path':
UBUNTU_ISO},
'disks': [{'size': 1, 'format': 'qcow2',
'pool': {
--
2.1.0