:_mod-docs-content-type: PROCEDURE
[id="proc_retrieving-topology-specific-service-configuration_{context}"]

= Retrieving topology-specific service configuration

[role="_abstract"]
Before you migrate your databases to the {rhos_long} control plane, retrieve the topology-specific service configuration from your {rhos_prev_long} ({OpenStackShort}) environment. You need this configuration for the following reasons:

* To check your current database for inaccuracies
* To ensure that you have the data you need before the migration
* To compare your {OpenStackShort} database with the adopted {rhos_acro} database

.Prerequisites

. Define the following shell variables. Replace the example values with values that are correct for your environment:
[NOTE]
If you use IPv6, define the `SOURCE_MARIADB_IP` value without brackets. For example, `SOURCE_MARIADB_IP=fd00:bbbb::2`.
+
----
$ PASSWORD_FILE="$HOME/overcloud-passwords.yaml"
ifeval::["{build}" != "downstream"]
$ MARIADB_IMAGE=quay.io/podified-antelope-centos9/openstack-mariadb:current-podified
endif::[]
ifeval::["{build}" == "downstream"]
$ MARIADB_IMAGE=registry.redhat.io/rhoso/openstack-mariadb-rhel9:18.0
endif::[]
$ declare -A TRIPLEO_PASSWORDS
ifeval::["{build_variant}" != "ospdo"]
$ CELLS="default cell1 cell2"
endif::[]
ifeval::["{build_variant}" == "ospdo"]
$ CELLS="default"
endif::[]
$ for CELL in $(echo $CELLS); do
>    TRIPLEO_PASSWORDS[$CELL]="$PASSWORD_FILE"
> done
ifeval::["{build_variant}" == "ospdo"]
$ oc get secret tripleo-passwords -o json | jq -r '.data["tripleo-overcloud-passwords.yaml"]' | base64 -d >"${TRIPLEO_PASSWORDS[$CELLS]}"
endif::[]
$ declare -A SOURCE_DB_ROOT_PASSWORD
$ for CELL in $(echo $CELLS); do
>     SOURCE_DB_ROOT_PASSWORD[$CELL]=$(cat ${TRIPLEO_PASSWORDS[$CELL]} | grep ' MysqlRootPassword:' | awk -F ': ' '{ print $2; }')
> done
----
+
ifeval::["{build_variant}" == "ospdo"]
* You can only deploy a single {compute service} cell on the source cloud.

. Get the name of the {OpenShiftShort} node where the {OpenStackShort} Controller virtual machine is running:
+
----
$ export CONTROLLER_NODE=$(oc get vmi -ojson | jq -r '.items[0].status.nodeName')
$ export SOURCE_OVN_OVSDB_IP=$(oc get cm tripleo-exports-default -o json | jq -r '.data["ctlplane-export.yaml"]' | awk '/ovn_controller_bootstrap_node_ip/ {print $2}')
----

. Find the mysql service IP in the `ctlplane-export.yaml` section of the `tripleo-exports-default` ConfigMap:
+
----
$ cpexport=$(oc get cm tripleo-exports-default -o json | jq -r '.data["ctlplane-export.yaml"]')
$ declare -A SOURCE_MARIADB_IP
$ for CELL in $(echo $CELLS); do
>     SOURCE_MARIADB_IP[$CELL]=$(echo "$cpexport" | sed -e '0,/ MysqlInternal/d' | sed -n '0,/host_nobrackets/s/^.*host_nobrackets\:\s*\(.*\)$/\1/p')
> done
$ RUN_OVERRIDES='{
>     "apiVersion": "v1",
>     "metadata": {
>         "annotations": {
>             "k8s.v1.cni.cncf.io/networks": "[{\"name\": \"internalapi-static\",\"namespace\": \"openstack\", \"ips\":[\"172.17.0.99/24\"]}]"
>         }
>     },
>     "spec": {
>         "nodeName": "'"$CONTROLLER_NODE"'",
>         "securityContext": {
>             "allowPrivilegeEscalation": false,
>             "capabilities": {
>                 "drop": ["ALL"]
>             },
>             "runAsNonRoot": true,
>             "seccompProfile": {
>                 "type": "RuntimeDefault"
>             }
>         }
>     }
> }'
----
+
* The `mariadb-client` needs to run on the same {rhocp_long} node where the {OpenStackShort} Controller node is running. In addition, the `internalapi-static` network needs to be attached to the pod.
endif::[]

. Define the following shell variables. Replace the example values with values that are correct for your environment:
+
----
ifeval::["{build_variant}" != "ospdo"]
$ MARIADB_CLIENT_ANNOTATIONS='--annotations=k8s.v1.cni.cncf.io/networks=internalapi'
$ MARIADB_RUN_OVERRIDES="$MARIADB_CLIENT_ANNOTATIONS"
----
+
[NOTE]
====
For environments that are enabled with border gateway protocol (BGP), the network annotation must include a default route to enable proper routing. Use the following instead:

----
$ MARIADB_CLIENT_ANNOTATIONS='--annotations=k8s.v1.cni.cncf.io/networks=[{"name":"internalapi","namespace":"openstack","default-route":["<172.17.0.1>"]}]'
$ MARIADB_RUN_OVERRIDES="$MARIADB_CLIENT_ANNOTATIONS"
----
where:

<172.17.0.1>::
Replace with the gateway IP address of your `internalapi` network.
====
+
----

ifeval::["{build}" != "downstream"]
$ CONTROLLER1_SSH="ssh -i ~/install_yamls/out/edpm/ansibleee-ssh-key-id_rsa root@192.168.122.100"
endif::[]
ifeval::["{build}" == "downstream"]
$ CONTROLLER1_SSH="ssh -i *<path to SSH key>* tripleo-admin@*<node IP>*"
endif::[]
endif::[]
ifeval::["{build_variant}" == "ospdo"]
$ MARIADB_RUN_OVERRIDES="--overrides='${RUN_OVERRIDES}' $MARIADB_CLIENT_ANNOTATIONS"

$ CONTROLLER1_SSH="oc rsh -c openstackclient openstackclient ssh controller-0.ctlplane"
$ oc get secret tripleo-passwords -o json | jq -r '.data["tripleo-overcloud-passwords.yaml"]' |
base64 -d >"${PASSWORD_FILE}"
endif::[]

$ declare -A SOURCE_MARIADB_IP
$ SOURCE_MARIADB_IP[default]=*<galera cluster VIP>*
ifeval::["{build_variant}" != "ospdo"]
$ SOURCE_MARIADB_IP[cell1]=*<galera cell1 cluster VIP>*
$ SOURCE_MARIADB_IP[cell2]=*<galera cell2 cluster VIP>*
# ...
endif::[]
----
+
* Provide `CONTROLLER1_SSH` settings with SSH connection details for any non-cell Controller of the source {OpenStackPreviousInstaller} cloud.
* For each cell that is defined in `CELLS`, replace `SOURCE_MARIADB_IP[*]= ...`, with the records lists for the cell names and VIP addresses of MariaDB Galera clusters, including the cells, of the source {OpenStackPreviousInstaller} cloud.
* To get the values for `SOURCE_MARIADB_IP`, query the puppet-generated configurations in a Controller
ifeval::["{build_variant}" != "ospdo"]
and CellController
endif::[]
node:
+
----
$ sudo grep -rI 'listen mysql' -A10 /var/lib/config-data/puppet-generated/ | grep bind
----
+

[NOTE]
The source cloud always uses the same password for cells databases. For that reason, the same passwords file is used for all cells stacks. However, split-stack topology allows using different passwords files for each stack.

.Procedure

. If your source {OpenStackShort} environment uses border gateway protocol (BGP) for Layer 3 networking, create a `BGPConfiguration` custom resource to enable BGP routing:
+
----
$ cat << EOF > bgp.yaml
apiVersion: network.openstack.org/v1beta1
kind: BGPConfiguration
metadata:
  name: bgpconfiguration
  namespace: openstack
spec: {}
EOF

$ oc apply -f bgp.yaml
----
+
The `BGPConfiguration` resource enables BGP route advertisement between the {rhocp_long} cluster and the source cloud, which is necessary for the `mariadb-client` pod to reach the source MariaDB cluster.

. Create a persistent `mariadb-client` pod for database operations:
+
----
$ oc delete pod mariadb-client || true
$ oc run mariadb-client ${MARIADB_RUN_OVERRIDES} -q --image ${MARIADB_IMAGE} --restart=Never -- /usr/bin/sleep infinity
----
+
This creates a long-running pod that is used for all subsequent database operations, avoiding the need to create temporary pods for each command.

. Wait for the `mariadb-client` pod to be able to reach the source MariaDB:
+
----
$ oc rsh mariadb-client mysql -rsh "${SOURCE_MARIADB_IP[default]}" -uroot -p"${SOURCE_DB_ROOT_PASSWORD[default]}" -e 'select 1;'
----
+
[NOTE]
====
For BGP-enabled environments, this command might take a few moments to succeed while BGP routes are advertised and propagated through the network. The `mariadb-client` pod needs to receive the route to the source MariaDB IP address through BGP before it can establish a connection. If the command fails, wait a few seconds and retry. The connection should succeed once the BGP route advertisement is complete.

For IPv6 environments, this command might take a few moments to succeed while the network IPv6 stack completes its setup. If the command fails, wait a few seconds and retry.

For standard deployments, such as non-BGP deployments or IPv4 deployments, this command should succeed immediately.
====

. Export the shell variables for the following outputs and test the connection to the {OpenStackShort} database:
+
----
$ unset PULL_OPENSTACK_CONFIGURATION_DATABASES
$ declare -xA PULL_OPENSTACK_CONFIGURATION_DATABASES
$ for CELL in $(echo $CELLS); do
>     PULL_OPENSTACK_CONFIGURATION_DATABASES[$CELL]=$(oc rsh mariadb-client \
>         mysql -rsh "${SOURCE_MARIADB_IP[$CELL]}" -uroot -p"${SOURCE_DB_ROOT_PASSWORD[$CELL]}" -e 'SHOW databases;')
> done
----
+
If the connection is successful, the expected output is nothing.
+
[NOTE]
The `nova`, `nova_api`, and `nova_cell0` databases are included in the same database host for the main overcloud {orchestration_first_ref} stack.
ifeval::["{build_variant}" != "ospdo"]
Additional cells use the `nova` database of their local Galera clusters.
endif::[]

. Run `mysqlcheck` on the {OpenStackShort} database to check for inaccuracies:
+
----
$ unset PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK
$ declare -xA PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK
$ run_mysqlcheck() {
>     PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK=$(oc rsh mariadb-client \
>         mysqlcheck --all-databases -h ${SOURCE_MARIADB_IP[$CELL]} -u root -p"${SOURCE_DB_ROOT_PASSWORD[$CELL]}" | grep -v OK)
> }
$ for CELL in $(echo $CELLS); do
>     run_mysqlcheck $CELL
> done
$ if [ "$PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK" != "" ]; then
>     for CELL in $(echo $CELLS); do
>         MYSQL_UPGRADE=$(oc rsh mariadb-client \
>             mysql_upgrade --skip-version-check -v -h ${SOURCE_MARIADB_IP[$CELL]} -u root -p"${SOURCE_DB_ROOT_PASSWORD[$CELL]}")
>         # rerun mysqlcheck to check if problem is resolved
>         run_mysqlcheck
>     done
> fi
----

. Get the {compute_service_first_ref} cell mappings:
+
----
export PULL_OPENSTACK_CONFIGURATION_NOVADB_MAPPED_CELLS=$(oc rsh mariadb-client \
    mysql -rsh "${SOURCE_MARIADB_IP[default]}" -uroot -p"${SOURCE_DB_ROOT_PASSWORD[default]}" nova_api -e \
    'select uuid,name,transport_url,database_connection,disabled from cell_mappings;')
----

. Get the hostnames of the registered Compute services:
+
----
$ unset PULL_OPENSTACK_CONFIGURATION_NOVA_COMPUTE_HOSTNAMES
$ declare -xA PULL_OPENSTACK_CONFIGURATION_NOVA_COMPUTE_HOSTNAMES
$ for CELL in $(echo $CELLS); do
>     PULL_OPENSTACK_CONFIGURATION_NOVA_COMPUTE_HOSTNAMES[$CELL]=$(oc rsh mariadb-client \
>         mysql -rsh "${SOURCE_MARIADB_IP[$CELL]}" -uroot -p"${SOURCE_DB_ROOT_PASSWORD[$CELL]}" -e \
>             "select host from nova.services where services.binary='nova-compute' and deleted=0;")
> done
----

. Get the list of the mapped {compute_service} cells:
+
----
export PULL_OPENSTACK_CONFIGURATION_NOVAMANAGE_CELL_MAPPINGS=$($CONTROLLER1_SSH sudo podman exec -it nova_conductor nova-manage cell_v2 list_cells)
----

. Store the exported variables for future use:
+
----
$ unset SRIOV_AGENTS
$ declare -xA SRIOV_AGENTS
$ for CELL in $(echo $CELLS); do
>     RCELL=$CELL
>     [ "$CELL" = "$DEFAULT_CELL_NAME" ] && RCELL=default
>     cat > ~/.source_cloud_exported_variables_$CELL << EOF
> unset PULL_OPENSTACK_CONFIGURATION_DATABASES
> unset PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK
> unset PULL_OPENSTACK_CONFIGURATION_NOVA_COMPUTE_HOSTNAMES
> declare -xA PULL_OPENSTACK_CONFIGURATION_DATABASES
> declare -xA PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK
> declare -xA PULL_OPENSTACK_CONFIGURATION_NOVA_COMPUTE_HOSTNAMES
> PULL_OPENSTACK_CONFIGURATION_DATABASES[$CELL]="$(oc rsh mariadb-client \
>     mysql -rsh ${SOURCE_MARIADB_IP[$RCELL]} -uroot -p${SOURCE_DB_ROOT_PASSWORD[$RCELL]} -e 'SHOW databases;')"
> PULL_OPENSTACK_CONFIGURATION_MYSQLCHECK_NOK[$CELL]="$(oc rsh mariadb-client \
>     mysqlcheck --all-databases -h ${SOURCE_MARIADB_IP[$RCELL]} -u root -p${SOURCE_DB_ROOT_PASSWORD[$RCELL]} | grep -v OK)"
> PULL_OPENSTACK_CONFIGURATION_NOVA_COMPUTE_HOSTNAMES[$CELL]="$(oc rsh mariadb-client \
>     mysql -rsh ${SOURCE_MARIADB_IP[$RCELL]} -uroot -p${SOURCE_DB_ROOT_PASSWORD[$RCELL]} -e \
>     "select host from nova.services where services.binary='nova-compute' and deleted=0;")"
> if [ "$RCELL" = "default" ]; then
>     PULL_OPENSTACK_CONFIGURATION_NOVADB_MAPPED_CELLS="$(oc rsh mariadb-client \
>         mysql -rsh ${SOURCE_MARIADB_IP[$RCELL]} -uroot -p${SOURCE_DB_ROOT_PASSWORD[$RCELL]} nova_api -e \
>             'select uuid,name,transport_url,database_connection,disabled from cell_mappings;')"
>     PULL_OPENSTACK_CONFIGURATION_NOVAMANAGE_CELL_MAPPINGS="$($CONTROLLER1_SSH sudo podman exec -it nova_conductor nova-manage cell_v2 list_cells)"
> fi
> EOF
> done
$ chmod 0600 ~/.source_cloud_exported_variables*
----
+
* `declare -xA SRIOV_AGENTS` gets the `neutron-sriov-nic-agent` configuration to use for the data plane adoption if `neutron-sriov-nic-agent` agents are running in your {OpenStackShort} deployment.

. Clean up the `mariadb-client` pod:
+
----
$ oc delete pod mariadb-client
----
+
The `mariadb-client` pod is no longer needed after all the data is exported and stored.

.Next steps

This configuration and the exported values are required later, during the data plane adoption post-checks. After the {OpenStackShort} control plane services are shut down, if any of the exported values are lost, re-running the `export` command fails because the control plane services are no longer running on the source cloud, and the data cannot be retrieved. To avoid data loss, preserve the exported values in an environment file before shutting down the control plane services.
