summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Herve <therve@redhat.com>2016-02-16 16:29:51 +0100
committerThomas Herve <therve@redhat.com>2016-04-05 20:47:25 +0200
commita709637a17166cb12e5d94944837bac6451b2851 (patch)
tree3d0172a7bf96975d42c10e26cbc3b0ea0ff4bfe1
parentd66b5441b37a1f4f7a66886a2b46c4ded1787f6c (diff)
downloadheat-a709637a17166cb12e5d94944837bac6451b2851.tar.gz
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
-rw-r--r--heat/engine/resources/openstack/heat/software_deployment.py4
-rw-r--r--heat/engine/service.py7
-rw-r--r--heat/engine/service_software_config.py19
-rw-r--r--heat/rpc/client.py14
-rw-r--r--heat/tests/engine/service/test_service_engine.py2
-rw-r--r--heat/tests/engine/service/test_software_config.py14
-rw-r--r--heat/tests/openstack/heat/test_software_deployment.py17
-rw-r--r--heat/tests/test_rpc_client.py5
8 files changed, 69 insertions, 13 deletions
diff --git a/heat/engine/resources/openstack/heat/software_deployment.py b/heat/engine/resources/openstack/heat/software_deployment.py
index 9af8eaf85..6c84e1f0e 100644
--- a/heat/engine/resources/openstack/heat/software_deployment.py
+++ b/heat/engine/resources/openstack/heat/software_deployment.py
@@ -287,8 +287,8 @@ class SoftwareDeployment(signal_responder.SignalResponder):
return sd
def _check_complete(self):
- sd = self.rpc_client().show_software_deployment(
- self.context, self.resource_id)
+ sd = self.rpc_client().check_software_deployment(
+ self.context, self.resource_id, self.stack.time_remaining())
status = sd[rpc_api.SOFTWARE_DEPLOYMENT_STATUS]
if status == SoftwareDeployment.COMPLETE:
return True
diff --git a/heat/engine/service.py b/heat/engine/service.py
index 9c03bc7bb..3770191bb 100644
--- a/heat/engine/service.py
+++ b/heat/engine/service.py
@@ -294,7 +294,7 @@ class EngineService(service.Service):
by the RPC caller.
"""
- RPC_API_VERSION = '1.26'
+ RPC_API_VERSION = '1.27'
def __init__(self, host, topic):
super(EngineService, self).__init__()
@@ -2015,6 +2015,11 @@ class EngineService(service.Service):
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
def create_software_deployment(self, cnxt, server_id, config_id,
input_values, action, status,
status_reason, stack_user_project_id,
diff --git a/heat/engine/service_software_config.py b/heat/engine/service_software_config.py
index 7ce1edeb8..cfc578759 100644
--- a/heat/engine/service_software_config.py
+++ b/heat/engine/service_software_config.py
@@ -27,6 +27,7 @@ from heat.common.i18n import _
from heat.common.i18n import _LI
from heat.db import api as db_api
from heat.engine import api
+from heat.engine import scheduler
from heat.objects import resource as resource_objects
from heat.objects import software_config as software_config_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(
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(
cnxt, deployment_id)
if sd.status == rpc_api.SOFTWARE_DEPLOYMENT_IN_PROGRESS:
@@ -209,6 +222,10 @@ class SoftwareConfigService(service.Service):
elif transport == 'ZAQAR_SIGNAL':
sd = self._refresh_zaqar_software_deployment(
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)
def create_software_deployment(self, cnxt, server_id, config_id,
diff --git a/heat/rpc/client.py b/heat/rpc/client.py
index be4ece09d..e611e98f1 100644
--- a/heat/rpc/client.py
+++ b/heat/rpc/client.py
@@ -47,6 +47,7 @@ class EngineClient(object):
1.24 - Adds ignorable_errors to validate_template
1.25 - list_stack_resource filter update
1.26 - Add mark_unhealthy
+ 1.27 - Add check_software_deployment
"""
BASE_RPC_API_VERSION = '1.0'
@@ -60,12 +61,17 @@ class EngineClient(object):
def make_msg(method, **kwargs):
return method, kwargs
- def call(self, ctxt, msg, version=None):
+ def call(self, ctxt, msg, version=None, timeout=None):
method, kwargs = msg
+
if version is not None:
client = self._client.prepare(version=version)
else:
client = self._client
+
+ if timeout is not None:
+ client = client.prepare(timeout=timeout)
+
return client.call(ctxt, method, **kwargs)
def cast(self, ctxt, msg, version=None):
@@ -681,6 +687,12 @@ class EngineClient(object):
return self.call(cnxt, self.make_msg('show_software_deployment',
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,
input_values=None, action='INIT',
status='COMPLETE', status_reason='',
diff --git a/heat/tests/engine/service/test_service_engine.py b/heat/tests/engine/service/test_service_engine.py
index bdc736724..403581fcd 100644
--- a/heat/tests/engine/service/test_service_engine.py
+++ b/heat/tests/engine/service/test_service_engine.py
@@ -40,7 +40,7 @@ class ServiceEngineTest(common.HeatTestCase):
def test_make_sure_rpc_version(self):
self.assertEqual(
- '1.26',
+ '1.27',
service.EngineService.RPC_API_VERSION,
('RPC version is changed, please update this test to new version '
'and make sure additional test cases are added for RPC APIs '
diff --git a/heat/tests/engine/service/test_software_config.py b/heat/tests/engine/service/test_software_config.py
index 1c6d7624c..84a4fa983 100644
--- a/heat/tests/engine/service/test_software_config.py
+++ b/heat/tests/engine/service/test_software_config.py
@@ -311,6 +311,20 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
deployment,
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,
'_push_metadata_software_deployments')
def test_signal_software_deployment(self, pmsd):
diff --git a/heat/tests/openstack/heat/test_software_deployment.py b/heat/tests/openstack/heat/test_software_deployment.py
index 80004eb5e..8c238809a 100644
--- a/heat/tests/openstack/heat/test_software_deployment.py
+++ b/heat/tests/openstack/heat/test_software_deployment.py
@@ -18,6 +18,8 @@ import uuid
import mock
import six
+from oslo_utils import timeutils
+
from heat.common import exception as exc
from heat.common.i18n import _
from heat.engine.clients.os import nova
@@ -168,6 +170,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
stack_user_project_id='65728b74-cfe7-4f17-9c15-11d4f686e591',
cache_data=cache_data
)
+ self.stack.created_time = timeutils.utcnow()
self.patchobject(nova.NovaClientPlugin, 'get_server',
return_value=mock.MagicMock())
@@ -546,7 +549,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
def test_check_create_complete(self):
self._create_stack(self.template)
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
self.assertTrue(self.deployment.check_create_complete(sd))
@@ -560,7 +563,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
def test_check_update_complete(self):
self._create_stack(self.template)
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
self.assertTrue(self.deployment.check_update_complete(sd))
@@ -575,7 +578,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
def test_check_suspend_complete(self):
self._create_stack(self.template)
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
self.assertTrue(self.deployment.check_suspend_complete(sd))
@@ -590,7 +593,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
def test_check_resume_complete(self):
self._create_stack(self.template)
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
self.assertTrue(self.deployment.check_resume_complete(sd))
@@ -608,7 +611,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
'status': self.deployment.FAILED,
'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(
exc.Error, self.deployment.check_create_complete, sd)
self.assertEqual(
@@ -641,7 +644,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
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.assertEqual(sd, self.deployment.handle_delete())
self.assertEqual({
@@ -748,7 +751,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
derived_sc = self.mock_derived_software_config()
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'
# first, handle the suspend
diff --git a/heat/tests/test_rpc_client.py b/heat/tests/test_rpc_client.py
index 9ad61b1b5..ae52ccba5 100644
--- a/heat/tests/test_rpc_client.py
+++ b/heat/tests/test_rpc_client.py
@@ -328,6 +328,11 @@ class EngineRpcAPITestCase(common.HeatTestCase):
self._test_engine_api('show_software_deployment', 'call',
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):
self._test_engine_api(
'create_software_deployment', 'call',