{"id":892,"sha1":"73618ef0c1dea54ecb37494e3f12fdc6c1093acf","playbook":{"id":4,"items":{"plays":107,"tasks":2438,"results":2413,"hosts":13,"files":511,"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-openstack.yml"]},"labels":[{"id":1,"name":"check:False"},{"id":2,"name":"tags:all"}],"started":"2025-12-14T10:21:40.790759Z","ended":"2025-12-14T11:05:36.775743Z","duration":"00:43:55.984984","name":null,"ansible_version":"2.18.6","client_version":"1.7.4","python_version":"3.13.5","server_version":"1.7.4","status":"completed","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible/playbooks/setup-openstack.yml","controller":"aio1.openstack.local","user":"root"},"content":"---\n# (c) 2021, Satish Patel <satish.txt@gmail.com>\n#\n# Copyright\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# checking if ovn db are clustered or not, if not then this is fresh node.\n- name: Check if ovn db is clustered\n  ansible.builtin.command: ovsdb-tool db-is-clustered /var/lib/ovn/ovnnb_db.db\n  ignore_errors: true\n  failed_when: false\n  changed_when: false\n  register: _check_cluster_db\n\n# We need to clean existing ovn db/lock file before cluster join.\n- name: Clean up db/lock files before creating ovn cluster\n  when:\n    - _check_cluster_db.rc != 0\n  block:\n    - name: Stop ovn services\n      ansible.builtin.service:\n        name: \"{{ neutron_ovn_northd_service_name }}\"\n        state: stopped\n\n    - name: Clean up ovn db directory\n      ansible.builtin.file:\n        path: /var/lib/ovn/\n        state: absent\n\n# We are finding leader node so new nodes use leader to join cluster.\n- name: Find leader node in ovn cluster\n  ansible.builtin.shell: ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | sed 's/ //g' | grep -oP '(?<=Role:).*'\n  args:\n    executable: /bin/bash\n  ignore_errors: true\n  delegate_to: \"{{ container }}\"\n  with_items: \"{{ groups['neutron_ovn_northd'] }}\"\n  loop_control:\n    loop_var: container\n  run_once: true\n  failed_when: false\n  changed_when: false\n  register: _find_leader\n\n# set leader_node variable\n- name: Set leader_node fact\n  ansible.builtin.set_fact:\n    leader_node: \"{{ (_find_leader.results | selectattr('stdout', 'search', 'leader')) | map(attribute='container') | list }}\"\n\n# This play only run first time to build cluster using primary node.\n- name: Setup ovn cluster using primary node.\n  ansible.builtin.template:\n    src: ovn-northd-opts.j2\n    dest: \"{{ neutron_ovn_northd_opts_file }}\"\n    mode: \"0644\"\n  when:\n    - \"inventory_hostname == neutron_ovn_primary_cluster_node\"\n    - _check_cluster_db.rc != 0\n    - not leader_node\n  register: ovn_northd_opts\n\n- name: Start ovn service\n  ansible.builtin.service:\n    name: \"{{ neutron_ovn_northd_service_name }}\"\n    state: started\n  when:\n    - \"inventory_hostname == neutron_ovn_primary_cluster_node\"\n    - _check_cluster_db.rc != 0\n    - not leader_node\n    - ovn_northd_opts.changed\n\n- name: Configure connection settings for ovn-nb and ovn-sb\n  ansible.builtin.command: \"{{ cmd }}\"\n  changed_when: false\n  with_items:\n    - \"ovn-nbctl --inactivity-probe={{ neutron_ovn_nb_inactivity_probe }} set-connection p{{ ovn_proto }}:6641\"\n    - \"ovn-sbctl --inactivity-probe={{ neutron_ovn_sb_inactivity_probe }} set-connection p{{ ovn_proto }}:6642\"\n  when:\n    - \"inventory_hostname == neutron_ovn_primary_cluster_node\"\n    - _check_cluster_db.rc != 0\n    - not leader_node\n    - ovn_northd_opts.changed\n  loop_control:\n    loop_var: cmd\n  register: _ovn_connection_settings\n  until: _ovn_connection_settings is success\n  retries: 5\n  delay: 2\n  tags:\n    - neutron_ovn-config\n\n# This play will add nodes in existing cluster using leader_node var.\n- name: Join new nodes to ovn cluster using leader node\n  ansible.builtin.template:\n    src: ovn-northd-opts.j2\n    dest: \"{{ neutron_ovn_northd_opts_file }}\"\n    mode: \"0644\"\n  when:\n    - _check_cluster_db.rc != 0\n  notify:\n    - start ovn service\n    - restart ovn service\n","created":"2025-12-14T10:54:34.737324Z","updated":"2025-12-14T10:54:34.737336Z","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible-os_neutron/tasks/providers/ovn_cluster_setup.yml"}