Avoid creating a root provider when parent is not found
Before this change, when agent called to conductor to report_data(), if the parent provider was not found by hostname, we would log an error, and then continue to create the "child" provider with no parent. We should never do this if we are supposed to have a parent. Cleanup from this situation is also messy. This makes us raise PlacementResourceProviderNotFound() in that case, which aborts the report and thus does not create the provider incorrectly. It also makes the agent catch that exception and moves the log message to the agent where the actual problem is (i.e. likely misconfiguration). The exception used here is actually defined incorrectly, having a message class variable instead of _msg_fmt, which caused it to not render properly. This fixes that along the way and adds tests for the new conductor and agent behaviors. Closes task: 38813 Closes task: 38814 Change-Id: Ied8ee91592eb0b4675f9c155e30a6c3a7df9b597
This commit is contained in:
parent
e0ba01891f
commit
d279c22d1e
@ -72,4 +72,7 @@ class ResourceTracker(object):
|
||||
acc_list.extend(acc_driver.discover())
|
||||
# Call conductor_api here to diff and report acc data. Now, we actually
|
||||
# do not have the method report_data.
|
||||
self.conductor_api.report_data(context, self.host, acc_list)
|
||||
try:
|
||||
self.conductor_api.report_data(context, self.host, acc_list)
|
||||
except exception.PlacementResourceProviderNotFound as e:
|
||||
LOG.error('Unable to report usage: %s', e)
|
||||
|
@ -243,7 +243,8 @@ class PlacementEndpointNotFound(NotFound):
|
||||
|
||||
|
||||
class PlacementResourceProviderNotFound(NotFound):
|
||||
message = _("Placement resource provider not found %(resource_provider)s.")
|
||||
_msg_fmt = _("Placement resource provider not found: "
|
||||
"%(resource_provider)s.")
|
||||
|
||||
|
||||
class PlacementInventoryNotFound(NotFound):
|
||||
|
@ -364,8 +364,8 @@ class ConductorManager(object):
|
||||
pr_uuid = provider["resource_providers"][0]["uuid"]
|
||||
return pr_uuid
|
||||
except IndexError:
|
||||
LOG.error("Error, provider %(hostname)s can not be found",
|
||||
{"hostname": hostname})
|
||||
raise exception.PlacementResourceProviderNotFound(
|
||||
resource_provider=hostname)
|
||||
except Exception as e:
|
||||
LOG.error("Error, could not access placement. Details: %(info)s",
|
||||
{"info": e})
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
"""Cyborg agent resource_tracker test cases."""
|
||||
from cyborg.agent.resource_tracker import ResourceTracker
|
||||
@ -49,3 +50,13 @@ class TestResourceTracker(base.TestCase):
|
||||
enabled_drivers = ['invalid_driver']
|
||||
self.assertRaises(exception.InvalidDriver, self.rt._initialize_drivers,
|
||||
enabled_drivers)
|
||||
|
||||
@mock.patch('cyborg.agent.resource_tracker.LOG')
|
||||
def test_update_usage_failed_parent_provider(self, mock_log):
|
||||
with mock.patch.object(self.rt.conductor_api, 'report_data') as m:
|
||||
m.side_effect = exception.PlacementResourceProviderNotFound(
|
||||
resource_provider='foo')
|
||||
self.rt.update_usage(None)
|
||||
m.assert_called_once_with(None, 'fake-mini', [])
|
||||
mock_log.error.assert_called_once_with('Unable to report usage: %s',
|
||||
m.side_effect)
|
||||
|
@ -12,6 +12,7 @@
|
||||
import fixtures
|
||||
import mock
|
||||
|
||||
from cyborg.common import exception
|
||||
from cyborg.conductor import manager
|
||||
from cyborg.tests import base
|
||||
|
||||
@ -70,3 +71,18 @@ class ConductorManagerTest(base.TestCase):
|
||||
self.placement_mock.add_traits_to_rp.assert_called_once_with(
|
||||
sub_pr_uuid, traits)
|
||||
self.assertEqual(sub_pr_uuid, actual)
|
||||
|
||||
def test_get_root_provider(self):
|
||||
self.placement_mock.get.return_value.json.return_value = {
|
||||
'resource_providers': [{'uuid': mock.sentinel.uuid}],
|
||||
}
|
||||
uuid = self.cm._get_root_provider(mock.sentinel.context, 'foo')
|
||||
self.assertEqual(mock.sentinel.uuid, uuid)
|
||||
|
||||
def test_get_root_provider_not_found(self):
|
||||
self.placement_mock.get.return_value.json.return_value = {
|
||||
'resource_providers': [],
|
||||
}
|
||||
self.assertRaises(exception.PlacementResourceProviderNotFound,
|
||||
self.cm._get_root_provider,
|
||||
mock.sentinel.context, 'foo')
|
||||
|
Loading…
x
Reference in New Issue
Block a user