render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
Blob Blame History Raw
From febb8d0b48c7a7bf7b587bc43d7e423318f49369 Mon Sep 17 00:00:00 2001
Message-Id: <febb8d0b48c7a7bf7b587bc43d7e423318f49369@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 22 Jan 2015 15:53:46 +0100
Subject: [PATCH] conf: allow to add XML metadata using the
 virDomainSetMetadata api

https://bugzilla.redhat.com/show_bug.cgi?id=1184929

The functionality wasn't originally implemented. This patch adds the
ability to modify domain's XML metadata using the API.

(cherry picked from commit 73bfac0e7182a3abde02304fd2f17845715a9a2e)

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 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 c104218..4dbe3fc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19038,9 +19038,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) {
@@ -19057,9 +19060,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:
@@ -19072,6 +19108,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
     ret = 0;
 
 cleanup:
+    xmlFreeDoc(doc);
     return ret;
 }
 
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 9048d78..de1e1e0 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 7dc6c9d..d967a2e 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__ */
-- 
2.2.1