relpipe-data/examples-in-xmltable-libvirt.xml
branchv_0
changeset 263 8bf13358a50a
child 264 d39cfc926f95
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relpipe-data/examples-in-xmltable-libvirt.xml	Thu Jul 25 22:16:12 2019 +0200
@@ -0,0 +1,139 @@
+<stránka
+	xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
+	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
+	
+	<nadpis>Reading Libvirt XML files using XMLTable</nadpis>
+	<perex>converting arbitrary XML into one or more relations</perex>
+	<m:pořadí-příkladu>02700</m:pořadí-příkladu>
+
+	<text xmlns="http://www.w3.org/1999/xhtml">
+		
+		<p>
+			<a href="https://libvirt.org/">Libvirt</a> is a popular API/tool for managing virtual machines (KVM/Qemu, LXC etc.) and stores its configuration in XML files.
+			Thanks to the tool <code>relpipe-in-xmltable</code> we can get aggregated overview of our virtual machines.
+			This tool does similar job like the <a href="https://www.postgresql.org/docs/current/functions-xml.html">xmltable</a> function known from SQL.
+			It uses the <a href="https://www.w3.org/TR/xpath/all/">XPath</a> language for selecting parts of the input XML – one XPath expression points to record nodes
+			and one or more XPath expressions point to attribute nodes/values relatively to particular record node.
+			Our tool is able to produce one or more relations from a single XML input.
+			The input is parsed at once and converted to DOM in memory i.e. no streaming – thus processing of huge XML files requires appropriate amounts of RAM, on the other hand: 
+			our expression can access whole XML document and pick values not only from currently processed record node.
+		</p>
+		
+		
+		<p>These XML config files contain lot of information describing given virtual machine:</p>
+		
+		
+		<m:pre jazyk="xml"><![CDATA[<?xml version="1.0" encoding="utf8"?>
+<domain type="kvm">
+	<name>relpipe-1</name>
+	<uuid>36d1e8b2-97e9-40cb-9fc2-306ebf989282</uuid>
+	<memory unit="KiB">1048576</memory>
+	<currentMemory unit="KiB">1048576</currentMemory>
+	<vcpu placement="static">2</vcpu>
+	<os>
+		<type arch="x86_64" machine="pc-i440fx-bionic">hvm</type>
+		<boot dev="hd"/>
+	</os>
+	<features>
+		<acpi/>
+		<apic/>
+		<vmport state="off"/>
+	</features>
+	<cpu mode="custom" match="exact" check="partial">
+		<model fallback="allow">Opteron_G5</model>
+	</cpu>
+	<clock offset="utc">
+		<timer name="rtc" tickpolicy="catchup"/>
+		<timer name="pit" tickpolicy="delay"/>
+		<timer name="hpet" present="no"/>
+	</clock>
+	…
+	<devices>
+		<emulator>/usr/bin/kvm-spice</emulator>
+		<disk type='file' device='disk'>
+			<driver name='qemu' type='qcow2'/>
+			<source file='/mnt/kvm-image/relpipe-1.qcow2'/>
+			<target dev='vda' bus='virtio'/>
+			<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+		</disk>
+		<disk type='file' device='cdrom'>
+			<driver name='qemu' type='raw'/>
+			<target dev='hda' bus='ide'/>
+			<readonly/>
+			<address type='drive' controller='0' bus='0' target='0' unit='0'/>
+		</disk>
+		…
+		<interface type='bridge'>
+			<mac address='52:54:e9:f2:f6:bb'/>
+			<source bridge='br0'/>
+			<model type='virtio'/>
+			<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+		</interface>
+		…
+	</devices>
+</domain>]]></m:pre>
+	
+	
+	<p>If we are interested only in certain parts, we can pick them using a command like this one:</p>		
+		
+		<m:pre jazyk="bash"><![CDATA[cat /etc/libvirt/qemu/relpipe-1.xml \
+	| relpipe-in-xmltable \
+		--relation "machine" \
+			--records "/domain" \
+			--attribute "uuid" string "uuid" \
+			--attribute "name" string "name" \
+			--attribute "memory_size" integer "memory" \
+			--attribute "memory_unit" string "memory/@unit" \
+			--attribute "cpu_count" integer "vcpu" \
+		--relation "storage" \
+			--records "/domain/devices/disk" \
+			--attribute "machine" string "/domain/uuid" \
+			--attribute "type" string "@device" \
+			--attribute "format" string "driver/@type" \
+			--attribute "source" string "source/@file" \
+			--attribute "target_dev" string "target/@dev" \
+			--attribute "target_type" string "target/@bus" \
+		--relation "network_interface" \
+			--records "/domain/devices/interface" \
+			--attribute "machine" string "/domain/uuid" \
+			--attribute "mac" string "mac/@address" \
+	| relpipe-out-tabular]]></m:pre>
+
+		
+		<p>And get three relations:</p>
+		
+		<pre><![CDATA[machine:
+ ╭──────────────────────────────────────┬───────────────┬───────────────────────┬──────────────────────┬─────────────────────╮
+ │ uuid                        (string) │ name (string) │ memory_size (integer) │ memory_unit (string) │ cpu_count (integer) │
+ ├──────────────────────────────────────┼───────────────┼───────────────────────┼──────────────────────┼─────────────────────┤
+ │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ relpipe-1     │               1048576 │ KiB                  │                   2 │
+ ╰──────────────────────────────────────┴───────────────┴───────────────────────┴──────────────────────┴─────────────────────╯
+Record count: 1
+
+storage:
+ ╭──────────────────────────────────────┬───────────────┬─────────────────┬─────────────────────────────────┬─────────────────────┬──────────────────────╮
+ │ machine                     (string) │ type (string) │ format (string) │ source                 (string) │ target_dev (string) │ target_type (string) │
+ ├──────────────────────────────────────┼───────────────┼─────────────────┼─────────────────────────────────┼─────────────────────┼──────────────────────┤
+ │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ disk          │ qcow2           │ /mnt/kvm-image/relpipe-1.qcow2  │ vda                 │ virtio               │
+ │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ cdrom         │ raw             │                                 │ hda                 │ ide                  │
+ ╰──────────────────────────────────────┴───────────────┴─────────────────┴─────────────────────────────────┴─────────────────────┴──────────────────────╯
+Record count: 2
+
+network_interface:
+ ╭──────────────────────────────────────┬───────────────────╮
+ │ machine                     (string) │ mac      (string) │
+ ├──────────────────────────────────────┼───────────────────┤
+ │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ 52:54:e9:f2:f6:bb │
+ ╰──────────────────────────────────────┴───────────────────╯
+Record count: 1]]></pre>
+
+		<p>
+			Each record contain ID of the machine, thus if we collect data from several VMs, 
+			we can JOIN relevant records together, do some aggregations or statistics.
+			If we are sure that the <code>name</code> field is unique, we can use it as a key instead of the UUID.
+		</p>
+		
+		
+	</text>
+
+</stránka>