378 lines
13 KiB
Django/Jinja
378 lines
13 KiB
Django/Jinja
#!/bin/bash
|
|
|
|
# See documentation for using the reproducer script:
|
|
# README-reproducer-quickstart.html
|
|
# (in the same top-level logs directory as this reproducer script).
|
|
|
|
: ${WORKSPACE:=$(mktemp -d -t reproduce-tmp.XXXXX)}
|
|
{% if 'ovb' in toci_jobtype %}
|
|
: ${CREATE_VIRTUALENV:=true}
|
|
{% else %}
|
|
: ${CREATE_VIRTUALENV:=false}
|
|
{% endif %}
|
|
: ${REMOVE_STACKS_KEYPAIRS:=false}
|
|
: ${NODESTACK_PREFIX:=""}
|
|
: ${AUTORUN:=0}
|
|
: ${TIMEOUT:=240}
|
|
: ${LIBVIRT:=0}
|
|
: ${TOCI_JOBTYPE:="{{ toci_jobtype }}"}
|
|
: ${NODES_FILE:="{{ nodes_config }}"}
|
|
: ${ZUUL_CHANGES:="{{ zuul_changes }}"}
|
|
: ${EXTRA_PARAMS:=""}
|
|
|
|
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
|
|
|
usage () {
|
|
echo "Usage: $0 [options]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -w, --workspace <dir>"
|
|
echo " directory where the virtualenv, inventory files, etc."
|
|
echo " are created. Defaults to creating a directory in /tmp"
|
|
echo " -v, --create-virtualenv"
|
|
echo " create a virtualenv to install Ansible and dependencies."
|
|
echo " Options to pass true/false. Defaults to true for OVB. "
|
|
echo " Defaults to false for other deployment types."
|
|
echo " -r, --remove-stacks-keypairs"
|
|
echo " delete all Heat stacks (both Multinode and OVB created) "
|
|
echo " in the tenant before deployment."
|
|
echo " Will also delete associated keypairs if they exist."
|
|
echo " Options to pass true/false. Defaults to false."
|
|
echo " -p, --nodestack-prefix"
|
|
echo " add a unique prefix for multinode and singlenode stacks"
|
|
echo " Defaults to empty."
|
|
echo " -a, --autorun"
|
|
echo " Run job on prepared environment automatically"
|
|
echo " Default is to stop after environment is ready"
|
|
echo " -t, --timeout"
|
|
echo " Timeout in minutes for the deployment"
|
|
echo " Default is 240 minutes"
|
|
echo " -l, --libvirt"
|
|
echo " Runs a 2-node multinode job or singlenode job on a"
|
|
echo " single virthost using libvirt to create the nodes."
|
|
echo " The script sets the virthost to be 127.0.0.2"
|
|
echo " so the reproducer must be run from the virthost."
|
|
echo " If a singlenode reproducer is run, two VMs will still be created."
|
|
echo " -n, --nodes-file"
|
|
echo " Node config file of the topology needed"
|
|
echo " default: $NODES_FILE"
|
|
echo " -z, --zuul-changes"
|
|
echo " Refspecs with changes to test"
|
|
echo " default: $ZUUL_CHANGES"
|
|
echo " -j, --toci-jobtype"
|
|
echo " TOCI description of the job to run"
|
|
echo " default: $TOCI_JOBTYPE"
|
|
echo " -e, --extra-params"
|
|
echo " File or/and parameters used to override default"
|
|
echo " parameters for playbooks. Multiple files"
|
|
echo " can be passed [-e @file1.yml -e @file2.yml ...]"
|
|
echo " and arguments [-e var=value -e var2=value2 ...]"
|
|
echo " -h, --help print this help and exit"
|
|
}
|
|
|
|
set -e
|
|
|
|
# Input argument assignments
|
|
while [ "x$1" != "x" ]; do
|
|
|
|
case "$1" in
|
|
--workspace|-w)
|
|
# realpath fails if /some/path doesn't exist. It is created l8r
|
|
WORKSPACE=$(realpath $2 || echo -n $2)
|
|
shift
|
|
;;
|
|
|
|
--create-virtualenv|-v)
|
|
CREATE_VIRTUALENV=$2
|
|
shift
|
|
;;
|
|
|
|
--remove-stacks-keypairs|-r)
|
|
REMOVE_STACKS_KEYPAIRS=$2
|
|
shift
|
|
;;
|
|
|
|
--nodestack-prefix|-p)
|
|
NODESTACK_PREFIX=$2
|
|
shift
|
|
;;
|
|
|
|
--autorun|-a)
|
|
AUTORUN=1
|
|
;;
|
|
|
|
--timeout|-t)
|
|
TIMEOUT=$2
|
|
shift
|
|
;;
|
|
|
|
--libvirt|-l)
|
|
LIBVIRT=1
|
|
;;
|
|
|
|
|
|
--extra-params|-e)
|
|
[[ ${2::1} == "@" ]] && EXTRA_PARAMS+=("-e @$(realpath ${2#@}) ") || EXTRA_PARAMS+=("-e ${2} ")
|
|
shift
|
|
;;
|
|
|
|
--nodes-file|-n)
|
|
NODES_FILE=$2
|
|
shift
|
|
;;
|
|
|
|
--zuul-changes|-z)
|
|
ZUUL_CHANGES=$2
|
|
shift
|
|
;;
|
|
|
|
--toci-jobtype|-j)
|
|
TOCI_JOBTYPE=$2
|
|
shift
|
|
;;
|
|
|
|
--help|-h)
|
|
usage
|
|
exit
|
|
;;
|
|
|
|
--) shift
|
|
break
|
|
;;
|
|
|
|
-*) echo "ERROR: unknown option: $1" >&2
|
|
usage >&2
|
|
exit 2
|
|
;;
|
|
|
|
*) break
|
|
;;
|
|
esac
|
|
|
|
shift
|
|
done
|
|
|
|
|
|
function check_installed {
|
|
local binary=$1
|
|
if ! which $binary >/dev/null ; then
|
|
echo "Error: Could not find required binary $binary. Ensure you have
|
|
it installed before trying again."
|
|
exit 1
|
|
fi
|
|
}
|
|
BOOTSTRAP_DEPENDENCIES=("virtualenv" "ansible" "pip" "openstack")
|
|
function check_bootstrap_dependencies {
|
|
for dependency in ${BOOTSTRAP_DEPENDENCIES[@]} ; do
|
|
check_installed $dependency
|
|
done
|
|
}
|
|
|
|
# Check that tenant credentials have been sourced
|
|
# when deploying on a host cloud
|
|
if [[ (! -v OS_TENANT_NAME) && ("$LIBVIRT" != "1") ]]; then
|
|
# TODO(aschultz): work around for LP#1750455
|
|
if [[ -v OS_PROJECT_NAME ]]; then
|
|
export OS_TENANT_NAME=$OS_PROJECT_NAME
|
|
else
|
|
echo "Tenant credentials are not sourced."
|
|
exit 1;
|
|
fi
|
|
fi
|
|
set -x
|
|
|
|
|
|
# Exit if running ovb-fakeha-caserver
|
|
# This test is not converted to run with tripleo-quickstart
|
|
if [[ "$TOCI_JOBTYPE" == *"ovb-fakeha-caserver"* ]]; then
|
|
echo "
|
|
ovb-fakeha-caserver is not run with tripleo-quickstart.
|
|
It can not be reproduced using this script.
|
|
"
|
|
exit 1;
|
|
fi
|
|
|
|
# Exit of the user request a Libvirt reproducer for an OVB job
|
|
if [[ "$TOCI_JOBTYPE" == *"ovb"* && "$LIBVIRT" == "1" ]]; then
|
|
echo "
|
|
The Libvirt reproducer option is only valid for
|
|
Multinode and Singlenode jobs."
|
|
exit 1;
|
|
fi
|
|
|
|
set -x
|
|
|
|
# Export set variables, they make visible to ansible roles
|
|
export WORKSPACE
|
|
export ZUUL_CHANGES
|
|
|
|
# Start from a clean workspace
|
|
mkdir -p $WORKSPACE
|
|
cd $WORKSPACE
|
|
rm -rf tripleo-quickstart tripleo-quickstart-extras
|
|
|
|
# Clone quickstart and quickstart-extras
|
|
git clone https://github.com/openstack/tripleo-quickstart
|
|
git clone https://github.com/openstack/tripleo-quickstart-extras
|
|
|
|
# cherry pick any zull changes affecting the cloned repos
|
|
for CR in ${ZUUL_CHANGES//^/ }; do
|
|
if [[ "${CR}" =~ ^openstack\/(tripleo\-quickstart|tripleo\-quickstart\-extras):[^:]+:(refs\/changes\/[[:digit:]]+\/[[:digit:]]+\/[[:digit:]]+) ]]; then
|
|
pushd ${WORKSPACE}/${BASH_REMATCH[1]} >/dev/null
|
|
git fetch https://git.openstack.org/openstack/${BASH_REMATCH[1]} ${BASH_REMATCH[2]}
|
|
git cherry-pick --allow-empty FETCH_HEAD
|
|
popd >/dev/null
|
|
fi
|
|
done
|
|
|
|
# Set up a virtual env if requested
|
|
if [ "$CREATE_VIRTUALENV" = "true" ]; then
|
|
check_installed virtualenv
|
|
virtualenv $WORKSPACE/venv_ansible
|
|
source $WORKSPACE/venv_ansible/bin/activate
|
|
pip install --upgrade setuptools pip
|
|
pip install -Ur $WORKSPACE/tripleo-quickstart/requirements.txt
|
|
fi
|
|
|
|
if [ "$REMOVE_STACKS_KEYPAIRS" = "true" ]; then
|
|
# The cleanup templates expects there to be in a /bin dir in the workspace # from quickstart setup.
|
|
# To use the clients sourced from venv
|
|
sed -i "s#{.*/bin/##g" $WORKSPACE/tripleo-quickstart-extras/roles/ovb-manage-stack/templates/cleanup-stacks-keypairs.sh.j2
|
|
fi
|
|
|
|
# sanity check the env has ansible/pip/virtualenv/openstack/etc bootstrap dependencies
|
|
check_bootstrap_dependencies
|
|
|
|
# Export our roles path so that we can use the roles from our workspace
|
|
export ANSIBLE_ROLES_PATH=$ANSIBLE_ROLES_PATH:$WORKSPACE/tripleo-quickstart/roles:$WORKSPACE/tripleo-quickstart-extras/roles
|
|
export ANSIBLE_HOST_KEY_CHECKING=False
|
|
export ANSIBLE_LIBRARY=$WORKSPACE/tripleo-quickstart/library
|
|
|
|
{% if 'ovb' in toci_jobtype %}
|
|
ansible-playbook $WORKSPACE/tripleo-quickstart-extras/playbooks/ovb-create-stack.yml \
|
|
-e local_working_dir=$WORKSPACE \
|
|
-e virthost=localhost \
|
|
-e @$WORKSPACE/tripleo-quickstart-extras/config/environments/rdocloud.yml \
|
|
-e ssh_extra_args="" \
|
|
-e ovb_dump_hosts=true \
|
|
-e ovb_setup_user=true \
|
|
-e ansible_python_interpreter="/usr/bin/python" \
|
|
-e cleanup_stacks_keypairs=$REMOVE_STACKS_KEYPAIRS \
|
|
-e @$WORKSPACE/tripleo-quickstart/$NODES_FILE \
|
|
${EXTRA_PARAMS[@]}
|
|
|
|
# Run the playbook to setup the undercloud/subnodes to look like nodepool nodes
|
|
ansible-playbook $WORKSPACE/tripleo-quickstart-extras/playbooks/nodepool-setup.yml \
|
|
-i $WORKSPACE/ovb_hosts \
|
|
${EXTRA_PARAMS[@]}
|
|
|
|
# Copy the nodes.json file to the undercloud
|
|
export $(awk '/subnode-0/ {print $2}' ovb_hosts)
|
|
scp ${SSH_OPTS} $WORKSPACE/nodes.json zuul@$ansible_host:/home/zuul/
|
|
{% endif %}
|
|
|
|
{% set jobtype = toci_jobtype.replace('periodic-','').split('-')[0] %}
|
|
{% set types = [ "multinode", "singlenode", "standalone" ] %}
|
|
{% if jobtype in types %}
|
|
|
|
if [[ "$LIBVIRT" == "1" ]]; then
|
|
echo "Running a libvirt reproducer ..."
|
|
|
|
# Run from the Virthost
|
|
export VIRTHOST=127.0.0.2
|
|
echo -e "[virthost]\n$VIRTHOST" > $WORKSPACE/virthost
|
|
|
|
ansible-playbook $WORKSPACE/tripleo-quickstart/playbooks/libvirt-nodepool.yml \
|
|
-i $WORKSPACE/virthost \
|
|
-e ansible_python_interpreter="/usr/bin/python" \
|
|
-e local_working_dir=$WORKSPACE \
|
|
-e working_dir=$WORKSPACE \
|
|
-e non_root_user=$USER \
|
|
-e non_root_group=$USER \
|
|
${EXTRA_PARAMS[@]}
|
|
|
|
HOSTS_FILE="hosts"
|
|
else
|
|
# Calculate subnode_count
|
|
if [[ -z "$NODES_FILE" ]]; then
|
|
SUBNODE_COUNT=1
|
|
else
|
|
SUBNODE_COUNT=$(( $( awk '/node_count: / {print $2}' $WORKSPACE/tripleo-quickstart/$NODES_FILE ) +1 ))
|
|
fi
|
|
|
|
ansible-playbook $WORKSPACE/tripleo-quickstart-extras/playbooks/provision_multinodes.yml \
|
|
-e local_working_dir=$WORKSPACE \
|
|
-e subnode_count=$SUBNODE_COUNT \
|
|
-e ansible_python_interpreter="/usr/bin/python" \
|
|
-e prefix=$NODESTACK_PREFIX \
|
|
${EXTRA_PARAMS[@]}
|
|
|
|
HOSTS_FILE="multinode_hosts"
|
|
fi
|
|
|
|
# Run the playbook to setup the undercloud/subnodes to look like nodepool nodes
|
|
ansible-playbook $WORKSPACE/tripleo-quickstart-extras/playbooks/nodepool-setup.yml \
|
|
-i $WORKSPACE/$HOSTS_FILE \
|
|
${EXTRA_PARAMS[@]}
|
|
|
|
# Get ansible_host
|
|
export $(awk '/subnode-0/ {print $2}' $WORKSPACE/$HOSTS_FILE)
|
|
{% endif %}
|
|
|
|
{% if dlrn_hash_newest is defined or ('undercloud' in hostvars and 'dlrn_hash_newest' in hostvars['undercloud']) %}
|
|
EXTRA_VARS="$EXTRA_VARS --extra-vars dlrn_hash_tag_newest={{ hostvars['undercloud'].dlrn_hash_newest }} "
|
|
{% endif %}
|
|
|
|
# Create the env_vars_to_source file and copy it to the undercloud
|
|
cat >"{{ env_vars_to_source_file }}" <<EOF
|
|
export ZUUL_CHANGES="${ZUUL_CHANGES}"
|
|
export NODES_FILE="${NODES_FILE}"
|
|
export TOCI_JOBTYPE="${TOCI_JOBTYPE}"
|
|
export EXTRA_VARS="\$EXTRA_VARS {% if dlrn_hash is defined or ('undercloud' in hostvars and 'dlrn_hash' in hostvars['undercloud']) %}--extra-vars dlrn_hash_tag={{ hostvars['undercloud'].dlrn_hash }}{% endif %} "
|
|
export REMAINING_TIME="$TIMEOUT"
|
|
export PLAYBOOKS=$PLAYBOOKS
|
|
EOF
|
|
|
|
{% if stable_release != '' %}
|
|
cat >>"{{ env_vars_to_source_file }}" <<EOF
|
|
export STABLE_RELEASE="{{ stable_release }}"
|
|
EOF
|
|
{% endif %}
|
|
|
|
{% if 'ovb' in toci_jobtype %}
|
|
cat >>"{{ env_vars_to_source_file }}" <<EOF
|
|
export TE_DATAFILE=/home/zuul/nodes.json
|
|
EOF
|
|
{% endif %}
|
|
|
|
if [[ "$LIBVIRT" == "1" ]]; then
|
|
cat >>"{{ env_vars_to_source_file }}" <<EOF
|
|
# Uncomment this if you have established docker proxy on virthost
|
|
# export NODEPOOL_DOCKER_REGISTRY_PROXY=$NODEPOOL_DOCKER_REGISTRY_PROXY
|
|
export NODEPOOL_CENTOS_MIRROR=$NODEPOOL_CENTOS_MIRROR
|
|
export NODEPOOL_MIRROR_HOST=mirror.mtl01.inap.openstack.org
|
|
EOF
|
|
fi
|
|
|
|
scp ${SSH_OPTS} "$WORKSPACE/{{ env_vars_to_source_file }}" zuul@$ansible_host:/home/zuul/
|
|
if [[ "$AUTORUN" == "1" ]]; then
|
|
ssh ${SSH_OPTS} zuul@$ansible_host -tt \
|
|
"screen -LS ci -h 25000 -dm bash -c 'set -m; source ~/{{ env_vars_to_source_file }}; ANSIBLE_FORCE_COLOR=true /opt/stack/tripleo-ci/toci_gate_test.sh 2>&1 | tee ~/console.log; exec bash' && screen -RD"
|
|
else
|
|
# Remove -x so that the instructions don't print twice
|
|
set +x
|
|
|
|
# Instruct the user to execute toci_gate_test.sh on the undercloud
|
|
echo "
|
|
# Now complete the test excution on the undercloud:
|
|
# ssh to the undercloud:
|
|
ssh ${SSH_OPTS} zuul@$ansible_host
|
|
# Source the environment settings file and run the toci gate script
|
|
source /home/zuul/env_vars_to_src.sh
|
|
/opt/stack/tripleo-ci/toci_gate_test.sh 2>&1 | tee console.log
|
|
|
|
# To avoid timeouts, you can start a screen session before executing the commands:
|
|
screen -S ci
|
|
"
|
|
fi
|