{"id":389,"sha1":"8865e58ff88a47f081fbe34eff19272fbe791a0c","playbook":{"id":3,"items":{"plays":37,"tasks":589,"results":576,"hosts":7,"files":222,"records":0},"arguments":{"version":null,"verbosity":0,"private_key_file":null,"remote_user":null,"connection":"openstack.osa.ssh","timeout":null,"ssh_common_args":null,"sftp_extra_args":null,"scp_extra_args":null,"ssh_extra_args":null,"ask_pass":false,"connection_password_file":null,"force_handlers":true,"flush_cache":false,"become":false,"become_method":"sudo","become_user":null,"become_ask_pass":false,"become_password_file":null,"tags":["all"],"skip_tags":[],"check":false,"diff":false,"inventory":["/home/zuul/src/opendev.org/openstack/openstack-ansible/inventory/dynamic_inventory.py","/home/zuul/src/opendev.org/openstack/openstack-ansible/inventory/inventory.ini","/etc/openstack_deploy/inventory.ini"],"listhosts":false,"subset":null,"extra_vars":"Not saved by ARA as configured by 'ignored_arguments'","vault_ids":[],"ask_vault_pass":false,"vault_password_files":[],"forks":4,"module_path":null,"syntax":false,"listtasks":false,"listtags":false,"step":false,"start_at_task":null,"args":["setup-infrastructure.yml"]},"labels":[{"id":1,"name":"check:False"},{"id":2,"name":"tags:all"}],"started":"2025-12-08T13:50:33.014895Z","ended":"2025-12-08T13:57:00.819740Z","duration":"00:06:27.804845","name":null,"ansible_version":"2.18.6","client_version":"1.7.4","python_version":"3.12.11","server_version":"1.7.4","status":"completed","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible/playbooks/setup-infrastructure.yml","controller":"aio1.openstack.local","user":"root"},"content":"---\n# Copyright 2015, Rackspace US, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# ansible-lint fails on this task due to the detected use of 'dpkg',\n# so we skip this task in the ansible-lint check by using the\n# 'skip_ansible_lint' tag\n- name: Get version of installed RabbitMQ package (deb)\n  ansible.builtin.command: \"dpkg-query -f='${Version}' -W rabbitmq-server\"\n  changed_when: false\n  check_mode: false\n  failed_when: false\n  register: installed_rabbitmq_deb\n  when:\n    - ansible_facts['pkg_mgr'] == 'apt'\n  tags:\n    - rabbitmq-package-deb\n    - rabbitmq-apt-packages\n    - skip_ansible_lint\n\n# ansible-lint fails on this task due to the detected use of 'rpm',\n# so we skip this task in the ansible-lint check by using the\n# 'skip_ansible_lint' tag\n- name: Get version of installed RabbitMQ package (rpm)\n  ansible.builtin.command: \"rpm --queryformat '%{VERSION}' -q rabbitmq-server\"\n  changed_when: false\n  check_mode: false\n  failed_when: false\n  register: installed_rabbitmq_rpm\n  when:\n    - ansible_facts['pkg_mgr'] == 'dnf'\n  tags:\n    - rabbitmq-package-rpm\n    - rabbitmq-dnf-packages\n    - skip_ansible_lint\n\n- name: Register a fact for the installed RabbitMQ version\n  ansible.builtin.set_fact:\n    installed_rabbitmq: \"{{ item }}\"\n  when:\n    - item is not skipped\n  with_items:\n    - \"{{ installed_rabbitmq_deb }}\"\n    - \"{{ installed_rabbitmq_rpm }}\"\n\n- name: Ensure installed RabbitMQ version is same as expected\n  ansible.builtin.fail:\n    msg: \"To install a new major/minor version of RabbitMQ set '-e rabbitmq_upgrade=true'.\"\n  any_errors_fatal: true\n  when:\n    - not rabbitmq_upgrade | bool\n    - installed_rabbitmq.rc == 0\n    - not (installed_rabbitmq.stdout | split('-') | first) is version(rabbitmq_package_version | split('-') | first)\n    - rabbitmq_install_method != 'distro'\n  tags:\n    - rabbitmq-package-deb\n    - rabbitmq-package-rpm\n    - rabbitmq-apt-packages\n\n- name: Ensure that RabbitMQ is running minimal required version for upgrade\n  ansible.builtin.fail:\n    msg: |\n      Minimal required version for proceeding with RabbitMQ upgrade to {{ rabbitmq_package_version }} is {{ _minimal_required_version }}.\n      Please, upgrade to the version {{ _minimal_required_version }} before proceeding with further upgrade.\n      Current detected version is {{ installed_rabbitmq.stdout }}.\n  any_errors_fatal: true\n  vars:\n    _minimal_required_version: >-\n      {{ (_rabbitmq_upgrade_minimal_requirement_mapping | selectattr('target', 'in', rabbitmq_package_version) | first)['requirement'] }}\n  when:\n    - rabbitmq_upgrade | bool\n    - installed_rabbitmq.rc == 0\n    - installed_rabbitmq.stdout is version(_minimal_required_version, '<')\n    - rabbitmq_install_method != 'distro'\n  tags:\n    - rabbitmq-package-deb\n    - rabbitmq-package-rpm\n    - rabbitmq-apt-packages\n\n- name: Including rabbitmq_cluster_state tasks\n  ansible.builtin.include_tasks: rabbitmq_cluster_state.yml\n  args:\n    apply:\n      tags:\n        - rabbitmq-upgrade\n  when:\n    - rabbitmq_upgrade | bool\n  tags:\n    - rabbitmq-upgrade\n\n- name: Fail if cluster state is not healthy for upgrade\n  vars:\n    _rabbitmq_cluster_health_issues:\n      - msg: |\n          The number of running RabbitMQ nodes is not equal to number of configured nodes in the {{ rabbitmq_host_group }} group.\n          Please ensure that all of the nodes are running and healthy before performing the upgrade.\n        condition: \"{{ ((_cluster_state.get('running_nodes', []) | length) != (groups[rabbitmq_host_group] | length)) }}\"\n      - msg: |\n          There are active alarms for the rabbitmq cluster. Please check the cluster status with `rabbitmq-diagnostics cluster_status` and\n          resolve any alarms before proceeding with the upgrade.\n        condition: \"{{ ((_cluster_state.get('alarms', []) | length) != 0) }}\"\n      - msg: |\n          A network partition has been detected within your cluster. This might indicate a split-brain or network connectivity problem.\n          Please check the cluster status with `rabbitmq-diagnostics cluster_status` and resolve any partitioning before proceeding with the upgrade.\n        condition: \"{{ ((_cluster_state.get('partitions', []) | length) != 0) }}\"\n    _rabbitmq_cluster_upgrade_blockers: \"{{ _rabbitmq_cluster_health_issues | selectattr('condition', 'true') }}\"\n  ansible.builtin.fail:\n    msg: \"{{ _rabbitmq_cluster_upgrade_blockers | map(attribute='msg') | join('\\n') }}\"\n  any_errors_fatal: true\n  when:\n    - rabbitmq_upgrade | bool\n    - _cluster_state\n    - _rabbitmq_cluster_upgrade_blockers | length > 0\n  tags:\n    - rabbitmq-upgrade\n\n- name: Verify if queues/streams are healthy\n  vars:\n    _rabbitmq_other_cluster_memembers: \"{{ _cluster_state.get('running_nodes', []) | reject('eq', 'rabbit@' ~ ansible_facts['hostname'].split('.')[0])  }}\"\n    _rabbitmq_quorum_critical_queues: \"{{ (_rabbitmq_is_quorum_critical.stderr | from_json)['queues'] }}\"\n  when:\n    - rabbitmq_upgrade | bool\n    - _cluster_state\n  tags:\n    - rabbitmq-upgrade\n  block:\n    - name: Check if all quorum queues and streams are above the minimum online quorum\n      ansible.builtin.command: rabbitmq-diagnostics check_if_node_is_quorum_critical --formatter json\n      changed_when: false\n      register: _rabbitmq_is_quorum_critical\n\n  rescue:\n    # NOTE(noonedeadpunk): In case this proves to be too slow, alternatively we can use smth like\n    #       rabbitmq-queues grow \"{{ item.0 }}\" \"all\" --vhost-pattern \".*\" --queue-pattern \".*\"\n    #       But: a) it is available only for quorum, not streams b) it may cause load on rabbit at scale\n    - name: Grow affected quorum queues to all cluster nodes\n      ansible.builtin.command: 'rabbitmq-queues add_member --vhost \"{{ item.1.virtual_host }}\" \"{{ item.1.name }}\" \"{{ item.0 }}\"'\n      changed_when: false\n      vars:\n        loop_label:\n          node: \"{{ item.0 }}\"\n          vhost: \"{{ item.1.virtual_host }}\"\n          queue: \"{{ item.1.name }}\"\n      loop: >-\n        {{\n          _rabbitmq_other_cluster_memembers | product(\n            _rabbitmq_quorum_critical_queues | selectattr('type', 'eq', 'rabbit_quorum_queue')\n          )\n        }}\n      loop_control:\n        label: \"{{ loop_label | to_json }}\"\n\n    - name: Grow affected stream queues to all cluster nodes\n      ansible.builtin.command: 'rabbitmq-streams add_replica --vhost \"{{ item.1.virtual_host }}\" \"{{ item.1.name }}\" \"{{ item.0 }}\"'\n      changed_when: false\n      vars:\n        loop_label:\n          node: \"{{ item.0 }}\"\n          vhost: \"{{ item.1.virtual_host }}\"\n          queue: \"{{ item.1.name }}\"\n      loop: >-\n        {{\n          _rabbitmq_other_cluster_memembers | product(\n            _rabbitmq_quorum_critical_queues | selectattr('type', 'eq', 'rabbit_stream_queue')\n          )\n        }}\n      loop_control:\n        label: \"{{ loop_label | to_json }}\"\n\n    - name: Wait for queues to go above minimum online quorum (120s)\n      ansible.builtin.command: rabbitmq-upgrade await_online_quorum_plus_one\n      changed_when: false\n\n- name: Prepare node for upgrade\n  when:\n    - rabbitmq_upgrade | bool\n    - _cluster_state\n    - (_cluster_state.get('running_nodes', []) | length) == (groups[rabbitmq_host_group] | length)\n    - (_cluster_state.get('alarms', []) | length) == 0\n    - (_cluster_state.get('partitions', []) | length) == 0\n  block:\n    - name: Including rabbitmq_feature_flags tasks\n      ansible.builtin.include_tasks: rabbitmq_feature_flags.yml\n      args:\n        apply:\n          tags:\n            - rabbitmq-upgrade\n      when:\n        - _rabbitmq_is_first_play_host\n      tags:\n        - rabbitmq-upgrade\n\n    - name: Including rabbitmq_upgrade_prep tasks\n      ansible.builtin.include_tasks: rabbitmq_upgrade_prep.yml\n      args:\n        apply:\n          tags:\n            - rabbitmq-upgrade\n      tags:\n        - always\n","created":"2025-12-08T13:54:33.903627Z","updated":"2025-12-08T13:54:33.903639Z","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible-rabbitmq_server/tasks/rabbitmq_upgrade_check.yml"}