]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Wait for any nova server status that makes sense
authorClint Byrum <clint@fewbar.com>
Wed, 1 May 2013 22:51:03 +0000 (15:51 -0700)
committerJeremy Stanley <fungi@yuggoth.org>
Tue, 7 May 2013 17:37:31 +0000 (17:37 +0000)
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

heat/engine/resources/instance.py
heat/tests/test_instance.py
heat/tests/v1_1/fakes.py

index 487b75dcb068cfa24878de15b34ed51fe55951a2..a83c49889eb6d44c8e2767e0e85112c473ac0b07 100644 (file)
@@ -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)
index 50e3d1442081932f580c78da5e0cd614dadb57a0..c032aef0c4f1899b4e152fa55800db2f86dee1d4 100644 (file)
@@ -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))
index cbccab1518d7f34e636c83ba00ab7ed51adfc561..1f3af004680657f3aa456534276a9b627c46bde4 100644 (file)
@@ -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,