32fc2599a6
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
458 lines
14 KiB
Bash
Executable File
458 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# This script can be used to interact with kolla via ansible.
|
|
|
|
function check_environment_coherence {
|
|
local ansible_path
|
|
ansible_path=$(which ansible)
|
|
|
|
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 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
|
|
elif [[ ${dir_name} == "/usr/local/bin" ]]; then
|
|
BASEDIR=/usr/local/share/kolla-ansible
|
|
elif [[ -n ${VIRTUAL_ENV} ]] && [[ ${dir_name} == "${VIRTUAL_ENV}/bin" ]]; then
|
|
BASEDIR="${VIRTUAL_ENV}/share/kolla-ansible"
|
|
else
|
|
BASEDIR="$(dirname ${dir_name})"
|
|
fi
|
|
else
|
|
BASEDIR="$SNAP/share/kolla-ansible"
|
|
fi
|
|
}
|
|
|
|
function process_cmd {
|
|
echo "$ACTION : $CMD"
|
|
$CMD
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "Command failed $CMD"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function usage {
|
|
cat <<EOF
|
|
Usage: $0 COMMAND [options]
|
|
|
|
Options:
|
|
--inventory, -i <inventory_path> Specify path to ansible inventory file
|
|
--playbook, -p <playbook_path> Specify path to ansible playbook file
|
|
--configdir <config_path> Specify path to directory with globals.yml
|
|
--key -k <key_path> Specify path to ansible vault keyfile
|
|
--help, -h Show this usage information
|
|
--tags, -t <tags> Only run plays and tasks tagged with these values
|
|
--skip-tags <tags> Only run plays and tasks whose tags do not match these values
|
|
--extra, -e <ansible variables> Set additional variables as key=value or YAML/JSON passed to ansible-playbook
|
|
--passwords <passwords_path> Specify path to the passwords file
|
|
--limit <host> Specify host to run plays
|
|
--forks <forks> Number of forks to run Ansible with
|
|
--vault-id <@prompt or path> Specify @prompt or password file (Ansible >= 2.4)
|
|
--ask-vault-pass Ask for vault password
|
|
--vault-password-file <path> Specify password file for vault decrypt
|
|
--verbose, -v Increase verbosity of ansible-playbook
|
|
|
|
Environment variables:
|
|
EXTRA_OPTS Additional arguments to pass to ansible-playbook
|
|
|
|
Commands:
|
|
prechecks Do pre-deployment checks for hosts
|
|
check Do post-deployment smoke tests
|
|
mariadb_recovery Recover a completely stopped mariadb cluster
|
|
mariadb_backup Take a backup of MariaDB databases
|
|
--full (default)
|
|
--incremental
|
|
bootstrap-servers Bootstrap servers with kolla deploy dependencies
|
|
destroy Destroy Kolla containers, volumes and host configuration
|
|
--include-images to also destroy Kolla images
|
|
--include-dev to also destroy dev mode repos
|
|
deploy Deploy and start all kolla containers
|
|
deploy-bifrost Deploy and start bifrost container
|
|
deploy-servers Enroll and deploy servers with bifrost
|
|
deploy-containers Only deploy and start containers (no config updates or bootstrapping)
|
|
post-deploy Do post deploy on deploy node
|
|
pull Pull all images for containers (only pulls, no running container changes)
|
|
reconfigure Reconfigure OpenStack service
|
|
stop Stop Kolla containers
|
|
certificates Generate self-signed certificate for TLS *For Development Only*
|
|
upgrade Upgrades existing OpenStack Environment
|
|
upgrade-bifrost Upgrades an existing bifrost container
|
|
genconfig Generate configuration files for enabled OpenStack services
|
|
prune-images Prune orphaned Kolla images
|
|
EOF
|
|
}
|
|
|
|
function bash_completion {
|
|
cat <<EOF
|
|
--inventory -i
|
|
--playbook -p
|
|
--configdir
|
|
--key -k
|
|
--help -h
|
|
--skip-tags
|
|
--tags -t
|
|
--extra -e
|
|
--passwords
|
|
--limit
|
|
--forks
|
|
--vault-id
|
|
--ask-vault-pass
|
|
--vault-password-file
|
|
--verbose -v
|
|
prechecks
|
|
check
|
|
mariadb_recovery
|
|
mariadb_backup
|
|
bootstrap-servers
|
|
destroy
|
|
deploy
|
|
deploy-bifrost
|
|
deploy-containers
|
|
deploy-servers
|
|
post-deploy
|
|
pull
|
|
reconfigure
|
|
stop
|
|
certificates
|
|
upgrade
|
|
upgrade-bifrost
|
|
genconfig
|
|
prune-images
|
|
EOF
|
|
}
|
|
|
|
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"
|
|
|
|
RAW_ARGS="$*"
|
|
ARGS=$(getopt -o "${SHORT_OPTS}" -l "${LONG_OPTS}" --name "$0" -- "$@") || { usage >&2; exit 2; }
|
|
|
|
eval set -- "$ARGS"
|
|
|
|
find_base_dir
|
|
|
|
INVENTORY="${BASEDIR}/ansible/inventory/all-in-one"
|
|
PLAYBOOK="${BASEDIR}/ansible/site.yml"
|
|
VERBOSITY=
|
|
EXTRA_OPTS=${EXTRA_OPTS}
|
|
CONFIG_DIR="/etc/kolla"
|
|
PASSWORDS_FILE="${CONFIG_DIR}/passwords.yml"
|
|
DANGER_CONFIRM=
|
|
INCLUDE_IMAGES=
|
|
INCLUDE_DEV=
|
|
BACKUP_TYPE="full"
|
|
# Serial is not recommended and disabled by default. Users can enable it by
|
|
# configuring ANSIBLE_SERIAL variable.
|
|
ANSIBLE_SERIAL=${ANSIBLE_SERIAL:-0}
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
|
|
(--inventory|-i)
|
|
INVENTORY="$2"
|
|
shift 2
|
|
;;
|
|
|
|
(--playbook|-p)
|
|
PLAYBOOK="$2"
|
|
shift 2
|
|
;;
|
|
|
|
(--skip-tags)
|
|
EXTRA_OPTS="$EXTRA_OPTS --skip-tags $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--tags|-t)
|
|
EXTRA_OPTS="$EXTRA_OPTS --tags $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--verbose|-v)
|
|
VERBOSITY="$VERBOSITY --verbose"
|
|
shift 1
|
|
;;
|
|
|
|
(--configdir)
|
|
CONFIG_DIR="$2"
|
|
shift 2
|
|
;;
|
|
|
|
(--yes-i-really-really-mean-it)
|
|
if [[ ${RAW_ARGS} =~ "$1" ]]
|
|
then
|
|
DANGER_CONFIRM="$1"
|
|
fi
|
|
shift 1
|
|
;;
|
|
|
|
(--include-images)
|
|
INCLUDE_IMAGES="$1"
|
|
shift 1
|
|
;;
|
|
|
|
(--include-dev)
|
|
INCLUDE_DEV="$1"
|
|
shift 1
|
|
;;
|
|
|
|
(--key|-k)
|
|
VAULT_PASS_FILE="$2"
|
|
EXTRA_OPTS="$EXTRA_OPTS --vault-password-file=$VAULT_PASS_FILE"
|
|
shift 2
|
|
;;
|
|
|
|
(--extra|-e)
|
|
EXTRA_OPTS="$EXTRA_OPTS -e $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--passwords)
|
|
PASSWORDS_FILE="$2"
|
|
shift 2
|
|
;;
|
|
|
|
(--limit)
|
|
EXTRA_OPTS="$EXTRA_OPTS --limit $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--forks)
|
|
EXTRA_OPTS="$EXTRA_OPTS --forks $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--vault-id)
|
|
EXTRA_OPTS="$EXTRA_OPTS --vault-id $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--ask-vault-pass)
|
|
VERBOSITY="$EXTRA_OPTS --ask-vault-pass"
|
|
shift 1
|
|
;;
|
|
|
|
(--vault-password-file)
|
|
EXTRA_OPTS="$EXTRA_OPTS --vault-password-file $2"
|
|
shift 2
|
|
;;
|
|
|
|
(--full)
|
|
BACKUP_TYPE="full"
|
|
shift 1
|
|
;;
|
|
|
|
(--incremental)
|
|
BACKUP_TYPE="incremental"
|
|
shift 1
|
|
;;
|
|
|
|
(--help|-h)
|
|
usage
|
|
shift
|
|
exit 0
|
|
;;
|
|
|
|
(--)
|
|
shift
|
|
break
|
|
;;
|
|
|
|
(*)
|
|
echo "error"
|
|
exit 3
|
|
;;
|
|
esac
|
|
done
|
|
|
|
case "$1" in
|
|
|
|
(prechecks)
|
|
ACTION="Pre-deployment checking"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=precheck"
|
|
;;
|
|
(check)
|
|
ACTION="Post-deployment checking"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=check"
|
|
;;
|
|
(mariadb_recovery)
|
|
ACTION="Attempting to restart mariadb cluster"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy -e common_run=true"
|
|
PLAYBOOK="${BASEDIR}/ansible/mariadb_recovery.yml"
|
|
;;
|
|
(mariadb_backup)
|
|
ACTION="Backup MariaDB databases"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=backup -e mariadb_backup_type=${BACKUP_TYPE} -e common_run=true"
|
|
PLAYBOOK="${BASEDIR}/ansible/mariadb_backup.yml"
|
|
;;
|
|
(destroy)
|
|
ACTION="Destroy Kolla containers, volumes and host configuration"
|
|
PLAYBOOK="${BASEDIR}/ansible/destroy.yml"
|
|
if [[ "${INCLUDE_IMAGES}" == "--include-images" ]]; then
|
|
EXTRA_OPTS="$EXTRA_OPTS -e destroy_include_images=yes"
|
|
fi
|
|
if [[ "${INCLUDE_DEV}" == "--include-dev" ]]; then
|
|
EXTRA_OPTS="$EXTRA_OPTS -e destroy_include_dev=yes"
|
|
fi
|
|
if [[ "${DANGER_CONFIRM}" != "--yes-i-really-really-mean-it" ]]; then
|
|
cat << EOF
|
|
WARNING:
|
|
This will PERMANENTLY DESTROY all deployed kolla containers, volumes and host configuration.
|
|
There is no way to recover from this action. To confirm, please add the following option:
|
|
--yes-i-really-really-mean-it
|
|
EOF
|
|
exit 1
|
|
fi
|
|
;;
|
|
(bootstrap-servers)
|
|
ACTION="Bootstrapping servers"
|
|
PLAYBOOK="${BASEDIR}/ansible/kolla-host.yml"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=bootstrap-servers"
|
|
;;
|
|
(deploy)
|
|
ACTION="Deploying Playbooks"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy"
|
|
;;
|
|
(deploy-bifrost)
|
|
ACTION="Deploying Bifrost"
|
|
PLAYBOOK="${BASEDIR}/ansible/bifrost.yml"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy"
|
|
;;
|
|
(deploy-containers)
|
|
ACTION="Deploying Containers"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy-containers"
|
|
;;
|
|
(deploy-servers)
|
|
ACTION="Deploying servers with bifrost"
|
|
PLAYBOOK="${BASEDIR}/ansible/bifrost.yml"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=deploy-servers"
|
|
;;
|
|
(post-deploy)
|
|
ACTION="Post-Deploying Playbooks"
|
|
PLAYBOOK="${BASEDIR}/ansible/post-deploy.yml"
|
|
;;
|
|
(pull)
|
|
ACTION="Pulling Docker images"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=pull"
|
|
;;
|
|
(upgrade)
|
|
ACTION="Upgrading OpenStack Environment"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=upgrade -e kolla_serial=${ANSIBLE_SERIAL}"
|
|
;;
|
|
(upgrade-bifrost)
|
|
ACTION="Upgrading Bifrost"
|
|
PLAYBOOK="${BASEDIR}/ansible/bifrost.yml"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=upgrade"
|
|
;;
|
|
(reconfigure)
|
|
ACTION="Reconfigure OpenStack service"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=reconfigure -e kolla_serial=${ANSIBLE_SERIAL}"
|
|
;;
|
|
(stop)
|
|
ACTION="Stop Kolla containers"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=stop"
|
|
if [[ "${DANGER_CONFIRM}" != "--yes-i-really-really-mean-it" ]]; then
|
|
cat << EOF
|
|
WARNING:
|
|
This will stop all deployed kolla containers, limit with tags is possible and also with
|
|
skip_stop_containers variable. To confirm, please add the following option:
|
|
--yes-i-really-really-mean-it
|
|
EOF
|
|
exit 1
|
|
fi
|
|
;;
|
|
(certificates)
|
|
ACTION="Generate TLS Certificates"
|
|
PLAYBOOK="${BASEDIR}/ansible/certificates.yml"
|
|
;;
|
|
(genconfig)
|
|
ACTION="Generate configuration files for enabled OpenStack services"
|
|
EXTRA_OPTS="$EXTRA_OPTS -e kolla_action=config"
|
|
;;
|
|
(prune-images)
|
|
ACTION="Prune orphaned Kolla images"
|
|
PLAYBOOK="${BASEDIR}/ansible/prune-images.yml"
|
|
if [[ "${DANGER_CONFIRM}" != "--yes-i-really-really-mean-it" ]]; then
|
|
cat << EOF
|
|
WARNING:
|
|
This will PERMANENTLY DELETE all orphaned kolla images. To confirm, please add the following option:
|
|
--yes-i-really-really-mean-it
|
|
EOF
|
|
exit 1
|
|
fi
|
|
;;
|
|
(bash-completion)
|
|
bash_completion
|
|
exit 0
|
|
;;
|
|
(*) usage
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
CONFIG_OPTS="-e @${CONFIG_DIR}/globals.yml -e @${PASSWORDS_FILE} -e CONFIG_DIR=${CONFIG_DIR}"
|
|
CMD="ansible-playbook -i $INVENTORY $CONFIG_OPTS $EXTRA_OPTS $PLAYBOOK $VERBOSITY"
|
|
process_cmd
|