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'>
|
<network ipv6='yes' trustGuestRxFilters='no'>
|
||||||
<name>default</name>
|
<name>default</name>
|
||||||
<uuid>3e3fce45-4f53-4fa7-bb32-11f34168b82b</uuid>
|
<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>
|
...</pre>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -54,6 +58,12 @@
|
||||||
The format must be RFC 4122 compliant, eg <code>3e3fce45-4f53-4fa7-bb32-11f34168b82b</code>.
|
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
|
If omitted when defining/creating a new network, a random
|
||||||
UUID is generated. <span class="since">Since 0.3.0</span></dd>
|
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>
|
<dt><code>ipv6</code></dt>
|
||||||
<dd>When set to <code>yes</code>, the optional parameter
|
<dd>When set to <code>yes</code>, the optional parameter
|
||||||
<code>ipv6</code> enables
|
<code>ipv6</code> enables
|
||||||
|
|
|
@ -495,4 +495,27 @@
|
||||||
</choice>
|
</choice>
|
||||||
</define>
|
</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>
|
</grammar>
|
||||||
|
|
|
@ -5322,29 +5322,6 @@
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</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
|
Type library
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -37,6 +37,11 @@
|
||||||
<text/>
|
<text/>
|
||||||
</element>
|
</element>
|
||||||
|
|
||||||
|
<!-- <metadata> element -->
|
||||||
|
<optional>
|
||||||
|
<ref name="metadata"/>
|
||||||
|
</optional>
|
||||||
|
|
||||||
<!-- <uuid> element -->
|
<!-- <uuid> element -->
|
||||||
<optional>
|
<optional>
|
||||||
<element name="uuid"><ref name="UUID"/></element>
|
<element name="uuid"><ref name="UUID"/></element>
|
||||||
|
|
|
@ -419,6 +419,9 @@ virNetworkDefFree(virNetworkDefPtr def)
|
||||||
|
|
||||||
virNetDevBandwidthFree(def->bandwidth);
|
virNetDevBandwidthFree(def->bandwidth);
|
||||||
virNetDevVlanClear(&def->vlan);
|
virNetDevVlanClear(&def->vlan);
|
||||||
|
|
||||||
|
xmlFreeNode(def->metadata);
|
||||||
|
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2059,6 +2062,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
||||||
xmlNodePtr save = ctxt->node;
|
xmlNodePtr save = ctxt->node;
|
||||||
xmlNodePtr bandwidthNode = NULL;
|
xmlNodePtr bandwidthNode = NULL;
|
||||||
xmlNodePtr vlanNode;
|
xmlNodePtr vlanNode;
|
||||||
|
xmlNodePtr metadataNode = NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC(def) < 0)
|
if (VIR_ALLOC(def) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2390,6 +2394,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(stp);
|
VIR_FREE(stp);
|
||||||
|
|
||||||
|
/* Extract custom metadata */
|
||||||
|
if ((metadataNode = virXPathNode("./metadata[1]", ctxt)) != NULL) {
|
||||||
|
def->metadata = xmlCopyNode(metadataNode, 1);
|
||||||
|
virXMLNodeSanitizeNamespaces(def->metadata);
|
||||||
|
}
|
||||||
|
|
||||||
ctxt->node = save;
|
ctxt->node = save;
|
||||||
return def;
|
return def;
|
||||||
|
|
||||||
|
@ -2412,12 +2423,14 @@ virNetworkDefParse(const char *xmlStr,
|
||||||
{
|
{
|
||||||
xmlDocPtr xml;
|
xmlDocPtr xml;
|
||||||
virNetworkDefPtr def = NULL;
|
virNetworkDefPtr def = NULL;
|
||||||
|
int keepBlanksDefault = xmlKeepBlanksDefault(0);
|
||||||
|
|
||||||
if ((xml = virXMLParse(filename, xmlStr, _("(network_definition)")))) {
|
if ((xml = virXMLParse(filename, xmlStr, _("(network_definition)")))) {
|
||||||
def = virNetworkDefParseNode(xml, xmlDocGetRootElement(xml));
|
def = virNetworkDefParseNode(xml, xmlDocGetRootElement(xml));
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlKeepBlanksDefault(keepBlanksDefault);
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2736,6 +2749,29 @@ virNetworkDefFormatBuf(virBufferPtr buf,
|
||||||
virUUIDFormat(uuid, uuidstr);
|
virUUIDFormat(uuid, uuidstr);
|
||||||
virBufferAsprintf(buf, "<uuid>%s</uuid>\n", 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) {
|
if (def->forward.type != VIR_NETWORK_FORWARD_NONE) {
|
||||||
const char *dev = NULL;
|
const char *dev = NULL;
|
||||||
if (!def->forward.npfs)
|
if (!def->forward.npfs)
|
||||||
|
|
|
@ -253,6 +253,9 @@ struct _virNetworkDef {
|
||||||
virNetDevBandwidthPtr bandwidth;
|
virNetDevBandwidthPtr bandwidth;
|
||||||
virNetDevVlan vlan;
|
virNetDevVlan vlan;
|
||||||
int trustGuestRxFilters; /* enum virTristateBool */
|
int trustGuestRxFilters; /* enum virTristateBool */
|
||||||
|
|
||||||
|
/* Application-specific custom metadata */
|
||||||
|
xmlNodePtr metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virNetworkObj virNetworkObj;
|
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("host-bridge-no-flood");
|
||||||
DO_TEST_PARSE_ERROR("hostdev-duplicate");
|
DO_TEST_PARSE_ERROR("hostdev-duplicate");
|
||||||
DO_TEST_PARSE_ERROR("passthrough-duplicate");
|
DO_TEST_PARSE_ERROR("passthrough-duplicate");
|
||||||
|
DO_TEST("metadata");
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue