From febb8d0b48c7a7bf7b587bc43d7e423318f49369 Mon Sep 17 00:00:00 2001 Message-Id: From: Peter Krempa 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 --- 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", - _(" 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