
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 をどう扱うかという点が重要です。
XMLから\nをすべて削除するという間違った方向から始めました。実際のデータには、いくつかのXMLタグの間に\nが含まれている可能性があります。
私はこれを見つけました質問ここで、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"