From 47a0866bce7fdb1287ad451b6fec5ae6d27affbc Mon Sep 17 00:00:00 2001 From: Brandon Bennett Date: Wed, 22 Jun 2016 16:05:50 -0600 Subject: [PATCH] Allow custom metadata in network configuration XML This replicates the metadata field found in the domain configuration and adds it to the network configuration XML. --- docs/formatnetwork.html.in | 10 ++++++++ docs/schemas/basictypes.rng | 23 ++++++++++++++++++ docs/schemas/domaincommon.rng | 23 ------------------ docs/schemas/network.rng | 5 ++++ src/conf/network_conf.c | 36 ++++++++++++++++++++++++++++ src/conf/network_conf.h | 3 +++ tests/networkxml2xmlin/metadata.xml | 10 ++++++++ tests/networkxml2xmlout/metadata.xml | 10 ++++++++ tests/networkxml2xmltest.c | 1 + 9 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 tests/networkxml2xmlin/metadata.xml create mode 100644 tests/networkxml2xmlout/metadata.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 1cea931da4..a9226e52ea 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -38,6 +38,10 @@ <network ipv6='yes' trustGuestRxFilters='no'> <name>default</name> <uuid>3e3fce45-4f53-4fa7-bb32-11f34168b82b</uuid> + <metadata> + <app1:foo xmlns:app1="http://app1.org/app1/">..</app1:foo> + <app2:bar xmlns:app2="http://app1.org/app2/">..</app2:bar> + </metadata> ...
@@ -54,6 +58,12 @@ The format must be RFC 4122 compliant, eg 3e3fce45-4f53-4fa7-bb32-11f34168b82b. If omitted when defining/creating a new network, a random UUID is generated. Since 0.3.0 +
The metadata node can be used by applications to + store custom metadata in the form of XML nodes/trees. Applications + must use custom namespaces on their XML nodes/trees, with only + one top-level element per namespace (if the application needs + structure, they should have sub-elements to their namespace + element). Since 2.1.0
ipv6
When set to yes, the optional parameter ipv6 enables diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng index 83fd4ec24d..474ad77b28 100644 --- a/docs/schemas/basictypes.rng +++ b/docs/schemas/basictypes.rng @@ -495,4 +495,27 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 563cb3c437..4314cbe6a2 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5322,29 +5322,6 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 4edb6eb31a..b67a5eae88 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -37,6 +37,11 @@ + + + + + diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 2d904dfbe2..a75ca7192c 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -419,6 +419,9 @@ virNetworkDefFree(virNetworkDefPtr def) virNetDevBandwidthFree(def->bandwidth); virNetDevVlanClear(&def->vlan); + + xmlFreeNode(def->metadata); + VIR_FREE(def); } @@ -2059,6 +2062,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) xmlNodePtr save = ctxt->node; xmlNodePtr bandwidthNode = NULL; xmlNodePtr vlanNode; + xmlNodePtr metadataNode = NULL; if (VIR_ALLOC(def) < 0) return NULL; @@ -2390,6 +2394,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) } VIR_FREE(stp); + + /* Extract custom metadata */ + if ((metadataNode = virXPathNode("./metadata[1]", ctxt)) != NULL) { + def->metadata = xmlCopyNode(metadataNode, 1); + virXMLNodeSanitizeNamespaces(def->metadata); + } + ctxt->node = save; return def; @@ -2412,12 +2423,14 @@ virNetworkDefParse(const char *xmlStr, { xmlDocPtr xml; virNetworkDefPtr def = NULL; + int keepBlanksDefault = xmlKeepBlanksDefault(0); if ((xml = virXMLParse(filename, xmlStr, _("(network_definition)")))) { def = virNetworkDefParseNode(xml, xmlDocGetRootElement(xml)); xmlFreeDoc(xml); } + xmlKeepBlanksDefault(keepBlanksDefault); return def; } @@ -2736,6 +2749,29 @@ virNetworkDefFormatBuf(virBufferPtr buf, virUUIDFormat(uuid, uuidstr); virBufferAsprintf(buf, "%s\n", uuidstr); + if (def->metadata) { + xmlBufferPtr xmlbuf; + int oldIndentTreeOutput = xmlIndentTreeOutput; + + /* Indentation on output requires that we previously set + * xmlKeepBlanksDefault to 0 when parsing; also, libxml does 2 + * spaces per level of indentation of intermediate elements, + * but no leading indentation before the starting element. + * Thankfully, libxml maps what looks like globals into + * thread-local uses, so we are thread-safe. */ + xmlIndentTreeOutput = 1; + xmlbuf = xmlBufferCreate(); + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, + virBufferGetIndent(buf, false) / 2, 1) < 0) { + xmlBufferFree(xmlbuf); + xmlIndentTreeOutput = oldIndentTreeOutput; + goto error; + } + virBufferAsprintf(buf, "%s\n", (char *) xmlBufferContent(xmlbuf)); + xmlBufferFree(xmlbuf); + xmlIndentTreeOutput = oldIndentTreeOutput; + } + if (def->forward.type != VIR_NETWORK_FORWARD_NONE) { const char *dev = NULL; if (!def->forward.npfs) diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index e7ce67424a..78148890c2 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -253,6 +253,9 @@ struct _virNetworkDef { virNetDevBandwidthPtr bandwidth; virNetDevVlan vlan; int trustGuestRxFilters; /* enum virTristateBool */ + + /* Application-specific custom metadata */ + xmlNodePtr metadata; }; typedef struct _virNetworkObj virNetworkObj; diff --git a/tests/networkxml2xmlin/metadata.xml b/tests/networkxml2xmlin/metadata.xml new file mode 100644 index 0000000000..c075f9380b --- /dev/null +++ b/tests/networkxml2xmlin/metadata.xml @@ -0,0 +1,10 @@ + + host-bridge-net + 81ff0d90-c91e-6742-64da-4a736edb9a8e + + + + fooish + barish + + diff --git a/tests/networkxml2xmlout/metadata.xml b/tests/networkxml2xmlout/metadata.xml new file mode 100644 index 0000000000..a9364ab54d --- /dev/null +++ b/tests/networkxml2xmlout/metadata.xml @@ -0,0 +1,10 @@ + + host-bridge-net + 81ff0d90-c91e-6742-64da-4a736edb9a8e + + fooish + barish + + + + diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c index d65f6aaf7e..2a2c348430 100644 --- a/tests/networkxml2xmltest.c +++ b/tests/networkxml2xmltest.c @@ -153,6 +153,7 @@ mymain(void) DO_TEST("host-bridge-no-flood"); DO_TEST_PARSE_ERROR("hostdev-duplicate"); DO_TEST_PARSE_ERROR("passthrough-duplicate"); + DO_TEST("metadata"); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 2.39.5