From: "Zeeshan Ali (Khattak)" <zeeshanak@xxxxxxxxx> 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> + <app2:bar xmlns:app2="http://app1.org/app2/">..</app2:bar> + </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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list