
Creo que estoy confundido con Python y Ansible Findall. ¿Puedo utilizar grupos de captura en Ansible? Por ejemplo, ¿cómo puedo capturar el grupo 1 y el grupo 2 y luego invertir la posición en la lista resultante?
Por ejemplo, estoy extrayendo información de dispositivos de bloque de una VM de un host KVM. La parte del XML tiene este aspecto. Estoy intentando obtener el nombre del dispositivo vda
y el archivo subyacente.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
Utilizo el virt
módulo para extraer el XML y luego elimino las nuevas líneas pensando que es más fácil lidiar con las expresiones regulares. El resultado se establece en un hecho, digamoscleanxml
Hice lo siguiente y obtuve una lista.
- 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+)'"
El resultado es
ok: [testhost] => {
"msg": [
[
"/var/lib/libvirt/images/win01.qcow2",
"vda"
],
[
"/var/lib/libvirt/images/win01-1.qcow2",
"vdb"
]
]
}
¿Hay alguna manera de que "vda" aparezca delante del archivo qcow2 en la lista? ¿O la secuencia de la lista no es fija?
Idealmente puedo intentar hacer cosas como
cleanxml | regex_findall(_q, '\\2', '\\1')
y tener el resultado similar a
[['vda','/var/lib/libvirt/images/win01.qcow2'], ['vdb','/var/lib/libvirt/images/win01-1.qcow2', 'vdb']]
Respuesta1
XML es una molestia y está mal comenzar con expresiones regulares en XML. La respuesta no es realmente regex_findall. Se trata más de cómo lidiar con libvirt XML.
Empecé por el camino equivocado para eliminar todos los \n del XML. Puede haber \n en los datos reales entre algunas etiquetas XML
encontré estopreguntadonde el XML libvirt se canaliza a ansible.utils.from_xml. Puedo obtener la información del dispositivo y del archivo desde la salida de libvirt.
p.ej
- 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"