- block: - become: true command: '{{ container_cli }} exec cinder_api cinder-manage db online_data_migrations' delegate_to: '{{ (groups[''cinder_api''] | difference(groups[''excluded_overcloud'']))[0] }}' name: Online data migration for Cinder tags: - online_upgrade - online_upgrade_cinder when: step|int == 1 - block: - block: - become: true name: Get cinder_backup image from pacemaker register: xmllint_pcmk_cinder_backup_image shell: xmllint --xpath "string(//bundle[@id='openstack-cinder-backup']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container cinder_backup image set_fact: cinder_backup_image: registry.redhat.io/rhosp-rhel9/openstack-cinder-backup:17.1 cinder_backup_image_latest: cluster.common.tag/cinder-backup:pcmklatest pcmk_cinder_backup_image: '{{xmllint_pcmk_cinder_backup_image.stdout}}' delegate_to: '{{ (groups["cinder_backup"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: cinder-backup temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: openstack-cinder-backup tripleo_ha_image_update_new_image: '{{cinder_backup_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["cinder_backup"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_cinder_backup_image}}' when: - (pcmk_cinder_backup_image != "") - (pcmk_cinder_backup_image != cinder_backup_image_latest) tags: ha_image_update when: step|int == 1 - block: - block: - become: true name: Get cinder_volume image from pacemaker register: xmllint_pcmk_cinder_volume_image shell: xmllint --xpath "string(//bundle[@id='openstack-cinder-volume']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container cinder_volume image set_fact: cinder_volume_image: registry.redhat.io/rhosp-rhel9/openstack-cinder-volume:17.1 cinder_volume_image_latest: cluster.common.tag/cinder-volume:pcmklatest pcmk_cinder_volume_image: '{{xmllint_pcmk_cinder_volume_image.stdout}}' delegate_to: '{{ (groups["cinder_volume"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: cinder-volume temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: openstack-cinder-volume tripleo_ha_image_update_new_image: '{{cinder_volume_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["cinder_volume"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_cinder_volume_image}}' when: - (pcmk_cinder_volume_image != "") - (pcmk_cinder_volume_image != cinder_volume_image_latest) tags: ha_image_update when: step|int == 1 - block: - block: - become: true name: Get haproxy image from pacemaker register: xmllint_pcmk_haproxy_image shell: xmllint --xpath "string(//bundle[@id='haproxy-bundle']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container haproxy image set_fact: haproxy_image: registry.redhat.io/rhosp-rhel9/openstack-haproxy:17.1 haproxy_image_latest: cluster.common.tag/haproxy:pcmklatest pcmk_haproxy_image: '{{xmllint_pcmk_haproxy_image.stdout}}' delegate_to: '{{ (groups["haproxy"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: haproxy temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: haproxy-bundle tripleo_ha_image_update_new_image: '{{haproxy_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["haproxy"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_haproxy_image}}' when: - (pcmk_haproxy_image != "") - (pcmk_haproxy_image != haproxy_image_latest) tags: ha_image_update when: step|int == 1 - block: - block: - become: true name: Get manila_share image from pacemaker register: xmllint_pcmk_manila_share_image shell: xmllint --xpath "string(//bundle[@id='openstack-manila-share']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container manila_share image set_fact: manila_share_image: registry.redhat.io/rhosp-rhel9/openstack-manila-share:17.1 manila_share_image_latest: cluster.common.tag/manila-share:pcmklatest pcmk_manila_share_image: '{{xmllint_pcmk_manila_share_image.stdout}}' delegate_to: '{{ (groups["manila_share"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: manila-share temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: openstack-manila-share tripleo_ha_image_update_new_image: '{{manila_share_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["manila_share"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_manila_share_image}}' when: - (pcmk_manila_share_image != "") - (pcmk_manila_share_image != manila_share_image_latest) tags: ha_image_update when: step|int == 1 - block: - block: - become: true name: Get galera image from pacemaker register: xmllint_pcmk_galera_image shell: xmllint --xpath "string(//bundle[@id='galera-bundle']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container galera image set_fact: galera_image: registry.redhat.io/rhosp-rhel9/openstack-mariadb:17.1 galera_image_latest: cluster.common.tag/mariadb:pcmklatest pcmk_galera_image: '{{xmllint_pcmk_galera_image.stdout}}' delegate_to: '{{ (groups["mysql"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: MySQL temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: galera-bundle tripleo_ha_image_update_new_image: '{{galera_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["mysql"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_galera_image}}' when: - (pcmk_galera_image != "") - (pcmk_galera_image != galera_image_latest) tags: ha_image_update when: step|int == 1 - become: true delegate_to: '{{groups[''neutron_api''][0]}}' failed_when: false name: Check if python3-openvswitch3.1 workaround is needed register: neutron_python_ovs_3_1 shell: 'podman exec neutron_api rpm -q python3-openvswitch3.1 ' tags: - ovn - ovn_image when: step|int == 1 - become: true block: - delegate_to: '{{groups[''neutron_api''][0]}}' name: Move virtual IPs to another node before stopping pacemaker shell: "CLUSTER_NODE=$(crm_node -n)\necho \"Retrieving all the VIPs which are\ \ hosted on this node\"\nVIPS_TO_MOVE=$(crm_mon --as-xml | xmllint --xpath '//resource[@resource_agent=\"\ ocf:heartbeat:IPaddr2\" and @role = \"Started\" and @managed = \"true\" and\ \ ./node[@name = \"'${CLUSTER_NODE}'\"]]/@id' - | sed -e 's/id=//g' -e 's/\"\ //g')\nfor v in ${VIPS_TO_MOVE}; do\n echo \"Moving VIP $v on another node\"\ \n pcs resource ban $v ${CLUSTER_NODE} --wait=300\ndone\necho \"Removing\ \ the location constraints that were created to move the VIPs\"\nfor v in ${VIPS_TO_MOVE};\ \ do\n echo \"Removing location ban for VIP $v\"\n ban_id=$(cibadmin --query\ \ | xmllint --xpath 'string(//rsc_location[@rsc=\"'${v}'\" and @node=\"'${CLUSTER_NODE}'\"\ \ and @score=\"-INFINITY\"]/@id)' -)\n if [ -n \"$ban_id\" ]; then\n \ \ pcs constraint remove ${ban_id}\n else\n echo \"Could not retrieve\ \ and clear location constraint for VIP $v\" 2>&1\n fi\ndone\n" when: - hostvars[groups['neutron_api'][0]]["haproxy_node_names"]|default([])|length > 1 - delegate_to: '{{groups[''neutron_api''][0]}}' name: Create firewall nat prerouting and postrouting shell: "set -o pipefail\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][0]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nif [[\ \ $IP =~ .*:.* ]]\n then\n PROTOCOL=\"ip6\"\n # we need to temporarly\ \ allow ipv6 forwarding, this will get reset by deployment run\n sysctl\ \ -w net.ipv6.conf.all.forwarding=1\n else PROTOCOL=\"ip\"\nfi\nnft add table\ \ $PROTOCOL nat\nnft -- add chain $PROTOCOL nat prerouting { type nat hook prerouting\ \ priority -100 \\; }\nnft add chain $PROTOCOL nat postrouting { type nat hook\ \ postrouting priority 100 \\; }\n" - delegate_to: '{{groups[''neutron_api''][0]}}' name: Redirect neutron backend traffic for 60s to other host shell: "set -o pipefail\nsource /etc/os-release; test \"${VERSION_ID%*}\" = \"\ 9.0\" && exit 0\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][0]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nREMOTE_BACKEND=$(grep \":9696\ \ \" /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg |\ \ \\\n grep server | grep -v {{groups['neutron_api'][0]}} | head -n1 | awk\ \ '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nPORT=9696\nif [[ $IP =~ .*:.* ]]\n\ \ then PROTOCOL=\"ip6\"\n else PROTOCOL=\"ip\"\nfi\nREMOTE_IP=${REMOTE_BACKEND%:*}\n\ nft add rule $PROTOCOL nat postrouting $PROTOCOL daddr $REMOTE_IP tcp dport\ \ 9696 counter meta time $(date +%s)-$(date -d'+60 seconds' +%s) masquerade\ \ comment neutron_api\nnft add rule $PROTOCOL nat prerouting $PROTOCOL daddr\ \ $IP tcp dport 9696 counter meta time $(date +%s)-$(date -d'+60 seconds' +%s)\ \ dnat to $REMOTE_IP comment neutron_api\n" - become: true delegate_to: '{{groups[''neutron_api''][0]}}' name: Insanity neutron update first tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_4 config_id: - neutron_api config_overrides: .*neutron_api: image: registry.redhat.io/rhosp-rhel9/openstack-neutron-server:17.1 name: neutron_api config_patterns: '*neutron_api.json' - wait_for: timeout: 50 - delegate_to: '{{groups[''neutron_api''][0]}}' name: Delete redirect rules shell: "set -o pipefail\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][0]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nif [[\ \ $IP =~ .*:.* ]]\n then\n PROTOCOL=\"ip6\"\n else PROTOCOL=\"ip\"\n\ fi\nnft -a list chain $PROTOCOL nat postrouting | grep neutron_api | awk -F#\ \ '{print \"nat postrouting \"$2}' | \\\nwhile read i; do bash -c \"nft delete\ \ rule $PROTOCOL $i\"; done\nnft -a list chain $PROTOCOL nat prerouting | grep\ \ neutron_api | awk -F# '{print \"nat prerouting \"$2}' | \\\nwhile read i;\ \ do bash -c \"nft delete rule $PROTOCOL $i\"; done\n" - delegate_to: '{{groups[''neutron_api''][1]}}' name: Move virtual IPs to another node before stopping pacemaker shell: "CLUSTER_NODE=$(crm_node -n)\necho \"Retrieving all the VIPs which are\ \ hosted on this node\"\nVIPS_TO_MOVE=$(crm_mon --as-xml | xmllint --xpath '//resource[@resource_agent=\"\ ocf:heartbeat:IPaddr2\" and @role = \"Started\" and @managed = \"true\" and\ \ ./node[@name = \"'${CLUSTER_NODE}'\"]]/@id' - | sed -e 's/id=//g' -e 's/\"\ //g')\nfor v in ${VIPS_TO_MOVE}; do\n echo \"Moving VIP $v on another node\"\ \n pcs resource ban $v ${CLUSTER_NODE} --wait=300\ndone\necho \"Removing\ \ the location constraints that were created to move the VIPs\"\nfor v in ${VIPS_TO_MOVE};\ \ do\n echo \"Removing location ban for VIP $v\"\n ban_id=$(cibadmin --query\ \ | xmllint --xpath 'string(//rsc_location[@rsc=\"'${v}'\" and @node=\"'${CLUSTER_NODE}'\"\ \ and @score=\"-INFINITY\"]/@id)' -)\n if [ -n \"$ban_id\" ]; then\n \ \ pcs constraint remove ${ban_id}\n else\n echo \"Could not retrieve\ \ and clear location constraint for VIP $v\" 2>&1\n fi\ndone\n" when: - hostvars[groups['neutron_api'][1]]["haproxy_node_names"]|default([])|length > 1 - groups['neutron_api'] | default([]) | length > 1 - delegate_to: '{{groups[''neutron_api''][1]}}' name: Create firewall nat prerouting and postrouting shell: "set -o pipefail\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][1]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nif [[\ \ $IP =~ .*:.* ]]\n then\n PROTOCOL=\"ip6\"\n # we need to temporarly\ \ allow ipv6 forwarding, this will get reset by deployment run\n sysctl\ \ -w net.ipv6.conf.all.forwarding=1\n else PROTOCOL=\"ip\"\nfi\nnft add table\ \ $PROTOCOL nat\nnft -- add chain $PROTOCOL nat prerouting { type nat hook prerouting\ \ priority -100 \\; }\nnft add chain $PROTOCOL nat postrouting { type nat hook\ \ postrouting priority 100 \\; }\n" when: - groups['neutron_api'] | default([]) | length > 1 - delegate_to: '{{groups[''neutron_api''][1]}}' name: Redirect neutron backend traffic for 60s to other host shell: "set -o pipefail\nsource /etc/os-release; test \"${VERSION_ID%*}\" = \"\ 9.0\" && exit 0\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][1]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nREMOTE_BACKEND=$(grep \":9696\ \ \" /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg |\ \ \\\n grep server | grep -v {{groups['neutron_api'][1]}} | head -n1 | awk\ \ '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nPORT=9696\nif [[ $IP =~ .*:.* ]]\n\ \ then PROTOCOL=\"ip6\"\n else PROTOCOL=\"ip\"\nfi\nREMOTE_IP=${REMOTE_BACKEND%:*}\n\ nft add rule $PROTOCOL nat postrouting $PROTOCOL daddr $REMOTE_IP tcp dport\ \ 9696 counter meta time $(date +%s)-$(date -d'+60 seconds' +%s) masquerade\ \ comment neutron_api\nnft add rule $PROTOCOL nat prerouting $PROTOCOL daddr\ \ $IP tcp dport 9696 counter meta time $(date +%s)-$(date -d'+60 seconds' +%s)\ \ dnat to $REMOTE_IP comment neutron_api\n" when: - groups['neutron_api'] | default([]) | length > 1 - become: true delegate_to: '{{groups[''neutron_api''][1]}}' name: Insanity neutron update first tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_4 config_id: - neutron_api config_overrides: .*neutron_api: image: registry.redhat.io/rhosp-rhel9/openstack-neutron-server:17.1 name: neutron_api config_patterns: '*neutron_api.json' when: - groups['neutron_api'] | default([]) | length > 1 - wait_for: timeout: 50 when: - groups['neutron_api'] | default([]) | length > 1 - delegate_to: '{{groups[''neutron_api''][1]}}' name: Delete redirect rules shell: "set -o pipefail\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][1]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nif [[\ \ $IP =~ .*:.* ]]\n then PROTOCOL=\"ip6\"\n else PROTOCOL=\"ip\"\nfi\nnft\ \ -a list chain $PROTOCOL nat postrouting | grep neutron_api | awk -F# '{print\ \ \"nat postrouting \"$2}' | \\\nwhile read i; do bash -c \"nft delete rule\ \ $PROTOCOL $i\"; done\nnft -a list chain $PROTOCOL nat prerouting | grep neutron_api\ \ | awk -F# '{print \"nat prerouting \"$2}' | \\\nwhile read i; do bash -c \"\ nft delete rule $PROTOCOL $i\"; done\n" when: - groups['neutron_api'] | default([]) | length > 1 - delegate_to: '{{groups[''neutron_api''][2]}}' name: Move virtual IPs to another node before stopping pacemaker shell: "CLUSTER_NODE=$(crm_node -n)\necho \"Retrieving all the VIPs which are\ \ hosted on this node\"\nVIPS_TO_MOVE=$(crm_mon --as-xml | xmllint --xpath '//resource[@resource_agent=\"\ ocf:heartbeat:IPaddr2\" and @role = \"Started\" and @managed = \"true\" and\ \ ./node[@name = \"'${CLUSTER_NODE}'\"]]/@id' - | sed -e 's/id=//g' -e 's/\"\ //g')\nfor v in ${VIPS_TO_MOVE}; do\n echo \"Moving VIP $v on another node\"\ \n pcs resource ban $v ${CLUSTER_NODE} --wait=300\ndone\necho \"Removing\ \ the location constraints that were created to move the VIPs\"\nfor v in ${VIPS_TO_MOVE};\ \ do\n echo \"Removing location ban for VIP $v\"\n ban_id=$(cibadmin --query\ \ | xmllint --xpath 'string(//rsc_location[@rsc=\"'${v}'\" and @node=\"'${CLUSTER_NODE}'\"\ \ and @score=\"-INFINITY\"]/@id)' -)\n if [ -n \"$ban_id\" ]; then\n \ \ pcs constraint remove ${ban_id}\n else\n echo \"Could not retrieve\ \ and clear location constraint for VIP $v\" 2>&1\n fi\ndone\n" when: - hostvars[groups['neutron_api'][2]]["haproxy_node_names"]|default([])|length > 1 - groups['neutron_api'] | default([]) | length > 2 - delegate_to: '{{groups[''neutron_api''][2]}}' name: Create firewall nat prerouting and postrouting shell: "set -o pipefail\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][2]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nif [[\ \ $IP =~ .*:.* ]]\n then\n PROTOCOL=\"ip6\"\n # we need to temporarly\ \ allow ipv6 forwarding, this will get reset by deployment run\n sysctl\ \ -w net.ipv6.conf.all.forwarding=1\n else PROTOCOL=\"ip\"\nfi\nnft add table\ \ $PROTOCOL nat\nnft -- add chain $PROTOCOL nat prerouting { type nat hook prerouting\ \ priority -100 \\; }\nnft add chain $PROTOCOL nat postrouting { type nat hook\ \ postrouting priority 100 \\; }\n" when: - groups['neutron_api'] | default([]) | length > 2 - delegate_to: '{{groups[''neutron_api''][2]}}' name: Redirect neutron backend traffic for 60s to other host shell: "set -o pipefail\nsource /etc/os-release; test \"${VERSION_ID%*}\" = \"\ 9.0\" && exit 0\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][2]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nREMOTE_BACKEND=$(grep \":9696\ \ \" /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg |\ \ \\\n grep server | grep -v {{groups['neutron_api'][2]}} | head -n1 | awk\ \ '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nPORT=9696\nif [[ $IP =~ .*:.* ]]\n\ \ then PROTOCOL=\"ip6\"\n else PROTOCOL=\"ip\"\nfi\nREMOTE_IP=${REMOTE_BACKEND%:*}\n\ nft add rule $PROTOCOL nat postrouting $PROTOCOL daddr $REMOTE_IP tcp dport\ \ 9696 counter meta time $(date +%s)-$(date -d'+60 seconds' +%s) masquerade\ \ comment neutron_api\nnft add rule $PROTOCOL nat prerouting $PROTOCOL daddr\ \ $IP tcp dport 9696 counter meta time $(date +%s)-$(date -d'+60 seconds' +%s)\ \ dnat to $REMOTE_IP comment neutron_api\n" when: - groups['neutron_api'] | default([]) | length > 2 - become: true delegate_to: '{{groups[''neutron_api''][2]}}' name: Insanity neutron update first tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_4 config_id: - neutron_api config_overrides: .*neutron_api: image: registry.redhat.io/rhosp-rhel9/openstack-neutron-server:17.1 name: neutron_api config_patterns: '*neutron_api.json' when: - groups['neutron_api'] | default([]) | length > 2 - wait_for: timeout: 50 when: - groups['neutron_api'] | default([]) | length > 2 - delegate_to: '{{groups[''neutron_api''][2]}}' name: Delete redirect rules shell: "set -o pipefail\nLOCAL_BACKEND=$(grep {{groups['neutron_api'][2]}} /var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg\ \ | \\\n grep \":9696 \" | awk '{print $3}')\nIP=${LOCAL_BACKEND%:*}\nif [[\ \ $IP =~ .*:.* ]]\n then PROTOCOL=\"ip6\"\n else PROTOCOL=\"ip\"\nfi\nnft\ \ -a list chain $PROTOCOL nat postrouting | grep neutron_api | awk -F# '{print\ \ \"nat postrouting \"$2}' | \\\nwhile read i; do bash -c \"nft delete rule\ \ $PROTOCOL $i\"; done\nnft -a list chain $PROTOCOL nat prerouting | grep neutron_api\ \ | awk -F# '{print \"nat prerouting \"$2}' | \\\nwhile read i; do bash -c \"\ nft delete rule $PROTOCOL $i\"; done\n" when: - groups['neutron_api'] | default([]) | length > 2 name: Update neutron_api first everywhere tags: - ovn - ovn_image when: - step|int == 1 - neutron_python_ovs_3_1.rc == 0 - block: - name: Set facts for running online DB migrations set_fact: is_additional_cell: false tags: - online_upgrade - online_upgrade_nova - become: true command: '{{ container_cli }} exec nova_conductor nova-manage db online_data_migrations' delegate_to: '{{ (groups[''nova_conductor''] | difference(groups[''excluded_overcloud'']))[0] }}' name: Online data migration for Nova tags: - online_upgrade - online_upgrade_nova when: not is_additional_cell|bool when: step|int == 1 - async: 600 become: true containers.podman.podman_image: force: true name: registry.redhat.io/rhosp-rhel9/openstack-ovn-controller:17.1 validate_certs: false delegate_to: '{{ item }}' loop: '{{ groups[''ovn_controller''] | difference(groups[''excluded_overcloud'']) }}' name: Force pull image in case image name doesn't change. poll: 0 register: ovn_controller_image_update tags: - ovn - ovn_image when: step|int == 1 - async_status: jid: '{{ async_result_item.ansible_job_id }}' become: true delay: 1 delegate_to: '{{ async_result_item.item }}' loop: '{{ovn_controller_image_update.results }}' loop_control: loop_var: async_result_item name: Was the ovn_controller image pull successful. register: async_poll_results retries: 600 tags: - ovn - ovn_image until: async_poll_results.finished when: - step|int == 1 - '''results'' in ovn_controller_image_update' - debug: msg: ovn container will be using {{ image }} name: OVN Container image used tags: ovn vars: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-controller:17.1 when: step|int == 1 - async: 600 become: true delegate_to: '{{ item }}' loop: '{{ groups[''ovn_controller''] | difference(groups[''excluded_overcloud'']) }}' name: Update OVN OVS related parameters before update. poll: 0 register: ovs_vsctl shell: 'set -e ovs-vsctl set Open_vSwitch . external_ids:ovn-ofctrl-wait-before-clear={{ timeout }} ovs-vsctl set Open_vSwitch . external_ids:ovn-monitor-all=true ovs-vsctl set Open_vSwitch . external_ids:ovn-match-northd-version=false ' tags: - ovn vars: timeout: 8000 when: - step|int == 1 - async_status: jid: '{{ async_result_item.ansible_job_id }}' become: true delay: 1 delegate_to: '{{ async_result_item.item }}' loop: '{{ovs_vsctl.results }}' loop_control: loop_var: async_result_item name: Was the update of OVN OVS related parameter successful. register: async_poll_results retries: 600 tags: - ovn until: async_poll_results.finished when: - step|int == 1 - '''results'' in ovs_vsctl' - set_fact: any_ovn_host: '{{groups[''ovn_controller''] | difference(groups[''excluded_overcloud'']) | first }}' tags: ovn when: step|int == 1 - become: true delegate_to: '{{ any_ovn_host }}' find: paths: /var/lib/tripleo-config/container-startup-config/ patterns: '*ovn_controller.json' recurse: true name: Find ovn_controller configs in container-startup-configs register: ovn_cont_17_0 tags: - ovn when: (step|int == 1) and (any_ovn_host is defined) and (any_ovn_host|length > 0) - name: get directory path from the ovn_cont_17_0 set_fact: ovn_config_path: '{{ ovn_cont_17_0.files.0.path | dirname }}' tags: ovn when: step|int == 1 - become: true delegate_to: '{{ item }}' loop: '{{ groups[''ovn_controller''] | difference(groups[''excluded_overcloud'']) }}' name: Get PIDfile used by systemd on each ovn node register: pidfile shell: 'set -e grep PID /etc/systemd/system/tripleo_ovn_controller.service | cut -d= -f2 ' tags: - ovn when: - step|int == 1 - async: 600 become: true delegate_to: '{{ item }}' loop: '{{ groups[''ovn_controller''] | difference(groups[''excluded_overcloud'']) }}' name: Update ovn_controller. poll: 0 register: ovn_controller_update tags: ovn tripleo_container_manage: config_dir: '{{ ovn_config_path }}' config_id: - tripleo_step{{config_step}} config_overrides: .*ovn_controller: conmon_pidfile: '{{ pidfile | json_query(query) | first }}' image: registry.redhat.io/rhosp-rhel9/openstack-ovn-controller:17.1 name: ovn_controller config_patterns: '*ovn_controller.json' debug: '{{ enable_debug | bool }}' log_base_path: '{{ container_log_stdout_path }}' vars: config_step: '{{ (''step_4'' in ovn_config_path) | ternary(''4'', ''3'')}}' query: results[?item == '{{item}}'].stdout when: step|int == 1 - async_status: jid: '{{ async_result_item.ansible_job_id }}' become: true delay: 1 delegate_to: '{{ async_result_item.item }}' loop: '{{ovn_controller_update.results }}' loop_control: loop_var: async_result_item name: Was the ovn_controller successful. register: async_poll_results retries: 600 tags: ovn until: async_poll_results.finished when: - step|int == 1 - '''results'' in ovn_controller_update' - name: Pause for 30s to give ovn_controllers time to reconnect to dbs tags: ovn wait_for: timeout: 30 when: - step|int == 1 - block: - become: true delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) }}' name: Get OVN_Northbound cluster leader register: ovn_nb_dbs_cluster_leader shell: 'podman exec -u root ovn_cluster_north_db_server ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | grep ''Leader: '' ' - set_fact: ovn_nb_leader: '{{ ovn_nb_dbs_cluster_leader| json_query("results[?contains(stdout,''Leader: self'')].item") }}' - become: true delegate_to: '{{ ovn_nb_leader[0] }}' name: Graceful stop OVN NB leader container shell: 'podman exec -u root ovn_cluster_north_db_server ovs-appctl -t /var/run/ovn/ovnnb_db.ctl exit ' - become: true delegate_to: '{{ ovn_nb_leader[0] }}' name: Start OVN NB leader container tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_north_db_server config_overrides: .*ovn_cluster_north_db_server: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-nb-db-server:17.1 name: ovn_cluster_north_db_server config_patterns: '*ovn_cluster_north_db_server.json' - become: true delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) }}' name: Get OVN_Southbound cluster leader register: ovn_sb_dbs_cluster_leader shell: 'sudo podman exec -u root ovn_cluster_south_db_server ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | grep ''Leader: '' ' - set_fact: ovn_sb_leader: '{{ ovn_sb_dbs_cluster_leader | json_query("results[?contains(stdout,''Leader: self'')].item") }}' - become: true delegate_to: '{{ ovn_sb_leader[0] }}' name: Graceful stop OVN SB leader container shell: 'sudo podman exec -u root ovn_cluster_south_db_server ovs-appctl -t /var/run/ovn/ovnsb_db.ctl exit ' - become: true delegate_to: '{{ ovn_sb_leader[0] }}' name: Start OVN SB leader container tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_south_db_server config_overrides: .*ovn_cluster_south_db_server: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-sb-db-server:17.1 name: ovn_cluster_south_db_server config_patterns: '*ovn_cluster_south_db_server.json' - become: true delay: 5 delegate_to: '{{ groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) | difference(ovn_nb_leader[0]) | first }}' failed_when: '''Leader: unknown'' in wait_leader.stdout or wait_leader.stderr != ''''' name: Loop on OVN_Northbound cluster for leader election register: wait_leader retries: 10 shell: 'podman exec -u root ovn_cluster_north_db_server ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | grep ''Leader: '' ' until: '''Leader: unknown'' not in wait_leader.stdout and wait_leader.stderr == ''''' - become: true delay: 5 delegate_to: '{{ groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) | difference(ovn_nb_leader[0]) | first }}' failed_when: '''Leader: unknown'' in wait_leader.stdout or wait_leader.stderr != ''''' name: Loop on OVN_Southbound cluster for leader election register: wait_leader retries: 10 shell: 'podman exec -u root ovn_cluster_south_db_server ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | grep ''Leader: '' ' until: '''Leader: unknown'' not in wait_leader.stdout and wait_leader.stderr == ''''' - name: Pause for 30 seconds to ensure ovn db leader knows it was elected and clients reconnect wait_for: timeout: 30 - become: true delay: 5 delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) }}' name: Get OVN_Northbound cluster new leader register: ovn_nb_dbs_cluster_leader_new retries: 10 shell: 'podman exec -u root ovn_cluster_north_db_server ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | grep ''Leader: '' ' until: '''Leader: unknown'' not in ovn_nb_dbs_cluster_leader_new.stdout' - set_fact: ovn_nb_leader_new: '{{ ovn_nb_dbs_cluster_leader_new| json_query("results[?contains(stdout,''Leader: self'')].item") }}' - become: true delay: 5 delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) }}' name: Get OVN_Southbound cluster new leader register: ovn_sb_dbs_cluster_leader_new retries: 10 shell: 'sudo podman exec -u root ovn_cluster_south_db_server ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | grep ''Leader: '' ' until: '''Leader: unknown'' not in ovn_sb_dbs_cluster_leader_new.stdout' - set_fact: ovn_sb_leader_new: '{{ ovn_sb_dbs_cluster_leader_new | json_query("results[?contains(stdout,''Leader: self'')].item") }}' - become: true delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) | difference(ovn_nb_leader[0])| difference(ovn_nb_leader_new[0])}}' loop_control: pause: 15 name: Start OVN NB containers (non-leader nodes) tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_north_db_server config_overrides: .*ovn_cluster_north_db_server: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-nb-db-server:17.1 name: ovn_cluster_north_db_server config_patterns: '*ovn_cluster_north_db_server.json' - become: true delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud'']) | difference(ovn_sb_leader[0])| difference(ovn_sb_leader_new[0])}}' loop_control: pause: 15 name: Start OVN SB containers (non-leader nodes) tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_south_db_server config_overrides: .*ovn_cluster_south_db_server: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-sb-db-server:17.1 name: ovn_cluster_south_db_server config_patterns: '*ovn_cluster_south_db_server.json' - name: Pause for 50 seconds before restarting new leaders of OVN wait_for: timeout: 50 - become: true delegate_to: '{{ ovn_nb_leader_new[0] }}' name: Graceful stop OVN NB new-leader container shell: 'podman exec -u root ovn_cluster_north_db_server ovs-appctl -t /var/run/ovn/ovnnb_db.ctl exit ' when: ovn_nb_leader_new[0] != ovn_nb_leader[0] - become: true delegate_to: '{{ ovn_nb_leader_new[0] }}' name: Start OVN NB containers (new-leader nodes) tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_north_db_server config_overrides: .*ovn_cluster_north_db_server: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-nb-db-server:17.1 name: ovn_cluster_north_db_server config_patterns: '*ovn_cluster_north_db_server.json' when: ovn_nb_leader_new[0] != ovn_nb_leader[0] - become: true delegate_to: '{{ ovn_sb_leader_new[0] }}' name: Graceful stop OVN SB new-leader container shell: 'sudo podman exec -u root ovn_cluster_south_db_server ovs-appctl -t /var/run/ovn/ovnsb_db.ctl exit ' when: ovn_sb_leader_new[0] != ovn_sb_leader[0] - become: true delegate_to: '{{ ovn_sb_leader_new[0] }}' name: Start OVN SB containers (new-leader nodes) tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_south_db_server config_overrides: .*ovn_cluster_south_db_server: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-sb-db-server:17.1 name: ovn_cluster_south_db_server config_patterns: '*ovn_cluster_south_db_server.json' when: ovn_sb_leader_new[0] != ovn_sb_leader[0] - become: true delegate_to: '{{ item }}' loop: '{{groups[''ovn_dbs''] | difference(groups[''excluded_overcloud''])}}' loop_control: pause: 15 name: Start OVN northd container tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_0 config_id: - ovn_cluster_northd config_overrides: .*ovn_cluster_northd: image: registry.redhat.io/rhosp-rhel9/openstack-ovn-northd:17.1 name: ovn_cluster_northd config_patterns: '*ovn_cluster_northd.json' name: Run ovndbs update tags: - ovn - ovn_image when: step|int == 2 - become: true delegate_to: '{{ item }}' failed_when: false loop: '{{ groups[''ovn_metadata''] | difference(groups[''excluded_overcloud'']) }}' name: Check if python3-openvswitch3.1 workaround is needed register: metadata_python_ovs_3_1 shell: 'if podman exec ovn_metadata_agent rpm -q python3-openvswitch3.1 > /dev/null ; then echo REQUIRED; else echo OK ; fi ' tags: - ovn - ovn_image when: step|int == 1 - block: - async: 600 become: true containers.podman.podman_image: force: true name: registry.redhat.io/rhosp-rhel9/openstack-neutron-metadata-agent-ovn:17.1 validate_certs: false delegate_to: '{{ item }}' loop: '{{ hosts_to_update_metadata }}' name: Force pull image in case image name doesn't change. poll: 0 register: ovn_metadata_image_update - async_status: jid: '{{ async_result_item.ansible_job_id }}' become: true delay: 1 delegate_to: '{{ async_result_item.item }}' loop: '{{ovn_metadata_image_update.results }}' loop_control: loop_var: async_result_item name: Was the ovn_metadata_agent image pull successful. register: async_poll_results retries: 600 until: async_poll_results.finished when: - '''results'' in ovn_metadata_image_update' - async: 600 become: true delegate_to: '{{ item }}' loop: '{{ hosts_to_update_metadata }}' name: Now rotate all ovn_metadata_agents poll: 0 tags: - ovn_metadata_parallel tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_4 config_id: - ovn_metadata_agent config_overrides: .*ovn_metadata_agent: image: registry.redhat.io/rhosp-rhel9/openstack-neutron-metadata-agent-ovn:17.1 name: ovn_metadata_agent config_patterns: '*ovn_metadata_agent.json' name: Update ovn_metadata_agents tags: - ovn - ovn_image vars: hosts_to_update_metadata: '{{ metadata_python_ovs_3_1.results | selectattr(''stdout'', ''eq'', ''REQUIRED'') | map(attribute=''item'') | list }}' when: - step|int == 1 - hosts_to_update_metadata | length > 0 - become: true delegate_to: '{{ item }}' loop: '{{ hosts_to_update_metadata }}' loop_control: pause: 1 name: Now rotate all ovn_metadata_agents tags: - never - ovn_metadata_serial tripleo_container_manage: config_dir: /var/lib/tripleo-config/container-startup-config/step_4 config_id: - ovn_metadata_agent config_overrides: .*ovn_metadata_agent: image: registry.redhat.io/rhosp-rhel9/openstack-neutron-metadata-agent-ovn:17.1 name: ovn_metadata_agent config_patterns: '*ovn_metadata_agent.json' vars: hosts_to_update_metadata: '{{ metadata_python_ovs_3_1.results | selectattr(''stdout'', ''eq'', ''REQUIRED'') | map(attribute=''item'') | list }}' when: - step|int == 1 - hosts_to_update_metadata | length > 0 - block: - block: - become: true name: Get rabbitmq image from pacemaker register: xmllint_pcmk_rabbitmq_rpc_image shell: xmllint --xpath "string(//bundle[@id='rabbitmq-bundle']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container rabbitmq image set_fact: pcmk_rabbitmq_rpc_image: '{{xmllint_pcmk_rabbitmq_rpc_image.stdout}}' rabbitmq_rpc_image: registry.redhat.io/rhosp-rhel9/openstack-rabbitmq:17.1 rabbitmq_rpc_image_latest: cluster.common.tag/rabbitmq:pcmklatest delegate_to: '{{ (groups["oslo_messaging_rpc"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: rabbitmq temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: rabbitmq-bundle tripleo_ha_image_update_new_image: '{{rabbitmq_rpc_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["oslo_messaging_rpc"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_rabbitmq_rpc_image}}' when: - (pcmk_rabbitmq_rpc_image != "") - (pcmk_rabbitmq_rpc_image != rabbitmq_rpc_image_latest) tags: ha_image_update when: step|int == 1 - block: - name: create redis virtual ip tripleo_service_vip: fixed_ips: - ip_address: 192.168.122.99 use_neutron: false network: internal_api playbook_dir: '{{ playbook_dir }}' service_name: redis stack_name: standalone name: redis_external_update_init when: - step|int == 0 - block: - block: - become: true name: Get redis image from pacemaker register: xmllint_pcmk_redis_image shell: xmllint --xpath "string(//bundle[@id='redis-bundle']/podman/@image)" /var/lib/pacemaker/cib/cib.xml - name: Get container redis image set_fact: pcmk_redis_image: '{{xmllint_pcmk_redis_image.stdout}}' redis_image: registry.redhat.io/rhosp-rhel9/openstack-redis:17.1 redis_image_latest: cluster.common.tag/redis:pcmklatest delegate_to: '{{ (groups["redis"] | difference(groups["excluded_overcloud"]))[0] }}' - become: true import_role: name: tripleo_ha_image_update name: redis temporary pacemaker container tag in case of image switch vars: tripleo_ha_image_update_bundle: redis-bundle tripleo_ha_image_update_new_image: '{{redis_image_latest}}' tripleo_ha_image_update_node_names: '{{ groups["redis"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_old_image: '{{pcmk_redis_image}}' when: - (pcmk_redis_image != "") - (pcmk_redis_image != redis_image_latest) tags: ha_image_update when: step|int == 1