From 32fc2599a665e01b47c74588cdc2b547dc208874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Piliszek?= Date: Fri, 24 Apr 2020 21:38:15 +0200 Subject: [PATCH] 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 --- .../notes/bug-1856346-59d0f01005d56e81.yaml | 6 ++ tools/kolla-ansible | 74 +++++++++++++++---- 2 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 releasenotes/notes/bug-1856346-59d0f01005d56e81.yaml diff --git a/releasenotes/notes/bug-1856346-59d0f01005d56e81.yaml b/releasenotes/notes/bug-1856346-59d0f01005d56e81.yaml new file mode 100644 index 0000000000..1524b39f43 --- /dev/null +++ b/releasenotes/notes/bug-1856346-59d0f01005d56e81.yaml @@ -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 `__ diff --git a/tools/kolla-ansible b/tools/kolla-ansible index 1afc41757c..dfc98cec5d 100755 --- a/tools/kolla-ansible +++ b/tools/kolla-ansible @@ -2,21 +2,71 @@ # # This script can be used to interact with kolla via ansible. -function check_ansible_compatibility { - ANSIBLE_VERSION_MIN=2.8 - ANSIBLE_VERSION_MAX=2.9 - ANSIBLE_VERSION_HOST=$(ANSIBLE_DEBUG=0 ansible --version | head -n1 | egrep -o '[0-9]\.[0-9]+') +function check_environment_coherence { + local ansible_path + ansible_path=$(which ansible) - if [[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ANSIBLE_VERSION_HOST" | sort -V | head -n1) != "$ANSIBLE_VERSION_MIN" ]] || - [[ $(printf "%s\n" "$ANSIBLE_VERSION_MIN" "$ANSIBLE_VERSION_MAX" "$ANSIBLE_VERSION_HOST" | sort -V | tail -1) != "$ANSIBLE_VERSION_MAX" ]]; then + if [[ $? -ne 0 ]]; 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." exit 1 fi } function find_base_dir { - local real_path=$(python3 -c "import os;print(os.path.realpath('$0'))") - local dir_name="$(dirname "$real_path")" + local dir_name + dir_name=$(cd "$(dirname "$0")" &>/dev/null && pwd) if [ -z "$SNAP" ]; then if [[ ${dir_name} == "/usr/bin" ]]; then BASEDIR=/usr/share/kolla-ansible @@ -131,7 +181,7 @@ prune-images EOF } -check_ansible_compatibility +check_environment_coherence 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" @@ -139,12 +189,6 @@ LONG_OPTS="help,inventory:,playbook:,skip-tags:,tags:,key:,extra:,verbose,config RAW_ARGS="$*" 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" find_base_dir