[placement] Fix resource provider delete
Due to foreign key constraints for the resource_provider.root_provider_id in mysql and the way of column filling it is impossible to delete newly created RP now. Patch sets root_provider_id to NULL before deletion if root_provider_id == id. Closes-Bug: #1739571 Co-Authored-by: Andrey Volkov <avolkov@mirantis.com> Change-Id: I256c901fdc02b1f764ea9f8d1a1a708e82cc369a
This commit is contained in:
parent
459353eec2
commit
4dd1406289
nova
@ -644,6 +644,13 @@ def _provider_ids_from_uuid(context, uuid):
|
||||
return ProviderIds(**dict(res))
|
||||
|
||||
|
||||
@db_api.api_context_manager.writer
|
||||
def _delete_rp_record(context, _id):
|
||||
return context.session.query(models.ResourceProvider).\
|
||||
filter(models.ResourceProvider.id == _id).\
|
||||
delete(synchronize_session=False)
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register_if(False)
|
||||
class ResourceProvider(base.NovaObject, base.NovaTimestampObject):
|
||||
SETTABLE_FIELDS = ('name', 'parent_provider_uuid')
|
||||
@ -841,11 +848,14 @@ class ResourceProvider(base.NovaObject, base.NovaTimestampObject):
|
||||
RPT_model = models.ResourceProviderTrait
|
||||
context.session.query(RPT_model).\
|
||||
filter(RPT_model.resource_provider_id == _id).delete()
|
||||
# set root_provider_id to null to make deletion possible
|
||||
context.session.query(models.ResourceProvider).\
|
||||
filter(models.ResourceProvider.id == _id,
|
||||
models.ResourceProvider.root_provider_id == _id).\
|
||||
update({'root_provider_id': None})
|
||||
# Now delete the RP record
|
||||
try:
|
||||
result = context.session.query(models.ResourceProvider).\
|
||||
filter(models.ResourceProvider.id == _id).\
|
||||
delete(synchronize_session=False)
|
||||
result = _delete_rp_record(context, _id)
|
||||
except sqla_exc.IntegrityError:
|
||||
# NOTE(jaypipes): Another thread snuck in and parented this
|
||||
# resource provider in between the above check for
|
||||
|
@ -17,6 +17,7 @@ from oslo_utils import timeutils
|
||||
|
||||
import nova
|
||||
from nova import context
|
||||
from nova.db.sqlalchemy import api_models as models
|
||||
from nova import exception
|
||||
from nova.objects import fields
|
||||
from nova.objects import resource_provider
|
||||
@ -219,6 +220,29 @@ class TestResourceProvider(test_objects._LocalTest):
|
||||
resource_provider.ResourceProvider.get_by_uuid,
|
||||
self.context, uuids.rp)
|
||||
|
||||
def test_destroy(self):
|
||||
|
||||
def emulate_rp_mysql_delete(func):
|
||||
def wrapped(context, _id):
|
||||
rp = context.session.query(
|
||||
models.ResourceProvider).\
|
||||
filter(
|
||||
models.ResourceProvider.id == _id).first()
|
||||
self.assertIsNone(rp.root_provider_id)
|
||||
return func(context, _id)
|
||||
return wrapped
|
||||
|
||||
emulated = emulate_rp_mysql_delete(resource_provider._delete_rp_record)
|
||||
|
||||
rp = resource_provider.ResourceProvider(
|
||||
self.context, uuid=_RESOURCE_PROVIDER_UUID,
|
||||
name=_RESOURCE_PROVIDER_NAME)
|
||||
rp.create()
|
||||
|
||||
with mock.patch.object(
|
||||
resource_provider, '_delete_rp_record', emulated):
|
||||
rp.destroy()
|
||||
|
||||
|
||||
class TestInventoryNoDB(test_objects._LocalTest):
|
||||
USES_DB = False
|
||||
|
Loading…
x
Reference in New Issue
Block a user