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