Improve service validation during upgrade Heat
* Added modules which allow to check services status.
Change-Id: Ifca2dab98dfba579b3118c1365caf9e818600bf5
Related-PROD: PROD-25156
diff --git a/_modules/heatv1/__init__.py b/_modules/heatv1/__init__.py
index 45c5cdb..91ecf60 100644
--- a/_modules/heatv1/__init__.py
+++ b/_modules/heatv1/__init__.py
@@ -13,15 +13,18 @@
from heatv1 import stack
+from heatv1 import services
stack_create = stack.stack_create
stack_delete = stack.stack_delete
stack_list = stack.stack_list
stack_show = stack.stack_show
stack_update = stack.stack_update
+service_list = services.service_list
+service_wait = services.wait_for_service
__all__ = ('stack_create', 'stack_list', 'stack_delete', 'stack_show',
- 'stack_update')
+ 'stack_update', 'service_wait', 'service_list')
def __virtual__():
diff --git a/_modules/heatv1/services.py b/_modules/heatv1/services.py
new file mode 100644
index 0000000..a8f952a
--- /dev/null
+++ b/_modules/heatv1/services.py
@@ -0,0 +1,56 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import time
+from salt.exceptions import CommandExecutionError
+
+from heatv1.common import send
+
+@send('get')
+def service_list(cloud_name):
+ """Return list of Heat services."""
+ url = '/services'
+ return url, {}
+
+def wait_for_service(cloud_name, host=None, binary=None, retries=18, timeout=10):
+ """Ensure the service is up and running on specified host.
+
+ :param host: name of a host where service is running
+ :param binary: name of the service
+ :param timeout: number of seconds to wait before retries
+ :param retries: number of retries
+ """
+ for _i in range(retries):
+ services = service_list(cloud_name=cloud_name)['body']['services']
+
+ down_services = [s for s in services if s['status'] == 'down']
+
+ # When Heat worker is reloaded, it creates new instance with different Engine ID.
+ # This is needed for checking that at least one instance on the host is running.
+ up_services_hosts = {s['host'] for s in services if s['status'] == 'up'}
+
+ if host:
+ down_services = [s for s in down_services if s['host'] == host \
+ and s['host'] not in up_services_hosts]
+
+ if binary:
+ down_services = [s for s in down_services if s['binary'] == binary \
+ and s['host'] not in up_services_hosts]
+
+ if not host and not binary:
+ down_services = [s for s in down_services if s['host'] not in up_services_hosts]
+
+ if not down_services:
+ return 'Heat services are running.'
+ time.sleep(timeout)
+
+ raise CommandExecutionError("Heat services {} are still down".format(down_services))