0

I think I'm confused with Python and Ansible findall. Can I use capture groups in Ansible? For example, How can I capture group 1 and group 2 then reverse the position in the resulting list?

For example, I'm pulling some block devices info of a VM from a KVM host. The part in the XML looks like this. I'm trying to get the device name vda and the underlying file win01.qcow2

<disk type='file' device='disk'>\n
<driver name='qemu' type='qcow2'/>\n
<source file='/var/lib/libvirt/images/win01.qcow2' index='2'/>\n
<backingStore/>\n      <target dev='vda' bus='virtio'/>\n
<alias name='virtio-disk0'/>\n
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>\n

I use the virt module to pull the XML and then remove the newlines thinking it is easier to deal with regex. The result is set in a fact, say cleanxml

I did the following and get a list.

- name: Get list of block device
  set_fact:
    listblockdev: "{{ cleanxml | regex_findall(_q) }}"
  vars:
    _q: "<disk type='file' device='disk'>.*?source file='(.+?)'.*?<target dev='(\\w+)'"

The result is

ok: [testhost] => {
    "msg": [
        [
            "/var/lib/libvirt/images/win01.qcow2",
            "vda"
        ],
        [
            "/var/lib/libvirt/images/win01-1.qcow2",
            "vdb"
        ]
    ]
}

Is there way I can have "vda" comes in front of the qcow2 file in the list? Or the sequence of the list is not fixed?

Ideally I can trying to do things like

cleanxml | regex_findall(_q, '\\2', '\\1') and have the result similar to [['vda','/var/lib/libvirt/images/win01.qcow2'], ['vdb','/var/lib/libvirt/images/win01-1.qcow2', 'vdb']]

Billy K
  • 121
  • 1
  • 3
  • 16

1 Answers1

1

XML is a pain and it is wrong to start with regex on XML. The answer is not really regex_findall. It is more on how to deal with libvirt XML

  1. I started in the wrong track to remove all the \n from the XML. There may be \n in the actual data between some XML tags

  2. I found this question where the libvirt XML is piped to ansible.utils.from_xml. I can get the device and file info from the libvirt output.

e.g.

  - name: Get XML
    set_fact:
      xmldict: "{{ lookup('file','./test.xml') | ansible.utils.from_xml }}"

  - name: debug
    debug:
      msg: "{{ item['target']['@dev'] }} {{ item['source']['@file'] }}"
    with_items: "{{ xmldict.domain.devices.disk }}"
    when: item['@device'] == "disk"
Billy K
  • 121
  • 1
  • 3
  • 16