From: Clint Byrum Date: Wed, 1 May 2013 22:51:03 +0000 (-0700) Subject: Wait for any nova server status that makes sense X-Git-Tag: 2014.1~635^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=9eec986f82e76b899835a8e6a1fafaa4474a7ff4;p=openstack-build%2Fheat-build.git Wait for any nova server status that makes sense Nova may return some transient states based on operator actions that do not mean a resource has failed. Rather than report these as unexpected, wait on them just like BUILD. Fixes bug #1140324 Change-Id: I757c073fb8a7da44f41e9a9cb9ae71dbc35d3c33 --- diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index 487b75dc..a83c4988 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -110,6 +110,17 @@ class Instance(resource.Resource): # is required for a single item to get a tuple not a string update_allowed_keys = ('Metadata',) + _deferred_server_statuses = ['BUILD', + 'HARD_REBOOT', + 'PASSWORD', + 'REBOOT', + 'RESCUE', + 'RESIZE', + 'REVERT_RESIZE', + 'SHUTOFF', + 'SUSPENDED', + 'VERIFY_RESIZE'] + def __init__(self, name, json_snippet, stack): super(Instance, self).__init__(name, json_snippet, stack) self.ipaddress = None @@ -317,7 +328,7 @@ class Instance(resource.Resource): return True server.get() - if server.status == 'BUILD': + if server.status in self._deferred_server_statuses: return False if server.status == 'ACTIVE': self._set_ipaddress(server.networks) diff --git a/heat/tests/test_instance.py b/heat/tests/test_instance.py index 50e3d144..c032aef0 100644 --- a/heat/tests/test_instance.py +++ b/heat/tests/test_instance.py @@ -15,6 +15,7 @@ import copy +import eventlet import mox from heat.tests.v1_1 import fakes @@ -158,6 +159,58 @@ class instancesTest(HeatTestCase): scheduler.TaskRunner(instance.create)() self.assertEqual(instance.state, instance.CREATE_COMPLETE) + def test_instance_status_hard_reboot(self): + self._test_instance_status_not_build_active('HARD_REBOOT') + + def test_instance_status_password(self): + self._test_instance_status_not_build_active('PASSWORD') + + def test_instance_status_reboot(self): + self._test_instance_status_not_build_active('REBOOT') + + def test_instance_status_rescue(self): + self._test_instance_status_not_build_active('RESCUE') + + def test_instance_status_resize(self): + self._test_instance_status_not_build_active('RESIZE') + + def test_instance_status_revert_resize(self): + self._test_instance_status_not_build_active('REVERT_RESIZE') + + def test_instance_status_shutoff(self): + self._test_instance_status_not_build_active('SHUTOFF') + + def test_instance_status_suspended(self): + self._test_instance_status_not_build_active('SUSPENDED') + + def test_instance_status_verify_resize(self): + self._test_instance_status_not_build_active('VERIFY_RESIZE') + + def _test_instance_status_not_build_active(self, uncommon_status): + return_server = self.fc.servers.list()[0] + instance = self._setup_test_instance(return_server, + 'test_instance_status_build') + instance.resource_id = 1234 + + # Bind new fake get method which Instance.check_active will call + def activate_status(server): + if hasattr(server, '_test_check_iterations'): + server._test_check_iterations += 1 + else: + server._test_check_iterations = 1 + if server._test_check_iterations == 1: + server.status = uncommon_status + if server._test_check_iterations > 2: + server.status = 'ACTIVE' + return_server.get = activate_status.__get__(return_server) + self.m.StubOutWithMock(eventlet, 'sleep') + eventlet.sleep(1).AndReturn(None) + eventlet.sleep(1).AndReturn(None) + self.m.ReplayAll() + + scheduler.TaskRunner(instance.create)() + self.assertEqual(instance.state, instance.CREATE_COMPLETE) + def test_build_nics(self): self.assertEqual(None, instances.Instance._build_nics([])) self.assertEqual(None, instances.Instance._build_nics(None)) diff --git a/heat/tests/v1_1/fakes.py b/heat/tests/v1_1/fakes.py index cbccab15..1f3af004 100644 --- a/heat/tests/v1_1/fakes.py +++ b/heat/tests/v1_1/fakes.py @@ -113,6 +113,7 @@ class FakeHTTPClient(base_client.HTTPClient): return (200, {"servers": [ {'id': 1234, 'name': 'sample-server'}, {'id': 5678, 'name': 'sample-server2'}, + {'id': 9101, 'name': 'hard-reboot'}, {'id': 9999, 'name': 'sample-server3'} ]}) @@ -155,6 +156,24 @@ class FakeHTTPClient(base_client.HTTPClient): "private": [{"version": 4, "addr": "10.13.12.13"}]}, "metadata": {"Server Label": "DB 1"}}, + {"id": 9101, + "name": "hard-reboot", + "image": {"id": 2, + "name": "sample image"}, + "flavor": {"id": 1, + "name": "256 MB Server"}, + "hostId": + "9e44d8d435c43dd8d96bb63ed995605f", + "status": "HARD_REBOOT", + "addresses": {"public": [{"version": 4, + "addr": + "172.17.1.2"}, + {"version": 4, + "addr": + "10.20.30.40"}], + "private": [{"version": 4, + "addr": "10.13.12.13"}]}, + "metadata": {"Server Label": "DB 1"}}, {"id": 9999, "name": "sample-server3", "image": {"id": 3,