[Kimchi-devel] [PATCH V4 5/5] manually manage the metadata element

shaohef at linux.vnet.ibm.com shaohef at linux.vnet.ibm.com
Wed Apr 23 09:53:13 UTC 2014


From: ShaoHe Feng <shaohef at 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 at linux.vnet.ibm.com>
Signed-off-by: Royce Lv <lvroyce at 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




More information about the Kimchi-devel mailing list