![Paul Bourke](/assets/img/avatar_default.png)
The only files in the docker image directories that differ majorly between distros are the Dockerfiles (e.g. different package manager mechanisms, different repo sources, etc). The supporting files such as the start.sh/check.sh and config files should largely stay the same between base images. This change moves these files up into a "common" directory, and symlinks them in the same way that the build script is managed. This means when adding a new base distro only new Dockerfiles need to be created. Also, if a distro does happen to require a vastly different start.sh script for example, one can choose to simply not symlink to the common and instead drop in a custom one. Implements: blueprint refactor-base-image-layout Change-Id: Ic4db69d31ff54a1fb95af4853a2e5ae490064284
171 lines
5.0 KiB
Bash
171 lines
5.0 KiB
Bash
#!/bin/bash
|
|
|
|
. /opt/kolla/service_hosts.sh
|
|
|
|
# Set some generally useful defaults.
|
|
MY_IP=$(ip route get $(ip route | awk '$1 == "default" {print $3}') |
|
|
awk '$4 == "src" {print $5}')
|
|
|
|
: ${PUBLIC_IP:=${MY_IP}}
|
|
|
|
# Iterate over a list of variable names and exit if one is
|
|
# undefined.
|
|
check_required_vars() {
|
|
for var in $*; do
|
|
if [ -z "${!var}" ]; then
|
|
echo "ERROR: missing $var" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
# The usage of the wait_for function looks like the following
|
|
# wait_for LOOPS_NUMBER SLEEP_TIME ARGS
|
|
#
|
|
# The ARGS are read and concatenated together into a single command and the
|
|
# command is executed in a loop until it succeeds or reaches the max number of
|
|
# attempts (LOOPS_NUMBER).
|
|
#
|
|
# Optional variables SUCCESSFUL_MATCH_OUTPUT and FAIL_MATCH_OUTPUT variable may
|
|
# also be set to control if the loop exits early if the commands stdout/stderr
|
|
# matches the supplied regex string. Consider using the `wait_for_output` and
|
|
# `wait_for_output_unless` functions in case there is a need to check for the
|
|
# command output.
|
|
#
|
|
# The script exits on failure, either when output contains string identified as
|
|
# failure, or when it reaches a timeout.
|
|
#
|
|
# Examples:
|
|
# wait_for 30 10 ping -c 1 192.0.2.2
|
|
# wait_for 10 1 ls file_we_are_waiting_for
|
|
# wait_for 10 3 date \| grep 8
|
|
wait_for() {
|
|
local loops=${1:-""}
|
|
local sleeptime=${2:-""}
|
|
FAIL_MATCH_OUTPUT=${FAIL_MATCH_OUTPUT:-""}
|
|
SUCCESSFUL_MATCH_OUTPUT=${SUCCESSFUL_MATCH_OUTPUT:-""}
|
|
shift 2 || true
|
|
local command="$@"
|
|
|
|
if [ -z "$loops" -o -z "$sleeptime" -o -z "$command" ]; then
|
|
echo "wait_for is missing a required parameter"
|
|
exit 1
|
|
fi
|
|
|
|
local i=0
|
|
while [ $i -lt $loops ]; do
|
|
i=$((i + 1))
|
|
local status=0
|
|
local output=$(eval $command 2>&1) || status=$?
|
|
if [[ -n "$SUCCESSFUL_MATCH_OUTPUT" ]] \
|
|
&& [[ $output =~ $SUCCESSFUL_MATCH_OUTPUT ]]; then
|
|
return 0
|
|
elif [[ -n "$FAIL_MATCH_OUTPUT" ]] \
|
|
&& [[ $output =~ $FAIL_MATCH_OUTPUT ]]; then
|
|
echo "Command output matched '$FAIL_MATCH_OUTPUT'."
|
|
exit 1
|
|
elif [[ -z "$SUCCESSFUL_MATCH_OUTPUT" ]] && [[ $status -eq 0 ]]; then
|
|
return 0
|
|
fi
|
|
sleep $sleeptime
|
|
done
|
|
local seconds=$((loops * sleeptime))
|
|
printf 'Timing out after %d seconds:\ncommand=%s\nOUTPUT=%s\n' \
|
|
"$seconds" "$command" "$output"
|
|
exit 1
|
|
}
|
|
|
|
# Helper function to `wait_for` that only succeeds when the given regex is
|
|
# matching the command's output. Exit early with a failure when the second
|
|
# supplied regexp is matching the output.
|
|
#
|
|
# Example:
|
|
# wait_for_output_unless CREATE_COMPLETE CREATE_FAIL 30 10 heat stack-show undercloud
|
|
wait_for_output_unless() {
|
|
SUCCESSFUL_MATCH_OUTPUT=$1
|
|
FAIL_MATCH_OUTPUT=$2
|
|
shift 2
|
|
wait_for $@
|
|
local status=$?
|
|
unset SUCCESSFUL_MATCH_OUTPUT
|
|
unset FAIL_MATCH_OUTPUT
|
|
return $status
|
|
}
|
|
|
|
# Helper function to `wait_for` that only succeeds when the given regex is
|
|
# matching the command's output.
|
|
#
|
|
# Example:
|
|
# wait_for_output CREATE_COMPLETE 30 10 heat stack-show undercloud
|
|
wait_for_output() {
|
|
local expected_output=$1
|
|
shift
|
|
wait_for_output_unless $expected_output '' $@
|
|
}
|
|
|
|
# Check if we receive a successful response from corresponding OpenStack
|
|
# service endpoint.
|
|
check_for_os_service_endpoint() {
|
|
local name=$1
|
|
local host_var=$2
|
|
local port_var=$3
|
|
local api_version=$4
|
|
|
|
check_required_vars $host_var $port_var
|
|
|
|
local endpoint="http://${!host_var}:${!port_var}/$api_version"
|
|
|
|
curl -sf -o /dev/null "$endpoint" || {
|
|
echo "ERROR: $name is not available @ $endpoint" >&2
|
|
return 1
|
|
}
|
|
|
|
echo "$name is active @ $endpoint"
|
|
}
|
|
|
|
check_for_os_service_running() {
|
|
local service=$1
|
|
local args=
|
|
case $service in
|
|
("glance") args="GLANCE_API_SERVICE_HOST GLANCE_API_SERVICE_PORT" ;;
|
|
("keystone") args="KEYSTONE_PUBLIC_SERVICE_HOST KEYSTONE_PUBLIC_SERVICE_PORT v2.0" ;;
|
|
("neutron") args="NEUTRON_SERVER_SERVICE_HOST NEUTRON_SERVER_SERVICE_PORT" ;;
|
|
("nova") args="NOVA_API_SERVICE_HOST NOVA_API_SERVICE_PORT" ;;
|
|
(*)
|
|
echo "Unknown service $service"
|
|
return 1 ;;
|
|
esac
|
|
check_for_os_service_endpoint $service $args
|
|
}
|
|
|
|
fail_unless_os_service_running() {
|
|
check_for_os_service_running $@ || exit $?
|
|
}
|
|
|
|
# Check if we receive a successful response from the database server.
|
|
# Optionally takes a database name to check for. Defaults to 'mysql'.
|
|
check_for_db() {
|
|
local database=${1:-mysql}
|
|
check_required_vars MARIADB_SERVICE_HOST DB_ROOT_PASSWORD
|
|
|
|
mysql -h ${MARIADB_SERVICE_HOST} -u root -p"${DB_ROOT_PASSWORD}" \
|
|
-e "select 1" $database > /dev/null 2>&1 || {
|
|
echo "ERROR: database $database is not available @ $MARIADB_SERVICE_HOST" >&2
|
|
return 1
|
|
}
|
|
|
|
echo "database is active @ ${MARIADB_SERVICE_HOST}"
|
|
}
|
|
|
|
fail_unless_db() {
|
|
check_for_db $@ || exit $?
|
|
}
|
|
|
|
# Dump shell environment to a file
|
|
dump_vars() {
|
|
set -o posix
|
|
set > /pid_$$_vars.sh
|
|
set +o posix
|
|
}
|
|
|