From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
Applications can now insert custom nodes and hierarchies into domain
cofiguration XML. Although currently not enforced, application are
required to use their own namespaces on every custom node they insert.
---
docs/formatdomain.html.in | 18 +++++++++
docs/schemas/domaincommon.rng | 26 +++++++++++++
src/conf/domain_conf.c | 24 ++++++++++++
src/conf/domain_conf.h | 3 ++
tests/domainsnapshotxml2xmlout/metadata.xml | 38 ++++++++++++++++++++
tests/domainsnapshotxml2xmltest.c | 1 +
tests/qemuxml2argvdata/qemuxml2argv-metadata.args | 4 ++
tests/qemuxml2argvdata/qemuxml2argv-metadata.xml | 29 +++++++++++++++
.../qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml | 29 +++++++++++++++
tests/qemuxml2xmltest.c | 2 +
10 files changed, 174 insertions(+), 0 deletions(-)
create mode 100644 tests/domainsnapshotxml2xmlout/metadata.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index de9b480..fa7dc7c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3548,6 +3548,24 @@ qemu-kvm -net nic,model=? /dev/null
sub-element <code>label</code> are supported.
</p>
+ <h3><a name="customMetadata">Custom
metadata</a></h3>
+
+<pre>
+ ...
+ <metadata>
+ <app1:foo
xmlns:app1="http://app1.org/app1/">..</app1:foo&a...
+ <app2:bar
xmlns:app2="http://app1.org/app2/">..</app2:bar&a...
+ </metadata>
+ ...</pre>
+
+ <dl>
+ <dt><code>metadata</code></dt>
+ <dd><code>metadata</code> node could 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.
+ <span class="since">Since 0.9.9</span></dd>
+ </dl>
+
<h2><a name="examples">Example configs</a></h2>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2041dfb..b42d758 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -43,6 +43,9 @@
<ref name="seclabel"/>
</optional>
<optional>
+ <ref name="metadata"/>
+ </optional>
+ <optional>
<ref name='qemucmdline'/>
</optional>
</interleave>
@@ -2942,6 +2945,29 @@
</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
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8eed85b..fb78d93 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1500,6 +1500,9 @@ void virDomainDefFree(virDomainDefPtr def)
if (def->namespaceData && def->ns.free)
(def->ns.free)(def->namespaceData);
+ if (def->metadata)
+ xmlFreeNode(def->metadata);
+
VIR_FREE(def);
}
@@ -8072,6 +8075,11 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
def->os.smbios_mode = VIR_DOMAIN_SMBIOS_NONE; /* not present */
}
+ /* Extract custom metadata */
+ if ((node = virXPathNode("./metadata[1]", ctxt)) != NULL) {
+ def->metadata = xmlCopyNode (node, 1);
+ }
+
/* we have to make a copy of all of the callback pointers here since
* we won't have the virCaps structure available during free
*/
@@ -11833,6 +11841,22 @@ virDomainDefFormatInternal(virDomainDefPtr def,
goto cleanup;
}
+ /* Custom metadata comes at the end */
+ if (def->metadata) {
+ xmlBufferPtr xmlbuf;
+
+ xmlbuf = xmlBufferCreate();
+ if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, 4, 1) < 0)
{
+ xmlBufferFree(xmlbuf);
+ goto cleanup;
+ }
+ virBufferAdjustIndent(buf, 2);
+ virBufferAdd(buf, (char *) xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
+ virBufferAdjustIndent(buf, -2);
+ xmlBufferFree(xmlbuf);
+ virBufferAddLit(buf, "\n");
+ }
+
virBufferAddLit(buf, "</domain>\n");
if (virBufferError(buf))
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a49795c..3b522a9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1525,6 +1525,9 @@ struct _virDomainDef {
void *namespaceData;
virDomainXMLNamespace ns;
+
+ /* Application-specific custom metadata */
+ xmlNodePtr metadata;
};
enum virDomainTaintFlags {
diff --git a/tests/domainsnapshotxml2xmlout/metadata.xml
b/tests/domainsnapshotxml2xmlout/metadata.xml
new file mode 100644
index 0000000..45180c9
--- /dev/null
+++ b/tests/domainsnapshotxml2xmlout/metadata.xml
@@ -0,0 +1,38 @@
+<domainsnapshot>
+ <name>my snap name</name>
+ <description>!@#$%^</description>
+ <state>running</state>
+ <parent>
+ <name>earlier_snap</name>
+ </parent>
+ <creationTime>1272917631</creationTime>
+ <domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <metadata>
+ <app1:foo
xmlns:app1="http://foo.org/">fooish</app1:foo>
+ <app2:bar
xmlns:app2="http://bar.com/"
maman="baz">barish</app2:bar>
+ </metadata>
+ </domain>
+</domainsnapshot>
diff --git a/tests/domainsnapshotxml2xmltest.c b/tests/domainsnapshotxml2xmltest.c
index 90ff9bb..5c2e670 100644
--- a/tests/domainsnapshotxml2xmltest.c
+++ b/tests/domainsnapshotxml2xmltest.c
@@ -109,6 +109,7 @@ mymain(void)
DO_TEST("noparent_nodescription_noactive", NULL, 0);
DO_TEST("noparent_nodescription", NULL, 1);
DO_TEST("noparent", "9d37b878-a7cc-9f9a-b78f-49b3abad25a8", 0);
+ DO_TEST("metadata", "c7a5fdbd-edaf-9455-926a-d65c16db1809", 0);
virCapabilitiesFree(driver.caps);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-metadata.args
b/tests/qemuxml2argvdata/qemuxml2argv-metadata.args
new file mode 100644
index 0000000..651793d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-metadata.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -name QEMUGuest1 -nographic -monitor unix:/tmp/test-monitor,\
+server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial \
+none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
b/tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
new file mode 100644
index 0000000..a6888ee
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
@@ -0,0 +1,29 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <metadata>
+ <app1:foo
xmlns:app1="http://foo.org/">fooish</app1:foo>
+ <app2:bar
xmlns:app2="http://bar.com/"
maman="baz">barish</app2:bar>
+ </metadata>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
new file mode 100644
index 0000000..a6888ee
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
@@ -0,0 +1,29 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <metadata>
+ <app1:foo
xmlns:app1="http://foo.org/">fooish</app1:foo>
+ <app2:bar
xmlns:app2="http://bar.com/"
maman="baz">barish</app2:bar>
+ </metadata>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 293c2a7..df317fd 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -210,6 +210,8 @@ mymain(void)
DO_TEST_DIFFERENT("graphics-listen-network2");
DO_TEST_DIFFERENT("graphics-spice-timeout");
+ DO_TEST_DIFFERENT("metadata");
+
virCapabilitiesFree(driver.caps);
return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
--
1.7.7.5