Replace SD RPC polling by long RPC call
This changes the way SoftwareDeployment updates its internal status. Instead of querying the deployment status in a loop using RPC client, it makes a single call, which returns once the status has been updated. Closes-Bug: #1549219 Change-Id: I484b7c8cb4a4e71817be6bea764f23b68a39b2d4
This commit is contained in:
parent
d66b5441b3
commit
a709637a17
@ -287,8 +287,8 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
|||||||
return sd
|
return sd
|
||||||
|
|
||||||
def _check_complete(self):
|
def _check_complete(self):
|
||||||
sd = self.rpc_client().show_software_deployment(
|
sd = self.rpc_client().check_software_deployment(
|
||||||
self.context, self.resource_id)
|
self.context, self.resource_id, self.stack.time_remaining())
|
||||||
status = sd[rpc_api.SOFTWARE_DEPLOYMENT_STATUS]
|
status = sd[rpc_api.SOFTWARE_DEPLOYMENT_STATUS]
|
||||||
if status == SoftwareDeployment.COMPLETE:
|
if status == SoftwareDeployment.COMPLETE:
|
||||||
return True
|
return True
|
||||||
|
@ -294,7 +294,7 @@ class EngineService(service.Service):
|
|||||||
by the RPC caller.
|
by the RPC caller.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RPC_API_VERSION = '1.26'
|
RPC_API_VERSION = '1.27'
|
||||||
|
|
||||||
def __init__(self, host, topic):
|
def __init__(self, host, topic):
|
||||||
super(EngineService, self).__init__()
|
super(EngineService, self).__init__()
|
||||||
@ -2014,6 +2014,11 @@ class EngineService(service.Service):
|
|||||||
return self.software_config.show_software_deployment(
|
return self.software_config.show_software_deployment(
|
||||||
cnxt, deployment_id)
|
cnxt, deployment_id)
|
||||||
|
|
||||||
|
@context.request_context
|
||||||
|
def check_software_deployment(self, cnxt, deployment_id, timeout):
|
||||||
|
return self.software_config.check_software_deployment(
|
||||||
|
cnxt, deployment_id, timeout)
|
||||||
|
|
||||||
@context.request_context
|
@context.request_context
|
||||||
def create_software_deployment(self, cnxt, server_id, config_id,
|
def create_software_deployment(self, cnxt, server_id, config_id,
|
||||||
input_values, action, status,
|
input_values, action, status,
|
||||||
|
@ -27,6 +27,7 @@ from heat.common.i18n import _
|
|||||||
from heat.common.i18n import _LI
|
from heat.common.i18n import _LI
|
||||||
from heat.db import api as db_api
|
from heat.db import api as db_api
|
||||||
from heat.engine import api
|
from heat.engine import api
|
||||||
|
from heat.engine import scheduler
|
||||||
from heat.objects import resource as resource_objects
|
from heat.objects import resource as resource_objects
|
||||||
from heat.objects import software_config as software_config_object
|
from heat.objects import software_config as software_config_object
|
||||||
from heat.objects import software_deployment as software_deployment_object
|
from heat.objects import software_deployment as software_deployment_object
|
||||||
@ -196,7 +197,19 @@ class SoftwareConfigService(service.Service):
|
|||||||
return software_deployment_object.SoftwareDeployment.get_by_id(
|
return software_deployment_object.SoftwareDeployment.get_by_id(
|
||||||
cnxt, sd.id)
|
cnxt, sd.id)
|
||||||
|
|
||||||
def show_software_deployment(self, cnxt, deployment_id):
|
def check_software_deployment(self, cnxt, deployment_id, timeout):
|
||||||
|
def _check():
|
||||||
|
while True:
|
||||||
|
sd = self._show_software_deployment(cnxt, deployment_id)
|
||||||
|
if sd.status != rpc_api.SOFTWARE_DEPLOYMENT_IN_PROGRESS:
|
||||||
|
return
|
||||||
|
yield
|
||||||
|
scheduler.TaskRunner(_check)(timeout=timeout)
|
||||||
|
sd = software_deployment_object.SoftwareDeployment.get_by_id(
|
||||||
|
cnxt, deployment_id)
|
||||||
|
return api.format_software_deployment(sd)
|
||||||
|
|
||||||
|
def _show_software_deployment(self, cnxt, deployment_id):
|
||||||
sd = software_deployment_object.SoftwareDeployment.get_by_id(
|
sd = software_deployment_object.SoftwareDeployment.get_by_id(
|
||||||
cnxt, deployment_id)
|
cnxt, deployment_id)
|
||||||
if sd.status == rpc_api.SOFTWARE_DEPLOYMENT_IN_PROGRESS:
|
if sd.status == rpc_api.SOFTWARE_DEPLOYMENT_IN_PROGRESS:
|
||||||
@ -209,6 +222,10 @@ class SoftwareConfigService(service.Service):
|
|||||||
elif transport == 'ZAQAR_SIGNAL':
|
elif transport == 'ZAQAR_SIGNAL':
|
||||||
sd = self._refresh_zaqar_software_deployment(
|
sd = self._refresh_zaqar_software_deployment(
|
||||||
cnxt, sd, input_values.get('deploy_queue_id'))
|
cnxt, sd, input_values.get('deploy_queue_id'))
|
||||||
|
return sd
|
||||||
|
|
||||||
|
def show_software_deployment(self, cnxt, deployment_id):
|
||||||
|
sd = self._show_software_deployment(cnxt, deployment_id)
|
||||||
return api.format_software_deployment(sd)
|
return api.format_software_deployment(sd)
|
||||||
|
|
||||||
def create_software_deployment(self, cnxt, server_id, config_id,
|
def create_software_deployment(self, cnxt, server_id, config_id,
|
||||||
|
@ -47,6 +47,7 @@ class EngineClient(object):
|
|||||||
1.24 - Adds ignorable_errors to validate_template
|
1.24 - Adds ignorable_errors to validate_template
|
||||||
1.25 - list_stack_resource filter update
|
1.25 - list_stack_resource filter update
|
||||||
1.26 - Add mark_unhealthy
|
1.26 - Add mark_unhealthy
|
||||||
|
1.27 - Add check_software_deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
BASE_RPC_API_VERSION = '1.0'
|
BASE_RPC_API_VERSION = '1.0'
|
||||||
@ -60,12 +61,17 @@ class EngineClient(object):
|
|||||||
def make_msg(method, **kwargs):
|
def make_msg(method, **kwargs):
|
||||||
return method, kwargs
|
return method, kwargs
|
||||||
|
|
||||||
def call(self, ctxt, msg, version=None):
|
def call(self, ctxt, msg, version=None, timeout=None):
|
||||||
method, kwargs = msg
|
method, kwargs = msg
|
||||||
|
|
||||||
if version is not None:
|
if version is not None:
|
||||||
client = self._client.prepare(version=version)
|
client = self._client.prepare(version=version)
|
||||||
else:
|
else:
|
||||||
client = self._client
|
client = self._client
|
||||||
|
|
||||||
|
if timeout is not None:
|
||||||
|
client = client.prepare(timeout=timeout)
|
||||||
|
|
||||||
return client.call(ctxt, method, **kwargs)
|
return client.call(ctxt, method, **kwargs)
|
||||||
|
|
||||||
def cast(self, ctxt, msg, version=None):
|
def cast(self, ctxt, msg, version=None):
|
||||||
@ -681,6 +687,12 @@ class EngineClient(object):
|
|||||||
return self.call(cnxt, self.make_msg('show_software_deployment',
|
return self.call(cnxt, self.make_msg('show_software_deployment',
|
||||||
deployment_id=deployment_id))
|
deployment_id=deployment_id))
|
||||||
|
|
||||||
|
def check_software_deployment(self, cnxt, deployment_id, timeout):
|
||||||
|
return self.call(cnxt, self.make_msg('check_software_deployment',
|
||||||
|
deployment_id=deployment_id,
|
||||||
|
timeout=timeout),
|
||||||
|
timeout=timeout, version='1.27')
|
||||||
|
|
||||||
def create_software_deployment(self, cnxt, server_id, config_id=None,
|
def create_software_deployment(self, cnxt, server_id, config_id=None,
|
||||||
input_values=None, action='INIT',
|
input_values=None, action='INIT',
|
||||||
status='COMPLETE', status_reason='',
|
status='COMPLETE', status_reason='',
|
||||||
|
@ -40,7 +40,7 @@ class ServiceEngineTest(common.HeatTestCase):
|
|||||||
|
|
||||||
def test_make_sure_rpc_version(self):
|
def test_make_sure_rpc_version(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'1.26',
|
'1.27',
|
||||||
service.EngineService.RPC_API_VERSION,
|
service.EngineService.RPC_API_VERSION,
|
||||||
('RPC version is changed, please update this test to new version '
|
('RPC version is changed, please update this test to new version '
|
||||||
'and make sure additional test cases are added for RPC APIs '
|
'and make sure additional test cases are added for RPC APIs '
|
||||||
|
@ -311,6 +311,20 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
|
|||||||
deployment,
|
deployment,
|
||||||
self.engine.show_software_deployment(self.ctx, deployment_id))
|
self.engine.show_software_deployment(self.ctx, deployment_id))
|
||||||
|
|
||||||
|
def test_check_software_deployment(self):
|
||||||
|
deployment_id = str(uuid.uuid4())
|
||||||
|
ex = self.assertRaises(dispatcher.ExpectedException,
|
||||||
|
self.engine.check_software_deployment,
|
||||||
|
self.ctx, deployment_id, 10)
|
||||||
|
self.assertEqual(exception.NotFound, ex.exc_info[0])
|
||||||
|
|
||||||
|
deployment = self._create_software_deployment()
|
||||||
|
self.assertIsNotNone(deployment)
|
||||||
|
deployment_id = deployment['id']
|
||||||
|
self.assertEqual(
|
||||||
|
deployment,
|
||||||
|
self.engine.check_software_deployment(self.ctx, deployment_id, 10))
|
||||||
|
|
||||||
@mock.patch.object(service_software_config.SoftwareConfigService,
|
@mock.patch.object(service_software_config.SoftwareConfigService,
|
||||||
'_push_metadata_software_deployments')
|
'_push_metadata_software_deployments')
|
||||||
def test_signal_software_deployment(self, pmsd):
|
def test_signal_software_deployment(self, pmsd):
|
||||||
|
@ -18,6 +18,8 @@ import uuid
|
|||||||
import mock
|
import mock
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from oslo_utils import timeutils
|
||||||
|
|
||||||
from heat.common import exception as exc
|
from heat.common import exception as exc
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
from heat.engine.clients.os import nova
|
from heat.engine.clients.os import nova
|
||||||
@ -168,6 +170,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
stack_user_project_id='65728b74-cfe7-4f17-9c15-11d4f686e591',
|
stack_user_project_id='65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
cache_data=cache_data
|
cache_data=cache_data
|
||||||
)
|
)
|
||||||
|
self.stack.created_time = timeutils.utcnow()
|
||||||
|
|
||||||
self.patchobject(nova.NovaClientPlugin, 'get_server',
|
self.patchobject(nova.NovaClientPlugin, 'get_server',
|
||||||
return_value=mock.MagicMock())
|
return_value=mock.MagicMock())
|
||||||
@ -546,7 +549,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
def test_check_create_complete(self):
|
def test_check_create_complete(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = self.mock_deployment()
|
sd = self.mock_deployment()
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
|
|
||||||
sd['status'] = self.deployment.COMPLETE
|
sd['status'] = self.deployment.COMPLETE
|
||||||
self.assertTrue(self.deployment.check_create_complete(sd))
|
self.assertTrue(self.deployment.check_create_complete(sd))
|
||||||
@ -560,7 +563,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
def test_check_update_complete(self):
|
def test_check_update_complete(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = self.mock_deployment()
|
sd = self.mock_deployment()
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
|
|
||||||
sd['status'] = self.deployment.COMPLETE
|
sd['status'] = self.deployment.COMPLETE
|
||||||
self.assertTrue(self.deployment.check_update_complete(sd))
|
self.assertTrue(self.deployment.check_update_complete(sd))
|
||||||
@ -575,7 +578,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
def test_check_suspend_complete(self):
|
def test_check_suspend_complete(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = self.mock_deployment()
|
sd = self.mock_deployment()
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
|
|
||||||
sd['status'] = self.deployment.COMPLETE
|
sd['status'] = self.deployment.COMPLETE
|
||||||
self.assertTrue(self.deployment.check_suspend_complete(sd))
|
self.assertTrue(self.deployment.check_suspend_complete(sd))
|
||||||
@ -590,7 +593,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
def test_check_resume_complete(self):
|
def test_check_resume_complete(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = self.mock_deployment()
|
sd = self.mock_deployment()
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
|
|
||||||
sd['status'] = self.deployment.COMPLETE
|
sd['status'] = self.deployment.COMPLETE
|
||||||
self.assertTrue(self.deployment.check_resume_complete(sd))
|
self.assertTrue(self.deployment.check_resume_complete(sd))
|
||||||
@ -608,7 +611,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
'status': self.deployment.FAILED,
|
'status': self.deployment.FAILED,
|
||||||
'status_reason': 'something wrong'
|
'status_reason': 'something wrong'
|
||||||
}
|
}
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
err = self.assertRaises(
|
err = self.assertRaises(
|
||||||
exc.Error, self.deployment.check_create_complete, sd)
|
exc.Error, self.deployment.check_create_complete, sd)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -641,7 +644,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
|
|
||||||
self.deployment.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
self.deployment.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
|
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
self.rpc_client.update_software_deployment.return_value = sd
|
self.rpc_client.update_software_deployment.return_value = sd
|
||||||
self.assertEqual(sd, self.deployment.handle_delete())
|
self.assertEqual(sd, self.deployment.handle_delete())
|
||||||
self.assertEqual({
|
self.assertEqual({
|
||||||
@ -748,7 +751,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
|||||||
derived_sc = self.mock_derived_software_config()
|
derived_sc = self.mock_derived_software_config()
|
||||||
sd = self.mock_deployment()
|
sd = self.mock_deployment()
|
||||||
|
|
||||||
self.rpc_client.show_software_deployment.return_value = sd
|
self.rpc_client.check_software_deployment.return_value = sd
|
||||||
self.deployment.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
self.deployment.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
|
|
||||||
# first, handle the suspend
|
# first, handle the suspend
|
||||||
|
@ -328,6 +328,11 @@ class EngineRpcAPITestCase(common.HeatTestCase):
|
|||||||
self._test_engine_api('show_software_deployment', 'call',
|
self._test_engine_api('show_software_deployment', 'call',
|
||||||
deployment_id=deployment_id)
|
deployment_id=deployment_id)
|
||||||
|
|
||||||
|
def test_check_software_deployment(self):
|
||||||
|
deployment_id = '86729f02-4648-44d8-af44-d0ec65b6abc9'
|
||||||
|
self._test_engine_api('check_software_deployment', 'call',
|
||||||
|
deployment_id=deployment_id, timeout=100)
|
||||||
|
|
||||||
def test_create_software_deployment(self):
|
def test_create_software_deployment(self):
|
||||||
self._test_engine_api(
|
self._test_engine_api(
|
||||||
'create_software_deployment', 'call',
|
'create_software_deployment', 'call',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user