mirror of https://gitee.com/openkylin/libvirt.git
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;
|
||||
|
|
|
@ -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>
|
|
@ -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