Delete trait from placement

If no rp uses the old device trait, we need clean it, else placement
will raise 409 exception.

Closes-Bug: #1928174

Change-Id: I0b1a6ba0b8a9934afe243d53bc0eb7f78e97de1d
This commit is contained in:
songwenping 2021-05-12 10:14:42 +00:00
parent bb35be1b86
commit 05f88530a3
5 changed files with 38 additions and 6 deletions

View File

@ -113,7 +113,7 @@ class PlacementClient(object):
traits_json['traits'] = traits
self._put_rp_traits(rp_uuid, traits_json)
def delete_trait_by_name(self, rp_uuid, trait_name):
def delete_trait_by_name(self, context, rp_uuid, trait_name):
traits_json = self._get_rp_traits(rp_uuid)
traits = [
trait for trait in traits_json['traits']
@ -121,15 +121,19 @@ class PlacementClient(object):
]
traits_json['traits'] = traits
self._put_rp_traits(rp_uuid, traits_json)
self._delete_trait(context, trait_name)
def delete_traits_with_prefixes(self, rp_uuid, trait_prefixes):
def delete_traits_with_prefixes(self, context, rp_uuid, trait_prefixes):
traits_json = self._get_rp_traits(rp_uuid)
traits = [
trait for trait in traits_json['traits']
if not any(trait.startswith(prefix)
for prefix in trait_prefixes)]
delete_traits = set(traits_json['traits']) - set(traits)
traits_json['traits'] = traits
self._put_rp_traits(rp_uuid, traits_json)
for trait in delete_traits:
self._delete_trait(context, trait)
def get_placement_request_id(self, response):
if response is not None:
@ -328,3 +332,22 @@ class PlacementClient(object):
elif resp.status_code == 204:
LOG.info("Successfully delete resource class %(rc_name).", {
"rc_name", name})
def _delete_trait(self, context, name):
"""Delete trait from placement by name."""
version = '1.6'
resp = self.delete("/traits/%s" % name, version=version,
global_request_id=context.global_id)
if not resp:
msg = ("Failed to delete trait record with placement "
"API for trait %(trait_name)s. Got "
"%(status_code)d: %(err_text)s.")
args = {
'trait_name': name,
'status_code': resp.status_code,
'err_text': resp.text,
}
LOG.error(msg, args)
elif resp.status_code == 204:
LOG.info("Successfully delete trait %(trait_name).", {
"trait_name", name})

View File

@ -294,7 +294,7 @@ class ConductorManager(object):
for d in deleted:
old_driver_attr_obj = old_driver_attr_list[old_key_list.index(d)]
self.placement_client.delete_trait_by_name(
rp_uuid, old_driver_attr_obj.value)
context, rp_uuid, old_driver_attr_obj.value)
old_driver_attr_obj.delete_by_key(context, dep_id, d)
# key is added.
added = set(new_key_list) - same
@ -315,7 +315,7 @@ class ConductorManager(object):
# Update traits here.
if new_driver_attr_obj.key.startswith("trait"):
self.placement_client.delete_trait_by_name(
rp_uuid, old_driver_attr_obj.value)
context, rp_uuid, old_driver_attr_obj.value)
self.placement_client.add_traits_to_rp(
rp_uuid, [new_driver_attr_obj.value])
# Update resource classes here.

View File

@ -179,7 +179,8 @@ class FPGAExtARQ(ExtARQ):
placement = placement_client.PlacementClient()
try:
placement.delete_traits_with_prefixes(
self.arq.device_rp_uuid, [constants.FPGA_FUNCTION_ID])
context, self.arq.device_rp_uuid,
[constants.FPGA_FUNCTION_ID])
except Exception as e:
LOG.error("Failed to delete traits(%s) from resources provider %s."
"Reason: %s", constants.FPGA_FUNCTION_ID,

View File

@ -335,7 +335,7 @@ class TestFPGAExtARQObject(base.DbTestCase):
constants.FPGA_FUNCTION_ID, vendor, function_id))]
mock_add_traits.assert_called_once_with(rp_uuid, trait_names)
mock_delete_traits.assert_called_once_with(
rp_uuid, [constants.FPGA_FUNCTION_ID])
self.context, rp_uuid, [constants.FPGA_FUNCTION_ID])
@mock.patch('cyborg.agent.rpcapi.AgentAPI.fpga_program')
@mock.patch('cyborg.objects.Deployable.get_cpid_list')

View File

@ -0,0 +1,8 @@
---
features:
- |
`Bug 1928174`_ is cleaned the old device trait on reporting data. the
trait will be removing succesfully if no rp uses, otherwise placement will
raise 409 exception.
.. _Bug 1928174: https://bugs.launchpad.net/openstack-cyborg/+bug/1928174