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