Update root providers in same tree

When updating a parent provider of a resource provider, placement
didn't update a root provider of another resource provider in the
same tree.

This patch fixes it to update the root provider field of all the
resource providers in the same tree.

Change-Id: Icdedc10cdd5ebfda672ca2d65a75bf0143aa769c
Closes-Bug: #1779818
This commit is contained in:
Tetsuro Nakamura 2018-07-05 11:02:08 +09:00 committed by Eric Fried
parent 8469fa70da
commit bc8027515d
2 changed files with 28 additions and 12 deletions

View File

@ -1015,6 +1015,9 @@ class ResourceProvider(base.VersionedObject, base.TimestampedObject):
@db_api.placement_context_manager.writer
def _update_in_db(self, context, id, updates):
# A list of resource providers in the same tree with the
# resource provider to update
same_tree = []
if 'parent_provider_uuid' in updates:
# TODO(jaypipes): For now, "re-parenting" and "un-parenting" are
# not possible. If the provider already had a parent, we don't
@ -1072,8 +1075,24 @@ class ResourceProvider(base.VersionedObject, base.TimestampedObject):
db_rp = context.session.query(models.ResourceProvider).filter_by(
id=id).first()
db_rp.update(updates)
context.session.add(db_rp)
# We should also update the root providers of resource providers
# originally in the same tree. If re-parenting is supported,
# this logic should be changed to update only descendents of the
# re-parented resource providers, not all the providers in the tree.
for rp in same_tree:
# If the parent is not updated, this clause is skipped since the
# `same_tree` has no element.
rp.root_provider_uuid = parent_ids.root_uuid
db_rp = context.session.query(
models.ResourceProvider).filter_by(id=rp.id).first()
data = {'root_provider_id': parent_ids.root_id}
db_rp.update(data)
context.session.add(db_rp)
try:
db_rp.save(context.session)
context.session.flush()
except sqla_exc.IntegrityError:
# NOTE(jaypipes): Another thread snuck in and deleted the parent
# for this resource provider in between the above check for a valid

View File

@ -95,32 +95,29 @@ tests:
$.resource_providers[?uuid="$ENVIRON['ALT_PARENT_PROVIDER_UUID']"].parent_provider_uuid: null
$.resource_providers[?uuid="$ENVIRON['PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['PARENT_PROVIDER_UUID']"].parent_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
# Bug#1779818: The child's root should be updated to the alt_parent,
# but we actually still get the native parent for root.
# $.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].parent_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID']
- name: list all resource providers in a tree with the child
GET: /resource_providers?in_tree=$ENVIRON['RP_UUID']
response_json_paths:
# There should be 3 providers but we actually get 2
$.resource_providers.`len`: 2
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['PARENT_PROVIDER_UUID']
$.resource_providers.`len`: 3
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['ALT_PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
- name: list all resource providers in a tree with the parent
GET: /resource_providers?in_tree=$ENVIRON['PARENT_PROVIDER_UUID']
response_json_paths:
# There should be 3 providers but we actually get 2
$.resource_providers.`len`: 2
$.resource_providers.`len`: 3
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['ALT_PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
- name: list all resource providers in a tree with the alternative parent
GET: /resource_providers?in_tree=$ENVIRON['ALT_PARENT_PROVIDER_UUID']
response_json_paths:
# There should be 3 providers but we actually get 2
$.resource_providers.`len`: 2
$.resource_providers.`len`: 3
$.resource_providers[?uuid="$ENVIRON['RP_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['ALT_PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']
$.resource_providers[?uuid="$ENVIRON['PARENT_PROVIDER_UUID']"].root_provider_uuid: $ENVIRON['ALT_PARENT_PROVIDER_UUID']