From 14509539f9645fa32fe39492a74bf0c75de27094 Mon Sep 17 00:00:00 2001 From: Helena McGough Date: Mon, 11 Mar 2019 09:12:06 +0000 Subject: [PATCH] BUG FIX: Cleanup resource providers - Update resource provider implementation - Updated unit tests for the change Change-Id: I9d659142b65680648bd65783346bb68bd4500a7b Signed-off-by: Helena McGough --- .../tests/virt/rsd/test_driver.py | 34 +-------- rsd_virt_for_nova/virt/rsd/driver.py | 71 ++++++++++++++----- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/rsd_virt_for_nova/tests/virt/rsd/test_driver.py b/rsd_virt_for_nova/tests/virt/rsd/test_driver.py index 4f5628d..b151364 100644 --- a/rsd_virt_for_nova/tests/virt/rsd/test_driver.py +++ b/rsd_virt_for_nova/tests/virt/rsd/test_driver.py @@ -259,26 +259,22 @@ class TestRSDDriver(base.BaseTestCase): info.assert_not_called() - @mock.patch.object(driver.RSDDriver, '_init_nodes') - def test_get_available_nodes_false_refresh(self, init_nodes): + def test_get_available_nodes_false_refresh(self): """Test getting a list of the available nodes, no refresh.""" # Run test checking the list of available nodes nodes = self.RSD.get_available_nodes(refresh=False) # Confirm that the correst functions are called and all of the correct # nodes are available - init_nodes.assert_called_once() self.assertEqual(nodes, self.RSD._nodes) - @mock.patch.object(driver.RSDDriver, '_init_nodes') - def test_get_available_nodes_true_refresh(self, init_nodes): + def test_get_available_nodes_true_refresh(self): """Test getting a list of the available nodes, with refresh.""" # Run test checking the list of available nodes, refresh nodes = self.RSD.get_available_nodes(refresh=True) # Confirm that the correst functions are called and all of the correct # nodes are available - init_nodes.assert_called_once() self.assertEqual(nodes, self.RSD._nodes) @mock.patch.object(driver.RSDDriver, 'get_available_nodes') @@ -419,32 +415,6 @@ class TestRSDDriver(base.BaseTestCase): 'vcpus': proc_info.return_value, 'vcpus_used': 0}, resources) - @mock.patch.object(driver.RSDDriver, '_create_flavors') - @mock.patch.object(driver.RSDDriver, 'check_flavors') - @mock.patch.object(driver.RSDDriver, 'check_chassis_systems') - @mock.patch.object(versionutils, 'convert_version_to_int') - @mock.patch.object(driver.RSDDriver, 'get_sys_proc_info') - @mock.patch.object(driver.RSDDriver, 'get_sys_memory_info') - def test_get_available_resource_failure(self, mem_info, proc_info, conv_v, - check_chas, check_flav, - create_flav): - """Test failing to available resources for a node.""" - # If there is no composed node for the compute node = Failure - self.RSD._nodes = [] - resources = self.RSD.get_available_resource(self.chassis_inst.identity) - - # Confirm that there are no available resource to boot composed node - # instances from - self.RSD.driver.PODM.get_chassis_collection.assert_called_once() - self.RSD.driver.PODM.get_system_collection.assert_not_called() - check_chas.assert_not_called() - mem_info.assert_not_called() - proc_info.assert_not_called() - conv_v.assert_not_called() - check_flav.assert_not_called() - create_flav.assert_not_called() - self.assertEqual(resources, {}) - @mock.patch.object(driver.RSDDriver, 'create_child_inventory') @mock.patch.object(driver.RSDDriver, 'create_inventory') @mock.patch.object(driver.RSDDriver, 'check_chassis_systems') diff --git a/rsd_virt_for_nova/virt/rsd/driver.py b/rsd_virt_for_nova/virt/rsd/driver.py index 3598046..0b77355 100644 --- a/rsd_virt_for_nova/virt/rsd/driver.py +++ b/rsd_virt_for_nova/virt/rsd/driver.py @@ -75,7 +75,7 @@ class RSDDriver(driver.ComputeDriver): self.driver = rsd.PODM_connection() self.instances = OrderedDict() self.rsd_flavors = OrderedDict() - self._nodes = self._init_nodes() + self._nodes = [] self._composed_nodes = OrderedDict() self.instance_node = None @@ -85,15 +85,21 @@ class RSDDriver(driver.ComputeDriver): nodes = [] CHASSIS_COL = self.driver.PODM.get_chassis_collection() for c in CHASSIS_COL.members_identities: - chas = CHASSIS_COL.get_member(c) - cha_sys = self.check_chassis_systems(chas) - if cha_sys != []: - nodes.append(c) + try: + chas = CHASSIS_COL.get_member(c) + cha_sys = self.check_chassis_systems(chas) + if cha_sys != []: + nodes.append(c) + except Exception as c_ex: + LOG.warn("Failed to get chassis information: %s", c_ex) + nodes = [] + set_nodes(nodes) return copy.copy(PODM_NODE) def init_host(self, host): """Initialize anything that is necessary for the driver to function.""" + self._nodes = self._init_nodes() return host def get_info(self, instance): @@ -105,7 +111,8 @@ class RSDDriver(driver.ComputeDriver): def get_available_nodes(self, refresh=True): """Return nodenames of all nodes managed by the compute service.""" - self._nodes = self._init_nodes() + if self._nodes == []: + self._nodes = self._init_nodes() return self._nodes def node_is_available(self, nodename): @@ -187,15 +194,16 @@ class RSDDriver(driver.ComputeDriver): def get_available_resource(self, nodename): """Update compute manager resource info on ComputeNode table.""" cpu_info = '' - if nodename not in self._nodes: - return {} SYSTEM_COL = self.driver.PODM.get_system_collection() members = SYSTEM_COL.members_identities CHASSIS_COL = self.driver.PODM.get_chassis_collection() - chas = CHASSIS_COL.get_member(nodename) - cha_sys = self.check_chassis_systems(chas) + try: + chas = CHASSIS_COL.get_member(nodename) + cha_sys = self.check_chassis_systems(chas) + except Exception as ex: + LOG.warn("Failed to retrieve chassis information:%s", ex) # Check if all flavors are valid self.check_flavors(SYSTEM_COL, members) @@ -237,14 +245,36 @@ class RSDDriver(driver.ComputeDriver): SYSTEM_COL = self.driver.PODM.get_system_collection() sys_s = SYSTEM_COL.members_identities systems = [] + sys_trees = {} + chas_ids = [] + cha_sys = [] for s in sys_s: systems.append(s) CHASSIS_COL = self.driver.PODM.get_chassis_collection() + chas_s = CHASSIS_COL.members_identities + for c in chas_s: + chas_ids.append(c) + + for chas_tree in provider_tree.roots: + sys_trees = chas_tree.children + for s_tree in sys_trees.values(): + # Removing all RPS that don't have an associated system + if s_tree.name not in systems: + provider_tree.remove(str(s_tree.uuid)) + + chassis = CHASSIS_COL.get_member(chas_tree.name) + if self.check_chassis_systems(chassis) == []: + provider_tree.remove(str(chas_tree.uuid)) + self._nodes = self._init_nodes() for c in CHASSIS_COL.members_identities: - chas = CHASSIS_COL.get_member(nodename) - cha_sys = self.check_chassis_systems(chas) + try: + chas = CHASSIS_COL.get_member(nodename) + cha_sys = self.check_chassis_systems(chas) + except Exception as c_ex: + LOG.warn("Failed to get chassis informantion:%s", c_ex) + if cha_sys != []: for s in cha_sys: sys_inv = self.create_child_inventory(s) @@ -253,8 +283,8 @@ class RSDDriver(driver.ComputeDriver): except Exception as ex: LOG.warn("Failed to create new RP: %s", ex) provider_tree.update_inventory(s, sys_inv) - chas_inv = self.create_inventory(cha_sys) - provider_tree.update_inventory(nodename, chas_inv) + chas_inv = self.create_inventory(cha_sys) + provider_tree.update_inventory(nodename, chas_inv) def get_sys_proc_info(self, systems): """Track vcpus made available by the PODM.""" @@ -429,6 +459,7 @@ class RSDDriver(driver.ComputeDriver): 'id': rsd_flav['id'], 'rsd_systems': [sys.identity] } + self._nodes = self._init_nodes() except Exception as ex: LOG.debug( "A flavor already exists for this rsd system: %s", ex) @@ -472,8 +503,12 @@ class RSDDriver(driver.ComputeDriver): sys_list = self.rsd_flavors[k]['rsd_systems'] for s in sys_list: if s not in sys_ids: - rsd_id = self.rsd_flavors[k]['id'] - flavor._flavor_destroy(context.get_admin_context(), rsd_id) - LOG.debug("Deleting flavor for removed systems: %s", k) - del self.rsd_flavors[k] + try: + rsd_id = self.rsd_flavors[k]['id'] + flavor._flavor_destroy( + context.get_admin_context(), rsd_id) + LOG.debug("Deleting flavor for removed systems: %s", k) + del self.rsd_flavors[k] + except KeyError as k_ex: + LOG.warn("Flavor has already been deleted:%s", k_ex) return