Ansible Findall キャプチャグループとリスト

Ansible Findall キャプチャグループとリスト

Python と Ansible の findall を混同しているようです。Ansible でキャプチャ グループを使用できますか? たとえば、グループ 1 とグループ 2 をキャプチャして、結果のリストで位置を逆にするにはどうすればよいでしょうか?

たとえば、KVMホストからVMのブロックデバイス情報を取得しています。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"
        ]
    ]
}

リスト内の qcow2 ファイルの前に「vda」が来るようにする方法はありますか? または、リストの順序は固定されていませんか?

理想的には、次のようなことを試してみましょう

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"

関連情報