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

Francesco Romani fromani at redhat.com
Thu Mar 16 08:45:56 UTC 2017


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).


<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



More information about the Devel mailing list