diff --git a/roles/libvirt_manager/molecule/deploy_layout/converge.yml b/roles/libvirt_manager/molecule/deploy_layout/converge.yml index da1094673d..4439b60b46 100644 --- a/roles/libvirt_manager/molecule/deploy_layout/converge.yml +++ b/roles/libvirt_manager/molecule/deploy_layout/converge.yml @@ -14,7 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -- name: Converge +- name: One hypervisor hosts: instance gather_facts: true vars: @@ -243,7 +243,7 @@ - expected_count == found_count loop: "{{ volume_count.results }}" -- name: Cleanup +- name: Cleanup one hypervisor hosts: instance tasks: - name: Clean layout @@ -251,23 +251,34 @@ name: libvirt_manager tasks_from: clean_layout.yml + - name: Reload clean inventory + ansible.builtin.meta: refresh_inventory + + - name: Expose current hosts + ansible.builtin.debug: + msg: "{{ hostvars.keys() }}" + - name: Inject fake hosts in inventory hosts: instance tasks: - - name: Inject compute-0 in inventory + - name: Inject hypervisor-0 in inventory ansible.builtin.add_host: - name: compute-0 + name: hypervisor-0 + groups: + - hypervisors ansible_host: localhost ansible_connection: local - - name: Inject compute-1 in inventory + - name: Inject hypervisor-1 in inventory ansible.builtin.add_host: - name: compute-1 + name: hypervisor-1 + groups: + - hypervisors ansible_host: localhost ansible_connection: local -- name: Converge - hosts: all +- name: Multiple hypervisors + hosts: hypervisors vars: ansible_user_dir: "{{ lookup('env', 'HOME') }}" cifmw_basedir: "/opt/basedir" @@ -287,7 +298,7 @@ cifmw_libvirt_manager_configuration: vms: computecp0: - target: compute-0 + target: hypervisor-0 amount: 1 disk_file_name: "blank" disksize: 20 @@ -297,7 +308,7 @@ - public - osp_trunk computecp1: - target: compute-1 + target: hypervisor-1 amount: 1 disk_file_name: "blank" disksize: 20 diff --git a/roles/libvirt_manager/tasks/deploy_layout.yml b/roles/libvirt_manager/tasks/deploy_layout.yml index f51f586135..eb9e1af0c8 100644 --- a/roles/libvirt_manager/tasks/deploy_layout.yml +++ b/roles/libvirt_manager/tasks/deploy_layout.yml @@ -84,22 +84,32 @@ loop_control: label: "{{ item.key }}" -- name: Create temporary ssh keypair - community.crypto.openssh_keypair: - path: "{{ ansible_user_dir }}/.ssh/cifmw_reproducer_key" - type: "{{ cifmw_libvirt_manager_reproducer_key_type }}" - size: "{{ cifmw_libvirt_manager_reproducer_key_size }}" - regenerate: full_idempotence +- name: Manage SSH key + vars: + _sshkey: "{{ ansible_user_dir }}/.ssh/cifmw_reproducer_key" + block: + - name: Get ssh key state + register: _keystat + ansible.builtin.stat: + path: "{{ _sshkey }}" + + - name: Create temporary ssh keypair + when: + - not _keystat.stat.exists + community.crypto.openssh_keypair: + path: "{{ _sshkey }}" + type: "{{ cifmw_libvirt_manager_reproducer_key_type }}" + size: "{{ cifmw_libvirt_manager_reproducer_key_size }}" -- name: Slurp public key for later use - register: pub_ssh_key - ansible.builtin.slurp: - path: "{{ ansible_user_dir }}/.ssh/cifmw_reproducer_key.pub" + - name: Slurp public key for later use + register: pub_ssh_key + ansible.builtin.slurp: + path: "{{ _sshkey }}.pub" -- name: Slurp private key for later use - register: priv_ssh_key - ansible.builtin.slurp: - path: "{{ ansible_user_dir }}/.ssh/cifmw_reproducer_key" + - name: Slurp private key for later use + register: priv_ssh_key + ansible.builtin.slurp: + path: "{{ _sshkey }}" - name: Inject cifmw_reproducer_key.pub in hypervisor authorized_keys ansible.posix.authorized_key: @@ -222,6 +232,52 @@ dest: "{{ cifmw_libvirt_manager_basedir }}/artifacts/interfaces-info.yml" content: "{{ cifmw_libvirt_manager_mac_map | to_nice_yaml }}" +- name: Extract VM UUIDs from libvirt + block: + - name: Get all XMLs + register: _all_xmls + community.libvirt.virt: + command: get_xml + name: "{{ item }}" + loop: "{{ _vms.list_vms }}" + + - name: Extract UUIDs from all XMLs + register: _extracted_uuids + community.general.xml: + xmlstring: "{{ vm.get_xml }}" + xpath: "/domain/uuid" + content: text + loop: "{{ _all_xmls.results }}" + loop_control: + label: "{{ vm.item }}" + loop_var: vm + + - name: Build UUIDs fact + vars: + vm_uuid: "{{ xml.matches | first }}" + ansible.builtin.set_fact: + cifmw_libvirt_manager_uuids: >- + {{ + cifmw_libvirt_manager_uuids | default({}) | + combine({xml.vm.item: vm_uuid.uuid}) + }} + loop: "{{ _extracted_uuids.results }}" + loop_control: + label: "{{ xml.vm.item }}" + loop_var: xml + + - name: Dump UUIDs + when: + - cifmw_libvirt_manager_uuids is defined + - cifmw_libvirt_manager_uuids | length > 0 + vars: + _content: + libvirt_uuid: "{{ cifmw_libvirt_manager_uuids }}" + ansible.builtin.copy: + dest: "{{ cifmw_libvirt_manager_basedir }}/artifacts/libvirt-uuids.yml" + content: "{{ _content | to_nice_yaml }}" + mode: "0644" + - name: Refresh and dump vbmc hosts when: - _vbmc_host is defined @@ -232,21 +288,34 @@ name: virtualbmc tasks_from: list_hosts.yml - - name: Dump vbmc known hosts + - name: Update vbmc related fact vars: _auth: username: "{{ cifmw_virtualbmc_ipmi_user | default('admin') }}" password: "{{ cifmw_virtualbmc_ipmi_password | default('password') }}" - _mapped: >- + _map_auth: >- {{ cifmw_virtualbmc_known_hosts | map('combine', _auth) }} + _map_uuid: >- + {% set ns = namespace(output=[]) -%} + {% for host in _map_auth -%} + {% set _uuid = {'uuid': cifmw_libvirt_manager_uuids[host['Domain name']]} -%} + {% set _host = host | combine(_uuid) -%} + {% set _ = ns.output.append(_host) -%} + {% endfor -%} + {{ ns.output }} + ansible.builtin.set_fact: + cifmw_virtualbmc_known_hosts: "{{ _map_uuid }}" + + - name: Dump vbmc known hosts + vars: content: - cifmw_virtualbmc_known_hosts: "{{ _mapped }}" + cifmw_virtualbmc_known_hosts: "{{ cifmw_virtualbmc_known_hosts }}" ansible.builtin.copy: dest: >- - {{ cifmw_libvirt_manager_basedir }}/artifacts/virtualbmc-nodes.yml + {{ cifmw_libvirt_manager_basedir }}/artifacts/virtual-nodes.yml content: "{{ content | to_nice_yaml }}" - name: Ensure we get proper access to CRC diff --git a/roles/reproducer/tasks/configure_controller.yml b/roles/reproducer/tasks/configure_controller.yml index d53224fee7..034e4af6d8 100644 --- a/roles/reproducer/tasks/configure_controller.yml +++ b/roles/reproducer/tasks/configure_controller.yml @@ -106,6 +106,54 @@ dest: "{{ _ctl_reproducer_basedir }}/parameters/interfaces-info.yml" content: "{{ cifmw_libvirt_manager_mac_map | to_nice_yaml }}" + # Here, we update the existing cifmw_virtualbmc_known_hosts fact + # to inject networking information such as provisioning MAC (if any), + # and fixed Boot mode + - name: Generate IPMI information + block: + - name: Convert VBMC list into a dict for better usage + vars: + keys: "{{ item.keys() | difference(['Domain name']) }}" + vals: "{{ keys | map('extract', item) | list }}" + value: "{{ dict(keys | map('lower') | zip(vals)) }}" + _host: "{{ item['Domain name'] | regex_replace('^cifmw-', '') }}" + _nics: >- + {{ + cifmw_libvirt_manager_mac_map[_host] + }} + _uefi: >- + {% set _type = _host | regex_replace('-[0-9]+$', '') -%} + {{ _layout.vms[_type].uefi | default(false) | bool }} + _boot_mode: "{{ _uefi | ternary('UEFI', 'legacy') }}" + ## TODO: add sushy driver address once we get sushy in + ## TODO: create new parameter to allow chosing which connection + # to expose in the generated file + _connections: + ipmi: "ipmi://{{ value.address }}:{{ value.port }}" + ansible.builtin.set_fact: + _ipmi_dict: >- + {{ + _ipmi_dict | default({}) | + combine({_host: value}, recursive=true) | + combine({_host: { + 'boot_mode': _boot_mode, + 'nics': _nics, + 'connection': _connections['ipmi'] + } + }, recursive=true) + }} + cacheable: false + loop: "{{ cifmw_virtualbmc_known_hosts }}" + + - name: Output IPMI data in a file + vars: + _content: + baremetal_nodes: "{{ _ipmi_dict }}" + ansible.builtin.copy: + dest: "{{ _ctl_reproducer_basedir }}/parameters/baremetal-info.yml" + content: "{{ _content | to_nice_yaml }}" + mode: "0644" + - name: Inject other Hypervisor SSH keys when: - hostvars[host]['priv_ssh_key'] is defined