From da9793f18e2c2225753be1623ae34d27787fcd11 Mon Sep 17 00:00:00 2001 From: Dmitriy Rabotyagov Date: Thu, 6 Jul 2023 15:43:49 +0200 Subject: [PATCH] Add quorum queues support for the service This change implements and enables by default quorum support for rabbitmq as well as providing default variables to globally tune it's behaviour. In order to ensure upgrade path and ability to switch back to HA queues we change vhost names with removing leading `/`, as enabling quorum requires to remove exchange which is tricky thing to do with running services. Depends-On: https://review.opendev.org/c/openstack/openstack-ansible-plugins/+/875399 Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/873618 Change-Id: I792595dac8b651debcd364cd245145721575a516 --- defaults/main.yml | 13 ++++++++++++- tasks/nova_db_setup.yml | 15 ++++++++++++++- templates/nova.conf.j2 | 7 +++++-- vars/main.yml | 14 ++++++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index d62ab8ef..3fcfb847 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -140,7 +140,11 @@ nova_oslomsg_rpc_servers: "{{ oslomsg_rpc_servers | default('127.0.0.1') }}" nova_oslomsg_rpc_port: "{{ oslomsg_rpc_port | default('5672') }}" nova_oslomsg_rpc_use_ssl: "{{ oslomsg_rpc_use_ssl | default(False) }}" nova_oslomsg_rpc_userid: nova -nova_oslomsg_rpc_vhost: /nova +nova_oslomsg_rpc_vhost: + - name: /nova + state: "{{ (nova_oslomsg_rabbit_quorum_queues | bool) | ternary('absent', 'present') }}" + - name: nova + state: "{{ (nova_oslomsg_rabbit_quorum_queues | bool) | ternary('present', 'absent') }}" nova_oslomsg_rpc_ssl_version: "{{ oslomsg_rpc_ssl_version | default('TLSv1_2') }}" nova_oslomsg_rpc_ssl_ca_file: "{{ oslomsg_rpc_ssl_ca_file | default('') }}" @@ -161,6 +165,13 @@ nova_oslomsg_notify_ssl_ca_file: "{{ oslomsg_notify_ssl_ca_file | default('') }} # TODO(ansmith): Change structure when more backends will be supported nova_oslomsg_amqp1_enabled: "{{ nova_oslomsg_rpc_transport == 'amqp' }}" +### +### RabbitMQ info +### +nova_oslomsg_rabbit_quorum_queues: "{{ oslomsg_rabbit_quorum_queues | default(True) }}" +nova_oslomsg_rabbit_quorum_delivery_limit: "{{ oslomsg_rabbit_quorum_delivery_limit | default(0) }}" +nova_oslomsg_rabbit_quorum_max_memory_bytes: "{{ oslomsg_rabbit_quorum_max_memory_bytes | default(0) }}" + ## Nova virtualization Types # The nova_virt_types dictionary contains global overrides used for # specific compute types. Every variable inside of this dictionary diff --git a/tasks/nova_db_setup.yml b/tasks/nova_db_setup.yml index 21331b76..4badd3ba 100644 --- a/tasks/nova_db_setup.yml +++ b/tasks/nova_db_setup.yml @@ -51,7 +51,7 @@ {{ nova_bin }}/nova-manage cell_v2 create_cell --name {{ nova_cell1_name }} --database_connection {scheme}://{username}:{password}@{hostname}:{port}/{path}?{query} - --transport-url {scheme}://{username}:{password}@{hostname}:{port}//{path}?{query} + --transport-url {scheme}://{username}:{password}@{hostname}:{port}/{{ (not nova_oslomsg_rabbit_quorum_queues | bool) | ternary('/{path}', '{path}') }}?{query} become: yes become_user: "{{ nova_system_user_name }}" register: nova_cell1_create @@ -67,6 +67,19 @@ changed_when: "nova_cell1_create.rc == 0" when: "_cell_uuid.rc == 1" +- name: "Change the template for cell {{ nova_cell1_name }}" + command: >- + {{ nova_bin }}/nova-manage cell_v2 update_cell + --cell_uuid {{ _cell_uuid['stdout'].split()[3] }} + --database_connection {scheme}://{username}:{password}@{hostname}:{port}/{path}?{query} + --transport-url {scheme}://{username}:{password}@{hostname}:{port}/{{ (not nova_oslomsg_rabbit_quorum_queues | bool) | ternary('/{path}', '{path}') }}?{query} + become: yes + become_user: "{{ nova_system_user_name }}" + changed_when: false + when: + - "_cell_uuid.rc == 0" + - (nova_oslomsg_rpc_port ~ '/' ~ _nova_oslomsg_rpc_vhost_conf) not in _cell_uuid.stdout + # The nova-status upgrade check command is typically run after upgrading the # controller services to new code, but is also OK to run for a greenfield # install to verify everything is setup correctly. This must run after cell diff --git a/templates/nova.conf.j2 b/templates/nova.conf.j2 index b38a113a..0153aab2 100644 --- a/templates/nova.conf.j2 +++ b/templates/nova.conf.j2 @@ -30,7 +30,7 @@ key = {{ nova_console_ssl_key }} enabled_apis = {{ nova_enabled_apis }} # Rpc all -transport_url = {{ nova_oslomsg_rpc_transport }}://{% for host in nova_oslomsg_rpc_servers.split(',') %}{{ nova_oslomsg_rpc_userid }}:{{ nova_oslomsg_rpc_password }}@{{ host }}:{{ nova_oslomsg_rpc_port }}{% if not loop.last %},{% else %}/{{ nova_oslomsg_rpc_vhost }}{% if nova_oslomsg_rpc_use_ssl | bool %}?ssl=1&ssl_version={{ nova_oslomsg_rpc_ssl_version }}&ssl_ca_file={{ nova_oslomsg_rpc_ssl_ca_file }}{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} +transport_url = {{ nova_oslomsg_rpc_transport }}://{% for host in nova_oslomsg_rpc_servers.split(',') %}{{ nova_oslomsg_rpc_userid }}:{{ nova_oslomsg_rpc_password }}@{{ host }}:{{ nova_oslomsg_rpc_port }}{% if not loop.last %},{% else %}/{{ _nova_oslomsg_rpc_vhost_conf }}{% if nova_oslomsg_rpc_use_ssl | bool %}?ssl=1&ssl_version={{ nova_oslomsg_rpc_ssl_version }}&ssl_ca_file={{ nova_oslomsg_rpc_ssl_ca_file }}{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} # Network my_ip = {% if nova_management_address == 'localhost' %}127.0.0.1{% else %}{{ nova_management_address }}{% endif %} @@ -55,11 +55,14 @@ instance_usage_audit_period = hour {% endif %} topics = {{ notification_topics | join(',') }} driver = {{ (notification_topics | length > 0) | ternary('messagingv2', 'noop') }} -transport_url = {{ nova_oslomsg_notify_transport }}://{% for host in nova_oslomsg_notify_servers.split(',') %}{{ nova_oslomsg_notify_userid }}:{{ nova_oslomsg_notify_password }}@{{ host }}:{{ nova_oslomsg_notify_port }}{% if not loop.last %},{% else %}/{{ nova_oslomsg_notify_vhost }}{% if nova_oslomsg_notify_use_ssl | bool %}?ssl=1&ssl_version={{ nova_oslomsg_notify_ssl_version }}&ssl_ca_file={{ nova_oslomsg_notify_ssl_ca_file }}{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} +transport_url = {{ nova_oslomsg_notify_transport }}://{% for host in nova_oslomsg_notify_servers.split(',') %}{{ nova_oslomsg_notify_userid }}:{{ nova_oslomsg_notify_password }}@{{ host }}:{{ nova_oslomsg_notify_port }}{% if not loop.last %},{% else %}/{{ _nova_oslomsg_notify_vhost_conf }}{% if nova_oslomsg_notify_use_ssl | bool %}?ssl=1&ssl_version={{ nova_oslomsg_notify_ssl_version }}&ssl_ca_file={{ nova_oslomsg_notify_ssl_ca_file }}{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} # Messaging [oslo_messaging_rabbit] heartbeat_in_pthread = {{ nova_oslomsg_heartbeat_in_pthread }} +rabbit_quorum_queue = {{ nova_oslomsg_rabbit_quorum_queues }} +rabbit_quorum_delivery_limit = {{ nova_oslomsg_rabbit_quorum_delivery_limit }} +rabbit_quorum_max_memory_bytes = {{ nova_oslomsg_rabbit_quorum_max_memory_bytes }} # Image cache [image_cache] diff --git a/vars/main.yml b/vars/main.yml index 617a07a3..845c42d3 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -19,6 +19,20 @@ _nova_is_first_play_host: >- inventory_hostname == (groups[nova_services['nova-conductor']['group']] | intersect(ansible_play_hosts)) | first) | bool }} +_nova_oslomsg_rpc_vhost_conf: >- + {{ + (nova_oslomsg_rpc_vhost is string) | ternary( + nova_oslomsg_rpc_vhost, nova_oslomsg_rpc_vhost | selectattr('state', 'eq', 'present') | map(attribute='name') | first + ) + }} + +_nova_oslomsg_notify_vhost_conf: >- + {{ + (nova_oslomsg_notify_vhost is string) | ternary( + nova_oslomsg_notify_vhost, nova_oslomsg_notify_vhost | selectattr('state', 'eq', 'present') | map(attribute='name') | first + ) + }} + nova_venv_packages: |- {%- set pkg_list = nova_pip_packages | union(nova_user_pip_packages) %} {%- if nova_oslomsg_amqp1_enabled | bool %}