From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
virDomain.metadata and virDomain.setMetadata does not work in all livirt
versions used in the supported distros.
So if libvirt do not support these two API.
let kimchi manually manage the metadata element
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/model/utils.py | 38 +++++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/kimchi/model/utils.py b/src/kimchi/model/utils.py
index 51acb68..2fefa6a 100644
--- a/src/kimchi/model/utils.py
+++ b/src/kimchi/model/utils.py
@@ -20,6 +20,7 @@
from kimchi.exception import OperationFailed
import libvirt
from lxml import etree
+from lxml.builder import E
KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/metadata/"
@@ -53,9 +54,30 @@ def set_vm_metadata_element(dom, meta_xml, mode="all"):
# From libvirt doc, Passing None for @metadata says to remove that element
# from the domain XML (passing the empty string leaves the element present)
# Do not support remove the old metadata
- dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, meta_xml,
- "kimchi", KIMCHI_META_URL + element.tag,
- flags=get_vm_config_flag(dom, mode))
+ try:
+ dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, meta_xml,
+ "kimchi", KIMCHI_META_URL + element.tag,
+ flags=get_vm_config_flag(dom, mode))
+ except libvirt.libvirtError as e:
+ # FIXME remove this code when all distro libvirt supports setMetadata
+ if e.get_error_code() == libvirt.VIR_ERR_ARGUMENT_UNSUPPORTED:
+ # some other tools will not let libvirt create a persistent
+ # configuration, raise exeption.
+ if not dom.isPersistent:
+ msg = 'The VM has not a persistent configuration'
+ raise OperationFailed("KCHVM0029E",
+ {'name': dom.name(), "err":
msg})
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+ metadata = root.find("metadata")
+ if metadata is None:
+ metadata = E.metadata()
+ root.append(metadata)
+ old_elem = metadata.find(element.tag)
+ (metadata.replace(old_elem, element) if old_elem is not None
+ else metadata.append(element))
+
+ dom.connect().defineXML(etree.tostring(root))
def get_vm_metadata_element(dom, element, mode="current"):
@@ -64,6 +86,16 @@ def get_vm_metadata_element(dom, element, mode="current"):
KIMCHI_META_URL + element,
flags=get_vm_config_flag(dom, mode))
except libvirt.libvirtError as e:
+ # FIXME remove this code when all distro libvirt supports metadata
+ if e.get_error_code() == libvirt.VIR_ERR_ARGUMENT_UNSUPPORTED:
+ # some other tools will not let libvirt create a persistent
+ # configuration, just return empty
+ if not dom.isPersistent:
+ return ""
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+ elements = root.xpath("metadata/%s" % element)
+ return etree.tostring(elements[0]) if elements else ""
if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN_METADATA:
return ""
else:
--
1.9.0