Ansible Findall 捕获组和列表

Ansible Findall 捕获组和列表

我认为我对 Python 和 Ansible findall 感到困惑。我可以在 Ansible 中使用捕获组吗?例如,如何捕获组 1 和组 2,然后在结果列表中反转位置?

例如,我从 KVM 主机中提取虚拟机的一些块设备信息。XML 中的部分如下所示。我试图获取设备名称vda和底层文件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

我使用virt模块提取 XML,然后删除换行符,认为使用正则表达式更容易处理。结果设置为事实,例如cleanxml

我做了以下事情并得到一个清单。

- 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+)'"

结果是

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

有没有办法让“vda”出现在列表中的 qcow2 文件前面?或者列表的顺序不是固定的?

理想情况下,我可以尝试做类似的事情

cleanxml | regex_findall(_q, '\\2', '\\1')结果类似于 [['vda','/var/lib/libvirt/images/win01.qcow2'], ['vdb','/var/lib/libvirt/images/win01-1.qcow2', 'vdb']]

答案1

XML 很麻烦,在 XML 上用正则表达式开始是错误的。答案并不是 regex_findall。它更多的是关于如何处理 libvirt XML

  1. 我从错误的轨道开始,删除了 XML 中的所有 \n。实际数据中的某些 XML 标签之间可能存在 \n

  2. 我找到了这个问题其中 libvirt XML 通过管道传输到 ansible.utils.from_xml。我可以从 libvirt 输出中获取设备和文件信息。

例如

  - 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"

相关内容