
我想我對 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"
]
]
}
有沒有辦法讓「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
我一開始就錯誤地從 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"