[ovirt-devel] [vdsm] Engine XML: metadata and devices from XML

Michal Skrivanek michal.skrivanek at redhat.com
Thu Mar 16 10:47:21 UTC 2017


> On 16 Mar 2017, at 09:45, Francesco Romani <fromani at redhat.com> wrote:
> 
> We talked about sending storage device purely on metadata, letting Vdsm
> rebuild them and getting the XML like today.
> 
> In the other direction, Vdsm will pass through the XML (perhaps only
> parts of it, e.g. the devices subtree) like before.
> 
> This way we can minimize the changes we are uncertain of, and more
> importantly, we can minimize the risky changes.
> 
> 
> The following is  a realistic example of how the XML could look like if
> we send all but the storage devices. It is built using my pyxmlpickle
> module (see [3] below).

That’s quite verbose. How much work would it need to actually minimize it and turn it into something more simple.
Most such stuff should go away and I believe it would be beneficial to make it difficult to use to discourage using metadata as a generic junkyard

> 
> 
> <domain type='kvm' id='10'>
>  <name>a0</name>
>  <uuid>ccd945c8-8069-4f31-8471-bbb58e9dd6ea</uuid>
>  <metadata xmlns:ovirt-tune="http://ovirt.org/vm/tune/1.0"
> xmlns:ovirt-vm="http://ovirt.org/vm/1.0"
> xmlns:ovirt-instance="http://ovirt.org/vm/instance/1.0">
>    <ovirt-tune:qos/>
>    <ovirt-vm:vm/>
>    <ovirt-instance:instance>
>      <ovirt-instance:value type="dict">
>        <ovirt-instance:item key="devices" type="list">
>          <ovirt-instance:item index="0" type="dict">
>            <ovirt-instance:item key="index"
> type="str">2</ovirt-instance:item>
>            <ovirt-instance:item key="iface"
> type="str">ide</ovirt-instance:item>
>            <ovirt-instance:item key="specParams" type="dict">
>              <ovirt-instance:item key="path" type="str"/>
>            </ovirt-instance:item>
>            <ovirt-instance:item key="readonly"
> type="str">true</ovirt-instance:item>
>            <ovirt-instance:item key="deviceId"
> type="str">e59c985c-46c2-4489-b355-a6f374125eb9</ovirt-instance:item>
>            <ovirt-instance:item key="address" type="dict">
>              <ovirt-instance:item key="bus"
> type="str">1</ovirt-instance:item>
>              <ovirt-instance:item key="controller"
> type="str">0</ovirt-instance:item>
>              <ovirt-instance:item key="type"
> type="str">drive</ovirt-instance:item>
>              <ovirt-instance:item key="target"
> type="str">0</ovirt-instance:item>
>              <ovirt-instance:item key="unit"
> type="str">0</ovirt-instance:item>
>            </ovirt-instance:item>
>            <ovirt-instance:item key="device"
> type="str">cdrom</ovirt-instance:item>
>            <ovirt-instance:item key="shared"
> type="str">false</ovirt-instance:item>
>            <ovirt-instance:item key="path" type="str"/>
>            <ovirt-instance:item key="type"
> type="str">disk</ovirt-instance:item>
>          </ovirt-instance:item>
>          <ovirt-instance:item index="1" type="dict">
>            <ovirt-instance:item key="poolID"
> type="str">5890a292-0390-01d2-01ed-00000000029a</ovirt-instance:item>
>            <ovirt-instance:item key="volumeInfo" type="dict">
>              <ovirt-instance:item key="domainID"
> type="str">c578566d-bc61-420c-8f1e-8dfa0a18efd5</ovirt-instance:item>
>              <ovirt-instance:item key="volType"
> type="str">path</ovirt-instance:item>
>              <ovirt-instance:item key="leaseOffset"
> type="int">0</ovirt-instance:item>
>              <ovirt-instance:item key="path"
> type="str">/rhev/data-center/mnt/192.168.1.20:_srv_virtstore_nfs_rel40x_data/c578566d-bc61-420c-8f1e-8dfa0a18efd5/images/66441539-f7ac-4946-8a25-75e422f939d4/5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>              <ovirt-instance:item key="volumeID"
> type="str">5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>              <ovirt-instance:item key="leasePath"
> type="str">/rhev/data-center/mnt/192.168.1.20:_srv_virtstore_nfs_rel40x_data/c578566d-bc61-420c-8f1e-8dfa0a18efd5/images/66441539-f7ac-4946-8a25-75e422f939d4/5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc.lease</ovirt-instance:item>
>              <ovirt-instance:item key="imageID"
> type="str">66441539-f7ac-4946-8a25-75e422f939d4</ovirt-instance:item>
>            </ovirt-instance:item>
>            <ovirt-instance:item key="index"
> type="int">0</ovirt-instance:item>
>            <ovirt-instance:item key="iface"
> type="str">virtio</ovirt-instance:item>
>            <ovirt-instance:item key="apparentsize"
> type="str">8589934592</ovirt-instance:item>
>            <ovirt-instance:item key="imageID"
> type="str">66441539-f7ac-4946-8a25-75e422f939d4</ovirt-instance:item>
>            <ovirt-instance:item key="readonly"
> type="str">false</ovirt-instance:item>
>            <ovirt-instance:item key="shared"
> type="str">false</ovirt-instance:item>
>            <ovirt-instance:item key="truesize"
> type="str">0</ovirt-instance:item>
>            <ovirt-instance:item key="type"
> type="str">disk</ovirt-instance:item>
>            <ovirt-instance:item key="domainID"
> type="str">c578566d-bc61-420c-8f1e-8dfa0a18efd5</ovirt-instance:item>
>            <ovirt-instance:item key="reqsize"
> type="str">0</ovirt-instance:item>
>            <ovirt-instance:item key="format"
> type="str">raw</ovirt-instance:item>
>            <ovirt-instance:item key="deviceId"
> type="str">66441539-f7ac-4946-8a25-75e422f939d4</ovirt-instance:item>
>            <ovirt-instance:item key="address" type="dict">
>              <ovirt-instance:item key="function"
> type="str">0x0</ovirt-instance:item>
>              <ovirt-instance:item key="bus"
> type="str">0x00</ovirt-instance:item>
>              <ovirt-instance:item key="domain"
> type="str">0x0000</ovirt-instance:item>
>              <ovirt-instance:item key="type"
> type="str">pci</ovirt-instance:item>
>              <ovirt-instance:item key="slot"
> type="str">0x05</ovirt-instance:item>
>            </ovirt-instance:item>
>            <ovirt-instance:item key="device"
> type="str">disk</ovirt-instance:item>
>            <ovirt-instance:item key="path"
> type="str">/rhev/data-center/5890a292-0390-01d2-01ed-00000000029a/c578566d-bc61-420c-8f1e-8dfa0a18efd5/images/66441539-f7ac-4946-8a25-75e422f939d4/5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>            <ovirt-instance:item key="propagateErrors"
> type="str">off</ovirt-instance:item>
>            <ovirt-instance:item key="optional"
> type="str">false</ovirt-instance:item>
>            <ovirt-instance:item key="bootOrder"
> type="str">1</ovirt-instance:item>
>            <ovirt-instance:item key="volumeID"
> type="str">5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>            <ovirt-instance:item key="specParams" type="dict"/>
>            <ovirt-instance:item key="volumeChain" type="list">
>              <ovirt-instance:item index="0" type="dict">
>                <ovirt-instance:item key="domainID"
> type="str">c578566d-bc61-420c-8f1e-8dfa0a18efd5</ovirt-instance:item>
>                <ovirt-instance:item key="volType"
> type="str">path</ovirt-instance:item>
>                <ovirt-instance:item key="leaseOffset"
> type="int">0</ovirt-instance:item>
>                <ovirt-instance:item key="path"
> type="str">/rhev/data-center/mnt/192.168.1.20:_srv_virtstore_nfs_rel40x_data/c578566d-bc61-420c-8f1e-8dfa0a18efd5/images/66441539-f7ac-4946-8a25-75e422f939d4/5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>                <ovirt-instance:item key="volumeID"
> type="str">5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>                <ovirt-instance:item key="leasePath"
> type="str">/rhev/data-center/mnt/192.168.1.20:_srv_virtstore_nfs_rel40x_data/c578566d-bc61-420c-8f1e-8dfa0a18efd5/images/66441539-f7ac-4946-8a25-75e422f939d4/5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc.lease</ovirt-instance:item>
>                <ovirt-instance:item key="imageID"
> type="str">66441539-f7ac-4946-8a25-75e422f939d4</ovirt-instance:item>
>              </ovirt-instance:item>
>            </ovirt-instance:item>
>          </ovirt-instance:item>
>        </ovirt-instance:item>
>      </ovirt-instance:value>
>    </ovirt-instance:instance>
>  </metadata>
>  <maxMemory slots='16' unit='KiB'>4294967296</maxMemory>
>  <memory unit='KiB'>4194304</memory>
>  <currentMemory unit='KiB'>4194304</currentMemory>
>  <vcpu placement='static' current='2'>16</vcpu>
>  <cputune>
>    <shares>1020</shares>
>  </cputune>
>  <resource>
>    <partition>/machine</partition>
>  </resource>
>  <sysinfo type='smbios'>
>    <system>
>      <entry name='manufacturer'>oVirt</entry>
>      <entry name='product'>oVirt Node</entry>
>      <entry name='version'>7-3.1611.el7.centos</entry>
>      <entry name='serial'>ccd79775-c888-4789-975a-fde1143dffc9</entry>
>      <entry name='uuid'>ccd945c8-8069-4f31-8471-bbb58e9dd6ea</entry>
>    </system>
>  </sysinfo>
>  <os>
>    <type arch='x86_64' machine='pc-i440fx-rhel7.2.0'>hvm</type>
>    <bios useserial='yes'/>
>    <smbios mode='sysinfo'/>
>  </os>
>  <features>
>    <acpi/>
>  </features>
>  <cpu mode='custom' match='exact'>
>    <model fallback='allow'>Haswell-noTSX</model>
>    <topology sockets='16' cores='1' threads='1'/>
>    <numa>
>      <cell id='0' cpus='0-1' memory='4194304' unit='KiB'/>
>    </numa>
>  </cpu>
>  <clock offset='variable' adjustment='0' basis='utc'>
>    <timer name='rtc' tickpolicy='catchup'/>
>    <timer name='pit' tickpolicy='delay'/>
>    <timer name='hpet' present='no'/>
>  </clock>
>  <on_poweroff>destroy</on_poweroff>
>  <on_reboot>restart</on_reboot>
>  <on_crash>destroy</on_crash>
>  <devices>
>    <emulator>/usr/libexec/qemu-kvm</emulator>
>    <controller type='virtio-serial' index='0' ports='16'>
>      <alias name='virtio-serial0'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
> function='0x0'/>
>    </controller>
>    <controller type='usb' index='0'>
>      <alias name='usb'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> function='0x2'/>
>    </controller>
>    <controller type='pci' index='0' model='pci-root'>
>      <alias name='pci.0'/>
>    </controller>
>    <controller type='ide' index='0'>
>      <alias name='ide'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> function='0x1'/>
>    </controller>
>    <interface type='bridge'>
>      <mac address='00:1a:4a:16:01:51'/>
>      <source bridge='ovirtmgmt'/>
>      <target dev='vnet0'/>
>      <model type='virtio'/>
>      <filterref filter='vdsm-no-mac-spoofing'/>
>      <link state='up'/>
>      <alias name='net0'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x03'
> function='0x0'/>
>    </interface>
>    <serial type='unix'>
>      <source mode='bind'
> path='/var/run/ovirt-vmconsole-console/ccd945c8-8069-4f31-8471-bbb58e9dd6ea.sock'/>
>      <target port='0'/>
>      <alias name='serial0'/>
>    </serial>
>    <console type='unix'>
>      <source mode='bind'
> path='/var/run/ovirt-vmconsole-console/ccd945c8-8069-4f31-8471-bbb58e9dd6ea.sock'/>
>      <target type='serial' port='0'/>
>      <alias name='serial0'/>
>    </console>
>    <channel type='unix'>
>      <source mode='bind'
> path='/var/lib/libvirt/qemu/channels/ccd945c8-8069-4f31-8471-bbb58e9dd6ea.com.redhat.rhevm.vdsm'/>
>      <target type='virtio' name='com.redhat.rhevm.vdsm'
> state='disconnected'/>
>      <alias name='channel0'/>
>      <address type='virtio-serial' controller='0' bus='0' port='1'/>
>    </channel>
>    <channel type='unix'>
>      <source mode='bind'
> path='/var/lib/libvirt/qemu/channels/ccd945c8-8069-4f31-8471-bbb58e9dd6ea.org.qemu.guest_agent.0'/>
>      <target type='virtio' name='org.qemu.guest_agent.0'
> state='disconnected'/>
>      <alias name='channel1'/>
>      <address type='virtio-serial' controller='0' bus='0' port='2'/>
>    </channel>
>    <channel type='spicevmc'>
>      <target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
>      <alias name='channel2'/>
>      <address type='virtio-serial' controller='0' bus='0' port='3'/>
>    </channel>
>    <input type='mouse' bus='ps2'>
>      <alias name='input0'/>
>    </input>
>    <input type='keyboard' bus='ps2'>
>      <alias name='input1'/>
>    </input>
>    <graphics type='vnc' port='5900' autoport='yes'
> listen='192.168.1.53' keymap='en-us' passwdValidTo='1970-01-01T00:00:01'>
>      <listen type='network' address='192.168.1.53'
> network='vdsm-ovirtmgmt'/>
>    </graphics>
>    <graphics type='spice' tlsPort='5901' autoport='yes'
> listen='192.168.1.53' keymap='en-us' defaultMode='secure'
> passwdValidTo='1970-01-01T00:00:01'>
>      <listen type='network' address='192.168.1.53'
> network='vdsm-ovirtmgmt'/>
>      <channel name='main' mode='secure'/>
>      <channel name='display' mode='secure'/>
>      <channel name='inputs' mode='secure'/>
>      <channel name='cursor' mode='secure'/>
>      <channel name='playback' mode='secure'/>
>      <channel name='record' mode='secure'/>
>      <channel name='smartcard' mode='secure'/>
>      <channel name='usbredir' mode='secure'/>
>    </graphics>
>    <sound model='ich6'>
>      <alias name='sound0'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x06'
> function='0x0'/>
>    </sound>
>    <video>
>      <model type='qxl' ram='65536' vram='8192' vgamem='16384' heads='1'
> primary='yes'/>
>      <alias name='video0'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x02'
> function='0x0'/>
>    </video>
>    <memballoon model='virtio'>
>      <alias name='balloon0'/>
>      <address type='pci' domain='0x0000' bus='0x00' slot='0x07'
> function='0x0'/>
>    </memballoon>
>  </devices>
>  <seclabel type='dynamic' model='selinux' relabel='yes'>
>    <label>system_u:system_r:svirt_t:s0:c207,c629</label>
>    <imagelabel>system_u:object_r:svirt_image_t:s0:c207,c629</imagelabel>
>  </seclabel>
>  <seclabel type='dynamic' model='dac' relabel='yes'>
>    <label>+107:+107</label>
>    <imagelabel>+107:+107</imagelabel>
>  </seclabel>
> </domain>
> 
> 
> On 03/15/2017 01:28 PM, Francesco Romani wrote:
>> Hi everyone,
>> 
>> This is both a report of the current state of my Vdsm patches for Engine
>> XML support, and a proposal to how move forward and solve
>> the current open issues.
>> 
>> TL;DR:
>> 1. we can and IMO should reuse the current JSON schema to describe the
>> structure (layout) and the types of the metadata section.
>> 2. we don't need a priori validation of stuff in the metadata section.
>> We will just raise in the creation flow if data is missing, or wrong,
>> according to our schema.
>> 2. we will add *few* items to the metadata section, only thing we can't
>> express clearly-or at all in the libvirt XML. Redundancy and verbosiness
>> will be thus kept at bay
>> 3. I believe [3] is the best tool to do (de)serialize data to the
>> metadata section. Existing tools fits poorly in our very specific use case
>> 
>> Examples below
>> 
>> +++
>> 
>> Long(er) discussion:
>> 
>> 
>> I have working code[1][2] to encode any custom, picklable, python
>> object in the metadata section.
>> 
>> We should decide which module will do the actual python<=>XML
>> transformation.
>> Please note that this actually also influences how the data in the
>> medata section look like, so the two things are a bit coupled.
>> 
>> I'm eager to reinvent another wheel, but after
>> initial evaluation I honestly think that my pyxmlpickle[3] is the best
>> tool for the job over the current alternatives: plistlib[4] and
>> xmltodict[5].
>> 
>> I added the initial rationale here:
>> https://gerrit.ovirt.org/#/c/73790/4//COMMIT_MSG
>> 
>> I have completed the initial draft of patches to make it possible to
>> initialize devices from their XML representation [6]. This is the bare
>> minimum we need to support the Engine XML, and we *need* this anyway to
>> unlock the cleanup we planned and I outlined in my google doc.
>> 
>> So we are progressing, but I'd like to speed up things. Those [6]
>> patches are not yet complete, many flows are not covered or tested;  but
>> they are good enough to demonstrate that there *are* pieces of
>> information wen need to properly initialize the devices, but we can't
>> easily extract from the XML.
>> 
>> First examples that come to my mind are the storage.Drive UUIDs; there
>> could also be some ambiguity I'm investigating right now for
>> displayIp/displayNetwork in Graphics devices. In [6] there are various
>> TODO to mark more of those cases. Most likely, few more cases will pop
>> out as I cover all the flows we support.
>> 
>> Long story short: it is hard to correctly rebuild the device conf from
>> the XML. This is why in [6] I added the 'meta' argument to from_xml_tree
>> classmethod in [7].
>> 
>> 'meta' is supposed to be the device metadata: extra data related to a
>> device which doesn't (yet) fit in the libvirt XML representation.
>> For example, we can store 'displayIp' and 'displayNetwork' here and be
>> done with that: using both per-device metadata and the XML
>> representation of one graphic device, we will have everything we need to
>> properly build one graphics.Graphics device.
>> This example may (hopefully) be bogus, but I'm keeping it because it is
>> one case easy to follow.
>> 
>> The device metadata is going to be stored in the vm metadata for the
>> short/mid term future. Even if the per-device metadata idea/RFE is
>> accepted (no answer yet, but we are working on it), we will not have in
>> 7.4, and unlikely in 7.5.
>> 
>> As it stands today, I believe there are two open questions:
>> 
>> 1. do we need a schema for the metadata section?
>> 2. how do we bind the metadata to the devices? How do we know which
>> metadata belongs to which metadata, if we don't have aliases nor
>> addresses to match? (e.g. very first time the VM is created!)
>> 
>> My current stance is the following
>> 1. In general, one schema gives us two benefits: 1.a. we document how
>> the layout of the data should be, including types; 1.b. we can validate
>> the data we receive.
>> So yes, we need a schema, but we don't need a *new* schema. I think we
>> are in good enough shape with the current Vdsm schema: we can just
>> translate the python object layout to a XML layout.
>> 
>> One example is probably more explicative. Some actual data may look
>> like, using my pyxmlpickle module:
>> 
>> <domain type='kvm' id='5'>
>>  <name>a0</name>
>>  <uuid>ccd945c8-8069-4f31-8471-bbb58e9dd6ea</uuid>
>>  <metadata xmlns:ovirt-tune="http://ovirt.org/vm/tune/1.0"
>> xmlns:ovirt-vm="http://ovirt.org/vm/1.0"
>> xmlns:ovirt-instance="http://ovirt.org/vm/instance/1.0">
>>    <ovirt-tune:qos/>
>>    <ovirt-vm:vm/>
>>    <ovirt-instance:instance>
>>      <ovirt-instance:value type="dict">
>>        <ovirt-instance:item key="devices" type="list">
>>          <ovirt-instance:item index="0" type="dict">
>>            <ovirt-instance:item key="device"
>> type="str">vnc</ovirt-instance:item>
>>            <ovirt-instance:item key="specParams" type="dict">
>>              <ovirt-instance:item key="displayNetwork"
>> type="str">ovirtmgmt</ovirt-instance:item>
>>              <ovirt-instance:item key="displayIp"
>> type="str">192.168.1.53</ovirt-instance:item>
>>            </ovirt-instance:item>
>>            <ovirt-instance:item key="type"
>> type="str">graphics</ovirt-instance:item>
>>          </ovirt-instance:item>
>>          <ovirt-instance:item index="1" type="dict">
>>            <ovirt-instance:item key="device"
>> type="str">spice</ovirt-instance:item>
>>            <ovirt-instance:item key="specParams" type="dict">
>>              <ovirt-instance:item key="displayNetwork"
>> type="str">ovirtmgmt</ovirt-instance:item>
>>              <ovirt-instance:item key="displayIp"
>> type="str">192.168.1.53</ovirt-instance:item>
>>            </ovirt-instance:item>
>>            <ovirt-instance:item key="type"
>> type="str">graphics</ovirt-instance:item>
>>          </ovirt-instance:item>
>>          <ovirt-instance:item index="2" type="dict">
>>            <ovirt-instance:item key="poolID"
>> type="str">5890a292-0390-01d2-01ed-00000000029a</ovirt-instance:item>
>>            <ovirt-instance:item key="imageID"
>> type="str">66441539-f7ac-4946-8a25-75e422f939d4</ovirt-instance:item>
>>            <ovirt-instance:item key="domainID"
>> type="str">c578566d-bc61-420c-8f1e-8dfa0a18efd5</ovirt-instance:item>
>>            <ovirt-instance:item key="device"
>> type="str">disk</ovirt-instance:item>
>>            <ovirt-instance:item key="path"
>> type="str">/rhev/data-center/5890a292-0390-01d2-01ed-00000000029a/c578566d-bc61-420c-8f1e-8dfa0a18efd5/images/66441539-f7ac-4946-8a25-75e422f939d4/5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>>            <ovirt-instance:item key="volumeID"
>> type="str">5c4eeed4-f2a7-490a-ab57-a0d6f3a711cc</ovirt-instance:item>
>>          </ovirt-instance:item>
>>        </ovirt-instance:item>
>>      </ovirt-instance:value>
>>    </ovirt-instance:instance>
>>  </metadata>
>> <!-- omitted for brevity -->
>> </domain>
>> 
>> 
>> Please note that yes, this is still verbose, but we don't want to add
>> much data here, for most of information the most reliable source will
>> be the domain XML. We will add here only the extra info we can't really
>> fetch from that.
>> 
>> 2. I don't think we need explicit validation: we could just raise along
>> the way in the creation flow if we don't find some extra metadata we
>> need. This will also solve the issue that if we reuse the current schema
>> and we omit most of data, we will lack quite a lot of elements
>> marked mandatory.
>> 
>> Once we reached agreement, I will update my
>> https://docs.google.com/document/d/1eD8KSLwwyo2Sk64MytbmE0wBxxMlpIyEI1GRcHDkp7Y/edit#heading=h.hqdqzmmm9i77
>> accordingly.
>> 
>> Final note: while device take the lion's share, we will likely need help
>> from the metadata section also to store VM extra info, but all the above
>> discussion also applies here.
>> 
>> +++
>> 
>> [1]
>> https://gerrit.ovirt.org/#/q/status:open+project:vdsm+branch:master+topic:virt-metadata3
>> - uses xmltodict
>> [2]
>> https://gerrit.ovirt.org/#/q/status:open+project:vdsm+branch:master+topic:virt-metadata-pyxmlpickle
>> ported the 'virt-metadata3' topic to pyxmlpickle
>> [3] https://github.com/fromanirh/pyxmlpickle
>> [4] https://docs.python.org/2/library/plistlib.html
>> [5] https://github.com/martinblech/xmltodict
>> [6]
>> https://gerrit.ovirt.org/#/q/status:open+project:vdsm+branch:master+topic:vm-devs-xml
>> [7] https://gerrit.ovirt.org/#/c/72880/15/lib/vdsm/virt/vmdevices/core.py
>> 
> 
> -- 
> Francesco Romani
> Red Hat Engineering Virtualization R & D
> IRC: fromani
> 
> _______________________________________________
> Devel mailing list
> Devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/devel
> 
> 



More information about the Devel mailing list