diff --git a/playbooks/configure_os.yaml b/playbooks/configure_os.yaml index 83d38190d..25b87be43 100644 --- a/playbooks/configure_os.yaml +++ b/playbooks/configure_os.yaml @@ -57,6 +57,12 @@ tasks_from: configure.yml tags: - edpm_iscsid + - name: Configure edpm_multipathd + import_role: + name: osp.edpm.edpm_multipathd + tasks_from: configure.yml + tags: + - edpm_multipathd - name: Configure nftables import_role: name: osp.edpm.edpm_nftables diff --git a/playbooks/install_os.yaml b/playbooks/install_os.yaml index b006f02f4..760506d95 100644 --- a/playbooks/install_os.yaml +++ b/playbooks/install_os.yaml @@ -34,3 +34,9 @@ tasks_from: install.yml tags: - edpm_iscsid + - name: Install edpm_multipathd + import_role: + name: osp.edpm.edpm_multipathd + tasks_from: install.yml + tags: + - edpm_multipathd diff --git a/playbooks/run_os.yaml b/playbooks/run_os.yaml index f65f75d12..b01a4dbce 100644 --- a/playbooks/run_os.yaml +++ b/playbooks/run_os.yaml @@ -53,3 +53,9 @@ tasks_from: run.yml tags: - edpm_iscsid + - name: Run edpm_multipathd + import_role: + name: osp.edpm.edpm_multipathd + tasks_from: run.yml + tags: + - edpm_multipathd diff --git a/roles/edpm_multipathd/defaults/main.yml b/roles/edpm_multipathd/defaults/main.yml new file mode 100644 index 000000000..6acddf2ee --- /dev/null +++ b/roles/edpm_multipathd/defaults/main.yml @@ -0,0 +1,46 @@ +--- +# 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. + +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_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:z + - /etc/multipath:/etc/multipath:z + - /etc/multipath.conf:/etc/multipath.conf:ro + +# 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 + +# These should not need to be overridden as they are the recommended values. +edpm_multipathd_find_multipaths: true +edpm_multipathd_recheck_wwid: true +edpm_multipathd_skip_kpartx: true +edpm_multipathd_user_friendly_names: false + +# This may be overridden to deploy a custom multipath.conf file. +edpm_multipathd_custom_config_file: '' diff --git a/roles/edpm_multipathd/files/custom_multipath.conf b/roles/edpm_multipathd/files/custom_multipath.conf new file mode 100644 index 000000000..ffc8cbd4f --- /dev/null +++ b/roles/edpm_multipathd/files/custom_multipath.conf @@ -0,0 +1,9 @@ +# This represents a custom configuration file the user wishes to deploy. + +defaults { + user_friendly_names yes + find_multipaths yes + # Use custom_variable as a marker to ensure this custom config file + # gets deployed. + custom_variable custom_value +} diff --git a/roles/edpm_multipathd/files/multipath.conf b/roles/edpm_multipathd/files/multipath.conf new file mode 100644 index 000000000..55ad657da --- /dev/null +++ b/roles/edpm_multipathd/files/multipath.conf @@ -0,0 +1,93 @@ +# This is a basic configuration file with some examples, for device mapper +# multipath. +# +# For a complete list of the default configuration values, run either +# multipath -t +# or +# multipathd show config +# +# For a list of configuration options with descriptions, see the multipath.conf +# man page + +## By default, devices with vendor = "IBM" and product = "S/390.*" are +## blacklisted. To enable mulitpathing on these devies, uncomment the +## following lines. +#blacklist_exceptions { +# device { +# vendor "IBM" +# product "S/390.*" +# } +#} + +## Use user friendly names, instead of using WWIDs as names. +defaults { + user_friendly_names yes + find_multipaths yes +} +## +## Here is an example of how to configure some standard options. +## +# +#defaults { +# udev_dir /dev +# polling_interval 10 +# selector "round-robin 0" +# path_grouping_policy multibus +# prio alua +# path_checker readsector0 +# rr_min_io 100 +# max_fds 8192 +# rr_weight priorities +# failback immediate +# no_path_retry fail +# user_friendly_names yes +#} +## +## The wwid line in the following blacklist section is shown as an example +## of how to blacklist devices by wwid. The 2 devnode lines are the +## compiled in default blacklist. If you want to blacklist entire types +## of devices, such as all scsi devices, you should use a devnode line. +## However, if you want to blacklist specific devices, you should use +## a wwid line. Since there is no guarantee that a specific device will +## not change names on reboot (from /dev/sda to /dev/sdb for example) +## devnode lines are not recommended for blacklisting specific devices. +## +#blacklist { +# wwid 26353900f02796769 +# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" +# devnode "^hd[a-z]" +#} +#multipaths { +# multipath { +# wwid 3600508b4000156d700012000000b0000 +# alias yellow +# path_grouping_policy multibus +# path_checker readsector0 +# path_selector "round-robin 0" +# failback manual +# rr_weight priorities +# no_path_retry 5 +# } +# multipath { +# wwid 1DEC_____321816758474 +# alias red +# } +#} +#devices { +# device { +# vendor "COMPAQ " +# product "HSV110 (C)COMPAQ" +# path_grouping_policy multibus +# path_checker readsector0 +# path_selector "round-robin 0" +# hardware_handler "0" +# failback 15 +# rr_weight priorities +# no_path_retry queue +# } +# device { +# vendor "COMPAQ " +# product "MSA1000 " +# path_grouping_policy multibus +# } +#} diff --git a/roles/edpm_multipathd/meta/argument_specs.yml b/roles/edpm_multipathd/meta/argument_specs.yml new file mode 100644 index 000000000..c7eece1ee --- /dev/null +++ b/roles/edpm_multipathd/meta/argument_specs.yml @@ -0,0 +1,75 @@ +--- +argument_specs: + # ./roles/edpm_multipathd/tasks/main.yml entry point + 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_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. + 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 + edpm_multipathd_custom_config_dir: + default: '/runner/multipath' + description: >- + Directory used by the ansibleee-runner pod to install a custom + multipath.conf file. + type: str + edpm_multipathd_enable: + default: true + description: 'Whether to enable the multipath daemon.' + type: bool + edpm_multipathd_find_multipaths: + default: true + description: >- + Whether to automatically create a multipath device for each path. + type: bool + edpm_multipathd_recheck_wwid: + default: true + description: >- + Whether to recheck the path WWID when a failed path is restored. + type: bool + edpm_multipathd_skip_kpartx: + default: true + description: >- + Whether to skip automatically creating partitions on the device. + type: bool + edpm_multipathd_user_friendly_names: + default: false + description: >- + Whether to enable assigning a user friendly name to each path. + type: bool + edpm_multipathd_custom_config_file: + default: '' + description: >- + Fully qualified path of a local multipath.conf file to be + installed on the overcloud nodes. By default, a minimal + multipath.conf file will be installed. NOTE - Other TripleO + multipath parameters will override any corresponding + value in the local custom config file. For example, if + MultipathdEnableUserFriendlyNames is False, the files on the + overcloud nodes will be updated match, even if the setting is + enabled in the local custom file. + type: str diff --git a/roles/edpm_multipathd/meta/main.yml b/roles/edpm_multipathd/meta/main.yml new file mode 100644 index 000000000..8f0c880e4 --- /dev/null +++ b/roles/edpm_multipathd/meta/main.yml @@ -0,0 +1,42 @@ +--- +# 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. + + +galaxy_info: + namespace: openstack + author: OpenStack + description: EDPM OpenStack Role -- edpm_multipathd + company: Red Hat + license: Apache-2.0 + min_ansible_version: '2.9' + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + platforms: + - name: 'EL' + versions: + - '9' + + galaxy_tags: + - edpm + + +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. +dependencies: [] diff --git a/roles/edpm_multipathd/molecule/custom_config/converge.yml b/roles/edpm_multipathd/molecule/custom_config/converge.yml new file mode 100644 index 000000000..9c8e27fee --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/converge.yml @@ -0,0 +1,22 @@ +--- +# 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 + vars: + edpm_multipathd_custom_config_dir: "." + edpm_multipathd_custom_config_file: custom_multipath.conf diff --git a/roles/edpm_multipathd/molecule/custom_config/molecule.yml b/roles/edpm_multipathd/molecule/custom_config/molecule.yml new file mode 100644 index 000000000..9f470bc9b --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/molecule.yml @@ -0,0 +1,31 @@ +--- +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/prepare.yml b/roles/edpm_multipathd/molecule/custom_config/prepare.yml new file mode 100644 index 000000000..0d5f140c7 --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/prepare.yml @@ -0,0 +1,19 @@ +--- +# 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/verify.yml b/roles/edpm_multipathd/molecule/custom_config/verify.yml new file mode 100644 index 000000000..c7032c625 --- /dev/null +++ b/roles/edpm_multipathd/molecule/custom_config/verify.yml @@ -0,0 +1,27 @@ +--- +# 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 verify playbook + import_playbook: ../default/verify.yml + +- name: Verify (custom) + hosts: all + gather_facts: false + tasks: + - name: Verify the custom setting is present + command: grep 'custom_variable custom_value' /etc/multipath.conf + changed_when: false diff --git a/roles/edpm_multipathd/molecule/default/converge.yml b/roles/edpm_multipathd/molecule/default/converge.yml new file mode 100644 index 000000000..10ad8864e --- /dev/null +++ b/roles/edpm_multipathd/molecule/default/converge.yml @@ -0,0 +1,36 @@ +--- +# 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: Converge + hosts: all + 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 diff --git a/roles/edpm_multipathd/molecule/default/molecule.yml b/roles/edpm_multipathd/molecule/default/molecule.yml new file mode 100644 index 000000000..9f470bc9b --- /dev/null +++ b/roles/edpm_multipathd/molecule/default/molecule.yml @@ -0,0 +1,31 @@ +--- +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/default/prepare.yml b/roles/edpm_multipathd/molecule/default/prepare.yml new file mode 100644 index 000000000..a3758af3d --- /dev/null +++ b/roles/edpm_multipathd/molecule/default/prepare.yml @@ -0,0 +1,26 @@ +--- +# 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: Prepare + hosts: all + roles: + - role: test_deps + test_deps_extra_packages: + - iproute + - iscsi-initiator-utils + - podman + - role: env_data diff --git a/roles/edpm_multipathd/molecule/default/verify.yml b/roles/edpm_multipathd/molecule/default/verify.yml new file mode 100644 index 000000000..60cfd353e --- /dev/null +++ b/roles/edpm_multipathd/molecule/default/verify.yml @@ -0,0 +1,41 @@ +--- +# 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: Verify + hosts: all + gather_facts: false + tasks: + - name: Check /etc/multipath.conf settings + lineinfile: + name: /etc/multipath.conf + regexp: "^\\s+{{ item.var }}" + line: " {{ item.var }} {{ item.value }}" + loop: + - {var: find_multipaths, value: 'yes'} + - {var: recheck_wwid, value: 'yes'} + - {var: skip_kpartx, value: 'yes'} + - {var: user_friendly_names, value: 'no'} + loop_control: + index_var: multipath_var_index + register: multipath_result + + - name: Fail if /etc/multipath.conf settings are not correct + debug: + msg: "/etc/multipath.conf settings are not correct." + when: + - multipath_result.changed + failed_when: + - true diff --git a/roles/edpm_multipathd/molecule/preexisting_config/converge.yml b/roles/edpm_multipathd/molecule/preexisting_config/converge.yml new file mode 100644 index 000000000..e072caf09 --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/converge.yml @@ -0,0 +1,19 @@ +--- +# 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/molecule.yml b/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml new file mode 100644 index 000000000..9f470bc9b --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/molecule.yml @@ -0,0 +1,31 @@ +--- +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/prepare.yml b/roles/edpm_multipathd/molecule/preexisting_config/prepare.yml new file mode 100644 index 000000000..af8c01f6f --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/prepare.yml @@ -0,0 +1,35 @@ +--- +# 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: Prepare + hosts: all + become: true + + pre_tasks: + - name: Precreate /etc/multipath.conf + copy: + src: ../../files/multipath.conf + dest: /etc/multipath.conf + + - name: Add a preexisting setting + lineinfile: + path: /etc/multipath.conf + insertafter: '^defaults' + line: ' preexisting_variable preexisting_value' + +- name: Run the default prepare playbook + import_playbook: ../default/prepare.yml diff --git a/roles/edpm_multipathd/molecule/preexisting_config/verify.yml b/roles/edpm_multipathd/molecule/preexisting_config/verify.yml new file mode 100644 index 000000000..4d4c672a9 --- /dev/null +++ b/roles/edpm_multipathd/molecule/preexisting_config/verify.yml @@ -0,0 +1,27 @@ +--- +# 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 verify playbook + import_playbook: ../default/verify.yml + +- name: Verify (preexisting) + hosts: all + gather_facts: false + tasks: + - name: Verify the preexisting setting is present + command: grep 'preexisting_variable preexisting_value' /etc/multipath.conf + changed_when: false diff --git a/roles/edpm_multipathd/tasks/configure.yml b/roles/edpm_multipathd/tasks/configure.yml new file mode 100644 index 000000000..f26c5a310 --- /dev/null +++ b/roles/edpm_multipathd/tasks/configure.yml @@ -0,0 +1,115 @@ +--- +# 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 multipathd install tasks with root privileges + become: true + block: + - name: Record the current multipath configuration + ansible.builtin.stat: + path: /etc/multipath.conf + register: stat_before + check_mode: false + + - name: Install custom multipath.conf if one is specified + ansible.builtin.copy: + src: "{{ edpm_multipathd_custom_config_dir }}/{{ edpm_multipathd_custom_config_file }}" + dest: /etc/multipath.conf + mode: "0644" + when: + - edpm_multipathd_custom_config_file|length > 0 + + - name: Ensure /etc/multipath.conf exists + 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 + + - name: Check if a blacklist section is present + ansible.builtin.shell: grep -q '^blacklist\s*{' /etc/multipath.conf + failed_when: false + changed_when: false + register: blacklist_section + + - name: Add a blacklist section if it's missing + block: + - name: Start the blacklist section + ansible.builtin.lineinfile: + path: /etc/multipath.conf + line: 'blacklist {' + - name: Terminate the blacklist section + ansible.builtin.replace: + path: /etc/multipath.conf + regexp: '^(blacklist {)' + replace: '\1\n}' + when: + - blacklist_section.rc|int == 1 + + - name: Remove global blacklist if multipathd is enabled + ansible.builtin.replace: + path: /etc/multipath.conf + regexp: '^blacklist\s*{\n[\s]+devnode \"\.\*\"' + replace: 'blacklist {' + when: + - edpm_multipathd_enable | bool + + - name: Add global blacklist if multipathd is disabled + ansible.builtin.lineinfile: + path: /etc/multipath.conf + insertafter: '^blacklist\s*{' + regexp: '^[\s]+devnode \"\.\*\"' + line: ' devnode ".*"' + when: + - not (edpm_multipathd_enable|bool) + + - name: Configure /etc/multipath.conf variables + ansible.builtin.lineinfile: + path: /etc/multipath.conf + insertafter: '^defaults' + firstmatch: true + regexp: "^\\s+{{ item.var }}" + line: " {{ item.var }} {{ (item.value|bool) | ternary('yes', 'no') }}" + loop: + - {var: find_multipaths, value: "{{edpm_multipathd_find_multipaths}}"} + - {var: recheck_wwid, value: "{{edpm_multipathd_recheck_wwid}}"} + - {var: skip_kpartx, value: "{{edpm_multipathd_skip_kpartx}}"} + - {var: user_friendly_names, value: "{{edpm_multipathd_user_friendly_names}}"} + loop_control: + index_var: multipath_var_index + + - name: Record the new multipath configuration + ansible.builtin.stat: + path: /etc/multipath.conf + register: stat_after + check_mode: false + + - name: Record multipath containers require a restart + 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" diff --git a/roles/edpm_multipathd/tasks/install.yml b/roles/edpm_multipathd/tasks/install.yml new file mode 100644 index 000000000..9eb304894 --- /dev/null +++ b/roles/edpm_multipathd/tasks/install.yml @@ -0,0 +1,58 @@ +--- +# 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 multipathd install tasks with root privileges + become: true + block: + - name: Check if multipathd is deployed on the host + ansible.builtin.command: systemctl is-enabled --quiet multipathd + failed_when: false + register: multipathd_enabled_result + check_mode: false + + - name: Set fact multipathd_enabled + set_fact: + multipathd_enabled: "{{ multipathd_enabled_result.rc == 0 }}" + + - name: Stop multipathd service on the host + ansible.builtin.systemd: + name: "{{ item }}" + state: stopped + enabled: false + when: + - multipathd_enabled|bool + ignore_errors: true + loop: + - multipathd.service + - multipathd.socket + loop_control: + index_var: multipath_service_index + + - name: Load dm-multipath + when: + - "'molecule-notest' not in ansible_skip_tags" + ansible.builtin.import_role: + name: edpm_module_load + vars: + modules: + - name: dm-multipath + + - name: Prepare /etc/multipath directory + ansible.builtin.file: + path: /etc/multipath + state: directory + mode: "0755" + setype: container_file_t diff --git a/roles/edpm_multipathd/tasks/main.yml b/roles/edpm_multipathd/tasks/main.yml new file mode 100644 index 000000000..72dfb3e29 --- /dev/null +++ b/roles/edpm_multipathd/tasks/main.yml @@ -0,0 +1,24 @@ +--- +# 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: Install multipathd + ansible.builtin.include_tasks: install.yml + +- name: Configure multipathd + ansible.builtin.include_tasks: configure.yml + +- name: Run multipathd + ansible.builtin.include_tasks: run.yml diff --git a/roles/edpm_multipathd/tasks/run.yml b/roles/edpm_multipathd/tasks/run.yml new file mode 100644 index 000000000..2fb7ec5d5 --- /dev/null +++ b/roles/edpm_multipathd/tasks/run.yml @@ -0,0 +1,68 @@ +--- +# 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: Ensure /usr/libexec/edpm-start-podman-container exists + ansible.builtin.import_role: + name: edpm_container_manage + tasks_from: shutdown.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 + 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 + +- name: Remove multipathd container restart sentinel file + become: true + ansible.builtin.file: + path: "{{ edpm_multipathd_restart_sentinel }}" + state: absent diff --git a/roles/edpm_multipathd/templates/kolla_multipathd.yaml.j2 b/roles/edpm_multipathd/templates/kolla_multipathd.yaml.j2 new file mode 100644 index 000000000..23cf3d245 --- /dev/null +++ b/roles/edpm_multipathd/templates/kolla_multipathd.yaml.j2 @@ -0,0 +1 @@ +command: "{{ edpm_multipathd_command }}" diff --git a/roles/edpm_multipathd/templates/multipathd.yaml.j2 b/roles/edpm_multipathd/templates/multipathd.yaml.j2 new file mode 100644 index 000000000..63f086a9b --- /dev/null +++ b/roles/edpm_multipathd/templates/multipathd.yaml.j2 @@ -0,0 +1,8 @@ +image: {{ edpm_multipathd_image }} +net: host +privileged: true +restart: always +volumes: + {{ edpm_container_standalone_common_volumes | default([]) + edpm_multipathd_volumes }} +environment: + KOLLA_CONFIG_STRATEGY: COPY_ALWAYS diff --git a/roles/edpm_nova/molecule/default/prepare.yml b/roles/edpm_nova/molecule/default/prepare.yml index 9f2bb462d..bd60e9b5a 100644 --- a/roles/edpm_nova/molecule/default/prepare.yml +++ b/roles/edpm_nova/molecule/default/prepare.yml @@ -67,3 +67,9 @@ - name: install libvirt import_role: name: osp.edpm.edpm_libvirt + - name: ensure /etc/multipath.conf exists + become: true + ansible.builtin.file: + path: /etc/multipath.conf + state: touch + mode: "0644" diff --git a/roles/edpm_nova/tasks/configure.yml b/roles/edpm_nova/tasks/configure.yml index 730fa0859..1cdc09d79 100644 --- a/roles/edpm_nova/tasks/configure.yml +++ b/roles/edpm_nova/tasks/configure.yml @@ -33,6 +33,7 @@ - { "path": "/var/log/containers/nova", "mode": "0750" } - { "path": "/var/log/containers/stdouts" } - { "path": "/etc/ceph", "mode": "0750", "owner": "root", "group": "root"} + - { "path": "/etc/multipath" } - { "path": "/etc/iscsi" } - { "path": "/var/lib/iscsi" } - { "path": "/run/openvswitch" } diff --git a/roles/edpm_nova/templates/nova_compute.json.j2 b/roles/edpm_nova/templates/nova_compute.json.j2 index 2d55164ed..e35c2fdbb 100644 --- a/roles/edpm_nova/templates/nova_compute.json.j2 +++ b/roles/edpm_nova/templates/nova_compute.json.j2 @@ -18,7 +18,9 @@ "/var/lib/libvirt:/var/lib/libvirt", "/run/libvirt:/run/libvirt:shared,z", "/var/lib/nova:/var/lib/nova:shared,z", - "/var/lib/iscsi:/var/lib/iscsi", + "/var/lib/iscsi:/var/lib/iscsi:z", + "/etc/multipath:/etc/multipath:z", + "/etc/multipath.conf:/etc/multipath.conf:ro", "/etc/iscsi:/etc/iscsi:ro", "/etc/ceph:/var/lib/kolla/config_files/ceph:ro" ]