diff --git a/.github/workflows/molecule.yaml b/.github/workflows/molecule.yaml index 0a2e90375..8a30c1191 100644 --- a/.github/workflows/molecule.yaml +++ b/.github/workflows/molecule.yaml @@ -29,7 +29,6 @@ jobs: - edpm_derive_pci_device_spec - edpm_download_cache - edpm_growvols - - edpm_multipathd - edpm_network_config - edpm_neutron_dhcp - edpm_neutron_metadata diff --git a/roles/edpm_download_cache/tasks/container_images.yml b/roles/edpm_download_cache/tasks/container_images.yml index 7cf0a2a3e..3af6c2fcf 100644 --- a/roles/edpm_download_cache/tasks/container_images.yml +++ b/roles/edpm_download_cache/tasks/container_images.yml @@ -52,15 +52,6 @@ - edpm_neutron_ovn - download_cache -- name: Download images for edpm_multipathd role - when: '"nova" in edpm_download_cache_running_services' - ansible.builtin.include_role: - name: osp.edpm.edpm_multipathd - tasks_from: download_cache.yml - tags: - - edpm_multipathd - - download_cache - - name: Download images for edpm_nova role when: '"nova" in edpm_download_cache_running_services' ansible.builtin.include_role: diff --git a/roles/edpm_download_cache/tasks/packages.yml b/roles/edpm_download_cache/tasks/packages.yml index ca1e69c4c..fc0564924 100644 --- a/roles/edpm_download_cache/tasks/packages.yml +++ b/roles/edpm_download_cache/tasks/packages.yml @@ -76,3 +76,13 @@ tags: - edpm_iscsid - download_cache + +- name: Download packages for edpm_multipathd role + # multipathd is part of the "nova" EDPM service + when: '"nova" in edpm_download_cache_running_services' + ansible.builtin.include_role: + name: osp.edpm.edpm_multipathd + tasks_from: download_cache.yml + tags: + - edpm_multipathd + - download_cache diff --git a/roles/edpm_multipathd/defaults/main.yml b/roles/edpm_multipathd/defaults/main.yml index 73d4705eb..641b5363f 100644 --- a/roles/edpm_multipathd/defaults/main.yml +++ b/roles/edpm_multipathd/defaults/main.yml @@ -18,24 +18,13 @@ edpm_container_cli: "{{ container_cli | default('podman') }}" # All variables intended for modification should be placed in this file. -edpm_multipathd_image: "quay.io/podified-antelope-centos9/openstack-multipathd:current-podified" -edpm_multipathd_image_download_delay: "{{ edpm_download_delay | default(60) }}" -edpm_multipathd_image_download_retries: "{{ edpm_download_retries | default(5) }}" - -edpm_multipathd_command: "/usr/sbin/multipathd -d" -edpm_multipathd_volumes: - - /var/lib/kolla/config_files/multipathd.json:/var/lib/kolla/config_files/config.json:ro - - /dev:/dev - - /run/udev:/run/udev - - /sys:/sys - - /lib/modules:/lib/modules:ro - - /etc/iscsi:/etc/iscsi:ro - - /var/lib/iscsi:/var/lib/iscsi - - /etc/multipath:/etc/multipath:z - - /etc/multipath.conf:/etc/multipath.conf:ro +edpm_multipathd_download_delay: "{{ edpm_download_delay | default(60) }}" +edpm_multipathd_download_retries: "{{ edpm_download_retries | default(5) }}" + +edpm_multipathd_packages: + - device-mapper-multipath # These should not need to be overridden except in unique situations. -edpm_multipathd_restart_sentinel: /etc/multipath/.multipath_restart_required edpm_multipathd_custom_config_dir: /runner/multipath edpm_multipathd_enable: true @@ -47,5 +36,7 @@ edpm_multipathd_user_friendly_names: false # This may be overridden to deploy a custom multipath.conf file. edpm_multipathd_custom_config_file: '' -# If container health check should be enabled -edpm_multipathd_healthcheck: true + +edpm_multipathd_legacy_services: + - tripleo_multipathd.service + - edpm_multipathd.service diff --git a/roles/edpm_multipathd/files/healthchecks/multipathd/healthcheck b/roles/edpm_multipathd/files/healthchecks/multipathd/healthcheck deleted file mode 100644 index 3d5530371..000000000 --- a/roles/edpm_multipathd/files/healthchecks/multipathd/healthcheck +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/bash -# -*- coding: utf-8 -*- -# Copyright 2024 Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -multipathd show daemon diff --git a/roles/edpm_multipathd/handlers/main.yml b/roles/edpm_multipathd/handlers/main.yml new file mode 100644 index 000000000..c47800eb7 --- /dev/null +++ b/roles/edpm_multipathd/handlers/main.yml @@ -0,0 +1,4 @@ +--- + +- name: Restart the multipath subsystem + ansible.builtin.include_tasks: restart_multipath.yml diff --git a/roles/edpm_multipathd/meta/argument_specs.yml b/roles/edpm_multipathd/meta/argument_specs.yml index 4d9af8cb4..5fa12ca5d 100644 --- a/roles/edpm_multipathd/meta/argument_specs.yml +++ b/roles/edpm_multipathd/meta/argument_specs.yml @@ -4,10 +4,6 @@ argument_specs: main: short_description: The main entry point for the edpm_multipathd role. options: - edpm_multipathd_image: - default: 'quay.io/podified-antelope-centos9/openstack-multipathd:current-podified' - description: 'URL of the multipathd image.' - type: str edpm_multipathd_image_download_delay: type: int default: 5 @@ -16,29 +12,11 @@ argument_specs: type: int default: 5 description: The number of retries for failed download tasks - edpm_multipathd_command: - default: '/usr/sbin/multipathd -d' - description: 'The command to start the multipathd daemon.' - type: str - edpm_multipathd_volumes: - default: - - /var/lib/kolla/config_files/multipathd.json:/var/lib/kolla/config_files/config.json:ro - - /dev:/dev - - /run/udev:/run/udev - - /sys:/sys - - /lib/modules:/lib/modules:ro - - /etc/iscsi:/etc/iscsi:ro - - /var/lib/iscsi:/var/lib/iscsi:z - - /etc/multipath:/etc/multipath:z - - /etc/multipath.conf:/etc/multipath.conf:ro - description: List of volumes in a mount point format. + edpm_multipathd_packages: type: list - edpm_multipathd_restart_sentinel: - default: '/etc/multipath/.multipath_restart_required' - description: >- - Path to the sentinel file that is used to signal when the multipath - daemon needs to be restarted. - type: str + description: The list of packages to install for multipathd. + default: + - device-mapper-multipath edpm_multipathd_custom_config_dir: default: '/runner/multipath' description: >- @@ -81,8 +59,11 @@ argument_specs: overcloud nodes will be updated match, even if the setting is enabled in the local custom file. type: str - edpm_multipathd_healthcheck: - type: bool - default: true + edpm_multipathd_legacy_services: + type: list description: | - Enable container health check injection + The list of legacy containerized services associated with adoption + and brownfield deployment scenarios. + default: + - tripleo_multipathd.service + - edpm_multipathd.service diff --git a/roles/edpm_multipathd/molecule/custom_config/collections.yml b/roles/edpm_multipathd/molecule/custom_config/collections.yml new file mode 120000 index 000000000..9e29b5f21 --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/collections.yml @@ -0,0 +1 @@ +../default/collections.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/custom_config/molecule.yml b/roles/edpm_multipathd/molecule/custom_config/molecule.yml deleted file mode 100644 index 9f470bc9b..000000000 --- a/roles/edpm_multipathd/molecule/custom_config/molecule.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -dependency: - name: galaxy - options: - role-file: collections.yml -driver: - name: podman -platforms: -- command: /sbin/init - dockerfile: ../../../../molecule/common/Containerfile.j2 - image: ${EDPM_ANSIBLE_MOLECULE_IMAGE:-"ubi9/ubi-init"} - name: instance - privileged: true - registry: - url: ${EDPM_ANSIBLE_MOLECULE_REGISTRY:-"registry.access.redhat.com"} - volumes: - - /run/udev:/run/udev -provisioner: - name: ansible - log: true -scenario: - test_sequence: - - destroy - - create - - prepare - - converge - - check - - verify - - destroy -verifier: - name: ansible diff --git a/roles/edpm_multipathd/molecule/custom_config/molecule.yml b/roles/edpm_multipathd/molecule/custom_config/molecule.yml new file mode 120000 index 000000000..19ed2bfe0 --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/molecule.yml @@ -0,0 +1 @@ +../default/molecule.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/custom_config/prepare.yml b/roles/edpm_multipathd/molecule/custom_config/prepare.yml deleted file mode 100644 index 0d5f140c7..000000000 --- a/roles/edpm_multipathd/molecule/custom_config/prepare.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -# Copyright 2023 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -- name: Run the default prepare playbook - import_playbook: ../default/prepare.yml diff --git a/roles/edpm_multipathd/molecule/custom_config/prepare.yml b/roles/edpm_multipathd/molecule/custom_config/prepare.yml new file mode 120000 index 000000000..1c017d9a2 --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/prepare.yml @@ -0,0 +1 @@ +../default/prepare.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/default/collections.yml b/roles/edpm_multipathd/molecule/default/collections.yml new file mode 100644 index 000000000..424ad60b8 --- /dev/null +++ b/roles/edpm_multipathd/molecule/default/collections.yml @@ -0,0 +1,3 @@ +--- +collections: +- name: community.general diff --git a/roles/edpm_multipathd/molecule/default/converge.yml b/roles/edpm_multipathd/molecule/default/converge.yml index 5e8db4243..e871ff9f8 100644 --- a/roles/edpm_multipathd/molecule/default/converge.yml +++ b/roles/edpm_multipathd/molecule/default/converge.yml @@ -18,20 +18,6 @@ hosts: all gather_facts: false vars: - # We cannot use the real multipathd command because the daemon needs - # privileges that are not available in a rootless molecule container, - # even with "privileged: true". - edpm_multipathd_command: "/usr/bin/sleep 3600" - tasks: - - name: Install multipathd - ansible.builtin.import_role: - name: osp.edpm.edpm_multipathd - tasks_from: install.yml - - name: Configure multipathd - ansible.builtin.import_role: - name: osp.edpm.edpm_multipathd - tasks_from: configure.yml - - name: Run multipathd - ansible.builtin.import_role: - name: osp.edpm.edpm_multipathd - tasks_from: run.yml + edpm_container_cli: "true" + roles: + - role: osp.edpm.edpm_multipathd diff --git a/roles/edpm_multipathd/molecule/default/molecule.yml b/roles/edpm_multipathd/molecule/default/molecule.yml index 9f470bc9b..1b975493b 100644 --- a/roles/edpm_multipathd/molecule/default/molecule.yml +++ b/roles/edpm_multipathd/molecule/default/molecule.yml @@ -1,20 +1,14 @@ --- dependency: name: galaxy - options: - role-file: collections.yml driver: - name: podman + name: delegated + options: + managed: false + ansible_connection_options: + ansible_connection: local platforms: -- command: /sbin/init - dockerfile: ../../../../molecule/common/Containerfile.j2 - image: ${EDPM_ANSIBLE_MOLECULE_IMAGE:-"ubi9/ubi-init"} - name: instance - privileged: true - registry: - url: ${EDPM_ANSIBLE_MOLECULE_REGISTRY:-"registry.access.redhat.com"} - volumes: - - /run/udev:/run/udev + - name: edpm_multipathd provisioner: name: ansible log: true diff --git a/roles/edpm_multipathd/molecule/default/prepare.yml b/roles/edpm_multipathd/molecule/default/prepare.yml index bc6f66b99..11b99eae7 100644 --- a/roles/edpm_multipathd/molecule/default/prepare.yml +++ b/roles/edpm_multipathd/molecule/default/prepare.yml @@ -14,25 +14,56 @@ # License for the specific language governing permissions and limitations # under the License. -- name: Prepare test deps +- name: Prepare hosts: all gather_facts: false roles: - role: ../../../../molecule/common/test_deps - test_deps_extra_packages: - - iproute - - iscsi-initiator-utils - - podman - test_deps_setup_edpm: true - test_deps_setup_stream: true -- name: Prepare - hosts: all - roles: - role: osp.edpm.env_data + +- name: Setup DUT + hosts: all + gather_facts: false + vars: + test_helper_dir: "../../../../molecule/test-helpers" tasks: - - name: set /etc/localtime + - name: Load role vars + ansible.builtin.include_vars: ../../defaults/main.yml + + - name: Create systemd unit file for mocked legacy containerized services + become: true + ansible.builtin.copy: + dest: "/etc/systemd/system/{{ legacy_service }}" + content: | + [Unit] + Description=Mock containerized multipathd service + + [Service] + ExecStart=sleep 9999 + + [Install] + WantedBy=multi-user.target + mode: '0644' + loop: "{{ edpm_multipathd_legacy_services }}" + loop_control: + loop_var: legacy_service + + - name: Enable and start mocked legacy services become: true - ansible.builtin.file: - path: /etc/localtime - src: /usr/share/zoneinfo/UTC - state: link + ansible.builtin.systemd_service: + name: "{{ legacy_service }}" + enabled: true + state: started + daemon_reload: true + loop: "{{ edpm_multipathd_legacy_services }}" + loop_control: + loop_var: legacy_service + + - name: Verify mocked legacy services are running + ansible.builtin.include_tasks: "{{test_helper_dir}}/verify_systemd_unit.yaml" + vars: + item: + name: "{{ legacy_service }}" + loop: "{{ edpm_multipathd_legacy_services }}" + loop_control: + loop_var: legacy_service diff --git a/roles/edpm_multipathd/molecule/default/verify.yml b/roles/edpm_multipathd/molecule/default/verify.yml index 60cfd353e..0128510cf 100644 --- a/roles/edpm_multipathd/molecule/default/verify.yml +++ b/roles/edpm_multipathd/molecule/default/verify.yml @@ -17,8 +17,14 @@ - name: Verify hosts: all gather_facts: false + vars: + test_helper_dir: "../../../../molecule/test-helpers" tasks: + - name: Load role vars + ansible.builtin.include_vars: ../../defaults/main.yml + - name: Check /etc/multipath.conf settings + become: true lineinfile: name: /etc/multipath.conf regexp: "^\\s+{{ item.var }}" @@ -39,3 +45,17 @@ - multipath_result.changed failed_when: - true + + - name: Ensure multipathd service is enabled and running + ansible.builtin.include_tasks: "{{test_helper_dir}}/verify_systemd_unit.yaml" + loop: + - { "name": "multipathd.service", "osp_service": false } + + - name: Ensure legacy services are disabled and not running + become: true + ansible.builtin.shell: | + ! systemctl is-enabled "{{ legacy_service }}" && ! systemctl is-active "{{ legacy_service }}" + changed_when: false + loop: "{{ edpm_multipathd_legacy_services }}" + loop_control: + loop_var: legacy_service diff --git a/roles/edpm_multipathd/molecule/preexisting_config/collections.yml b/roles/edpm_multipathd/molecule/preexisting_config/collections.yml new file mode 120000 index 000000000..9e29b5f21 --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/collections.yml @@ -0,0 +1 @@ +../default/collections.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/preexisting_config/converge.yml b/roles/edpm_multipathd/molecule/preexisting_config/converge.yml deleted file mode 100644 index e072caf09..000000000 --- a/roles/edpm_multipathd/molecule/preexisting_config/converge.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -# Copyright 2023 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -- name: Run the default converge playbook - import_playbook: ../default/converge.yml diff --git a/roles/edpm_multipathd/molecule/preexisting_config/converge.yml b/roles/edpm_multipathd/molecule/preexisting_config/converge.yml new file mode 120000 index 000000000..73cb8dadb --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/converge.yml @@ -0,0 +1 @@ +../default/converge.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml b/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml deleted file mode 100644 index 9f470bc9b..000000000 --- a/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -dependency: - name: galaxy - options: - role-file: collections.yml -driver: - name: podman -platforms: -- command: /sbin/init - dockerfile: ../../../../molecule/common/Containerfile.j2 - image: ${EDPM_ANSIBLE_MOLECULE_IMAGE:-"ubi9/ubi-init"} - name: instance - privileged: true - registry: - url: ${EDPM_ANSIBLE_MOLECULE_REGISTRY:-"registry.access.redhat.com"} - volumes: - - /run/udev:/run/udev -provisioner: - name: ansible - log: true -scenario: - test_sequence: - - destroy - - create - - prepare - - converge - - check - - verify - - destroy -verifier: - name: ansible diff --git a/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml b/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml new file mode 120000 index 000000000..19ed2bfe0 --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml @@ -0,0 +1 @@ +../default/molecule.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/vagrant/collections.yml b/roles/edpm_multipathd/molecule/vagrant/collections.yml new file mode 120000 index 000000000..9e29b5f21 --- /dev/null +++ b/roles/edpm_multipathd/molecule/vagrant/collections.yml @@ -0,0 +1 @@ +../default/collections.yml \ No newline at end of file diff --git a/roles/edpm_multipathd/molecule/vagrant/molecule.yml b/roles/edpm_multipathd/molecule/vagrant/molecule.yml new file mode 100644 index 000000000..3e1b4a5d4 --- /dev/null +++ b/roles/edpm_multipathd/molecule/vagrant/molecule.yml @@ -0,0 +1,44 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: libvirt + provision: no + parallel: true + default_box: 'generic/centos9s' +platforms: +- name: edpm-multipathd + memory: 1024 + cpus: 2 + provider_options: + cpu_mode: 'host-passthrough' + nested: true + machine_type: 'q35' + groups: + - compute +provisioner: + name: ansible + playbooks: + # Choose your scenario + prepare: ../default/prepare.yml + converge: ../default/converge.yml + verify: ../default/verify.yml + # prepare: ../custom_config/prepare.yml + # converge: ../custom_config/converge.yml + # verify: ../custom_config/verify.yml + # prepare: ../preexisting_config/prepare.yml + # converge: ../preexisting_config/converge.yml + # verify: ../preexisting_config/verify.yml +verifier: + name: ansible +scenario: + # The vagrant scenario is for development/debug. + # Disable all tests so they don't run in CI + test_sequence: [] + # - destroy + # - create + # - prepare + # - converge + # - verify diff --git a/roles/edpm_multipathd/tasks/cleanup_containers.yml b/roles/edpm_multipathd/tasks/cleanup_containers.yml new file mode 100644 index 000000000..c0b630daa --- /dev/null +++ b/roles/edpm_multipathd/tasks/cleanup_containers.yml @@ -0,0 +1,40 @@ +--- +# Copyright 2025 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Gather services facts + ansible.builtin.service_facts: + +- name: Identify legacy multipathd containerized services + ansible.builtin.set_fact: + legacy_multipathd_services: "{{ edpm_multipathd_legacy_services | intersect(ansible_facts.services.keys()) }}" + +- name: Clean up legacy multipathd containerized services + become: true + when: legacy_multipathd_services | default([]) | length > 0 + block: + - name: Stop and disable legacy multipathd containerized services + # The edpm_tripleo_cleanup role works for stopping and disabling the + # legacy tripleo_multipathd.service (adoption scenario) or the + # edpm_multipathd.service (update scenario). + ansible.builtin.include_role: + role: osp.edpm.edpm_tripleo_cleanup + vars: + edpm_old_tripleo_services: "{{ legacy_multipathd_services }}" + + - name: Delete containerized multipathd healthcheck script + ansible.builtin.file: + path: /var/lib/openstack/healthchecks/multipathd + state: absent diff --git a/roles/edpm_multipathd/tasks/configure.yml b/roles/edpm_multipathd/tasks/configure.yml index 1b5ebc20d..33a07eb9e 100644 --- a/roles/edpm_multipathd/tasks/configure.yml +++ b/roles/edpm_multipathd/tasks/configure.yml @@ -35,18 +35,13 @@ when: - edpm_multipathd_custom_config_file|length == 0 block: - - name: Check for existing /etc/multipath.conf - ansible.builtin.stat: - path: /etc/multipath.conf - register: result - check_mode: false - name: Create /etc/multipath.conf if file is missing ansible.builtin.copy: src: "{{ role_path }}/files/multipath.conf" dest: /etc/multipath.conf mode: "0644" when: - - not result.stat.exists or result.stat.size == 0 + - not stat_before.stat.exists or stat_before.stat.size == 0 - name: Check if a blacklist section is present ansible.builtin.shell: grep -q '^blacklist\s*{' /etc/multipath.conf @@ -68,7 +63,6 @@ regexp: '^(blacklist {)' replace: '\1\n}' - - name: Remove global blacklist if multipathd is enabled ansible.builtin.replace: path: /etc/multipath.conf @@ -107,10 +101,11 @@ register: stat_after check_mode: false - - name: Record multipath containers require a restart + - name: Notify the multipath configuration changed when: - not stat_before.stat.exists or stat_after.stat.checksum != stat_before.stat.checksum - ansible.builtin.file: - path: "{{ edpm_multipathd_restart_sentinel }}" - state: touch - mode: "0644" + # Use 'true' as a no-op command for what's essentially a conditional notify + ansible.builtin.command: /usr/bin/true + changed_when: true + notify: + - Restart the multipath subsystem diff --git a/roles/edpm_multipathd/tasks/download_cache.yml b/roles/edpm_multipathd/tasks/download_cache.yml index 8ca6ad240..d2a6f3edb 100644 --- a/roles/edpm_multipathd/tasks/download_cache.yml +++ b/roles/edpm_multipathd/tasks/download_cache.yml @@ -1,11 +1,11 @@ --- -- name: Download needed container - containers.podman.podman_image: - name: "{{ edpm_multipathd_image }}" - auth_file: "{{ edpm_download_cache_podman_auth_file }}" +- name: Download multipathd packages + ansible.builtin.dnf: + name: "{{ edpm_multipathd_packages }}" + download_only: true become: true - register: edpm_multipathd_image_download - until: edpm_multipathd_image_download.failed == false - retries: "{{ edpm_multipathd_image_download_retries }}" - delay: "{{ edpm_multipathd_image_download_delay }}" + register: edpm_multipathd_packages_install + until: edpm_multipathd_packages_install is succeeded + retries: "{{ edpm_multipathd_download_retries }}" + delay: "{{ edpm_multipathd_download_delay }}" diff --git a/roles/edpm_multipathd/tasks/healthchecks.yml b/roles/edpm_multipathd/tasks/healthchecks.yml deleted file mode 100644 index 66b51839b..000000000 --- a/roles/edpm_multipathd/tasks/healthchecks.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- - -- name: Gather user fact - ansible.builtin.setup: - gather_subset: - - "!all" - - "!min" - - "user" - when: - - ansible_user is undefined - -- name: Ensure base directory for health checks exists - become: true - ansible.builtin.file: - path: /var/lib/openstack/healthchecks - state: directory - setype: container_file_t - owner: "{{ ansible_user | default(ansible_user_id) }}" - group: "{{ ansible_user | default(ansible_user_id) }}" - mode: '0755' - -- name: Deploy multipathd health check script - become: true - ansible.builtin.copy: - src: healthchecks/multipathd/ - dest: /var/lib/openstack/healthchecks/multipathd - setype: container_file_t - owner: "{{ ansible_user | default(ansible_user_id) }}" - group: "{{ ansible_user | default(ansible_user_id) }}" - mode: '0700' diff --git a/roles/edpm_multipathd/tasks/install.yml b/roles/edpm_multipathd/tasks/install.yml index 6ccca3698..99e9345cc 100644 --- a/roles/edpm_multipathd/tasks/install.yml +++ b/roles/edpm_multipathd/tasks/install.yml @@ -14,37 +14,33 @@ # License for the specific language governing permissions and limitations # under the License. -- name: Gather user fact +- name: Gather ansible_local facts ansible.builtin.setup: gather_subset: - "!all" - "!min" - - "user" - - "user_id" + - "local" when: - - ansible_user is undefined + - ansible_local is not defined + +- name: Clean up legacy containerized multipathd + ansible.builtin.include_tasks: cleanup_containers.yml - name: Run multipathd install tasks with root privileges become: true block: - - name: Gather services facts - ansible.builtin.service_facts: - - - name: Stop multipathd service on the host - ansible.builtin.systemd: - name: "{{ item }}" - state: stopped - enabled: false - when: - - ansible_facts.services["multipathd"] is defined - - ansible_facts.services["multipathd"]["status"] != "not-found" - - ansible_facts.services["multipathd"]["status"] == "enabled" - failed_when: false - loop: - - multipathd.service - - multipathd.socket - loop_control: - index_var: multipath_service_index + - name: Install multipathd packages + tags: + - install + - edpm_multipathd + ansible.builtin.dnf: + name: "{{ edpm_multipathd_packages }}" + state: present + register: edpm_multipathd_packages_install + until: edpm_multipathd_packages_install is succeeded + retries: "{{ edpm_multipathd_download_retries }}" + delay: "{{ edpm_multipathd_download_delay }}" + when: ansible_local.bootc is not defined or not ansible_local.bootc - name: Load dm-multipath when: @@ -55,9 +51,11 @@ modules: - name: dm-multipath - - name: Prepare /etc/multipath directory - ansible.builtin.file: - path: /etc/multipath - state: directory - mode: "0755" - setype: container_file_t + - name: Check SELinux context of /etc/multipath directory + ansible.builtin.command: "/usr/sbin/restorecon -nvr /etc/multipath" + changed_when: false + register: iscsi_selinux_status + + - name: Restore SELinux context of /etc/multipath directory + ansible.builtin.command: "/usr/sbin/restorecon -rF /etc/multipath" + changed_when: true diff --git a/roles/edpm_multipathd/tasks/restart_multipath.yml b/roles/edpm_multipathd/tasks/restart_multipath.yml new file mode 100644 index 000000000..c0ada2be7 --- /dev/null +++ b/roles/edpm_multipathd/tasks/restart_multipath.yml @@ -0,0 +1,36 @@ +--- +# Copyright 2025 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Run multipath restart tasks with root privileges + become: true + block: + - name: Restart the multipathd service + ansible.builtin.systemd_service: + name: multipathd + state: restarted + + - name: Identify containers using /etc/multipath.conf + ansible.builtin.command: "{{ edpm_container_cli }} ps --filter volume=/etc/multipath.conf --format {{ '{{' }}.Names{{ '}}' }}" + register: multipath_conf_containers + changed_when: false + + - name: "Restart container to refresh its /etc/multipath.conf" + ansible.builtin.systemd: + name: "edpm_{{ multipath_container }}" + state: restarted + loop: "{{ multipath_conf_containers.stdout_lines | default([]) }}" + loop_control: + loop_var: multipath_container diff --git a/roles/edpm_multipathd/tasks/run.yml b/roles/edpm_multipathd/tasks/run.yml index 4d7e7214f..8485e4a76 100644 --- a/roles/edpm_multipathd/tasks/run.yml +++ b/roles/edpm_multipathd/tasks/run.yml @@ -14,59 +14,16 @@ # License for the specific language governing permissions and limitations # under the License. -- name: Ensure /var/local/libexec/edpm-start-podman-container exists - ansible.builtin.import_role: - name: edpm_container_manage - tasks_from: shutdown.yml - -- name: Update multipathd health check script - ansible.builtin.include_tasks: - file: healthchecks.yml - -- name: Manage multipathd containers - ansible.builtin.include_role: - name: edpm_container_standalone - vars: - edpm_container_standalone_service: multipathd - edpm_container_standalone_container_defs: - multipathd: "{{ lookup('template', 'multipathd.yaml.j2') | from_yaml }}" - edpm_container_standalone_kolla_config_files: - multipathd: "{{ lookup('template', 'kolla_multipathd.yaml.j2') | from_yaml }}" - register: manage_multipathd_stat - -- name: Check if the multipathd container restart is required - ansible.builtin.stat: - path: "{{ edpm_multipathd_restart_sentinel }}" - register: multipath_restart_stat - -# Existence the edpm_multipathd_restart_sentinel file on the host -# indicates that restart of the multipathd container is needed to refresh -# /etc/multipathd.conf -# sentinel file will exist on an initial deployment, but the restart is -# actually needed only if the service is already running, so we check if -# the manage_multipathd_stat changed. - -- name: Restart containers when the multipath configuration changes - when: - - not manage_multipathd_stat.changed|bool - - multipath_restart_stat.stat.exists|bool +- name: Start the multipathd socket become: true - block: - - name: Identify containers using /etc/multipath.conf - ansible.builtin.command: "{{ edpm_container_cli }} ps --filter volume=/etc/multipath.conf --format {{ '{{' }}.Names{{ '}}' }}" - register: multipath_conf_containers - changed_when: false - - - name: "Restart container to refresh its /etc/multipath.conf" - ansible.builtin.systemd: - name: "edpm_{{ multipath_container }}" - state: restarted - loop: "{{ multipath_conf_containers.stdout_lines | default([]) }}" - loop_control: - loop_var: multipath_container + ansible.builtin.systemd_service: + name: multipathd.socket + state: started + enabled: true -- name: Remove multipathd container restart sentinel file +- name: Start the multipathd service become: true - ansible.builtin.file: - path: "{{ edpm_multipathd_restart_sentinel }}" - state: absent + ansible.builtin.systemd_service: + name: multipathd + state: started + enabled: true diff --git a/roles/edpm_multipathd/tasks/update.yml b/roles/edpm_multipathd/tasks/update.yml new file mode 100644 index 000000000..6e3a53090 --- /dev/null +++ b/roles/edpm_multipathd/tasks/update.yml @@ -0,0 +1,21 @@ +--- +# Copyright 2025 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Ensure multipathd is running on the EDPM host + ansible.builtin.include_tasks: install.yml + +- name: Run multipathd + ansible.builtin.include_tasks: run.yml diff --git a/roles/edpm_multipathd/templates/kolla_multipathd.yaml.j2 b/roles/edpm_multipathd/templates/kolla_multipathd.yaml.j2 deleted file mode 100644 index 23cf3d245..000000000 --- a/roles/edpm_multipathd/templates/kolla_multipathd.yaml.j2 +++ /dev/null @@ -1 +0,0 @@ -command: "{{ edpm_multipathd_command }}" diff --git a/roles/edpm_multipathd/templates/multipathd.yaml.j2 b/roles/edpm_multipathd/templates/multipathd.yaml.j2 deleted file mode 100644 index 13f1f7d36..000000000 --- a/roles/edpm_multipathd/templates/multipathd.yaml.j2 +++ /dev/null @@ -1,13 +0,0 @@ -image: {{ edpm_multipathd_image }} -net: host -privileged: true -restart: always -{% if edpm_multipathd_healthcheck %} -healthcheck: - test: /openstack/healthcheck - mount: /var/lib/openstack/healthchecks/multipathd -{% endif %} -volumes: - {{ edpm_container_standalone_common_volumes | default([]) + edpm_multipathd_volumes }} -environment: - KOLLA_CONFIG_STRATEGY: COPY_ALWAYS diff --git a/roles/edpm_nova/templates/nova_compute.json.j2 b/roles/edpm_nova/templates/nova_compute.json.j2 index 1f5a0536e..ec9e23ea4 100644 --- a/roles/edpm_nova/templates/nova_compute.json.j2 +++ b/roles/edpm_nova/templates/nova_compute.json.j2 @@ -21,7 +21,7 @@ "/run/libvirt:/run/libvirt:shared", "/var/lib/nova:/var/lib/nova:shared", "/var/lib/iscsi:/var/lib/iscsi", - "/etc/multipath:/etc/multipath:z", + "/etc/multipath:/etc/multipath", "/etc/multipath.conf:/etc/multipath.conf:ro", "/etc/iscsi:/etc/iscsi:ro", "/etc/nvme:/etc/nvme", diff --git a/roles/edpm_update/tasks/containers.yml b/roles/edpm_update/tasks/containers.yml index ea4dc0b57..ead316324 100644 --- a/roles/edpm_update/tasks/containers.yml +++ b/roles/edpm_update/tasks/containers.yml @@ -77,10 +77,10 @@ - edpm_update when: '"neutron-ovn" in edpm_update_running_services' -- name: Updates containers for edpm_multipathd role +- name: Updates multipathd service for edpm_multipathd role ansible.builtin.include_role: name: osp.edpm.edpm_multipathd - tasks_from: run.yml + tasks_from: update.yml apply: become: true tags: diff --git a/roles/edpm_update_services/tasks/containers.yml b/roles/edpm_update_services/tasks/containers.yml index dd5ce969e..66c3fbbfb 100644 --- a/roles/edpm_update_services/tasks/containers.yml +++ b/roles/edpm_update_services/tasks/containers.yml @@ -77,10 +77,10 @@ - edpm_update_services when: '"neutron-ovn" in edpm_update_services_running_services' -- name: Updates containers for edpm_multipathd role +- name: Updates multipathd service for edpm_multipathd role ansible.builtin.include_role: name: osp.edpm.edpm_multipathd - tasks_from: run.yml + tasks_from: update.yml apply: become: true tags: diff --git a/scripts/test_roles.py b/scripts/test_roles.py index e6a480770..d9ff971e9 100755 --- a/scripts/test_roles.py +++ b/scripts/test_roles.py @@ -13,6 +13,7 @@ "edpm_ovn", "edpm_nova", "edpm_module_load", + "edpm_multipathd", "edpm_podman", "edpm_ceph_client_files", "edpm_frr", diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index 35f73af65..8bc2dfa6b 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -68,6 +68,13 @@ - ^roles/edpm_iscsid/(defaults|files|handlers|library|lookup_plugins|module_utils|molecule|tasks|templates|vars).* vars: TEST_RUN: edpm_iscsid +- job: + name: edpm-ansible-molecule-edpm_multipathd + parent: edpm-ansible-molecule-base + files: + - ^roles/edpm_multipathd/(defaults|files|handlers|library|lookup_plugins|module_utils|molecule|tasks|templates|vars).* + vars: + TEST_RUN: edpm_multipathd - job: name: edpm-ansible-molecule-edpm_ovn_bgp_agent parent: edpm-ansible-molecule-base diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 98eec49d9..e648fcfa6 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -16,6 +16,7 @@ - edpm-ansible-molecule-edpm_nova - edpm-ansible-molecule-edpm_frr - edpm-ansible-molecule-edpm_iscsid + - edpm-ansible-molecule-edpm_multipathd - edpm-ansible-molecule-edpm_ovn_bgp_agent - edpm-ansible-molecule-edpm_ovs - edpm-ansible-molecule-edpm_tripleo_cleanup