From 05f88530a3c3c6d75e4b67eb01df08ec94955036 Mon Sep 17 00:00:00 2001 From: songwenping Date: Wed, 12 May 2021 10:14:42 +0000 Subject: [PATCH] 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 --- cyborg/common/placement_client.py | 27 +++++++++++++++++-- cyborg/conductor/manager.py | 4 +-- cyborg/objects/extarq/fpga_ext_arq.py | 3 ++- .../tests/unit/objects/test_fpga_ext_arq.py | 2 +- ...trait_from_placement-266caf73cf289759.yaml | 8 ++++++ 5 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/bug-1928174-delete_trait_from_placement-266caf73cf289759.yaml diff --git a/cyborg/common/placement_client.py b/cyborg/common/placement_client.py index f45ede7f..b543788e 100644 --- a/cyborg/common/placement_client.py +++ b/cyborg/common/placement_client.py @@ -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}) diff --git a/cyborg/conductor/manager.py b/cyborg/conductor/manager.py index ef31e769..b093f558 100644 --- a/cyborg/conductor/manager.py +++ b/cyborg/conductor/manager.py @@ -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. diff --git a/cyborg/objects/extarq/fpga_ext_arq.py b/cyborg/objects/extarq/fpga_ext_arq.py index 4276a3a1..78f4568e 100644 --- a/cyborg/objects/extarq/fpga_ext_arq.py +++ b/cyborg/objects/extarq/fpga_ext_arq.py @@ -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, diff --git a/cyborg/tests/unit/objects/test_fpga_ext_arq.py b/cyborg/tests/unit/objects/test_fpga_ext_arq.py index 77b7936a..2681986a 100644 --- a/cyborg/tests/unit/objects/test_fpga_ext_arq.py +++ b/cyborg/tests/unit/objects/test_fpga_ext_arq.py @@ -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') diff --git a/releasenotes/notes/bug-1928174-delete_trait_from_placement-266caf73cf289759.yaml b/releasenotes/notes/bug-1928174-delete_trait_from_placement-266caf73cf289759.yaml new file mode 100644 index 00000000..473925e4 --- /dev/null +++ b/releasenotes/notes/bug-1928174-delete_trait_from_placement-266caf73cf289759.yaml @@ -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 \ No newline at end of file