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
(cherry picked from commit 39c8616876)
This commit is contained in:
James Slagle 2017-08-02 14:15:00 -04:00 committed by Emilien Macchi
parent c535ca47d8
commit 6a939cb994
3 changed files with 75 additions and 1 deletions

View File

@ -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.

View File

@ -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:

View File

@ -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')