Blame SOURCES/libvirt-conf-allow-to-add-XML-metadata-using-the-virDomainSetMetadata-api.patch

898951
From febb8d0b48c7a7bf7b587bc43d7e423318f49369 Mon Sep 17 00:00:00 2001
898951
Message-Id: <febb8d0b48c7a7bf7b587bc43d7e423318f49369@dist-git>
898951
From: Peter Krempa <pkrempa@redhat.com>
898951
Date: Thu, 22 Jan 2015 15:53:46 +0100
898951
Subject: [PATCH] conf: allow to add XML metadata using the
898951
 virDomainSetMetadata api
898951
898951
https://bugzilla.redhat.com/show_bug.cgi?id=1184929
898951
898951
The functionality wasn't originally implemented. This patch adds the
898951
ability to modify domain's XML metadata using the API.
898951
898951
(cherry picked from commit 73bfac0e7182a3abde02304fd2f17845715a9a2e)
898951
898951
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
898951
---
898951
 src/conf/domain_conf.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
898951
 src/util/virxml.c      | 32 ++++++++++++++++++++++++++++++++
898951
 src/util/virxml.h      |  4 ++++
898951
 3 files changed, 78 insertions(+), 5 deletions(-)
898951
898951
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
898951
index c104218..4dbe3fc 100644
898951
--- a/src/conf/domain_conf.c
898951
+++ b/src/conf/domain_conf.c
898951
@@ -19038,9 +19038,12 @@ static int
898951
 virDomainDefSetMetadata(virDomainDefPtr def,
898951
                         int type,
898951
                         const char *metadata,
898951
-                        const char *key ATTRIBUTE_UNUSED,
898951
-                        const char *uri ATTRIBUTE_UNUSED)
898951
+                        const char *key,
898951
+                        const char *uri)
898951
 {
898951
+    xmlDocPtr doc = NULL;
898951
+    xmlNodePtr old;
898951
+    xmlNodePtr new;
898951
     int ret = -1;
898951
 
898951
     switch ((virDomainMetadataType) type) {
898951
@@ -19057,9 +19060,42 @@ virDomainDefSetMetadata(virDomainDefPtr def,
898951
         break;
898951
 
898951
     case VIR_DOMAIN_METADATA_ELEMENT:
898951
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
898951
-                       _("<metadata> element is not supported"));
898951
-        goto cleanup;
898951
+        if (metadata) {
898951
+            /* parse and modify the xml from the user */
898951
+            if (!(doc = virXMLParseString(metadata, _("(metadata_xml)"))))
898951
+                goto cleanup;
898951
+
898951
+            if (virXMLInjectNamespace(doc->children, uri, key) < 0)
898951
+                goto cleanup;
898951
+
898951
+            /* create the root node if needed */
898951
+            if (!def->metadata &&
898951
+                !(def->metadata = xmlNewNode(NULL, (unsigned char *)"metadata"))) {
898951
+                virReportOOMError();
898951
+                goto cleanup;
898951
+            }
898951
+
898951
+            if (!(new = xmlCopyNode(doc->children, 1))) {
898951
+                virReportOOMError();
898951
+                goto cleanup;
898951
+            }
898951
+        }
898951
+
898951
+        /* remove possible other nodes sharing the namespace */
898951
+        while ((old = virXMLFindChildNodeByNs(def->metadata, uri))) {
898951
+            xmlUnlinkNode(old);
898951
+            xmlFreeNode(old);
898951
+        }
898951
+
898951
+        /* just delete the metadata */
898951
+        if (!metadata)
898951
+            break;
898951
+
898951
+        if (!(xmlAddChild(def->metadata, new))) {
898951
+            xmlFreeNode(new);
898951
+            virReportOOMError();
898951
+            goto cleanup;
898951
+        }
898951
         break;
898951
 
898951
     default:
898951
@@ -19072,6 +19108,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
898951
     ret = 0;
898951
 
898951
 cleanup:
898951
+    xmlFreeDoc(doc);
898951
     return ret;
898951
 }
898951
 
898951
diff --git a/src/util/virxml.c b/src/util/virxml.c
898951
index 9048d78..de1e1e0 100644
898951
--- a/src/util/virxml.c
898951
+++ b/src/util/virxml.c
898951
@@ -1050,3 +1050,35 @@ cleanup:
898951
     xmlFreeNode(nodeCopy);
898951
     return ret;
898951
 }
898951
+
898951
+
898951
+static int
898951
+virXMLAddElementNamespace(xmlNodePtr node,
898951
+                          void *opaque)
898951
+{
898951
+    xmlNsPtr ns = opaque;
898951
+
898951
+    if (!node->ns)
898951
+        xmlSetNs(node, ns);
898951
+
898951
+    return 0;
898951
+}
898951
+
898951
+
898951
+int
898951
+virXMLInjectNamespace(xmlNodePtr node,
898951
+                      const char *uri,
898951
+                      const char *key)
898951
+{
898951
+    xmlNsPtr ns;
898951
+
898951
+    if (!(ns = xmlNewNs(node, (const unsigned char *)uri, (const unsigned char *)key))) {
898951
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
898951
+                       _("failed to create a new XML namespace"));
898951
+        return -1;
898951
+    }
898951
+
898951
+    virXMLForeachNode(node, virXMLAddElementNamespace, ns);
898951
+
898951
+    return 0;
898951
+}
898951
diff --git a/src/util/virxml.h b/src/util/virxml.h
898951
index 7dc6c9d..d967a2e 100644
898951
--- a/src/util/virxml.h
898951
+++ b/src/util/virxml.h
898951
@@ -172,4 +172,8 @@ int virXMLExtractNamespaceXML(xmlNodePtr root,
898951
                               const char *uri,
898951
                               char **doc);
898951
 
898951
+int virXMLInjectNamespace(xmlNodePtr node,
898951
+                          const char *uri,
898951
+                          const char *key);
898951
+
898951
 #endif                          /* __VIR_XML_H__ */
898951
-- 
898951
2.2.1
898951