|
|
898951 |
From 25d339a412b1a3d3436d3ff3c9ed63139c8f2428 Mon Sep 17 00:00:00 2001
|
|
|
898951 |
Message-Id: <25d339a412b1a3d3436d3ff3c9ed63139c8f2428@dist-git>
|
|
|
898951 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
898951 |
Date: Thu, 22 Jan 2015 15:53:45 +0100
|
|
|
898951 |
Subject: [PATCH] conf: Add support for requesting of XML metadata via the API
|
|
|
898951 |
|
|
|
898951 |
https://bugzilla.redhat.com/show_bug.cgi?id=1184929
|
|
|
898951 |
|
|
|
898951 |
The virDomainGetMetadata function was designed to support also retrieval
|
|
|
898951 |
of app specific metadata from the <metadata> element. This functionality
|
|
|
898951 |
was never implemented originally.
|
|
|
898951 |
|
|
|
898951 |
(cherry picked from commit ac38bff077642daa17f9a82480062ebef4c11a7b)
|
|
|
898951 |
|
|
|
898951 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
898951 |
---
|
|
|
898951 |
src/conf/domain_conf.c | 19 ++++----
|
|
|
898951 |
src/libvirt_private.syms | 1 +
|
|
|
898951 |
src/util/virxml.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
898951 |
src/util/virxml.h | 7 +++
|
|
|
898951 |
4 files changed, 140 insertions(+), 9 deletions(-)
|
|
|
898951 |
|
|
|
898951 |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
898951 |
index 6817e0e..c104218 100644
|
|
|
898951 |
--- a/src/conf/domain_conf.c
|
|
|
898951 |
+++ b/src/conf/domain_conf.c
|
|
|
898951 |
@@ -18987,7 +18987,6 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
|
|
|
898951 |
unsigned int flags)
|
|
|
898951 |
{
|
|
|
898951 |
virDomainDefPtr def;
|
|
|
898951 |
- char *field = NULL;
|
|
|
898951 |
char *ret = NULL;
|
|
|
898951 |
|
|
|
898951 |
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
898951 |
@@ -19002,17 +19001,21 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
|
|
|
898951 |
|
|
|
898951 |
switch ((virDomainMetadataType) type) {
|
|
|
898951 |
case VIR_DOMAIN_METADATA_DESCRIPTION:
|
|
|
898951 |
- field = def->description;
|
|
|
898951 |
+ if (VIR_STRDUP(ret, def->description) < 0)
|
|
|
898951 |
+ goto cleanup;
|
|
|
898951 |
break;
|
|
|
898951 |
|
|
|
898951 |
case VIR_DOMAIN_METADATA_TITLE:
|
|
|
898951 |
- field = def->title;
|
|
|
898951 |
+ if (VIR_STRDUP(ret, def->title) < 0)
|
|
|
898951 |
+ goto cleanup;
|
|
|
898951 |
break;
|
|
|
898951 |
|
|
|
898951 |
case VIR_DOMAIN_METADATA_ELEMENT:
|
|
|
898951 |
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
|
898951 |
- _("<metadata> element is not yet supported"));
|
|
|
898951 |
- goto cleanup;
|
|
|
898951 |
+ if (!def->metadata)
|
|
|
898951 |
+ break;
|
|
|
898951 |
+
|
|
|
898951 |
+ if (virXMLExtractNamespaceXML(def->metadata, uri, &ret) < 0)
|
|
|
898951 |
+ goto cleanup;
|
|
|
898951 |
break;
|
|
|
898951 |
|
|
|
898951 |
default:
|
|
|
898951 |
@@ -19022,12 +19025,10 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
|
|
|
898951 |
break;
|
|
|
898951 |
}
|
|
|
898951 |
|
|
|
898951 |
- if (!field)
|
|
|
898951 |
+ if (!ret)
|
|
|
898951 |
virReportError(VIR_ERR_NO_DOMAIN_METADATA, "%s",
|
|
|
898951 |
_("Requested metadata element is not present"));
|
|
|
898951 |
|
|
|
898951 |
- ignore_value(VIR_STRDUP(ret, field));
|
|
|
898951 |
-
|
|
|
898951 |
cleanup:
|
|
|
898951 |
return ret;
|
|
|
898951 |
}
|
|
|
898951 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
898951 |
index 3df4379..1fbee18 100644
|
|
|
898951 |
--- a/src/libvirt_private.syms
|
|
|
898951 |
+++ b/src/libvirt_private.syms
|
|
|
898951 |
@@ -2140,6 +2140,7 @@ virUUIDParse;
|
|
|
898951 |
|
|
|
898951 |
# util/virxml.h
|
|
|
898951 |
virXMLChildElementCount;
|
|
|
898951 |
+virXMLExtractNamespaceXML;
|
|
|
898951 |
virXMLNodeToString;
|
|
|
898951 |
virXMLParseHelper;
|
|
|
898951 |
virXMLPickShellSafeComment;
|
|
|
898951 |
diff --git a/src/util/virxml.c b/src/util/virxml.c
|
|
|
898951 |
index 9bb8bf0..9048d78 100644
|
|
|
898951 |
--- a/src/util/virxml.c
|
|
|
898951 |
+++ b/src/util/virxml.c
|
|
|
898951 |
@@ -928,3 +928,125 @@ cleanup:
|
|
|
898951 |
|
|
|
898951 |
return ret;
|
|
|
898951 |
}
|
|
|
898951 |
+
|
|
|
898951 |
+typedef int (*virXMLForeachCallback)(xmlNodePtr node,
|
|
|
898951 |
+ void *opaque);
|
|
|
898951 |
+
|
|
|
898951 |
+static int
|
|
|
898951 |
+virXMLForeachNode(xmlNodePtr root,
|
|
|
898951 |
+ virXMLForeachCallback cb,
|
|
|
898951 |
+ void *opaque);
|
|
|
898951 |
+
|
|
|
898951 |
+static int
|
|
|
898951 |
+virXMLForeachNode(xmlNodePtr root,
|
|
|
898951 |
+ virXMLForeachCallback cb,
|
|
|
898951 |
+ void *opaque)
|
|
|
898951 |
+{
|
|
|
898951 |
+ xmlNodePtr next;
|
|
|
898951 |
+ int ret;
|
|
|
898951 |
+
|
|
|
898951 |
+ for (next = root; next; next = next->next) {
|
|
|
898951 |
+ if ((ret = cb(next, opaque)) != 0)
|
|
|
898951 |
+ return ret;
|
|
|
898951 |
+
|
|
|
898951 |
+ /* recurse into children */
|
|
|
898951 |
+ if (next->children) {
|
|
|
898951 |
+ if ((ret = virXMLForeachNode(next->children, cb, opaque)) != 0)
|
|
|
898951 |
+ return ret;
|
|
|
898951 |
+ }
|
|
|
898951 |
+ }
|
|
|
898951 |
+
|
|
|
898951 |
+ return 0;
|
|
|
898951 |
+}
|
|
|
898951 |
+
|
|
|
898951 |
+
|
|
|
898951 |
+static int
|
|
|
898951 |
+virXMLRemoveElementNamespace(xmlNodePtr node,
|
|
|
898951 |
+ void *opaque)
|
|
|
898951 |
+{
|
|
|
898951 |
+ const char *uri = opaque;
|
|
|
898951 |
+
|
|
|
898951 |
+ if (node->ns &&
|
|
|
898951 |
+ STREQ_NULLABLE((const char *)node->ns->href, uri))
|
|
|
898951 |
+ xmlSetNs(node, NULL);
|
|
|
898951 |
+ return 0;
|
|
|
898951 |
+}
|
|
|
898951 |
+
|
|
|
898951 |
+
|
|
|
898951 |
+xmlNodePtr
|
|
|
898951 |
+virXMLFindChildNodeByNs(xmlNodePtr root,
|
|
|
898951 |
+ const char *uri)
|
|
|
898951 |
+{
|
|
|
898951 |
+ xmlNodePtr next;
|
|
|
898951 |
+
|
|
|
898951 |
+ for (next = root->children; next; next = next->next) {
|
|
|
898951 |
+ if (next->ns &&
|
|
|
898951 |
+ STREQ_NULLABLE((const char *) next->ns->href, uri))
|
|
|
898951 |
+ return next;
|
|
|
898951 |
+ }
|
|
|
898951 |
+
|
|
|
898951 |
+ return NULL;
|
|
|
898951 |
+}
|
|
|
898951 |
+
|
|
|
898951 |
+
|
|
|
898951 |
+/**
|
|
|
898951 |
+ * virXMLExtractNamespaceXML: extract a sub-namespace of XML as string
|
|
|
898951 |
+ */
|
|
|
898951 |
+int
|
|
|
898951 |
+virXMLExtractNamespaceXML(xmlNodePtr root,
|
|
|
898951 |
+ const char *uri,
|
|
|
898951 |
+ char **doc)
|
|
|
898951 |
+{
|
|
|
898951 |
+ xmlNodePtr node;
|
|
|
898951 |
+ xmlNodePtr nodeCopy = NULL;
|
|
|
898951 |
+ xmlNsPtr actualNs;
|
|
|
898951 |
+ xmlNsPtr prevNs = NULL;
|
|
|
898951 |
+ char *xmlstr = NULL;
|
|
|
898951 |
+ int ret = -1;
|
|
|
898951 |
+
|
|
|
898951 |
+ if (!(node = virXMLFindChildNodeByNs(root, uri))) {
|
|
|
898951 |
+ /* node not found */
|
|
|
898951 |
+ ret = 1;
|
|
|
898951 |
+ goto cleanup;
|
|
|
898951 |
+ }
|
|
|
898951 |
+
|
|
|
898951 |
+ /* copy the node so that we can modify the namespace */
|
|
|
898951 |
+ if (!(nodeCopy = xmlCopyNode(node, 1))) {
|
|
|
898951 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
898951 |
+ _("Failed to copy XML node"));
|
|
|
898951 |
+ goto cleanup;
|
|
|
898951 |
+ }
|
|
|
898951 |
+
|
|
|
898951 |
+ virXMLForeachNode(nodeCopy, virXMLRemoveElementNamespace,
|
|
|
898951 |
+ (void *)uri);
|
|
|
898951 |
+
|
|
|
898951 |
+ /* remove the namespace declaration
|
|
|
898951 |
+ * - it's only a single linked list ... doh */
|
|
|
898951 |
+ for (actualNs = nodeCopy->nsDef; actualNs; actualNs = actualNs->next) {
|
|
|
898951 |
+ if (STREQ_NULLABLE((const char *)actualNs->href, uri)) {
|
|
|
898951 |
+
|
|
|
898951 |
+ /* unlink */
|
|
|
898951 |
+ if (prevNs)
|
|
|
898951 |
+ prevNs->next = actualNs->next;
|
|
|
898951 |
+ else
|
|
|
898951 |
+ nodeCopy->nsDef = actualNs->next;
|
|
|
898951 |
+
|
|
|
898951 |
+ /* discard */
|
|
|
898951 |
+ xmlFreeNs(actualNs);
|
|
|
898951 |
+ break;
|
|
|
898951 |
+ }
|
|
|
898951 |
+
|
|
|
898951 |
+ prevNs = actualNs;
|
|
|
898951 |
+ }
|
|
|
898951 |
+
|
|
|
898951 |
+ if (!(xmlstr = virXMLNodeToString(nodeCopy->doc, nodeCopy)))
|
|
|
898951 |
+ goto cleanup;
|
|
|
898951 |
+
|
|
|
898951 |
+ ret = 0;
|
|
|
898951 |
+
|
|
|
898951 |
+cleanup:
|
|
|
898951 |
+ if (doc)
|
|
|
898951 |
+ *doc = xmlstr;
|
|
|
898951 |
+ xmlFreeNode(nodeCopy);
|
|
|
898951 |
+ return ret;
|
|
|
898951 |
+}
|
|
|
898951 |
diff --git a/src/util/virxml.h b/src/util/virxml.h
|
|
|
898951 |
index bb34069..7dc6c9d 100644
|
|
|
898951 |
--- a/src/util/virxml.h
|
|
|
898951 |
+++ b/src/util/virxml.h
|
|
|
898951 |
@@ -165,4 +165,11 @@ int virXMLSaveFile(const char *path,
|
|
|
898951 |
|
|
|
898951 |
char *virXMLNodeToString(xmlDocPtr doc, xmlNodePtr node);
|
|
|
898951 |
|
|
|
898951 |
+xmlNodePtr virXMLFindChildNodeByNs(xmlNodePtr root,
|
|
|
898951 |
+ const char *uri);
|
|
|
898951 |
+
|
|
|
898951 |
+int virXMLExtractNamespaceXML(xmlNodePtr root,
|
|
|
898951 |
+ const char *uri,
|
|
|
898951 |
+ char **doc);
|
|
|
898951 |
+
|
|
|
898951 |
#endif /* __VIR_XML_H__ */
|
|
|
898951 |
--
|
|
|
898951 |
2.2.1
|
|
|
898951 |
|