Add mariadb-cli, kubectl and openstack commands to collect

This adds containerized related commands to collect:
- containerized wrapper script mariadb-cli to access MariaDB mysql
- various kubectl commands to understand resource usage
- various containerized openstack commands to understand resource usage

mariadb-cli is used to dump contents of all mariadb databases.

Change-Id: I70a08e38adbba247152509a22a8b9beac9128ff9
Closes-Bug: 1889678
Closes-Bug: 1894103
Signed-off-by: Jim Gauld <james.gauld@windriver.com>
This commit is contained in:
Jim Gauld 2020-09-08 11:13:24 -04:00
parent 533d4fff06
commit dd902cf386
5 changed files with 515 additions and 52 deletions

View File

@ -32,9 +32,11 @@ install -m 755 collect_utils %{buildroot}/usr/local/sbin/collect_utils
install -m 755 collect_parms %{buildroot}/usr/local/sbin/collect_parms
install -m 755 collect_mask_passwords %{buildroot}/usr/local/sbin/collect_mask_passwords
install -m 755 expect_done %{buildroot}/usr/local/sbin/expect_done
install -m 755 mariadb-cli.sh %{buildroot}/usr/local/sbin/mariadb-cli
install -m 755 collect_sysinv.sh %{buildroot}%{_sysconfdir}/collect.d/collect_sysinv
install -m 755 collect_psqldb.sh %{buildroot}%{_sysconfdir}/collect.d/collect_psqldb
install -m 755 collect_mariadb.sh %{buildroot}%{_sysconfdir}/collect.d/collect_mariadb
install -m 755 collect_openstack.sh %{buildroot}%{_sysconfdir}/collect.d/collect_openstack
install -m 755 collect_networking.sh %{buildroot}%{_sysconfdir}/collect.d/collect_networking
install -m 755 collect_ceph.sh %{buildroot}%{_sysconfdir}/collect.d/collect_ceph

View File

@ -13,6 +13,14 @@ source /usr/local/sbin/collect_utils
SERVICE="containerization"
LOGFILE="${extradir}/${SERVICE}.info"
LOGFILE_EVENT="${extradir}/${SERVICE}_events.info"
LOGFILE_API="${extradir}/${SERVICE}_api.info"
LOGFILE_HOST="${extradir}/${SERVICE}_host.info"
LOGFILE_IMG="${extradir}/${SERVICE}_images.info"
LOGFILE_KUBE="${extradir}/${SERVICE}_kube.info"
LOGFILE_PODS="${extradir}/${SERVICE}_pods.info"
LOGFILE_HELM="${extradir}/${SERVICE}_helm.info"
HELM_DIR="${extradir}/helm"
ETCD_DB_FILE="${extradir}/etcd_database.dump"
KUBE_CONFIG_FILE="/etc/kubernetes/admin.conf"
@ -26,57 +34,131 @@ mkdir -p ${HELM_DIR}
source_openrc_if_needed
CMD="docker image ls -a"
delimiter ${LOGFILE} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
delimiter ${LOGFILE_IMG} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_IMG}
CMD="crictl images"
delimiter ${LOGFILE} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
delimiter ${LOGFILE_IMG} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_IMG}
CMD="docker container ps -a"
delimiter ${LOGFILE} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
delimiter ${LOGFILE_IMG} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_IMG}
CMD="crictl ps -a"
delimiter ${LOGFILE} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
delimiter ${LOGFILE_IMG} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_IMG}
CMD="cat /var/lib/kubelet/cpu_manager_state | python -mjson.tool"
delimiter ${LOGFILE_HOST} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HOST}
###############################################################################
# Active Controller
###############################################################################
if [ "$nodetype" = "controller" -a "${ACTIVE}" = true ] ; then
declare -a KUBE_CMDS=(
"kubectl ${KUBE_CONFIG} version"
"kubectl ${KUBE_CONFIG} api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl ${KUBE_CONFIG} get --show-kind --ignore-not-found --all-namespaces"
"kubectl ${KUBE_CONFIG} api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl ${KUBE_CONFIG} get --show-kind --ignore-not-found --all-namespaces -o yaml"
"kubectl ${KUBE_CONFIG} get pvc --all-namespaces"
"kubectl ${KUBE_CONFIG} get pvc --all-namespaces -o yaml"
"kubectl ${KUBE_CONFIG} get pv --all-namespaces"
"kubectl ${KUBE_CONFIG} get pv --all-namespaces -o yaml"
"kubectl ${KUBE_CONFIG} get events --all-namespaces --sort-by='.metadata.creationTimestamp' -o go-template='{{range .items}}{{printf \"%s %s\t%s\t%s\t%s\t%s\n\" .firstTimestamp .involvedObject.name .involvedObject.kind .message .reason .type}}{{end}}'"
)
# Environment for kubectl and helm
export KUBECONFIG=${KUBE_CONFIG_FILE}
for CMD in "${KUBE_CMDS[@]}" ; do
delimiter ${LOGFILE} "${CMD}"
eval ${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
declare -a CMDS=()
CMDS+=("kubectl version")
CMDS+=("kubectl get nodes -o wide")
CMDS+=("kubectl get nodes --show-labels")
CMDS+=("kubectl get nodes -o json")
CMDS+=("kubectl describe nodes")
CMDS+=("kubectl services")
CMDS+=("kubectl get configmaps --all-namespaces")
CMDS+=("kubectl get daemonsets --all-namespaces")
CMDS+=("kubectl get pods --all-namespaces -o wide")
CMDS+=("kubectl get pvc --all-namespaces")
CMDS+=("kubectl get pvc --all-namespaces -o yaml")
CMDS+=("kubectl get pv --all-namespaces")
CMDS+=("kubectl get pv --all-namespaces -o yaml")
CMDS+=("kubectl get sc --all-namespaces")
CMDS+=("kubectl get serviceaccounts --all-namespaces")
CMDS+=("kubectl get deployments.apps --all-namespaces")
CMDS+=("kubectl get rolebindings.rbac.authorization.k8s.io --all-namespaces")
CMDS+=("kubectl get roles.rbac.authorization.k8s.io --all-namespaces")
CMDS+=("kubectl get clusterrolebindings.rbac.authorization.k8s.io")
CMDS+=("kubectl get clusterroles.rbac.authorization.k8s.io")
for CMD in "${CMDS[@]}" ; do
delimiter ${LOGFILE_KUBE} "${CMD}"
eval ${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_KUBE}
echo >>${LOGFILE_KUBE}
done
CMD="helm ${KUBE_CONFIG} version"
delimiter ${LOGFILE} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
# api-resources; verbose, place in separate file
CMDS=()
CMDS+=("kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found --all-namespaces")
CMDS+=("kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found --all-namespaces -o yaml")
for CMD in "${CMDS[@]}" ; do
delimiter ${LOGFILE_API} "${CMD}"
eval ${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_API}
echo >>${LOGFILE_API}
done
CMD="helm ${KUBE_CONFIG} list -a"
delimiter ${LOGFILE} "${CMD}"
APPLIST=$(${CMD} 2>>${COLLECT_ERROR_LOG} | tee -a ${LOGFILE})
APPLIST=$(echo "${APPLIST}" | awk '{if (NR!=1) {print}}')
while read -r app; do
APPNAME=$(echo ${app} | awk '{print $1}')
APPREVISION=$(echo ${app} | awk '{print $2}')
helm ${KUBE_CONFIG} status ${APPNAME} > ${HELM_DIR}/${APPNAME}.status
helm ${KUBE_CONFIG} get values ${APPNAME} --revision ${APPREVISION} \
> ${HELM_DIR}/${APPNAME}.v${APPREVISION}
done <<< "${APPLIST}"
# describe pods; verbose, place in separate file
CMDS=()
CMDS+=("kubectl describe pods --all-namespaces")
for CMD in "${CMDS[@]}" ; do
delimiter ${LOGFILE_PODS} "${CMD}"
eval ${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_PODS}
echo >>${LOGFILE_API}
done
# events; verbose, place in separate file
CMDS=()
CMDS+=("kubectl get events --all-namespaces --sort-by='.metadata.creationTimestamp' -o go-template='{{range .items}}{{printf \"%s %s\t%s\t%s\t%s\t%s\n\" .firstTimestamp .involvedObject.name .involvedObject.kind .message .reason .type}}{{end}}'")
for CMD in "${CMDS[@]}" ; do
delimiter ${LOGFILE_EVENT} "${CMD}"
eval ${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_EVENT}
echo >>${LOGFILE_EVENT}
done
# Helm related
CMD="helm version"
delimiter ${LOGFILE_HELM} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HELM}
echo >>${LOGFILE_HELM}
HELM_VERSION=$(helm version --client --short)
if [[ $HELM_VERSION =~ v2 ]]; then
CMD="helm list -a"
delimiter ${LOGFILE_HELM} "${CMD}"
APPLIST=$(${CMD} 2>>${COLLECT_ERROR_LOG} | tee -a ${LOGFILE_HELM})
APPLIST=$(echo "${APPLIST}" | awk '{if (NR!=1) {print}}')
while read -r app; do
APPNAME=$(echo ${app} | awk '{print $1}')
APPREVISION=$(echo ${app} | awk '{print $2}')
helm status ${APPNAME} > ${HELM_DIR}/${APPNAME}.status
helm get values ${APPNAME} --revision ${APPREVISION} \
> ${HELM_DIR}/${APPNAME}.v${APPREVISION}
done <<< "${APPLIST}"
elif [[ $HELM_VERSION =~ v3 ]]; then
CMD="helm list --all --all-namespaces"
delimiter ${LOGFILE_HELM} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HELM}
CMD="helm repo list"
delimiter ${LOGFILE_HELM} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HELM}
fi
HELM2CLI=$(which helmv2-cli)
if [ $? -eq 0 ]; then
CMD="helmv2-cli -- helm list"
delimiter ${LOGFILE_HELM} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HELM}
CMD="helmv2-cli -- helm search"
delimiter ${LOGFILE_HELM} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HELM}
CMD="helmv2-cli -- helm repo list"
delimiter ${LOGFILE_HELM} "${CMD}"
${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE_HELM}
fi
CMD="cp -r /opt/platform/helm_charts ${HELM_DIR}/"
delimiter ${LOGFILE} "${CMD}"

View File

@ -0,0 +1,61 @@
#! /bin/bash
#
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Gather containerized MariaDB information from active controller.
# Loads Up Utilities and Commands Variables
source /usr/local/sbin/collect_parms
source /usr/local/sbin/collect_utils
SERVICE="mariadb"
DB_DIR="${extradir}/${SERVICE}"
LOGFILE="${extradir}/${SERVICE}.info"
echo "${hostname}: MariaDB Info .....: ${LOGFILE}"
function is_service_active {
active=$(sm-query service postgres | grep "enabled-active")
if [ -z "${active}" ] ; then
return 0
else
return 1
fi
}
if [ "${nodetype}" = "controller" ] ; then
is_service_active
if [ "$?" = "0" ] ; then
exit 0
fi
# MariaDB databases
delimiter ${LOGFILE} "MariaDB databases:"
mariadb-cli --command 'show databases' >> ${LOGFILE}
# MariaDB database sizes
delimiter ${LOGFILE} "MariaDB database sizes:"
mariadb-cli --command '
SELECT table_schema AS "database",
ROUND(SUM(DATA_LENGTH + INDEX_LENGTH)/1024/1024, 3) AS "Size (MiB)",
SUM(TABLE_ROWS) AS "rowCount"
FROM information_schema.TABLES
GROUP BY table_schema' >> ${LOGFILE}
delimiter ${LOGFILE} "MariaDB database table sizes:"
mariadb-cli --command '
SELECT
table_schema AS "database", TABLE_NAME AS "table",
ROUND((DATA_LENGTH + INDEX_LENGTH)/1024/1024, 6) AS "Size (MiB)",
TABLE_ROWS AS "rowCount"
FROM information_schema.TABLES
ORDER BY table_schema, TABLE_NAME' >> ${LOGFILE}
# MariaDB dump all databases
delimiter ${LOGFILE} "Dumping MariaDB databases: ${DB_DIR}"
mkdir -p ${DB_DIR}
(cd ${DB_DIR}; mariadb-cli --dump --exclude keystone,ceilometer)
fi
exit 0

View File

@ -10,38 +10,99 @@
source /usr/local/sbin/collect_parms
source /usr/local/sbin/collect_utils
# Environment for kubectl
export KUBECONFIG=/etc/kubernetes/admin.conf
SERVICE="openstack"
LOGFILE="${extradir}/${SERVICE}.info"
echo "${hostname}: Openstack Info ....: ${LOGFILE}"
function is_service_active {
active=`sm-query service rabbit-fs | grep "enabled-active"`
if [ -z "$active" ] ; then
active=$(sm-query service rabbit-fs | grep "enabled-active")
if [ -z "${active}" ] ; then
return 0
else
return 1
fi
}
SERVICE="openstack"
LOGFILE="${extradir}/${SERVICE}.info"
echo "${hostname}: Openstack Info ....: ${LOGFILE}"
function is_openstack_node {
local PASS=0
local FAIL=1
# NOTE: hostname changes during first configuration
local this_node=$(cat /proc/sys/kernel/hostname)
###############################################################################
# Only Controller
###############################################################################
if [ "$nodetype" = "controller" ] ; then
is_service_active
if [ "$?" = "0" ] ; then
exit 0
labels=$(kubectl get node ${this_node} \
--no-headers --show-labels 2>/dev/null | awk '{print $NF}')
if [[ $labels =~ openstack-control-plane=enabled ]]; then
return ${PASS}
else
return ${FAIL}
fi
}
delimiter ${LOGFILE} "openstack project list"
openstack project list >> ${LOGFILE} 2>>${COLLECT_ERROR_LOG}
function openstack_credentials {
# Setup openstack admin tenant credentials using environment variables
unset OS_SERVICE_TOKEN
export OS_ENDPOINT_TYPE=internalURL
export CINDER_ENDPOINT_TYPE=internalURL
export OS_USERNAME=admin
export OS_PASSWORD=$(TERM=linux /opt/platform/.keyring/*/.CREDENTIAL 2>/dev/null)
export OS_AUTH_TYPE=password
export OS_AUTH_URL=http://keystone.openstack.svc.cluster.local/v3
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_IDENTITY_API_VERSION=3
export OS_REGION_NAME=RegionOne
export OS_INTERFACE=internal
}
delimiter ${LOGFILE} "openstack user list"
openstack user list >> ${LOGFILE} 2>>${COLLECT_ERROR_LOG}
function openstack_commands {
declare -a CMDS=()
CMDS+=("openstack project list --long")
CMDS+=("openstack user list --long")
CMDS+=("openstack service list --long")
CMDS+=("openstack router list --long")
CMDS+=("openstack network list --long")
CMDS+=("openstack subnet list --long")
CMDS+=("openstack image list --long")
CMDS+=("openstack volume list --all-projects --long")
CMDS+=("openstack availability zone list --long")
CMDS+=("openstack server group list --all-projects --long")
CMDS+=('openstack server list --all-projects --long -c ID -c Name -c Status -c "Task State" -c "Power State" -c Networks -c "Image Name" -c "Image ID" -c "Flavor Name" -c "Flavor ID" -c "Availability Zone" -c Host -c Properties')
CMDS+=("openstack stack list --long --all-projects")
CMDS+=("openstack security group list --all-projects")
CMDS+=("openstack security group rule list --all-projects --long")
CMDS+=("openstack keypair list")
CMDS+=("openstack configuration show")
CMDS+=("openstack quota list --compute")
CMDS+=("openstack quota list --volume")
CMDS+=("openstack quota list --network")
CMDS+=("openstack host list")
CMDS+=("openstack hypervisor list --long")
CMDS+=("openstack hypervisor stats show")
HOSTS=( $(openstack hypervisor list -f value -c "Hypervisor Hostname" 2>/dev/null) )
for host in "${HOSTS[@]}" ; do
CMDS+=("openstack hypervisor show -f yaml ${host}")
done
# nova commands
CMDS+=("nova service-list")
for CMD in "${CMDS[@]}" ; do
delimiter ${LOGFILE} "${CMD}"
eval ${CMD} 2>>${COLLECT_ERROR_LOG} >>${LOGFILE}
echo >>${LOGFILE}
done
}
function rabbitmq_usage_stats {
# RabbitMQ usage stats
MQ_STATUS="rabbitmqctl status"
delimiter ${LOGFILE} "${MQ_STATUS} | grep -e '{memory' -A30"
${MQ_STATUS} 2>/dev/null | grep -e '{memory' -A30 >> ${LOGFILE}
echo >>${LOGFILE}
delimiter ${LOGFILE} "RabbitMQ Queue Info"
num_queues=$(rabbitmqctl list_queues | wc -l); ((num_queues-=2))
@ -54,6 +115,31 @@ if [ "$nodetype" = "controller" ] ; then
messages=${arr[0]}; consumers=${arr[1]}; memory=${arr[2]}
printf "%6s %8s %9s %11s %8s %8s %9s %10s\n" "queues" "bindings" "exchanges" "connections" "channels" "messages" "consumers" "memory" >> ${LOGFILE} 2>>${COLLECT_ERROR_LOG}
printf "%6d %8d %9d %11d %8d %8d %9d %10d\n" $num_queues $num_bindings $num_exchanges $num_connections $num_channels $messages $consumers $memory >> ${LOGFILE} 2>>${COLLECT_ERROR_LOG}
}
###############################################################################
# Only Controller
###############################################################################
if [ "$nodetype" = "controller" ] ; then
is_service_active
if [ "$?" = "0" ] ; then
exit 0
fi
# host rabbitmq usage
rabbitmq_usage_stats
# Check for openstack label on this node
if ! is_openstack_node; then
exit 0
fi
# Run as subshell so we don't contaminate environment
(openstack_credentials; openstack_commands)
# TODO(jgauld): Should also get containerized rabbitmq usage,
# need wrapper script rabbitmq-cli
fi
###############################################################################

View File

@ -0,0 +1,232 @@
#!/bin/bash
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script is wrapper to containerized mariadb-server mysql client.
# This provides access to MariaDB databases.
#
# There are three modes of operation:
# - no command specified gives an interactive mysql shell
# - command specified executes a single mysql command
# - dump option to dump database contents to sql text file
#
set -euo pipefail
# Define minimal path
PATH=/bin:/usr/bin:/usr/local/bin
# Environment for kubectl
export KUBECONFIG=/etc/kubernetes/admin.conf
# Process input options
SCRIPT=$(basename $0)
OPTS=$(getopt -o dh --long debug,help,command:,database:,exclude:,dump -n ${SCRIPT} -- "$@")
if [ $? != 0 ]; then
echo "Failed parsing options." >&2
exit 1
fi
eval set -- "$OPTS"
DEBUG=false
HELP=false
DUMP=false
COMMAND=""
DATABASE=""
EXCLUDE=""
while true
do
case "$1" in
-d | --debug ) DEBUG=true; shift ;;
-h | --help ) HELP=true; shift ;;
--command )
COMMAND="$2"
shift 2
;;
--database )
DATABASE="$2"
shift 2
;;
--exclude )
EXCLUDE="$2"
shift 2
;;
--dump )
DUMP=true
shift
;;
-- )
shift
break
;;
* )
break
;;
esac
done
# Treat remaining arguments as commands + options
shift $((OPTIND-1))
OTHERARGS="$@"
if [ ${HELP} == 'true' ]; then
echo "Usage: ${SCRIPT} [-d|--debug] [-h|--help] [--database <db>] [--exclude <db,...>] [--command <cmd>] [--dump]"
echo "Options:"
echo " -d | --debug : display debug information"
echo " -h | --help : this help"
echo " --database <db> : connect to database db"
echo " --exclude <db1,...> : list of databases to exclude"
echo " --command <cmd> : execute mysql command cmd"
echo " --dump : dump database(s) to sql file in current directory"
echo
echo "Command option examples:"
echo
echo "Interactive mysql shell:"
echo " mariadb-cli"
echo " mariadb-cli --database nova"
echo " mariadb-cli --command 'show_databases'"
echo " mariadb-cli --database nova --command 'select * from compute_nodes'"
echo
echo "Dump MariaDB databases to sql file:"
echo " mariadb-cli --dump"
echo " mariadb-cli --dump --database nova"
echo " mariadb-cli --dump --exclude keystone"
exit 0
fi
# Logger setup
LOG_FACILITY=user
LOG_PRIORITY=info
function LOG {
logger -t "${0##*/}[$$]" -p ${LOG_FACILITY}.${LOG_PRIORITY} "$@"
echo "${0##*/}[$$]" "$@"
}
function ERROR {
MSG="ERROR"
LOG "${MSG} $@"
}
function is_openstack_node {
local PASS=0
local FAIL=1
# NOTE: hostname changes during first configuration
local this_node=$(cat /proc/sys/kernel/hostname)
labels=$(kubectl get node ${this_node} \
--no-headers --show-labels 2>/dev/null | awk '{print $NF}')
if [[ $labels =~ openstack-control-plane=enabled ]]; then
return ${PASS}
else
return ${FAIL}
fi
}
# Selected options
if [ ${DEBUG} == 'true' ]; then
LOG "Options: DUMP=${DUMP} OTHERARGS: ${OTHERARGS}"
if [ ! -z "${DATABASE}" ]; then
LOG "Options: DATABASE:${DATABASE}"
fi
if [ ! -z "${EXCLUDE}" ]; then
LOG "Options: EXCLUDE:${EXCLUDE}"
fi
if [ ! -z "${COMMAND}" ]; then
LOG "Options: COMMAND:${COMMAND}"
fi
fi
# Check for openstack label on this node
if ! is_openstack_node; then
ERROR "This node not configured for openstack."
exit 1
fi
# Determine running mariadb pods
MARIADB_PODS=( $(kubectl get pods -n openstack \
--selector=application=mariadb,component=server \
--field-selector status.phase=Running \
--output=jsonpath={.items..metadata.name}) )
if [ ${DEBUG} == 'true' ]; then
LOG "Found mariadb-server pods: ${MARIADB_PODS[@]}"
fi
# Get first available mariadb pod with container we can exec
DBPOD=""
for POD in "${MARIADB_PODS[@]}"
do
kubectl exec -it -n openstack ${POD} -c mariadb -- pwd 1>/dev/null 2>/dev/null
RC=$?
if [ ${RC} -eq 0 ]; then
DBPOD=${POD}
break
fi
done
if [ -z "${DBPOD}" ]; then
ERROR "Could not find mariadb-server pod."
exit 1
fi
if [ ${DEBUG} == 'true' ]; then
LOG "Found mariadb-server pod: ${DBPOD}"
fi
EVAL='eval env 1>/dev/null'
DBOPTS='--password=$MYSQL_DBADMIN_PASSWORD --user=$MYSQL_DBADMIN_USERNAME'
if [ ${DUMP} == 'true' ]; then
# Dump database contents to sql text file
DB_EXT=sql
DATABASES=()
if [ ! -z "${DATABASE}" ]; then
DATABASES+=( $DATABASE )
else
# Get list of databases
MYSQL_CMD="${EVAL}; mysql ${DBOPTS} -e 'show databases' -sN --disable-pager"
if [ ${DEBUG} == 'true' ]; then
LOG "MYSQL_CMD: ${MYSQL_CMD}"
fi
# Suppress error: line from stdout, eg.,
# error: Found option without preceding group in config file: /etc/mysql/conf.d/20-override.cnf at line: 1
# Exclude databases: mysql, information_schema, performance_schema
# Remove linefeed control character.
DATABASES=( $(kubectl exec -it -n openstack ${DBPOD} -c mariadb -- bash -c "${MYSQL_CMD}" | \
grep -v -e error: -e mysql -e information_schema -e performance_schema | tr -d '\r') )
fi
for dbname in "${DATABASES[@]}"
do
re=\\b"${dbname}"\\b
if [[ "${EXCLUDE}" =~ ${re} ]]; then
LOG "excluding: ${dbname}"
continue
fi
# NOTE: --skip-opt will show an INSERT for each record
DUMP_CMD="${EVAL}; mysqldump ${DBOPTS} --skip-opt --skip-comments --skip-set-charset ${dbname}"
dbfile=${dbname}.${DB_EXT}
LOG "Dump database: $dbname to file: ${dbfile}"
if [ ${DEBUG} == 'true' ]; then
LOG "DUMP_CMD: ${DUMP_CMD}"
fi
kubectl exec -it -n openstack ${DBPOD} -c mariadb -- bash -c "${DUMP_CMD}" > ${dbfile}
done
else
# Interactive mariadb mysql client
LOG "Interactive MariaDB mysql shell"
MYSQL_CMD="${EVAL}; mysql ${DBOPTS} ${DATABASE}"
if [ ! -z "${COMMAND}" ]; then
MYSQL_CMD="${MYSQL_CMD} -e '${COMMAND}'"
fi
if [ ${DEBUG} == 'true' ]; then
LOG "MYSQL_CMD: ${MYSQL_CMD}"
fi
kubectl exec -it -n openstack ${DBPOD} -c mariadb -- bash -c "${MYSQL_CMD}"
fi
exit 0