From 39c8616876267644052c457eb3b7af4219a0a09c Mon Sep 17 00:00:00 2001 From: James Slagle Date: Wed, 2 Aug 2017 14:15:00 -0400 Subject: [PATCH] Prompt to clear breakpoints when using deployed-server On a minor interactive update, we never prompoted to clear breakpoints when using deployed-server since the code reads the server id's from nova, of which there are none. This modifies the behavior to read the server id's and names from Heat when nova returns no servers. Change-Id: I682f6dc66705c9d42b9c2d21f675491ea60c9c3c Closes-Bug: #1708236 --- ...ver-clear-breakpoint-ee1a984f3366598a.yaml | 6 +++ tripleo_common/_stack_update.py | 29 ++++++++++++- tripleo_common/tests/test_stack_update.py | 41 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/deployed-server-clear-breakpoint-ee1a984f3366598a.yaml diff --git a/releasenotes/notes/deployed-server-clear-breakpoint-ee1a984f3366598a.yaml b/releasenotes/notes/deployed-server-clear-breakpoint-ee1a984f3366598a.yaml new file mode 100644 index 000000000..33c6c7e20 --- /dev/null +++ b/releasenotes/notes/deployed-server-clear-breakpoint-ee1a984f3366598a.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - When performing an interactive minor update with deployed-server, the + client never prompted to clear breakpoints and just ran to completion and + exited. The stack was left IN_PROGRESS. That issue has now been fixed so + that the client will prompt to clear breakpoints. diff --git a/tripleo_common/_stack_update.py b/tripleo_common/_stack_update.py index 9112d0017..5820c2728 100644 --- a/tripleo_common/_stack_update.py +++ b/tripleo_common/_stack_update.py @@ -25,6 +25,11 @@ import heatclient.exc LOG = logging.getLogger(__name__) +class DeployedServer(object): + id = None + name = None + + class StackUpdateManager(object): def __init__(self, heatclient, novaclient, stack, hook_type, nested_depth=5, hook_resource=None): @@ -182,13 +187,35 @@ class StackUpdateManager(object): name = self.server_names.get(deployment_id) if not name: if not self.servers: - self.servers = self.novaclient.servers.list() + self.servers = self._get_servers() depl = self.heatclient.software_deployments.get(deployment_id) name = next(server.name for server in self.servers if server.id == depl.server_id) self.server_names[deployment_id] = name return name + def _get_servers(self): + servers = self.novaclient.servers.list() + + # If no servers were found from Nova, we must be using split-stack, + # so we will have to interrogate Heat for the names and id's. + if not servers: + resources = self.heatclient.resources.list( + self.stack.id, nested_depth=self.nested_depth, + filters=dict(type="OS::Heat::DeployedServer")) + for res in resources: + server = DeployedServer() + stack_name, stack_id = next( + x['href'] for x in res.links if + x['rel'] == 'stack').rsplit('/', 2)[1:] + stack = self.heatclient.stacks.get(stack_id) + server.name = next(o['output_value'] for o in stack.outputs if + o['output_key'] == 'name') + server.id = res.physical_resource_id + servers.append(server) + + return servers + def _input_to_refs(self, regexp, refs): if regexp: try: diff --git a/tripleo_common/tests/test_stack_update.py b/tripleo_common/tests/test_stack_update.py index 86a12bb93..ba08b3e30 100644 --- a/tripleo_common/tests/test_stack_update.py +++ b/tripleo_common/tests/test_stack_update.py @@ -99,3 +99,44 @@ class StackUpdateManagerTest(base.TestCase): result = self.stack_update_manager._input_to_refs( ']].*', ['instance_id']) self.assertEqual(result, []) + + def test_get_servers(self): + self.stack_update_manager._get_servers() + self.novaclient.servers.list.assert_called() + + def test_get_servers_deployed_server(self): + self.novaclient.servers.list.return_value = [] + self.heatclient.resources.list.return_value = [ + mock.MagicMock( + links=[{'rel': 'stack', + 'href': 'http://192.0.2.1:8004/v1/' + 'a959ac7d6a4a475daf2428df315c41ef/' + 'stacks/overcloud/123'}], + logical_resource_id='logical_id', + physical_resource_id='controller_resource_id', + type='OS::Heat::DeployedServer' + ), + mock.MagicMock( + links=[{'rel': 'stack', + 'href': 'http://192.0.2.1:8004/v1/' + 'a959ac7d6a4a475daf2428df315c41ef/' + 'stacks/overcloud/123'}], + logical_resource_id='logical_id', + physical_resource_id='compute_resource_id', + type='OS::Heat::DeployedServer' + ) + ] + self.heatclient.stacks.get.side_effect = [ + mock.MagicMock( + outputs=[{'output_key': 'name', + 'output_value': 'overcloud-controller-0'}]), + mock.MagicMock( + outputs=[{'output_key': 'name', + 'output_value': 'overcloud-compute-0'}]), + ] + + servers = self.stack_update_manager._get_servers() + self.assertEqual(servers[0].name, 'overcloud-controller-0') + self.assertEqual(servers[0].id, 'controller_resource_id') + self.assertEqual(servers[1].name, 'overcloud-compute-0') + self.assertEqual(servers[1].id, 'compute_resource_id')