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"

관련 정보