[libvirt] [PATCH 10/14] conf: allow to add XML metadata using the virDomainSetMetadata api

Peter Krempa pkrempa at redhat.com
Tue Sep 10 10:15:46 UTC 2013


The functionality wasn't originally implemented. This patch adds the
ability to modify domain's XML metadata using the API.
---
 src/conf/domain_conf.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
 src/util/virxml.c      | 32 ++++++++++++++++++++++++++++++++
 src/util/virxml.h      |  4 ++++
 3 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4269690..69a8748 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -18589,9 +18589,12 @@ static int
 virDomainDefSetMetadata(virDomainDefPtr def,
                         int type,
                         const char *metadata,
-                        const char *key ATTRIBUTE_UNUSED,
-                        const char *uri ATTRIBUTE_UNUSED)
+                        const char *key,
+                        const char *uri)
 {
+    xmlDocPtr doc = NULL;
+    xmlNodePtr old;
+    xmlNodePtr new;
     int ret = -1;

     switch ((virDomainMetadataType) type) {
@@ -18608,9 +18611,42 @@ virDomainDefSetMetadata(virDomainDefPtr def,
         break;

     case VIR_DOMAIN_METADATA_ELEMENT:
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-                       _("<metadata> element is not supported"));
-        goto cleanup;
+        if (metadata) {
+            /* parse and modify the xml from the user */
+            if (!(doc = virXMLParseString(metadata, _("(metadata_xml)"))))
+                goto cleanup;
+
+            if (virXMLInjectNamespace(doc->children, uri, key) < 0)
+                goto cleanup;
+
+            /* create the root node if needed */
+            if (!def->metadata &&
+                !(def->metadata = xmlNewNode(NULL, (unsigned char *)"metadata"))) {
+                virReportOOMError();
+                goto cleanup;
+            }
+
+            if (!(new = xmlCopyNode(doc->children, 1))) {
+                virReportOOMError();
+                goto cleanup;
+            }
+        }
+
+        /* remove possible other nodes sharing the namespace */
+        while ((old = virXMLFindChildNodeByNs(def->metadata, uri))) {
+            xmlUnlinkNode(old);
+            xmlFreeNode(old);
+        }
+
+        /* just delete the metadata */
+        if (!metadata)
+            break;
+
+        if (!(xmlAddChild(def->metadata, new))) {
+            xmlFreeNode(new);
+            virReportOOMError();
+            goto cleanup;
+        }
         break;

     default:
@@ -18623,6 +18659,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
     ret = 0;

 cleanup:
+    xmlFreeDoc(doc);
     return ret;
 }

diff --git a/src/util/virxml.c b/src/util/virxml.c
index 0fac931..59e04f5 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -1050,3 +1050,35 @@ cleanup:
     xmlFreeNode(nodeCopy);
     return ret;
 }
+
+
+static int
+virXMLAddElementNamespace(xmlNodePtr node,
+                          void *opaque)
+{
+    xmlNsPtr ns = opaque;
+
+    if (!node->ns)
+        xmlSetNs(node, ns);
+
+    return 0;
+}
+
+
+int
+virXMLInjectNamespace(xmlNodePtr node,
+                      const char *uri,
+                      const char *key)
+{
+    xmlNsPtr ns;
+
+    if (!(ns = xmlNewNs(node, (const unsigned char *)uri, (const unsigned char *)key))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("failed to create a new XML namespace"));
+        return -1;
+    }
+
+    virXMLForeachNode(node, virXMLAddElementNamespace, ns);
+
+    return 0;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
index aab29fb..ff0265b 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -172,4 +172,8 @@ int virXMLExtractNamespaceXML(xmlNodePtr root,
                               const char *uri,
                               char **doc);

+int virXMLInjectNamespace(xmlNodePtr node,
+                          const char *uri,
+                          const char *key);
+
 #endif                          /* __VIR_XML_H__ */
-- 
1.8.3.2




More information about the libvir-list mailing list