Check that used Ansible can see Kolla Ansible

Fix-feature following up on the original check [1] to make it
test the correct interpreter.

Additionally, this change removes last, unneeded call to
random python - getting script directory is perfectly
doable in bash.

All checks are done from Python, not Ansible, due to its
performance. Python version feels snappy (0.2 s to check),
compared to sluggish Ansible (2.0 s to check).
What is more, relying on Ansible would require hacky solutions
to e.g. prevent custom config from interfering with it.
We might be willing to steer Ansible from Python in the future
anyhow.

[1] Icf0399d21b3fde8d530d73e6e7ee4a57665da276

Change-Id: Ib8f2e6b6672e7c06aa94bc226c4d72640d25d8c2
Closes-Bug: #1856346
This commit is contained in:
Radosław Piliszek 2020-04-24 21:38:15 +02:00
parent 3036c7cfda
commit 32fc2599a6
2 changed files with 65 additions and 15 deletions

View File

@ -0,0 +1,6 @@
---
features:
- |
Kolla Ansible checks now that the local Ansible Python environment
is coherent, i.e. used Ansible can see Kolla Ansible.
`LP#1856346 <https://launchpad.net/bugs/1856346>`__

View File

@ -2,21 +2,71 @@
# #
# This script can be used to interact with kolla via ansible. # This script can be used to interact with kolla via ansible.
function check_ansible_compatibility { function check_environment_coherence {
ANSIBLE_VERSION_MIN=2.8 local ansible_path
ANSIBLE_VERSION_MAX=2.9 ansible_path=$(which ansible)
ANSIBLE_VERSION_HOST=$(ANSIBLE_DEBUG=0 ansible --version | head -n1 | egrep -o '[0-9]\.[0-9]+')
if [[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ANSIBLE_VERSION_HOST" | sort -V | head -n1) != "$ANSIBLE_VERSION_MIN" ]] || if [[ $? -ne 0 ]]; then
[[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ANSIBLE_VERSION_HOST" | sort -V | tail -1) != "$ANSIBLE_VERSION_MAX" ]]; then echo "ERROR: Ansible is not installed in the current (virtual) environment." >&2
exit 1
fi
local ansible_shebang_line
ansible_shebang_line=$(head -n1 "$ansible_path")
if ! echo "$ansible_shebang_line" | egrep "^#!" &>/dev/null; then
echo "ERROR: Ansible script is malformed (missing shebang line)." >&2
exit 1
fi
local ansible_python_cmdline
# NOTE(yoctozepto): may have multiple parts
ansible_python_cmdline=${ansible_shebang_line#\#\!}
if ! $ansible_python_cmdline --version &>/dev/null; then
echo "ERROR: Ansible Python is not functional." >&2
echo "Tried '$ansible_python_cmdline'" >&2
exit 1
fi
# Check for existence of kolla_ansible module using Ansible's Python.
if ! $ansible_python_cmdline -c 'import kolla_ansible' &>/dev/null; then
echo "ERROR: kolla_ansible has to be available in the Ansible PYTHONPATH." >&2
echo "Please install both in the same (virtual) environment." >&2
exit 1
fi
local ansible_version_output
ansible_full_version=$($ansible_python_cmdline -c 'import ansible; print(ansible.__version__)')
if [[ $? -ne 0 ]]; then
echo "ERROR: Failed to obtain Ansible version:" >&2
echo "$ansible_full_version" >&2
exit 1
fi
local ansible_version
ansible_version=$(echo "$ansible_full_version" | egrep -o '^[0-9]+\.[0-9]+')
if [[ $? -ne 0 ]]; then
echo "ERROR: Failed to parse Ansible version:" >&2
echo "$ansible_full_version" >&2
exit 1
fi
local ANSIBLE_VERSION_MIN=2.8
local ANSIBLE_VERSION_MAX=2.9
if [[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ansible_version" | sort -V | head -n1) != "$ANSIBLE_VERSION_MIN" ]] ||
[[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ansible_version" | sort -V | tail -n1) != "$ANSIBLE_VERSION_MAX" ]]; then
echo "ERROR: Ansible version should be between $ANSIBLE_VERSION_MIN and $ANSIBLE_VERSION_MAX. Current version is $ANSIBLE_VERSION_HOST which is not supported." echo "ERROR: Ansible version should be between $ANSIBLE_VERSION_MIN and $ANSIBLE_VERSION_MAX. Current version is $ANSIBLE_VERSION_HOST which is not supported."
exit 1 exit 1
fi fi
} }
function find_base_dir { function find_base_dir {
local real_path=$(python3 -c "import os;print(os.path.realpath('$0'))") local dir_name
local dir_name="$(dirname "$real_path")" dir_name=$(cd "$(dirname "$0")" &>/dev/null && pwd)
if [ -z "$SNAP" ]; then if [ -z "$SNAP" ]; then
if [[ ${dir_name} == "/usr/bin" ]]; then if [[ ${dir_name} == "/usr/bin" ]]; then
BASEDIR=/usr/share/kolla-ansible BASEDIR=/usr/share/kolla-ansible
@ -131,7 +181,7 @@ prune-images
EOF EOF
} }
check_ansible_compatibility check_environment_coherence
SHORT_OPTS="hi:p:t:k:e:v" SHORT_OPTS="hi:p:t:k:e:v"
LONG_OPTS="help,inventory:,playbook:,skip-tags:,tags:,key:,extra:,verbose,configdir:,passwords:,limit:,forks:,vault-id:,ask-vault-pass,vault-password-file:,yes-i-really-really-mean-it,include-images,include-dev:,full,incremental" LONG_OPTS="help,inventory:,playbook:,skip-tags:,tags:,key:,extra:,verbose,configdir:,passwords:,limit:,forks:,vault-id:,ask-vault-pass,vault-password-file:,yes-i-really-really-mean-it,include-images,include-dev:,full,incremental"
@ -139,12 +189,6 @@ LONG_OPTS="help,inventory:,playbook:,skip-tags:,tags:,key:,extra:,verbose,config
RAW_ARGS="$*" RAW_ARGS="$*"
ARGS=$(getopt -o "${SHORT_OPTS}" -l "${LONG_OPTS}" --name "$0" -- "$@") || { usage >&2; exit 2; } ARGS=$(getopt -o "${SHORT_OPTS}" -l "${LONG_OPTS}" --name "$0" -- "$@") || { usage >&2; exit 2; }
# Check for existence of kolla_ansible module using python3 interpreter.
if ! python3 -c 'import kolla_ansible' &>/dev/null; then
echo "ERROR: kolla_ansible has to be available in the PYTHONPATH (e.g. installed)" >&2
exit 1
fi
eval set -- "$ARGS" eval set -- "$ARGS"
find_base_dir find_base_dir