lib/tempest
e263c82e
 #!/bin/bash
 #
d093121f
 # lib/tempest
6d04fd7b
 # Install and configure Tempest
d093121f
 
 # Dependencies:
6a5aa7c6
 #
 # - ``functions`` file
 # - ``lib/nova`` service is running
 # - Global vars that are assumed to be defined:
 #   - ``DEST``, ``FILES``
 #   - ``ADMIN_PASSWORD``
 #   - ``DEFAULT_IMAGE_NAME``
 #   - ``S3_SERVICE_PORT``
 #   - ``SERVICE_HOST``
 #   - ``BASE_SQL_CONN`` ``lib/database`` declares
 #   - ``PUBLIC_NETWORK_NAME``
 #   - ``Q_USE_NAMESPACE``
 #   - ``Q_ROUTER_NAME``
afbc631c
 #   - ``Q_L3_ENABLED``
6a5aa7c6
 #   - ``VIRT_DRIVER``
 #   - ``LIBVIRT_TYPE``
 #   - ``KEYSTONE_SERVICE_PROTOCOL``, ``KEYSTONE_SERVICE_HOST`` from lib/keystone
 #
2aa35174
 # Optional Dependencies:
6a5aa7c6
 #
 # - ``ALT_*`` (similar vars exists in keystone_data.sh)
 # - ``LIVE_MIGRATION_AVAILABLE``
 # - ``USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION``
 # - ``DEFAULT_INSTANCE_TYPE``
 # - ``DEFAULT_INSTANCE_USER``
09fb7baf
 # - ``CINDER_ENABLED_BACKENDS``
89ee5852
 # - ``NOVA_ALLOW_DUPLICATE_NETWORKS``
6a5aa7c6
 #
d093121f
 # ``stack.sh`` calls the entry points in this order:
 #
6a5aa7c6
 # - install_tempest
 # - configure_tempest
 # - init_tempest
d093121f
 
 # Save trace setting
 XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
6d04fd7b
 
d093121f
 # Defaults
 # --------
 
 # Set up default directories
91b22905
 GITDIR["tempest-lib"]=$DEST/tempest-lib
5cb19069
 
d093121f
 TEMPEST_DIR=$DEST/tempest
dc4dc7f0
 TEMPEST_CONFIG_DIR=${TEMPEST_CONFIG_DIR:-$TEMPEST_DIR/etc}
 TEMPEST_CONFIG=$TEMPEST_CONFIG_DIR/tempest.conf
14ccba0e
 TEMPEST_STATE_PATH=${TEMPEST_STATE_PATH:=$DATA_DIR/tempest}
2aa35174
 
6d04fd7b
 NOVA_SOURCE_DIR=$DEST/nova
 
bae0233c
 BUILD_INTERVAL=1
1bde9b4b
 
 # This is the timeout that tempest will wait for a VM to change state,
 # spawn, delete, etc.
 # The default is set to 196 seconds.
 BUILD_TIMEOUT=${BUILD_TIMEOUT:-196}
d093121f
 
c9b245bb
 # This must be False on stable branches, as master tempest
 # deps do not match stable branch deps. Set this to True to
dc97cb71
 # have tempest installed in DevStack by default.
71af1ee7
 INSTALL_TEMPEST=${INSTALL_TEMPEST:-"False"}
c9b245bb
 
2d4c8da8
 BOTO_MATERIALS_PATH="$FILES/images/s3-materials/cirros-${CIRROS_VERSION}"
58e694e2
 BOTO_CONF=/etc/boto.cfg
1d29d8bc
 
525bc5cf
 # This variable is passed directly to pip install inside the common tox venv
 # that is created
 TEMPEST_PLUGINS=${TEMPEST_PLUGINS:-0}
 
dc4dc7f0
 # Cinder/Volume variables
 TEMPEST_VOLUME_DRIVER=${TEMPEST_VOLUME_DRIVER:-default}
01456487
 TEMPEST_DEFAULT_VOLUME_VENDOR="Open Source"
 TEMPEST_VOLUME_VENDOR=${TEMPEST_VOLUME_VENDOR:-$TEMPEST_DEFAULT_VOLUME_VENDOR}
 TEMPEST_DEFAULT_STORAGE_PROTOCOL="iSCSI"
 TEMPEST_STORAGE_PROTOCOL=${TEMPEST_STORAGE_PROTOCOL:-$TEMPEST_DEFAULT_STORAGE_PROTOCOL}
cc6b4435
 
71ef61ac
 # Neutron/Network variables
53753293
 IPV6_ENABLED=$(trueorfalse True IPV6_ENABLED)
 IPV6_SUBNET_ATTRIBUTES_ENABLED=$(trueorfalse True IPV6_SUBNET_ATTRIBUTES_ENABLED)
71ef61ac
 
df8f43b4
 # Do we want to make a configuration where Tempest has admin on
 # the cloud. We don't always want to so that we can ensure Tempest
 # would work on a public cloud.
 TEMPEST_HAS_ADMIN=$(trueorfalse True TEMPEST_HAS_ADMIN)
 
 # Credential provider configuration option variables
 TEMPEST_ALLOW_TENANT_ISOLATION=${TEMPEST_ALLOW_TENANT_ISOLATION:-$TEMPEST_HAS_ADMIN}
403fbb1d
 TEMPEST_USE_TEST_ACCOUNTS=$(trueorfalse False TEMPEST_USE_TEST_ACCOUNTS)
df8f43b4
 
 # The number of workers tempest is expected to be run with. This is used for
 # generating a accounts.yaml for running with test-accounts. This is also the
 # same variable that devstack-gate uses to specify the number of workers that
 # it will run tempest with
 TEMPEST_CONCURRENCY=${TEMPEST_CONCURRENCY:-$(nproc)}
 
dc97cb71
 
cc6b4435
 # Functions
 # ---------
d093121f
 
33e8ee20
 # remove_disabled_extension - removes disabled extensions from the list of extensions
 # to test for a given service
 function remove_disabled_extensions {
     local extensions_list=$1
     shift
     local disabled_exts=$*
8606c98c
     remove_disabled_services "$extensions_list" "$disabled_exts"
33e8ee20
 }
 
d093121f
 # configure_tempest() - Set config files, create data dirs, etc
aee18c74
 function configure_tempest {
c9b245bb
     if [[ "$INSTALL_TEMPEST" == "True" ]]; then
         setup_develop $TEMPEST_DIR
     else
         # install testr since its used to process tempest logs
60996b1b
         pip_install_gr testrepository
c9b245bb
     fi
d5ac7852
 
1fa82aab
     # Used during configuration so make sure we have the correct
     # version installed
     pip_install_gr python-openstackclient
 
65c0846e
     local image_lines
     local images
     local num_images
     local image_uuid
     local image_uuid_alt
     local password
     local line
     local flavors
3b80bde8
     local available_flavors
65c0846e
     local flavors_ref
     local flavor_lines
a5c774ea
     local public_network_id
31c94ab5
     local public_router_id
a5c774ea
     local tenant_networks_reachable
1d29d8bc
     local boto_instance_type="m1.tiny"
57628163
     local ssh_connect_method="floating"
2aa35174
 
6d04fd7b
     # Save IFS
2aa35174
     ifs=$IFS
 
     # Glance should already contain images to be used in tempest
     # testing. Here we simply look for images stored in Glance
     # and set the appropriate variables for use in the tempest config
     # We ignore ramdisk and kernel images, look for the default image
65c0846e
     # ``DEFAULT_IMAGE_NAME``. If not found, we set the ``image_uuid`` to the
     # first image returned and set ``image_uuid_alt`` to the second,
2aa35174
     # if there is more than one returned...
     # ... Also ensure we only take active images, so we don't get snapshots in process
c24e23b4
     declare -a images
 
c411fcfc
     if is_service_enabled glance; then
         while read -r IMAGE_NAME IMAGE_UUID; do
             if [ "$IMAGE_NAME" = "$DEFAULT_IMAGE_NAME" ]; then
                 image_uuid="$IMAGE_UUID"
                 image_uuid_alt="$IMAGE_UUID"
c24e23b4
             fi
c411fcfc
             images+=($IMAGE_UUID)
a747cd25
         done < <(openstack image list --property status=active | awk -F'|' '!/^(+--)|ID|aki|ari/ { print $3,$2 }')
c411fcfc
 
         case "${#images[*]}" in
             0)
                 echo "Found no valid images to use!"
                 exit 1
                 ;;
             1)
                 if [ -z "$image_uuid" ]; then
                     image_uuid=${images[0]}
                     image_uuid_alt=${images[0]}
                 fi
                 ;;
             *)
                 if [ -z "$image_uuid" ]; then
                     image_uuid=${images[0]}
                     image_uuid_alt=${images[1]}
                 fi
                 ;;
         esac
     fi
2aa35174
 
93c10571
     # (Re)create ``tempest.conf``
     # Create every time because the image UUIDS are going to change
8421c2b9
     sudo install -d -o $STACK_USER $TEMPEST_CONFIG_DIR
93c10571
     rm -f $TEMPEST_CONFIG
2aa35174
 
65c0846e
     password=${ADMIN_PASSWORD:-secrete}
2aa35174
 
dc97cb71
     # See ``lib/keystone`` where these users and tenants are set up
d46d9dd8
     ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
     ADMIN_TENANT_NAME=${ADMIN_TENANT_NAME:-admin}
03523256
     ADMIN_DOMAIN_NAME=${ADMIN_DOMAIN_NAME:-Default}
d46d9dd8
     TEMPEST_USERNAME=${TEMPEST_USERNAME:-demo}
     TEMPEST_TENANT_NAME=${TEMPEST_TENANT_NAME:-demo}
2aa35174
     ALT_USERNAME=${ALT_USERNAME:-alt_demo}
     ALT_TENANT_NAME=${ALT_TENANT_NAME:-alt_demo}
49126233
     ADMIN_TENANT_ID=$(openstack project list | awk "/ admin / { print \$2 }")
2aa35174
 
c411fcfc
     if is_service_enabled nova; then
dc97cb71
         # If ``DEFAULT_INSTANCE_TYPE`` is not declared, use the new behavior
         # Tempest creates its own instance types
c411fcfc
         if  [[ -z "$DEFAULT_INSTANCE_TYPE" ]]; then
             available_flavors=$(nova flavor-list)
             if [[ ! ( $available_flavors =~ 'm1.nano' ) ]]; then
                 if is_arch "ppc64"; then
dc97cb71
                     # Qemu needs at least 128MB of memory to boot on ppc64
c411fcfc
                     nova flavor-create m1.nano 42 128 0 1
                 else
                     nova flavor-create m1.nano 42 64 0 1
                 fi
ba0f1d36
             fi
c411fcfc
             flavor_ref=42
             boto_instance_type=m1.nano
             if [[ ! ( $available_flavors =~ 'm1.micro' ) ]]; then
                 if is_arch "ppc64"; then
                     nova flavor-create m1.micro 84 256 0 1
                 else
                     nova flavor-create m1.micro 84 128 0 1
                 fi
ba0f1d36
             fi
c411fcfc
             flavor_ref_alt=84
         else
dc97cb71
             # Check Nova for existing flavors, if ``DEFAULT_INSTANCE_TYPE`` is set use it.
c411fcfc
             boto_instance_type=$DEFAULT_INSTANCE_TYPE
             flavor_lines=`nova flavor-list`
             IFS=$'\r\n'
             flavors=""
             for line in $flavor_lines; do
                 f=$(echo $line | awk "/ $DEFAULT_INSTANCE_TYPE / { print \$2 }")
                 flavors="$flavors $f"
             done
 
             for line in $flavor_lines; do
                 flavors="$flavors `echo $line | grep -v "^\(|\s*ID\|+--\)" | cut -d' ' -f2`"
             done
 
             IFS=" "
             flavors=($flavors)
             num_flavors=${#flavors[*]}
             echo "Found $num_flavors flavors"
             if [[ $num_flavors -eq 0 ]]; then
                 echo "Found no valid flavors to use!"
                 exit 1
63a71a23
             fi
c411fcfc
             flavor_ref=${flavors[0]}
             flavor_ref_alt=$flavor_ref
 
dc97cb71
             # Ensure ``flavor_ref`` and ``flavor_ref_alt`` have different values.
             # Some resize instance in tempest tests depends on this.
c411fcfc
             for f in ${flavors[@]:1}; do
                 if [[ $f -ne $flavor_ref ]]; then
                     flavor_ref_alt=$f
                     break
                 fi
             done
         fi
2aa35174
     fi
 
a5c774ea
     if [ "$Q_USE_NAMESPACE" != "False" ]; then
         tenant_networks_reachable=false
     else
         tenant_networks_reachable=true
     fi
 
386ae8c1
     ssh_connect_method=${TEMPEST_SSH_CONNECT_METHOD:-$ssh_connect_method}
 
afbc631c
     if [ "$Q_L3_ENABLED" = "True" ]; then
b05c8769
         public_network_id=$(neutron net-list | grep $PUBLIC_NETWORK_NAME | \
a5c774ea
             awk '{print $2}')
31c94ab5
         if [ "$Q_USE_NAMESPACE" == "False" ]; then
dc97cb71
             # If namespaces are disabled, DevStack will create a single
31c94ab5
             # public router that tempest should be configured to use.
b05c8769
             public_router_id=$(neutron router-list | awk "/ $Q_ROUTER_NAME / \
101b4248
                 { print \$2 }")
31c94ab5
         fi
a5c774ea
     fi
 
b17ad756
     EC2_URL=$(get_endpoint_url ec2 public || true)
40e652af
     if [[ -z $EC2_URL ]]; then
         EC2_URL="$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/"
     fi
b17ad756
     S3_URL=$(get_endpoint_url s3 public || true)
40e652af
     if [[ -z $S3_URL ]]; then
         S3_URL="http://$SERVICE_HOST:${S3_SERVICE_PORT:-3333}"
     fi
 
5a252d9a
     iniset $TEMPEST_CONFIG DEFAULT use_syslog $SYSLOG
dc97cb71
 
859cc680
     # Oslo
23d6d506
     iniset $TEMPEST_CONFIG oslo_concurrency lock_path $TEMPEST_STATE_PATH
14ccba0e
     mkdir -p $TEMPEST_STATE_PATH
dc4dc7f0
     iniset $TEMPEST_CONFIG DEFAULT use_stderr False
     iniset $TEMPEST_CONFIG DEFAULT log_file tempest.log
     iniset $TEMPEST_CONFIG DEFAULT debug True
859cc680
 
2aa35174
     # Timeouts
dc4dc7f0
     iniset $TEMPEST_CONFIG compute build_timeout $BUILD_TIMEOUT
     iniset $TEMPEST_CONFIG volume build_timeout $BUILD_TIMEOUT
     iniset $TEMPEST_CONFIG boto build_timeout $BUILD_TIMEOUT
     iniset $TEMPEST_CONFIG boto http_socket_timeout 5
2aa35174
 
97d3d202
     # Identity
dc4dc7f0
     iniset $TEMPEST_CONFIG identity uri "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:5000/v2.0/"
b74e01c3
     iniset $TEMPEST_CONFIG identity uri_v3 "$KEYSTONE_SERVICE_URI_V3"
d46d9dd8
     iniset $TEMPEST_CONFIG identity username $TEMPEST_USERNAME
dc4dc7f0
     iniset $TEMPEST_CONFIG identity password "$password"
d46d9dd8
     iniset $TEMPEST_CONFIG identity tenant_name $TEMPEST_TENANT_NAME
dc4dc7f0
     iniset $TEMPEST_CONFIG identity alt_username $ALT_USERNAME
     iniset $TEMPEST_CONFIG identity alt_password "$password"
     iniset $TEMPEST_CONFIG identity alt_tenant_name $ALT_TENANT_NAME
7ced150f
     if [[ "$TEMPEST_HAS_ADMIN" == "True" ]]; then
         iniset $TEMPEST_CONFIG identity admin_username $ADMIN_USERNAME
         iniset $TEMPEST_CONFIG identity admin_password "$password"
         iniset $TEMPEST_CONFIG identity admin_tenant_name $ADMIN_TENANT_NAME
         iniset $TEMPEST_CONFIG identity admin_tenant_id $ADMIN_TENANT_ID
         iniset $TEMPEST_CONFIG identity admin_domain_name $ADMIN_DOMAIN_NAME
     fi
3fd71d68
     if [ "$ENABLE_IDENTITY_V2" == "False" ]; then
         # Only Identity v3 is available; then skip Identity API v2 tests
75c1dfe3
         iniset $TEMPEST_CONFIG identity-feature-enabled api_v2 False
3fd71d68
         # In addition, use v3 auth tokens for running all Tempest tests
         iniset $TEMPEST_CONFIG identity auth_version v3
     else
         iniset $TEMPEST_CONFIG identity auth_version ${TEMPEST_AUTH_VERSION:-v2}
     fi
 
e1d013f9
     if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
         iniset $TEMPEST_CONFIG identity ca_certificates_file $SSL_BUNDLE_FILE
     fi
ab6da555
     iniset $TEMPEST_CONFIG identity-feature-enabled api_extensions OS-EC2
97d3d202
 
c3771456
     # Image
dc97cb71
     # We want to be able to override this variable in the gate to avoid
     # doing an external HTTP fetch for this test.
c3771456
     if [[ ! -z "$TEMPEST_HTTP_IMAGE" ]]; then
dc4dc7f0
         iniset $TEMPEST_CONFIG image http_image $TEMPEST_HTTP_IMAGE
c3771456
     fi
019bd53f
     if [ "$VIRT_DRIVER" = "xenserver" ]; then
         iniset $TEMPEST_CONFIG image disk_formats "ami,ari,aki,vhd,raw,iso"
5cdb66d7
         iniset $TEMPEST_CONFIG scenario img_disk_format vhd
019bd53f
     fi
c3771456
 
f100e1cf
     # Image Features
     iniset $TEMPEST_CONFIG image-feature-enabled deactivate_image True
 
97d3d202
     # Compute
dc4dc7f0
     iniset $TEMPEST_CONFIG compute ssh_user ${DEFAULT_INSTANCE_USER:-cirros} # DEPRECATED
     iniset $TEMPEST_CONFIG compute network_for_ssh $PRIVATE_NETWORK_NAME
     iniset $TEMPEST_CONFIG compute ip_version_for_ssh 4
     iniset $TEMPEST_CONFIG compute ssh_timeout $BUILD_TIMEOUT
     iniset $TEMPEST_CONFIG compute image_ref $image_uuid
     iniset $TEMPEST_CONFIG compute image_ssh_user ${DEFAULT_INSTANCE_USER:-cirros}
     iniset $TEMPEST_CONFIG compute image_ref_alt $image_uuid_alt
608f884e
     iniset $TEMPEST_CONFIG compute image_alt_ssh_user ${ALT_INSTANCE_USER:-cirros}
dc4dc7f0
     iniset $TEMPEST_CONFIG compute flavor_ref $flavor_ref
     iniset $TEMPEST_CONFIG compute flavor_ref_alt $flavor_ref_alt
     iniset $TEMPEST_CONFIG compute ssh_connect_method $ssh_connect_method
4b684aed
     if [[ ! $(is_service_enabled n-cell) && ! $(is_service_enabled neutron) ]]; then
f5b550ee
         iniset $TEMPEST_CONFIG compute fixed_network_name $PRIVATE_NETWORK_NAME
     fi
97d3d202
 
8349aff5
     # Set the service catalog entry for Tempest to run on. Typically
     # used to try different compute API version targets. The tempest
     # default if 'compute', which is typically valid, so only set this
     # if you want to change it.
     if [[ -n "$TEMPEST_COMPUTE_TYPE" ]]; then
         iniset $TEMPEST_CONFIG compute catalog_type $TEMPEST_COMPUTE_TYPE
     fi
 
de19bf9b
     # Compute Features
dc97cb71
     # Run ``verify_tempest_config -ur`` to retrieve enabled extensions on API endpoints
33e8ee20
     # NOTE(mtreinish): This must be done after auth settings are added to the tempest config
     local tmp_cfg_file=$(mktemp)
1368b986
     cd $TEMPEST_DIR
525bc5cf
     tox -revenv-tempest -- verify-tempest-config -u -r -o $tmp_cfg_file
33e8ee20
 
     local compute_api_extensions=${COMPUTE_API_EXTENSIONS:-"all"}
     if [[ ! -z "$DISABLE_COMPUTE_API_EXTENSIONS" ]]; then
         # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
         compute_api_extensions=${COMPUTE_API_EXTENSIONS:-$(iniget $tmp_cfg_file compute-feature-enabled api_extensions | tr -d " ")}
         # Remove disabled extensions
         compute_api_extensions=$(remove_disabled_extensions $compute_api_extensions $DISABLE_COMPUTE_API_EXTENSIONS)
     fi
 
de19bf9b
     iniset $TEMPEST_CONFIG compute-feature-enabled resize True
270f93e5
     iniset $TEMPEST_CONFIG compute-feature-enabled live_migration ${LIVE_MIGRATION_AVAILABLE:-False}
     iniset $TEMPEST_CONFIG compute-feature-enabled change_password False
     iniset $TEMPEST_CONFIG compute-feature-enabled block_migration_for_live_migration ${USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION:-False}
33e8ee20
     iniset $TEMPEST_CONFIG compute-feature-enabled api_extensions $compute_api_extensions
58065f26
     # TODO(mriedem): Remove the preserve_ports flag when Juno is end of life.
     iniset $TEMPEST_CONFIG compute-feature-enabled preserve_ports True
1b5a4982
     # TODO(gilliard): Remove the live_migrate_paused_instances flag when Juno is end of life.
     iniset $TEMPEST_CONFIG compute-feature-enabled live_migrate_paused_instances True
e57a3322
     iniset $TEMPEST_CONFIG compute-feature-enabled attach_encrypted_volume ${ATTACH_ENCRYPTED_VOLUME_AVAILABLE:-True}
89ee5852
     # TODO(mriedem): Remove this when kilo-eol happens since the
     # neutron.allow_duplicate_networks option was removed from nova in Liberty
     # and is now the default behavior.
     iniset $TEMPEST_CONFIG compute-feature-enabled allow_duplicate_networks ${NOVA_ALLOW_DUPLICATE_NETWORKS:-True}
09b431d7
     if is_service_enabled n-cell; then
         # Cells doesn't support shelving/unshelving
         iniset $TEMPEST_CONFIG compute-feature-enabled shelve False
8c432d93
         # Cells doesn't support hot-plugging virtual interfaces.
         iniset $TEMPEST_CONFIG compute-feature-enabled interface_attach False
73e16ae4
 
         if  [[ -z "$DEFAULT_INSTANCE_TYPE" ]]; then
             # Cells supports resize but does not currently work with devstack
             # because of the custom flavors created for Tempest runs which are
             # not in the cells database.
             # TODO(mriedem): work on adding a nova-manage command to sync
             # flavors into the cells database.
             iniset $TEMPEST_CONFIG compute-feature-enabled resize False
         fi
09b431d7
     fi
de19bf9b
 
ea21eb4f
     # Network
dc4dc7f0
     iniset $TEMPEST_CONFIG network api_version 2.0
     iniset $TEMPEST_CONFIG network tenant_networks_reachable "$tenant_networks_reachable"
     iniset $TEMPEST_CONFIG network public_network_id "$public_network_id"
     iniset $TEMPEST_CONFIG network public_router_id "$public_router_id"
     iniset $TEMPEST_CONFIG network default_network "$FIXED_RANGE"
ccf60f75
     iniset $TEMPEST_CONFIG network-feature-enabled ipv6 "$IPV6_ENABLED"
bb2908b7
     iniset $TEMPEST_CONFIG network-feature-enabled ipv6_subnet_attributes "$IPV6_SUBNET_ATTRIBUTES_ENABLED"
33e8ee20
 
3deab5cd
     DEFAULT_NET_EXT="agent,allowed-address-pairs,binding"
     DEFAULT_NET_EXT+=",dhcp_agent_scheduler,dns-integration"
     DEFAULT_NET_EXT+=",dvr,ext-gw-mode,external-net"
     DEFAULT_NET_EXT+=",extra_dhcp_opt,extraroute,flavors,fwaas"
     DEFAULT_NET_EXT+=",fwaasrouterinsertion,l3-ha,l3_agent_scheduler,lbaas"
     DEFAULT_NET_EXT+=",lbaas_agent_scheduler,metering,multi-provider,net-mtu,port-security"
     DEFAULT_NET_EXT+=",provider,quotas,rbac-policies,router,security-group,service-type"
     DEFAULT_NET_EXT+=",subnet_allocation,vpnaas"
     local network_api_extensions="${NETWORK_API_EXTENSIONS:-$DEFAULT_NET_EXT}"
33e8ee20
     if [[ ! -z "$DISABLE_NETWORK_API_EXTENSIONS" ]]; then
         # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
         network_api_extensions=${NETWORK_API_EXTENSIONS:-$(iniget $tmp_cfg_file network-feature-enabled api_extensions | tr -d " ")}
         # Remove disabled extensions
         network_api_extensions=$(remove_disabled_extensions $network_api_extensions $DISABLE_NETWORK_API_EXTENSIONS)
     fi
     iniset $TEMPEST_CONFIG network-feature-enabled api_extensions $network_api_extensions
2aa35174
 
97e1bd03
     # boto
40e652af
     iniset $TEMPEST_CONFIG boto ec2_url "$EC2_URL"
     iniset $TEMPEST_CONFIG boto s3_url "$S3_URL"
dc4dc7f0
     iniset $TEMPEST_CONFIG boto s3_materials_path "$BOTO_MATERIALS_PATH"
53971539
     iniset $TEMPEST_CONFIG boto ari_manifest cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-initrd.manifest.xml
     iniset $TEMPEST_CONFIG boto ami_manifest cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-blank.img.manifest.xml
     iniset $TEMPEST_CONFIG boto aki_manifest cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-vmlinuz.manifest.xml
dc4dc7f0
     iniset $TEMPEST_CONFIG boto instance_type "$boto_instance_type"
     iniset $TEMPEST_CONFIG boto http_socket_timeout 30
2aa35174
 
669c4fc4
     # Orchestration Tests
     if is_service_enabled heat; then
         if [[ ! -z "$HEAT_CFN_IMAGE_URL" ]]; then
f3e75bf9
             iniset $TEMPEST_CONFIG orchestration image_ref $(basename "${HEAT_CFN_IMAGE_URL%.*}")
669c4fc4
         fi
51557a50
         # build a specialized heat flavor
669c4fc4
         available_flavors=$(nova flavor-list)
         if [[ ! ( $available_flavors =~ 'm1.heat' ) ]]; then
51557a50
             nova flavor-create m1.heat 451 512 0 1
669c4fc4
         fi
         iniset $TEMPEST_CONFIG orchestration instance_type "m1.heat"
         iniset $TEMPEST_CONFIG orchestration build_timeout 900
886cbb2a
         iniset $TEMPEST_CONFIG orchestration stack_owner_role "_member_"
d5cccad2
     fi
 
24d866ef
     # Scenario
d870047b
     SCENARIO_IMAGE_DIR=${SCENARIO_IMAGE_DIR:-$FILES/images/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec}
d2cb234b
     iniset $TEMPEST_CONFIG scenario img_dir $SCENARIO_IMAGE_DIR
d870047b
     iniset $TEMPEST_CONFIG scenario ami_img_file "cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-blank.img"
     iniset $TEMPEST_CONFIG scenario ari_img_file "cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-initrd"
     iniset $TEMPEST_CONFIG scenario aki_img_file "cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-vmlinuz"
     iniset $TEMPEST_CONFIG scenario img_file "cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-disk.img"
24d866ef
 
bb8c6d42
     # Large Ops Number
dc4dc7f0
     iniset $TEMPEST_CONFIG scenario large_ops_number ${TEMPEST_LARGE_OPS_NUMBER:-0}
bb8c6d42
 
2541d611
     # Telemetry
71e4e6f6
     iniset $TEMPEST_CONFIG telemetry-feature-enabled events "True"
2541d611
 
dc97cb71
     # Object Store
3deab5cd
     DEFAULT_SWIFT_OPT="account_quotas,bulk,bulk_delete,bulk_upload,container_quotas"
     DEFAULT_SWIFT_OPT+=",container_sync,crossdomain,formpost,ratelimit,slo"
     DEFAULT_SWIFT_OPT+=",staticweb,tempauth,tempurl"
 
     local object_storage_api_extensions="${OBJECT_STORAGE_API_EXTENSIONS:-$DEFAULT_SWIFT_OPT}"
33e8ee20
     if [[ ! -z "$DISABLE_OBJECT_STORAGE_API_EXTENSIONS" ]]; then
         # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
         object_storage_api_extensions=${OBJECT_STORAGE_API_EXTENSIONS:-$(iniget $tmp_cfg_file object-storage-feature-enabled discoverable_apis | tr -d " ")}
         # Remove disabled extensions
         object_storage_api_extensions=$(remove_disabled_extensions $object_storage_api_extensions $DISABLE_STORAGE_API_EXTENSIONS)
     fi
     iniset $TEMPEST_CONFIG object-storage-feature-enabled discoverable_apis $object_storage_api_extensions
3046bc68
 
994db617
     # Validation
     iniset $TEMPEST_CONFIG validation run_validation ${TEMPEST_RUN_VALIDATION:-False}
 
97e1bd03
     # Volume
d1d6667c
     # TODO(dkranz): Remove the bootable flag when Juno is end of life.
     iniset $TEMPEST_CONFIG volume-feature-enabled bootable True
e8c70e23
     # TODO(jordanP): Remove the extend_with_snapshot flag when Juno is end of life.
     iniset $TEMPEST_CONFIG volume-feature-enabled extend_with_snapshot True
0355ecc4
     # TODO(obutenko): Remove the incremental_backup_force flag when Kilo and Juno is end of life.
     iniset $TEMPEST_CONFIG volume-feature-enabled incremental_backup_force True
d1d6667c
 
3deab5cd
     DEFAULT_VOL_EXT="OS-SCH-HNT,backups,capabilities,cgsnapshots,consistencygroups"
     DEFAULT_VOL_EXT+=",encryption,os-admin-actions,os-availability-zone"
     DEFAULT_VOL_EXT+=",os-extended-services,os-extended-snapshot-attributes"
     DEFAULT_VOL_EXT+=",os-hosts,os-image-create,os-quota-class-sets,os-quota-sets"
     DEFAULT_VOL_EXT+=",os-services,os-snapshot-actions,os-snapshot-manage,os-snapshot-unmanage"
     DEFAULT_VOL_EXT+=",os-types-extra-specs"
     DEFAULT_VOL_EXT+=",os-types-manage,os-used-limits,os-vol-host-attr,os-vol-image-meta"
     DEFAULT_VOL_EXT+=",os-vol-mig-status-attr,os-vol-tenant-attr,os-volume-actions"
     DEFAULT_VOL_EXT+=",os-volume-encryption-metadata,os-volume-manage"
     DEFAULT_VOL_EXT+=",os-volume-replication,os-volume-transfer,os-volume-type-access"
     DEFAULT_VOL_EXT+=",os-volume-unmanage,qos-specs,scheduler-stats"
     local volume_api_extensions="${VOLUME_API_EXTENSIONS:-$DEFAULT_VOL_EXT}"
33e8ee20
     if [[ ! -z "$DISABLE_VOLUME_API_EXTENSIONS" ]]; then
         # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
         volume_api_extensions=${VOLUME_API_EXTENSIONS:-$(iniget $tmp_cfg_file volume-feature-enabled api_extensions | tr -d " ")}
ea21eb4f
         # Remove disabled extensions
33e8ee20
         volume_api_extensions=$(remove_disabled_extensions $volume_api_extensions $DISABLE_VOLUME_API_EXTENSIONS)
     fi
     iniset $TEMPEST_CONFIG volume-feature-enabled api_extensions $volume_api_extensions
 
3d60f4dd
     if ! is_service_enabled c-bak; then
         iniset $TEMPEST_CONFIG volume-feature-enabled backup False
3632ab1b
     fi
09fb7baf
 
dc97cb71
     # Using ``CINDER_ENABLED_BACKENDS``
09fb7baf
     if [[ -n "$CINDER_ENABLED_BACKENDS" ]] && [[ $CINDER_ENABLED_BACKENDS =~ .*,.* ]]; then
db1c3847
         iniset $TEMPEST_CONFIG volume-feature-enabled multi_backend "True"
09fb7baf
         local i=1
         local be
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             local be_name=${be##*:}
             iniset $TEMPEST_CONFIG volume "backend${i}_name" "$be_name"
             i=$(( i + 1 ))
         done
dc4dc7f0
     fi
 
01456487
     if [ $TEMPEST_VOLUME_DRIVER != "default" -o \
1c0628f8
         "$TEMPEST_VOLUME_VENDOR" != "$TEMPEST_DEFAULT_VOLUME_VENDOR" ]; then
2f23d757
         iniset $TEMPEST_CONFIG volume vendor_name "$TEMPEST_VOLUME_VENDOR"
01456487
     fi
     if [ $TEMPEST_VOLUME_DRIVER != "default" -o \
82a7d939
         "$TEMPEST_STORAGE_PROTOCOL" != "$TEMPEST_DEFAULT_STORAGE_PROTOCOL" ]; then
         iniset $TEMPEST_CONFIG volume storage_protocol "$TEMPEST_STORAGE_PROTOCOL"
97e1bd03
     fi
 
fea70f80
     # Dashboard
dc4dc7f0
     iniset $TEMPEST_CONFIG dashboard dashboard_url "http://$SERVICE_HOST/"
     iniset $TEMPEST_CONFIG dashboard login_url "http://$SERVICE_HOST/auth/login/"
fea70f80
 
dc97cb71
     # CLI
dc4dc7f0
     iniset $TEMPEST_CONFIG cli cli_dir $NOVA_BIN_DIR
7fa1902f
 
43bd667b
     # Baremetal
     if [ "$VIRT_DRIVER" = "ironic" ] ; then
         iniset $TEMPEST_CONFIG baremetal driver_enabled True
bcc239f3
         iniset $TEMPEST_CONFIG baremetal unprovision_timeout $BUILD_TIMEOUT
         iniset $TEMPEST_CONFIG baremetal active_timeout $BUILD_TIMEOUT
41309002
         iniset $TEMPEST_CONFIG baremetal deploy_img_dir $FILES
         iniset $TEMPEST_CONFIG baremetal node_uuid $IRONIC_NODE_UUID
fdfe7a01
         iniset $TEMPEST_CONFIG compute-feature-enabled change_password False
         iniset $TEMPEST_CONFIG compute-feature-enabled console_output False
         iniset $TEMPEST_CONFIG compute-feature-enabled interface_attach False
         iniset $TEMPEST_CONFIG compute-feature-enabled live_migration False
         iniset $TEMPEST_CONFIG compute-feature-enabled pause False
         iniset $TEMPEST_CONFIG compute-feature-enabled rescue False
         iniset $TEMPEST_CONFIG compute-feature-enabled resize False
         iniset $TEMPEST_CONFIG compute-feature-enabled shelve False
         iniset $TEMPEST_CONFIG compute-feature-enabled snapshot False
cf21b710
         iniset $TEMPEST_CONFIG compute-feature-enabled suspend False
43bd667b
     fi
 
7b47c473
     # Libvirt-LXC
     if [ "$VIRT_DRIVER" = "libvirt" ] && [ "$LIBVIRT_TYPE" = "lxc" ]; then
         iniset $TEMPEST_CONFIG compute-feature-enabled rescue False
         iniset $TEMPEST_CONFIG compute-feature-enabled resize False
         iniset $TEMPEST_CONFIG compute-feature-enabled suspend False
     fi
 
dc97cb71
     # ``service_available``
346edcc5
     #
     # this tempest service list needs to be all the services that
     # tempest supports, otherwise we can have an erroneous set of
     # defaults (something defaulting true in Tempest, but not listed here).
624ab1e6
     TEMPEST_SERVICES="key,glance,nova,neutron,cinder,swift,heat,ceilometer,horizon,sahara,ironic,trove"
4237f590
     for service in ${TEMPEST_SERVICES//,/ }; do
b56d81d5
         if is_service_enabled $service ; then
dc4dc7f0
             iniset $TEMPEST_CONFIG service_available $service "True"
b56d81d5
         else
dc4dc7f0
             iniset $TEMPEST_CONFIG service_available $service "False"
b56d81d5
         fi
     done
 
e1d013f9
     if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
dc97cb71
         # Use the ``BOTO_CONFIG`` environment variable to point to this file
9c0b9f30
         iniset -sudo $BOTO_CONF Boto ca_certificates_file $SSL_BUNDLE_FILE
90c20209
         sudo chown $STACK_USER $BOTO_CONF
     fi
 
df8f43b4
     # Auth
     iniset $TEMPEST_CONFIG auth tempest_roles "Member"
     if [[ $TEMPEST_USE_TEST_ACCOUNTS == "True" ]]; then
         if [[ $TEMPEST_HAS_ADMIN == "True" ]]; then
             tempest-account-generator -c $TEMPEST_CONFIG --os-username $ADMIN_USERNAME --os-password $ADMIN_PASSWORD --os-tenant-name $ADMIN_TENANT_NAME -r $TEMPEST_CONCURRENCY --with-admin etc/accounts.yaml
b274dbd7
         else
df8f43b4
             tempest-account-generator -c $TEMPEST_CONFIG --os-username $ADMIN_USERNAME --os-password $ADMIN_PASSWORD --os-tenant-name $ADMIN_TENANT_NAME -r $TEMPEST_CONCURRENCY etc/accounts.yaml
         fi
         iniset $TEMPEST_CONFIG auth allow_tenant_isolation False
         iniset $TEMPEST_CONFIG auth test_accounts_file "etc/accounts.yaml"
     else
         iniset $TEMPEST_CONFIG auth allow_tenant_isolation ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
     fi
2aa35174
     # Restore IFS
     IFS=$ifs
d093121f
 }
 
42a59c2b
 # create_tempest_accounts() - Set up common required tempest accounts
 
 # Project              User         Roles
 # ------------------------------------------------------------------
 # alt_demo             alt_demo     Member
 
 function create_tempest_accounts {
     if is_service_enabled tempest; then
         # Tempest has some tests that validate various authorization checks
         # between two regular users in separate tenants
b632c9ef
         get_or_create_project alt_demo default
9d7e776b
         get_or_create_user alt_demo "$ADMIN_PASSWORD" "default" "alt_demo@example.com"
9b215db5
         get_or_add_user_project_role Member alt_demo alt_demo
42a59c2b
     fi
 }
 
dc97cb71
 # install_tempest_lib() - Collect source, prepare, and install ``tempest-lib``
34723862
 function install_tempest_lib {
91b22905
     if use_library_from_git "tempest-lib"; then
         git_clone_by_name "tempest-lib"
86b65dd7
         setup_dev_lib "tempest-lib"
dc97cb71
         # NOTE(mtreinish) For testing ``tempest-lib`` from git with Tempest we need to
         # put the git version of ``tempest-lib`` in the Tempest job's tox venv
83e166b7
         export PIP_VIRTUAL_ENV=${PROJECT_VENV["tempest"]}
         setup_dev_lib "tempest-lib"
         unset PIP_VIRTUAL_ENV
5cb19069
     fi
34723862
 }
 
d093121f
 # install_tempest() - Collect source and prepare
aee18c74
 function install_tempest {
d093121f
     git_clone $TEMPEST_REPO $TEMPEST_DIR $TEMPEST_BRANCH
33dc8699
     pip_install tox
83e166b7
     pushd $TEMPEST_DIR
     tox --notest -efull
525bc5cf
     PROJECT_VENV["tempest"]=${TEMPEST_DIR}/.tox/tempest
fee3d18f
     popd
 }
 
 # install_tempest_plugins() - Install any specified plugins into the tempest venv
 function install_tempest_plugins {
     pushd $TEMPEST_DIR
525bc5cf
     if [[ $TEMPEST_PLUGINS != 0 ]] ; then
         tox -evenv-tempest -- pip install $TEMPEST_PLUGINS
86b0f804
     fi
83e166b7
     install_tempest_lib
     popd
d093121f
 }
 
dc97cb71
 # init_tempest() - Initialize EC2 images
aee18c74
 function init_tempest {
53971539
     local base_image_name=cirros-${CIRROS_VERSION}-${CIRROS_ARCH}
     # /opt/stack/devstack/files/images/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec
3c52922f
     local image_dir="$FILES/images/${base_image_name}-uec"
1d29d8bc
     local kernel="$image_dir/${base_image_name}-vmlinuz"
     local ramdisk="$image_dir/${base_image_name}-initrd"
     local disk_image="$image_dir/${base_image_name}-blank.img"
c411fcfc
     if is_service_enabled nova; then
dc97cb71
         # If the CirrOS uec downloaded and the system is UEC capable
c411fcfc
         if [ -f "$kernel" -a -f "$ramdisk" -a -f "$disk_image" -a  "$VIRT_DRIVER" != "openvz" \
             -a \( "$LIBVIRT_TYPE" != "lxc" -o "$VIRT_DRIVER" != "libvirt" \) ]; then
             echo "Prepare aki/ari/ami Images"
             mkdir -p $BOTO_MATERIALS_PATH
             ( #new namespace
7cc3907f
                 # euca2ools should be installed to call euca-* commands
                 is_package_installed euca2ools || install_package euca2ools
c411fcfc
                 # tenant:demo ; user: demo
                 source $TOP_DIR/accrc/demo/demo
                 euca-bundle-image -r ${CIRROS_ARCH} -i "$kernel" --kernel true -d "$BOTO_MATERIALS_PATH"
                 euca-bundle-image -r ${CIRROS_ARCH} -i "$ramdisk" --ramdisk true -d "$BOTO_MATERIALS_PATH"
                 euca-bundle-image -r ${CIRROS_ARCH} -i "$disk_image" -d "$BOTO_MATERIALS_PATH"
             ) 2>&1 </dev/null | cat
         else
             echo "Boto materials are not prepared"
         fi
1d29d8bc
     fi
 }
 
d093121f
 # Restore xtrace
 $XTRACE
584d90ec
 
6a5aa7c6
 # Tell emacs to use shell-script-mode
 ## Local variables:
 ## mode: shell-script
 ## End: