mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-09 01:18:00 +03:00
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.
This commit is contained in:
parent
b874f26b8b
commit
47a0866bce
@ -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>
|
||||
...</pre>
|
||||
|
||||
<dl>
|
||||
@ -54,6 +58,12 @@
|
||||
The format must be RFC 4122 compliant, eg <code>3e3fce45-4f53-4fa7-bb32-11f34168b82b</code>.
|
||||
If omitted when defining/creating a new network, a random
|
||||
UUID is generated. <span class="since">Since 0.3.0</span></dd>
|
||||
<dd>The <code>metadata</code> 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). <span class="since">Since 2.1.0</span></dd>
|
||||
<dt><code>ipv6</code></dt>
|
||||
<dd>When set to <code>yes</code>, the optional parameter
|
||||
<code>ipv6</code> enables
|
||||
|
@ -495,4 +495,27 @@
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="metadata">
|
||||
<element name="metadata">
|
||||
<zeroOrMore>
|
||||
<ref name="customElement"/>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="customElement">
|
||||
<element>
|
||||
<anyName/>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="customElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
|
@ -5322,29 +5322,6 @@
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="metadata">
|
||||
<element name="metadata">
|
||||
<zeroOrMore>
|
||||
<ref name="customElement"/>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="customElement">
|
||||
<element>
|
||||
<anyName/>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="customElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<!--
|
||||
Type library
|
||||
-->
|
||||
|
@ -37,6 +37,11 @@
|
||||
<text/>
|
||||
</element>
|
||||
|
||||
<!-- <metadata> element -->
|
||||
<optional>
|
||||
<ref name="metadata"/>
|
||||
</optional>
|
||||
|
||||
<!-- <uuid> element -->
|
||||
<optional>
|
||||
<element name="uuid"><ref name="UUID"/></element>
|
||||
|
@ -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, "<uuid>%s</uuid>\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)
|
||||
|
@ -253,6 +253,9 @@ struct _virNetworkDef {
|
||||
virNetDevBandwidthPtr bandwidth;
|
||||
virNetDevVlan vlan;
|
||||
int trustGuestRxFilters; /* enum virTristateBool */
|
||||
|
||||
/* Application-specific custom metadata */
|
||||
xmlNodePtr metadata;
|
||||
};
|
||||
|
||||
typedef struct _virNetworkObj virNetworkObj;
|
||||
|
10
tests/networkxml2xmlin/metadata.xml
Normal file
10
tests/networkxml2xmlin/metadata.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<network>
|
||||
<name>host-bridge-net</name>
|
||||
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a8e</uuid>
|
||||
<forward mode='bridge'/>
|
||||
<bridge name='br0'/>
|
||||
<metadata>
|
||||
<app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
|
||||
<app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
|
||||
</metadata>
|
||||
</network>
|
10
tests/networkxml2xmlout/metadata.xml
Normal file
10
tests/networkxml2xmlout/metadata.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<network>
|
||||
<name>host-bridge-net</name>
|
||||
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a8e</uuid>
|
||||
<metadata>
|
||||
<app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
|
||||
<app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
|
||||
</metadata>
|
||||
<forward mode='bridge'/>
|
||||
<bridge name='br0'/>
|
||||
</network>
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user