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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list