From: Peter Krempa Date: Mon, 9 Sep 2013 09:49:11 +0000 (+0200) Subject: conf: allow to add XML metadata using the virDomainSetMetadata api X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=73bfac0e7182a3abde02304fd2f17845715a9a2e;p=libvirt.git conf: allow to add XML metadata using the virDomainSetMetadata api The functionality wasn't originally implemented. This patch adds the ability to modify domain's XML metadata using the API. --- diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 509e7228af..7e78068452 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18593,9 +18593,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) { @@ -18612,9 +18615,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: @@ -18627,6 +18663,7 @@ virDomainDefSetMetadata(virDomainDefPtr def, ret = 0; cleanup: + xmlFreeDoc(doc); return ret; } diff --git a/src/util/virxml.c b/src/util/virxml.c index 7a9bcf9cab..58523745cb 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 7dc6c9d427..d967a2e1c6 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__ */