|
1 <stránka |
|
2 xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana" |
|
3 xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro"> |
|
4 |
|
5 <nadpis>Reading Libvirt XML files using XMLTable</nadpis> |
|
6 <perex>converting arbitrary XML into one or more relations</perex> |
|
7 <m:pořadí-příkladu>02700</m:pořadí-příkladu> |
|
8 |
|
9 <text xmlns="http://www.w3.org/1999/xhtml"> |
|
10 |
|
11 <p> |
|
12 <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. |
|
13 Thanks to the tool <code>relpipe-in-xmltable</code> we can get aggregated overview of our virtual machines. |
|
14 This tool does similar job like the <a href="https://www.postgresql.org/docs/current/functions-xml.html">xmltable</a> function known from SQL. |
|
15 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 |
|
16 and one or more XPath expressions point to attribute nodes/values relatively to particular record node. |
|
17 Our tool is able to produce one or more relations from a single XML input. |
|
18 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: |
|
19 our expression can access whole XML document and pick values not only from currently processed record node. |
|
20 </p> |
|
21 |
|
22 |
|
23 <p>These XML config files contain lot of information describing given virtual machine:</p> |
|
24 |
|
25 |
|
26 <m:pre jazyk="xml"><![CDATA[<?xml version="1.0" encoding="utf8"?> |
|
27 <domain type="kvm"> |
|
28 <name>relpipe-1</name> |
|
29 <uuid>36d1e8b2-97e9-40cb-9fc2-306ebf989282</uuid> |
|
30 <memory unit="KiB">1048576</memory> |
|
31 <currentMemory unit="KiB">1048576</currentMemory> |
|
32 <vcpu placement="static">2</vcpu> |
|
33 <os> |
|
34 <type arch="x86_64" machine="pc-i440fx-bionic">hvm</type> |
|
35 <boot dev="hd"/> |
|
36 </os> |
|
37 <features> |
|
38 <acpi/> |
|
39 <apic/> |
|
40 <vmport state="off"/> |
|
41 </features> |
|
42 <cpu mode="custom" match="exact" check="partial"> |
|
43 <model fallback="allow">Opteron_G5</model> |
|
44 </cpu> |
|
45 <clock offset="utc"> |
|
46 <timer name="rtc" tickpolicy="catchup"/> |
|
47 <timer name="pit" tickpolicy="delay"/> |
|
48 <timer name="hpet" present="no"/> |
|
49 </clock> |
|
50 … |
|
51 <devices> |
|
52 <emulator>/usr/bin/kvm-spice</emulator> |
|
53 <disk type='file' device='disk'> |
|
54 <driver name='qemu' type='qcow2'/> |
|
55 <source file='/mnt/kvm-image/relpipe-1.qcow2'/> |
|
56 <target dev='vda' bus='virtio'/> |
|
57 <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> |
|
58 </disk> |
|
59 <disk type='file' device='cdrom'> |
|
60 <driver name='qemu' type='raw'/> |
|
61 <target dev='hda' bus='ide'/> |
|
62 <readonly/> |
|
63 <address type='drive' controller='0' bus='0' target='0' unit='0'/> |
|
64 </disk> |
|
65 … |
|
66 <interface type='bridge'> |
|
67 <mac address='52:54:e9:f2:f6:bb'/> |
|
68 <source bridge='br0'/> |
|
69 <model type='virtio'/> |
|
70 <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> |
|
71 </interface> |
|
72 … |
|
73 </devices> |
|
74 </domain>]]></m:pre> |
|
75 |
|
76 |
|
77 <p>If we are interested only in certain parts, we can pick them using a command like this one:</p> |
|
78 |
|
79 <m:pre jazyk="bash"><![CDATA[cat /etc/libvirt/qemu/relpipe-1.xml \ |
|
80 | relpipe-in-xmltable \ |
|
81 --relation "machine" \ |
|
82 --records "/domain" \ |
|
83 --attribute "uuid" string "uuid" \ |
|
84 --attribute "name" string "name" \ |
|
85 --attribute "memory_size" integer "memory" \ |
|
86 --attribute "memory_unit" string "memory/@unit" \ |
|
87 --attribute "cpu_count" integer "vcpu" \ |
|
88 --relation "storage" \ |
|
89 --records "/domain/devices/disk" \ |
|
90 --attribute "machine" string "/domain/uuid" \ |
|
91 --attribute "type" string "@device" \ |
|
92 --attribute "format" string "driver/@type" \ |
|
93 --attribute "source" string "source/@file" \ |
|
94 --attribute "target_dev" string "target/@dev" \ |
|
95 --attribute "target_type" string "target/@bus" \ |
|
96 --relation "network_interface" \ |
|
97 --records "/domain/devices/interface" \ |
|
98 --attribute "machine" string "/domain/uuid" \ |
|
99 --attribute "mac" string "mac/@address" \ |
|
100 | relpipe-out-tabular]]></m:pre> |
|
101 |
|
102 |
|
103 <p>And get three relations:</p> |
|
104 |
|
105 <pre><![CDATA[machine: |
|
106 ╭──────────────────────────────────────┬───────────────┬───────────────────────┬──────────────────────┬─────────────────────╮ |
|
107 │ uuid (string) │ name (string) │ memory_size (integer) │ memory_unit (string) │ cpu_count (integer) │ |
|
108 ├──────────────────────────────────────┼───────────────┼───────────────────────┼──────────────────────┼─────────────────────┤ |
|
109 │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ relpipe-1 │ 1048576 │ KiB │ 2 │ |
|
110 ╰──────────────────────────────────────┴───────────────┴───────────────────────┴──────────────────────┴─────────────────────╯ |
|
111 Record count: 1 |
|
112 |
|
113 storage: |
|
114 ╭──────────────────────────────────────┬───────────────┬─────────────────┬─────────────────────────────────┬─────────────────────┬──────────────────────╮ |
|
115 │ machine (string) │ type (string) │ format (string) │ source (string) │ target_dev (string) │ target_type (string) │ |
|
116 ├──────────────────────────────────────┼───────────────┼─────────────────┼─────────────────────────────────┼─────────────────────┼──────────────────────┤ |
|
117 │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ disk │ qcow2 │ /mnt/kvm-image/relpipe-1.qcow2 │ vda │ virtio │ |
|
118 │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ cdrom │ raw │ │ hda │ ide │ |
|
119 ╰──────────────────────────────────────┴───────────────┴─────────────────┴─────────────────────────────────┴─────────────────────┴──────────────────────╯ |
|
120 Record count: 2 |
|
121 |
|
122 network_interface: |
|
123 ╭──────────────────────────────────────┬───────────────────╮ |
|
124 │ machine (string) │ mac (string) │ |
|
125 ├──────────────────────────────────────┼───────────────────┤ |
|
126 │ 36d1e8b2-97e9-40cb-9fc2-306ebf989282 │ 52:54:e9:f2:f6:bb │ |
|
127 ╰──────────────────────────────────────┴───────────────────╯ |
|
128 Record count: 1]]></pre> |
|
129 |
|
130 <p> |
|
131 Each record contain ID of the machine, thus if we collect data from several VMs, |
|
132 we can JOIN relevant records together, do some aggregations or statistics. |
|
133 If we are sure that the <code>name</code> field is unique, we can use it as a key instead of the UUID. |
|
134 </p> |
|
135 |
|
136 |
|
137 </text> |
|
138 |
|
139 </stránka> |