Takashi Kajinami 0e51506419 Bump Fedora image used in CI
Fedora 36 is already EOLed so we should use more recent version.

Because guest enters to emergency shell when Fedora 38 (latest at
the time of writing) is used, we select Fedora 37 for now.

Change-Id: Ie0876080c771fb124d4dd36f803fbfd3b108e240
2023-09-07 21:20:31 +09:00

517 lines
20 KiB
Bash

#!/bin/bash
#
# lib/heat
# Install and start **Heat** service
# To enable, add the following to localrc
#
# ENABLED_SERVICES+=,heat,h-api,h-api-cfn,h-eng
# Dependencies:
# (none)
# stack.sh
# ---------
# - install_heatclient
# - install_heat
# - configure_heatclient
# - configure_heat
# - init_heat
# - start_heat
# - stop_heat
# - cleanup_heat
# Save trace setting
_XTRACE_HEAT=$(set +o | grep xtrace)
set +o xtrace
# Defaults
# --------
# set up default directories
GITDIR["python-heatclient"]=$DEST/python-heatclient
# python heat client library
GITREPO["python-heatclient"]=${HEATCLIENT_REPO:-${GIT_BASE}/openstack/python-heatclient.git}
GITBRANCH["python-heatclient"]=${HEATCLIENT_BRANCH:-master}
# Use HEAT_USE_MOD_WSGI for backward compatibility
HEAT_USE_APACHE=${HEAT_USE_APACHE:-${HEAT_USE_MOD_WSGI:-True}}
HEAT_DIR=$DEST/heat
HEAT_FILES_DIR=$HEAT_DIR/heat/httpd/files
HEAT_STANDALONE=$(trueorfalse False HEAT_STANDALONE)
HEAT_ENABLE_ADOPT_ABANDON=$(trueorfalse False HEAT_ENABLE_ADOPT_ABANDON)
HEAT_CONF_DIR=/etc/heat
HEAT_CONF=$HEAT_CONF_DIR/heat.conf
HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
HEAT_API_HOST=${HEAT_API_HOST:-$SERVICE_HOST}
HEAT_API_PORT=${HEAT_API_PORT:-8004}
HEAT_SERVICE_USER=${HEAT_SERVICE_USER:-heat}
HEAT_TRUSTEE_USER=${HEAT_TRUSTEE_USER:-$HEAT_SERVICE_USER}
HEAT_TRUSTEE_PASSWORD=${HEAT_TRUSTEE_PASSWORD:-$SERVICE_PASSWORD}
HEAT_TRUSTEE_DOMAIN=${HEAT_TRUSTEE_DOMAIN:-default}
# Support entry points installation of console scripts
HEAT_BIN_DIR=$(get_python_exec_prefix)
HEAT_API_UWSGI_CONF=$HEAT_CONF_DIR/heat-api-uwsgi.ini
HEAT_CFN_API_UWSGI_CONF=$HEAT_CONF_DIR/heat-api-cfn-uwsgi.ini
HEAT_API_UWSGI=$HEAT_BIN_DIR/heat-wsgi-api
HEAT_CFN_API_UWSGI=$HEAT_BIN_DIR/heat-wsgi-api-cfn
# other default options
if [[ "$HEAT_STANDALONE" == "True" ]]; then
# for standalone, use defaults which require no service user
HEAT_STACK_DOMAIN=$(trueorfalse False HEAT_STACK_DOMAIN)
HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-password}
if [[ ${HEAT_DEFERRED_AUTH} != "password" ]]; then
# Heat does not support keystone trusts when deployed in
# standalone mode
die $LINENO \
'HEAT_DEFERRED_AUTH can only be set to "password" when HEAT_STANDALONE is True.'
fi
else
HEAT_STACK_DOMAIN=$(trueorfalse True HEAT_STACK_DOMAIN)
HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-}
fi
HEAT_PLUGIN_DIR=${HEAT_PLUGIN_DIR:-$DATA_DIR/heat/plugins}
ENABLE_HEAT_PLUGINS=${ENABLE_HEAT_PLUGINS:-}
HEAT_ENGINE_WORKERS=${HEAT_ENGINE_WORKERS:=$(( ($(nproc)/4)<2 ? 2 : ($(nproc)/4) ))}
# Functions
# ---------
# Test if any Heat services are enabled
# is_heat_enabled
function is_heat_enabled {
[[ ,${ENABLED_SERVICES} =~ ,"h-" ]] && return 0
return 1
}
# cleanup_heat() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_heat {
if [[ "$HEAT_USE_APACHE" == "True" ]]; then
_cleanup_heat_apache_wsgi
fi
sudo rm -rf $HEAT_ENV_DIR
sudo rm -rf $HEAT_TEMPLATES_DIR
sudo rm -rf $HEAT_CONF_DIR
}
# configure_heat() - Set config files, create data dirs, etc
function configure_heat {
sudo install -d -o $STACK_USER $HEAT_CONF_DIR
# remove old config files
rm -f $HEAT_CONF_DIR/heat-*.conf
HEAT_API_CFN_HOST=${HEAT_API_CFN_HOST:-$SERVICE_HOST}
HEAT_API_CFN_PORT=${HEAT_API_CFN_PORT:-8000}
HEAT_ENGINE_HOST=${HEAT_ENGINE_HOST:-$SERVICE_HOST}
HEAT_ENGINE_PORT=${HEAT_ENGINE_PORT:-8001}
HEAT_API_PASTE_FILE=$HEAT_CONF_DIR/api-paste.ini
cp $HEAT_DIR/etc/heat/api-paste.ini $HEAT_API_PASTE_FILE
# common options
iniset_rpc_backend heat $HEAT_CONF
if [[ "$HEAT_USE_APACHE" == "True" && "$WSGI_MODE" == "uwsgi" ]]; then
iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST/heat-api-cfn
iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST/heat-api-cfn/v1/waitcondition
else
iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT
iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
fi
iniset $HEAT_CONF database connection `database_connection_url heat`
# we are using a hardcoded auth_encryption_key as it has to be the same for
# multinode deployment.
iniset $HEAT_CONF DEFAULT auth_encryption_key "767c3ed056cbaa3b9dfedb8c6f825bf0"
iniset $HEAT_CONF DEFAULT region_name_for_services "$REGION_NAME"
# logging
iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
# reduce Heat engine workers
iniset $HEAT_CONF DEFAULT num_engine_workers "$HEAT_ENGINE_WORKERS"
local no_format="False"
if [[ "$HEAT_USE_APACHE" == "True" && "$WSGI_MODE" != "uwsgi" ]]; then
no_format="True"
fi
# Format logging
setup_logging $HEAT_CONF $no_format
if [[ ! -z "$HEAT_DEFERRED_AUTH" ]]; then
iniset $HEAT_CONF DEFAULT deferred_auth_method $HEAT_DEFERRED_AUTH
fi
if [[ "$HEAT_USE_APACHE" == "True" ]]; then
if [[ $WSGI_MODE == "uwsgi" ]]; then
write_uwsgi_config "$HEAT_API_UWSGI_CONF" "$HEAT_API_UWSGI" "/heat-api"
# configure threads for h-api to avoid IO wait and messaging timeout. We use
# 'nproc/4' to calculate API workers, hence, 4 would be probably correct
# approximation.
iniset "$HEAT_API_UWSGI_CONF" uwsgi threads 4
write_uwsgi_config "$HEAT_CFN_API_UWSGI_CONF" "$HEAT_CFN_API_UWSGI" "/heat-api-cfn"
else
_config_heat_apache_wsgi
fi
fi
if [[ "$HEAT_STANDALONE" = "True" ]]; then
iniset $HEAT_CONF paste_deploy flavor standalone
iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
else
configure_auth_token_middleware $HEAT_CONF heat
fi
# If HEAT_DEFERRED_AUTH is unset or explicitly set to trusts, configure
# the section for the client plugin associated with the trustee
if [ -z "$HEAT_DEFERRED_AUTH" -o "trusts" == "$HEAT_DEFERRED_AUTH" ]; then
iniset $HEAT_CONF trustee auth_type password
iniset $HEAT_CONF trustee auth_url $KEYSTONE_AUTH_URI
iniset $HEAT_CONF trustee username $HEAT_TRUSTEE_USER
iniset $HEAT_CONF trustee password $HEAT_TRUSTEE_PASSWORD
iniset $HEAT_CONF trustee user_domain_id $HEAT_TRUSTEE_DOMAIN
fi
# clients_keystone
iniset $HEAT_CONF clients_keystone auth_uri $KEYSTONE_AUTH_URI
# OpenStack API
iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT
iniset $HEAT_CONF heat_api workers "$API_WORKERS"
# Cloudformation API
iniset $HEAT_CONF heat_api_cfn bind_port $HEAT_API_CFN_PORT
if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
iniset $HEAT_CONF clients_keystone ca_file $SSL_BUNDLE_FILE
fi
if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
iniset $HEAT_CONF clients_nova ca_file $SSL_BUNDLE_FILE
fi
if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
iniset $HEAT_CONF clients_cinder ca_file $SSL_BUNDLE_FILE
fi
if [[ "$HEAT_ENABLE_ADOPT_ABANDON" = "True" ]]; then
iniset $HEAT_CONF DEFAULT enable_stack_adopt true
iniset $HEAT_CONF DEFAULT enable_stack_abandon true
fi
iniset $HEAT_CONF cache enabled "True"
iniset $HEAT_CONF cache backend "dogpile.cache.memory"
if ! is_service_enabled c-bak; then
iniset $HEAT_CONF volumes backups_enabled false
fi
sudo install -d -o $STACK_USER $HEAT_ENV_DIR $HEAT_TEMPLATES_DIR
# copy the default environment
cp $HEAT_DIR/etc/heat/environment.d/* $HEAT_ENV_DIR/
# copy the default templates
cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/
# Enable heat plugins.
# NOTE(nic): The symlink nonsense is necessary because when
# plugins are installed in "developer mode", the final component
# of their target directory is always "resources", which confuses
# Heat's plugin loader into believing that all plugins are named
# "resources", and therefore are all the same plugin; so it
# will only load one of them. Linking them all to a common
# location with unique names avoids that type of collision,
# while still allowing the plugins to be edited in-tree.
local err_count=0
if [[ -n "$ENABLE_HEAT_PLUGINS" ]]; then
mkdir -p $HEAT_PLUGIN_DIR
# Clean up cruft from any previous runs
rm -f $HEAT_PLUGIN_DIR/*
iniset $HEAT_CONF DEFAULT plugin_dirs $HEAT_PLUGIN_DIR
fi
for heat_plugin in $ENABLE_HEAT_PLUGINS; do
if [[ -d $HEAT_DIR/contrib/$heat_plugin ]]; then
setup_package $HEAT_DIR/contrib/$heat_plugin -e
ln -s $HEAT_DIR/contrib/$heat_plugin/$heat_plugin/resources $HEAT_PLUGIN_DIR/$heat_plugin
else
: # clear retval on the test so that we can roll up errors
err $LINENO "Requested Heat plugin(${heat_plugin}) not found."
err_count=$(($err_count + 1))
fi
done
[ $err_count -eq 0 ] || die $LINENO "$err_count of the requested Heat plugins could not be installed."
}
# init_heat() - Initialize database
function init_heat {
# recreate db only if one of the db services is enabled
if is_service_enabled $DATABASE_BACKENDS; then
# (re)create heat database
recreate_database heat
$HEAT_BIN_DIR/heat-manage db_sync
fi
}
# install_heatclient() - Collect source and prepare
function install_heatclient {
if use_library_from_git "python-heatclient"; then
git_clone_by_name "python-heatclient"
setup_dev_lib "python-heatclient"
sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-heatclient"]}/tools/,/etc/bash_completion.d/}heat.bash_completion
fi
}
# install_heat() - Collect source and prepare
function install_heat {
setup_develop $HEAT_DIR
if [[ "$HEAT_USE_APACHE" == "True" ]]; then
if [ "$WSGI_MODE" == "uwsgi" ]; then
pip_install uwsgi
else
install_apache_wsgi
fi
fi
}
# start_heat() - Start running processes, including screen
function start_heat {
run_process h-eng "$HEAT_BIN_DIR/heat-engine --config-file=$HEAT_CONF"
# If the site is not enabled then we are in a grenade scenario
local enabled_site_file
enabled_site_file=$(apache_site_config_for heat-api)
if [[ "$HEAT_USE_APACHE" == "True" ]]; then
if [[ -f ${enabled_site_file} && "$WSGI_MODE" != "uwsgi" ]]; then
enable_apache_site heat-api
enable_apache_site heat-api-cfn
restart_apache_server
else
run_process h-api "$HEAT_BIN_DIR/uwsgi --ini $HEAT_API_UWSGI_CONF" ""
run_process h-api-cfn "$HEAT_BIN_DIR/uwsgi --ini $HEAT_CFN_API_UWSGI_CONF" ""
fi
else
run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
fi
}
function _stop_processes {
local serv
for serv in h-api h-api-cfn; do
stop_process $serv
done
}
# stop_heat() - Stop running processes
function stop_heat {
# Kill the screen windows
stop_process h-eng
if [[ "$HEAT_USE_APACHE" == "True" ]]; then
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
_stop_processes
else
disable_apache_site heat-api
disable_apache_site heat-api-cfn
restart_apache_server
fi
else
_stop_processes
fi
}
# _cleanup_heat_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cleanup_heat_apache_wsgi {
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
remove_uwsgi_config "$HEAT_API_UWSGI_CONF" "$HEAT_API_UWSGI"
remove_uwsgi_config "$HEAT_CFN_API_UWSGI_CONF" "$HEAT_CFN_API_UWSGI"
fi
sudo rm -f $(apache_site_config_for heat-api)
sudo rm -f $(apache_site_config_for heat-api-cfn)
}
# _config_heat_apache_wsgi() - Set WSGI config files of Heat
function _config_heat_apache_wsgi {
local heat_apache_conf
heat_apache_conf=$(apache_site_config_for heat-api)
local heat_cfn_apache_conf
heat_cfn_apache_conf=$(apache_site_config_for heat-api-cfn)
local heat_ssl=""
local heat_certfile=""
local heat_keyfile=""
local heat_api_port=$HEAT_API_PORT
local heat_cfn_api_port=$HEAT_API_CFN_PORT
local venv_path=""
sudo cp $HEAT_FILES_DIR/heat-api.conf $heat_apache_conf
sudo sed -e "
s|%PUBLICPORT%|$heat_api_port|g;
s|%APACHE_NAME%|$APACHE_NAME|g;
s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
s|%API_WORKERS%|$API_WORKERS|g;
s|%SSLENGINE%|$heat_ssl|g;
s|%SSLCERTFILE%|$heat_certfile|g;
s|%SSLKEYFILE%|$heat_keyfile|g;
s|%USER%|$STACK_USER|g;
s|%VIRTUALENV%|$venv_path|g
" -i $heat_apache_conf
sudo cp $HEAT_FILES_DIR/heat-api-cfn.conf $heat_cfn_apache_conf
sudo sed -e "
s|%PUBLICPORT%|$heat_cfn_api_port|g;
s|%APACHE_NAME%|$APACHE_NAME|g;
s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
s|%API_WORKERS%|$API_WORKERS|g;
s|%SSLENGINE%|$heat_ssl|g;
s|%SSLCERTFILE%|$heat_certfile|g;
s|%SSLKEYFILE%|$heat_keyfile|g;
s|%USER%|$STACK_USER|g;
s|%VIRTUALENV%|$venv_path|g
" -i $heat_cfn_apache_conf
}
# create_heat_accounts() - Set up common required heat accounts
function create_heat_accounts {
if [[ "$HEAT_STANDALONE" != "True" ]]; then
local heat_api_service_url
local heat_cfn_api_service_url
if [[ "$HEAT_USE_APACHE" == "True" && "$WSGI_MODE" == "uwsgi" ]]; then
heat_api_service_url="$SERVICE_PROTOCOL://$HEAT_API_HOST/heat-api/v1/\$(project_id)s"
heat_cfn_api_service_url="$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST/heat-api-cfn/v1"
else
heat_api_service_url="$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s"
heat_cfn_api_service_url="$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
fi
create_service_user "heat" "admin"
get_or_create_service "heat" "orchestration" "Heat Orchestration Service"
get_or_create_endpoint \
"orchestration" \
"$REGION_NAME" \
"$heat_api_service_url"
get_or_create_service "heat-cfn" "cloudformation" "Heat CloudFormation Service"
get_or_create_endpoint \
"cloudformation" \
"$REGION_NAME" \
"$heat_cfn_api_service_url"
# heat_stack_user role is for users created by Heat
get_or_create_role "heat_stack_user"
fi
if [[ "$HEAT_STACK_DOMAIN" == "True" ]]; then
# domain -> heat and user -> heat_domain_admin
domain_id=$(get_or_create_domain heat 'Owns users and projects created by heat')
iniset $HEAT_CONF DEFAULT stack_user_domain_id ${domain_id}
get_or_create_user heat_domain_admin $SERVICE_PASSWORD heat
get_or_add_user_domain_role admin heat_domain_admin heat
iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
fi
}
# configure_tempest_for_heat()
# NOTE (gmann): Configure all the Tempest setting for Heat service in
# this function.
function configure_tempest_for_heat {
# Skip SoftwareConfigIntegrationTest because it requires a custom image
SKIP_SCENARIO_TEST_LIST='SoftwareConfigIntegrationTest'
# Skip AutoscalingLoadBalancerTest and AutoscalingLoadBalancerv2Test as deprecated neutron-lbaas service is not enabled
SKIP_SCENARIO_TEST_LIST+=',AutoscalingLoadBalancerTest,AutoscalingLoadBalancerv2Test'
SKIP_SCENARIO_TEST_LIST+=',AodhAlarmTest'
# Skip CfnInitIntegrationTest as latest fedora images don't have heat-cfntools
SKIP_SCENARIO_TEST_LIST+=',CfnInitIntegrationTest'
if is_ubuntu; then
# Skip a few tests failing because of a known libvirt issue in Jammy
# https://bugs.launchpad.net/nova/+bug/1998274
SKIP_SCENARIO_TEST_LIST+=',BasicResourcesTest'
fi
iniset $TEMPEST_CONFIG heat_plugin skip_scenario_test_list $SKIP_SCENARIO_TEST_LIST
# Skip LoadBalancerv2Test as deprecated neutron-lbaas service is not enabled.
SKIP_FUNCTIONAL_TEST_LIST='LoadBalancerv2Test,NotificationTest'
if is_ubuntu; then
# Skip a few tests failing because of a known libvirt issue in Jammy
# https://bugs.launchpad.net/nova/+bug/1998274
SKIP_FUNCTIONAL_TEST_LIST+=',UpdateStackTest.test_stack_update_with_replacing_userdata'
SKIP_FUNCTIONAL_TEST_LIST+=',CancelUpdateTest.test_cancel_update_server_with_port'
fi
iniset $TEMPEST_CONFIG heat_plugin skip_functional_test_list $SKIP_FUNCTIONAL_TEST_LIST
openstack flavor show m1.heat_int || openstack flavor create m1.heat_int --ram 512 --disk 10
openstack flavor show m1.heat_micro || openstack flavor create m1.heat_micro --ram 128 --disk 1
export OS_CLOUD=devstack
openstack network show heat-net || openstack network create heat-net
openstack subnet show heat-subnet || openstack subnet create heat-subnet --network heat-net --subnet-range 10.0.5.0/24
openstack router add subnet router1 heat-subnet
# NOTE(ianw) OpenDev infra only keeps the latest two Fedora's
# around; prefer the mirror but allow fallback
if [[ -e /etc/ci/mirror_info.sh ]]; then
source /etc/ci/mirror_info.sh
fi
HEAT_TEST_FEDORA_IMAGE_UPSTREAM=https://download.fedoraproject.org/pub/fedora/linux
HEAT_TEST_FEDORA_IMAGE_PATH=releases/37/Cloud/x86_64/images/Fedora-Cloud-Base-37-1.7.x86_64.qcow2
if curl --output /dev/null --silent --head --fail "${NODEPOOL_FEDORA_MIRROR}/${HEAT_TEST_FEDORA_IMAGE_PATH}"; then
export HEAT_TEST_FEDORA_IMAGE="${NODEPOOL_FEDORA_MIRROR}/${HEAT_TEST_FEDORA_IMAGE_PATH}"
else
export HEAT_TEST_FEDORA_IMAGE="${HEAT_TEST_FEDORA_IMAGE_UPSTREAM}/${HEAT_TEST_FEDORA_IMAGE_PATH}"
fi
TOKEN=$(openstack token issue -c id -f value)
local image_exists=$( openstack image list | grep "Fedora-Cloud-Base-37-1.7.x86_64" )
if [[ -z $image_exists ]]; then
if is_service_enabled g-api; then
upload_image $HEAT_TEST_FEDORA_IMAGE $TOKEN
fi
fi
if is_service_enabled tls-proxy; then
iniset $TEMPEST_CONFIG heat_plugin ca_file $SSL_BUNDLE_FILE
fi
# add application credential and secret to support test multi-cloud
app_cred_id=$(openstack application credential show heat_multicloud || openstack application credential create heat_multicloud \
--secret secret --unrestricted -c id -f value)
export OS_CREDENTIAL_SECRET_ID=$(openstack secret store -n heat-multi-cloud-test-cred --payload \
'{"auth_type": "v3applicationcredential", "auth": {"auth_url": $OS_AUTH_URL, "application_credential_id": $app_cred_id, "application_credential_secret": "secret"}}'\
-c "Secret href" -f value)
source $TOP_DIR/openrc demo demo
iniset $TEMPEST_CONFIG heat_plugin username $OS_USERNAME
iniset $TEMPEST_CONFIG heat_plugin password $OS_PASSWORD
iniset $TEMPEST_CONFIG heat_plugin project_name $OS_PROJECT_NAME
iniset $TEMPEST_CONFIG heat_plugin auth_url $OS_AUTH_URL
iniset $TEMPEST_CONFIG heat_plugin user_domain_id $OS_USER_DOMAIN_ID
iniset $TEMPEST_CONFIG heat_plugin project_domain_id $OS_PROJECT_DOMAIN_ID
iniset $TEMPEST_CONFIG heat_plugin user_domain_name $OS_USER_DOMAIN_NAME
iniset $TEMPEST_CONFIG heat_plugin project_domain_name $OS_PROJECT_DOMAIN_NAME
iniset $TEMPEST_CONFIG heat_plugin region $OS_REGION_NAME
iniset $TEMPEST_CONFIG heat_plugin auth_version $OS_IDENTITY_API_VERSION
source $TOP_DIR/openrc admin admin
iniset $TEMPEST_CONFIG heat_plugin admin_username $OS_USERNAME
iniset $TEMPEST_CONFIG heat_plugin admin_password $OS_PASSWORD
export OS_CLOUD=devstack-admin
}
# Restore xtrace
$_XTRACE_HEAT