
This makes 'nova-manage limits migrate_to_unified_limits' scan the API database for flavors and detect if any resource classes are missing registered limits in Keystone. Related to blueprint unified-limits-nova-unset-limits Change-Id: I431176fd4d09201c551d8f82c71515cd4616cfea
375 lines
13 KiB
Bash
Executable File
375 lines
13 KiB
Bash
Executable File
#!/bin/bash -x
|
|
|
|
MANAGE="/usr/local/bin/nova-manage"
|
|
|
|
function archive_deleted_rows {
|
|
# NOTE(danms): Run this a few times to make sure that we end
|
|
# up with nothing more to archive
|
|
if ! $MANAGE db archive_deleted_rows --verbose --before "$(date -d yesterday)" 2>&1 | grep 'Nothing was archived'; then
|
|
echo "Archiving yesterday data should have done nothing"
|
|
return 1
|
|
fi
|
|
for i in `seq 30`; do
|
|
if [[ $i -eq 1 ]]; then
|
|
# This is just a test wrinkle to make sure we're covering the
|
|
# non-all-cells (cell0) case, as we're not passing in the cell1
|
|
# config.
|
|
$MANAGE db archive_deleted_rows --verbose --max_rows 50 --before "$(date -d tomorrow)"
|
|
else
|
|
$MANAGE db archive_deleted_rows --verbose --max_rows 1000 --before "$(date -d tomorrow)" --all-cells
|
|
fi
|
|
RET=$?
|
|
if [[ $RET -gt 1 ]]; then
|
|
echo Archiving failed with result $RET
|
|
return $RET
|
|
# When i = 1, we only archive cell0 (without --all-cells), so run at
|
|
# least twice to ensure --all-cells are archived before considering
|
|
# archiving complete.
|
|
elif [[ $RET -eq 0 && $i -gt 1 ]]; then
|
|
echo Archiving Complete
|
|
break;
|
|
fi
|
|
done
|
|
}
|
|
|
|
function purge_db {
|
|
$MANAGE db purge --all --verbose --all-cells
|
|
RET=$?
|
|
if [[ $RET -eq 0 ]]; then
|
|
echo Purge successful
|
|
else
|
|
echo Purge failed with result $RET
|
|
return $RET
|
|
fi
|
|
}
|
|
|
|
BASE=${BASE:-/opt/stack}
|
|
source ${BASE}/devstack/functions-common
|
|
source ${BASE}/devstack/lib/nova
|
|
|
|
# This needs to go before 'set -e' because otherwise the intermediate runs of
|
|
# 'nova-manage db archive_deleted_rows' returning 1 (normal and expected) would
|
|
# cause this script to exit and fail.
|
|
archive_deleted_rows
|
|
|
|
set -e
|
|
|
|
# This needs to go after 'set -e' because otherwise a failure to purge the
|
|
# database would not cause this script to exit and fail.
|
|
purge_db
|
|
|
|
# We need to get the admin credentials to run the OSC CLIs for Placement.
|
|
export OS_CLOUD=devstack-admin
|
|
|
|
# Verify whether instances were archived from all cells. Admin credentials are
|
|
# needed to list deleted instances across all projects.
|
|
echo "Verifying that instances were archived from all cells"
|
|
deleted_servers=$(openstack server list --deleted --all-projects -c ID -f value)
|
|
|
|
# Fail if any deleted servers were found.
|
|
if [[ -n "$deleted_servers" ]]; then
|
|
echo "There were unarchived instances found after archiving; failing."
|
|
exit 1
|
|
fi
|
|
|
|
# TODO(mriedem): Consider checking for instances in ERROR state because
|
|
# if there are any, we would expect them to retain allocations in Placement
|
|
# and therefore we don't really need to check for leaked allocations.
|
|
|
|
# Check for orphaned instance allocations in Placement which could mean
|
|
# something failed during a test run and isn't getting cleaned up properly.
|
|
echo "Looking for leaked resource provider allocations in Placement"
|
|
LEAKED_ALLOCATIONS=0
|
|
for provider in $(openstack resource provider list -c uuid -f value); do
|
|
echo "Looking for allocations for provider $provider"
|
|
allocations=$(openstack resource provider show --allocations $provider \
|
|
-c allocations -f value)
|
|
if [[ "$allocations" != "{}" ]]; then
|
|
echo "Resource provider has allocations:"
|
|
openstack resource provider show --allocations $provider
|
|
LEAKED_ALLOCATIONS=1
|
|
fi
|
|
done
|
|
|
|
# Fail if there were any leaked allocations.
|
|
if [[ $LEAKED_ALLOCATIONS -eq 1 ]]; then
|
|
echo "There were leaked allocations; failing."
|
|
exit 1
|
|
fi
|
|
echo "Resource provider allocations were cleaned up properly."
|
|
|
|
|
|
# Test "nova-manage placement heal_allocations" by creating a server, deleting
|
|
# its allocations in placement, and then running heal_allocations and assert
|
|
# the allocations were healed as expected.
|
|
|
|
function get_binding_profile_value
|
|
{
|
|
# Returns the value of the key in the binding profile if exists or return
|
|
# empty.
|
|
local port=${1}
|
|
local key=${2}
|
|
local print_value='import sys, json; print(json.load(sys.stdin).get("binding_profile", {}).get("'${key}'", ""))'
|
|
openstack port show ${port} -f json -c binding_profile \
|
|
| /usr/bin/env python3 -c "${print_value}"
|
|
}
|
|
|
|
echo "Creating port with bandwidth request for heal_allocations testing"
|
|
openstack network create net0 \
|
|
--provider-network-type vlan \
|
|
--provider-physical-network public \
|
|
--provider-segment 100
|
|
|
|
openstack subnet create subnet0 \
|
|
--network net0 \
|
|
--subnet-range 10.0.4.0/24 \
|
|
|
|
openstack network qos policy create qp0
|
|
openstack network qos rule create qp0 \
|
|
--type minimum-bandwidth \
|
|
--min-kbps 1000 \
|
|
--egress
|
|
|
|
openstack network qos rule create qp0 \
|
|
--type minimum-bandwidth \
|
|
--min-kbps 1000 \
|
|
--ingress
|
|
|
|
openstack port create port-normal-qos \
|
|
--network net0 \
|
|
--vnic-type normal \
|
|
--qos-policy qp0
|
|
|
|
image_id=$(openstack image list -f value -c ID | awk 'NR==1{print $1}')
|
|
flavor_id=$(openstack flavor list -f value -c ID | awk 'NR==1{print $1}')
|
|
network_id=$(openstack network list --no-share -f value -c ID | awk 'NR==1{print $1}')
|
|
|
|
echo "Creating server for heal_allocations testing"
|
|
# microversion 2.72 introduced the support for bandwidth aware ports
|
|
openstack --os-compute-api-version 2.72 \
|
|
server create --image ${image_id} --flavor ${flavor_id} \
|
|
--nic net-id=${network_id} --nic port-id=port-normal-qos \
|
|
--wait heal-allocations-test
|
|
server_id=$(openstack server show heal-allocations-test -f value -c id)
|
|
|
|
# Make sure there are allocations for the consumer.
|
|
allocations=$(openstack resource provider allocation show ${server_id} \
|
|
-c resources -f value)
|
|
if [[ "$allocations" == "" ]]; then
|
|
echo "No allocations found for the server."
|
|
exit 2
|
|
fi
|
|
|
|
echo "Deleting allocations in placement for the server"
|
|
openstack resource provider allocation delete ${server_id}
|
|
|
|
# Make sure the allocations are gone.
|
|
allocations=$(openstack resource provider allocation show ${server_id} \
|
|
-c resources -f value)
|
|
if [[ "$allocations" != "" ]]; then
|
|
echo "Server allocations were not deleted."
|
|
exit 2
|
|
fi
|
|
|
|
echo "Healing allocations"
|
|
# First test with the --dry-run over all instances in all cells.
|
|
set +e
|
|
nova-manage placement heal_allocations --verbose --dry-run
|
|
rc=$?
|
|
set -e
|
|
# Since we did not create allocations because of --dry-run the rc should be 4.
|
|
if [[ ${rc} -ne 4 ]]; then
|
|
echo "Expected return code 4 from heal_allocations with --dry-run"
|
|
exit 2
|
|
fi
|
|
# Now test with just the single instance and actually perform the heal.
|
|
nova-manage placement heal_allocations --verbose --instance ${server_id}
|
|
|
|
# Make sure there are allocations for the consumer.
|
|
allocations=$(openstack resource provider allocation show ${server_id} \
|
|
-c resources -f value)
|
|
if [[ "$allocations" == "" ]]; then
|
|
echo "Failed to heal allocations."
|
|
exit 2
|
|
fi
|
|
|
|
echo "Verifying online_data_migrations idempotence"
|
|
# We will reuse the server created earlier for this test. (A server needs to
|
|
# be present during the run of online_data_migrations and archiving).
|
|
|
|
# Run the online data migrations before archiving.
|
|
$MANAGE db online_data_migrations
|
|
|
|
# We need to archive the deleted marker instance used by the
|
|
# fill_virtual_interface_list online data migration in order to trigger
|
|
# creation of a new deleted marker instance.
|
|
set +e
|
|
archive_deleted_rows
|
|
set -e
|
|
|
|
# Verify whether online data migrations run after archiving will succeed.
|
|
# See for more details: https://bugs.launchpad.net/nova/+bug/1824435
|
|
$MANAGE db online_data_migrations
|
|
|
|
|
|
# Test global registered unified limits by updating registered limits and
|
|
# attempting to create resources. Because these quota limits are global, we
|
|
# can't test them in tempest because modifying global limits can cause other
|
|
# tests running in parallel to fail.
|
|
echo "Testing unified limits registered limits"
|
|
|
|
# Get the registered limits IDs.
|
|
reglimit_ids_names=$(openstack registered limit list -f value -c "ID" -c "Resource Name")
|
|
|
|
# Put them in a map to lookup ID from name for subsequent limit set commands.
|
|
# Requires Bash 4.
|
|
declare -A id_name_map
|
|
while read id name
|
|
do id_name_map["$name"]="$id"
|
|
done <<< "$reglimit_ids_names"
|
|
|
|
# Server metadata items
|
|
#
|
|
# Set the quota to 1.
|
|
metadata_items_id="${id_name_map["server_metadata_items"]}"
|
|
|
|
bash -c "unset OS_USERNAME OS_TENANT_NAME OS_PROJECT_NAME;
|
|
openstack --os-cloud devstack-system-admin registered limit set \
|
|
--default-limit 1 $metadata_items_id"
|
|
|
|
# Create a server. Should succeed with one metadata item.
|
|
openstack --os-compute-api-version 2.37 \
|
|
server create --image ${image_id} --flavor ${flavor_id} --nic none \
|
|
--property cool=true --wait metadata-items-test1
|
|
|
|
# Try to create another server with two metadata items. This should fail.
|
|
set +e
|
|
output=$(openstack --os-compute-api-version 2.37 \
|
|
server create --image ${image_id} --flavor ${flavor_id} --nic none \
|
|
--property cool=true --property location=fridge \
|
|
--wait metadata-items-test2)
|
|
rc=$?
|
|
set -e
|
|
# Return code should be 1 if server create failed.
|
|
if [[ ${rc} -ne 1 ]]; then
|
|
echo "Expected return code 1 from server create with two metadata items"
|
|
exit 2
|
|
fi
|
|
# Verify it's a quota error.
|
|
if [[ ! "HTTP 403" =~ "$output" ]]; then
|
|
echo "Expected HTTP 403 from server create with two metadata items"
|
|
exit 2
|
|
fi
|
|
|
|
# Increase the quota limit to two.
|
|
bash -c "unset OS_USERNAME OS_TENANT_NAME OS_PROJECT_NAME;
|
|
openstack --os-cloud devstack-system-admin registered limit set \
|
|
--default-limit 2 $metadata_items_id"
|
|
|
|
# Second server create should succeed now.
|
|
openstack --os-compute-api-version 2.37 \
|
|
server create --image ${image_id} --flavor ${flavor_id} --nic none \
|
|
--property cool=true --property location=fridge --wait metadata-items-test2
|
|
|
|
# Delete the servers.
|
|
openstack server delete metadata-items-test1 metadata-items-test2
|
|
|
|
|
|
# Test 'nova-manage limits migrate_to_unified_limits' by creating a test region
|
|
# with no registered limits in it, run the nova-manage command, and verify the
|
|
# expected limits were created and warned about.
|
|
echo "Testing nova-manage limits migrate_to_unified_limits"
|
|
|
|
ul_test_region=RegionTestNovaUnifiedLimits
|
|
|
|
openstack --os-cloud devstack-admin region create $ul_test_region
|
|
|
|
# Verify there are no registered limits in the test region.
|
|
registered_limits=$(openstack --os-cloud devstack registered limit list \
|
|
--region $ul_test_region -f value)
|
|
|
|
if [[ "$registered_limits" != "" ]]; then
|
|
echo "There should be no registered limits in the test region; failing"
|
|
exit 2
|
|
fi
|
|
|
|
# Get existing legacy quota limits to use for verification.
|
|
legacy_limits=$(openstack --os-cloud devstack quota show --compute -f value -c "Resource" -c "Limit")
|
|
# Requires Bash 4.
|
|
declare -A legacy_name_limit_map
|
|
while read name limit
|
|
do legacy_name_limit_map["$name"]="$limit"
|
|
done <<< "$legacy_limits"
|
|
|
|
set +e
|
|
set -o pipefail
|
|
$MANAGE limits migrate_to_unified_limits --region-id $ul_test_region --verbose | tee /tmp/output
|
|
rc=$?
|
|
set +o pipefail
|
|
set -e
|
|
|
|
if [[ ${rc} -eq 0 ]]; then
|
|
echo "nova-manage should have warned about unset registered limits; failing"
|
|
exit 2
|
|
fi
|
|
|
|
# Verify there are now registered limits in the test region.
|
|
registered_limits=$(openstack --os-cloud devstack registered limit list \
|
|
--region $ul_test_region -f value -c "Resource Name" -c "Default Limit")
|
|
|
|
if [[ "$registered_limits" == "" ]]; then
|
|
echo "There should be registered limits in the test region now; failing"
|
|
exit 2
|
|
fi
|
|
|
|
# Get the new unified limits to use for verification.
|
|
declare -A unified_name_limit_map
|
|
while read name limit
|
|
do unified_name_limit_map["$name"]="$limit"
|
|
done <<< "$registered_limits"
|
|
|
|
declare -A old_to_new_name_map
|
|
old_to_new_name_map["instances"]="servers"
|
|
old_to_new_name_map["cores"]="class:VCPU"
|
|
old_to_new_name_map["ram"]="class:MEMORY_MB"
|
|
old_to_new_name_map["properties"]="server_metadata_items"
|
|
old_to_new_name_map["injected-files"]="server_injected_files"
|
|
old_to_new_name_map["injected-file-size"]="server_injected_file_content_bytes"
|
|
old_to_new_name_map["injected-path-size"]="server_injected_file_path_bytes"
|
|
old_to_new_name_map["key-pairs"]="server_key_pairs"
|
|
old_to_new_name_map["server-groups"]="server_groups"
|
|
old_to_new_name_map["server-group-members"]="server_group_members"
|
|
|
|
for old_name in "${!old_to_new_name_map[@]}"; do
|
|
new_name="${old_to_new_name_map[$old_name]}"
|
|
if [[ "${legacy_name_limit_map[$old_name]}" != "${unified_name_limit_map[$new_name]}" ]]; then
|
|
echo "Legacy limit value does not match unified limit value; failing"
|
|
exit 2
|
|
fi
|
|
done
|
|
|
|
# Create the missing registered limits that were warned about earlier.
|
|
missing_limits=$(grep missing /tmp/output | awk '{print $2}')
|
|
while read limit
|
|
do openstack --os-cloud devstack-system-admin registered limit create \
|
|
--region $ul_test_region --service nova --default-limit 5 $limit
|
|
done <<< "$missing_limits"
|
|
|
|
# Run migrate_to_unified_limits again. There should be a success message in the
|
|
# output because there should be no resources found that are missing registered
|
|
# limits.
|
|
$MANAGE limits migrate_to_unified_limits --region-id $ul_test_region --verbose
|
|
rc=$?
|
|
|
|
if [[ ${rc} -ne 0 ]]; then
|
|
echo "nova-manage should have output a success message; failing"
|
|
exit 2
|
|
fi
|
|
|
|
registered_limit_ids=$(openstack --os-cloud devstack registered limit list \
|
|
--region $ul_test_region -f value -c "ID")
|
|
|
|
openstack --os-cloud devstack-system-admin registered limit delete $registered_limit_ids
|
|
|
|
openstack --os-cloud devstack-admin region delete $ul_test_region
|