[libvirt] [libvirt-glib] Allow custom metadata in domain configuration XML

Zeeshan Ali (Khattak) zeeshanak at gnome.org
Tue Jan 24 00:57:51 UTC 2012


From: "Zeeshan Ali (Khattak)" <zeeshanak at 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>
+    <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




More information about the libvir-list mailing list