Support time-delays in server.resize
Resize operation in nova(that we are for flavor update) is asynchronous. So the server may be ACTIVE when we are checking server-resize operations(not RESIZE as was excepted). We need to wait for a while till the server becomes RESIZE. The patch add support of this case to Server resource in heat. Closes-bug: #1471135 Change-Id: I19914081996104c5f2144a6de795173f26774c21
This commit is contained in:
parent
7dcb065b55
commit
f46af8a8e2
@ -432,7 +432,10 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
|
|||||||
If that's the case, confirm the resize, if not raise an error.
|
If that's the case, confirm the resize, if not raise an error.
|
||||||
"""
|
"""
|
||||||
self.refresh_server(server)
|
self.refresh_server(server)
|
||||||
while server.status == 'RESIZE':
|
# resize operation is asynchronous so the server resize may not start
|
||||||
|
# when checking server status (the server may stay ACTIVE instead
|
||||||
|
# of RESIZE).
|
||||||
|
while server.status in ('RESIZE', 'ACTIVE'):
|
||||||
yield
|
yield
|
||||||
self.refresh_server(server)
|
self.refresh_server(server)
|
||||||
if server.status == 'VERIFY_RESIZE':
|
if server.status == 'VERIFY_RESIZE':
|
||||||
|
@ -701,9 +701,9 @@ class InstancesTest(common.HeatTestCase):
|
|||||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
self.fc.servers.get('1234').AndReturn(return_server)
|
self.fc.servers.get('1234').AndReturn(return_server)
|
||||||
|
|
||||||
def activate_status(server):
|
def fail_status(server):
|
||||||
server.status = 'ACTIVE'
|
server.status = 'ERROR'
|
||||||
return_server.get = activate_status.__get__(return_server)
|
return_server.get = fail_status.__get__(return_server)
|
||||||
|
|
||||||
self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
|
self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
|
||||||
self.fc.client.post_servers_1234_action(
|
self.fc.client.post_servers_1234_action(
|
||||||
@ -714,7 +714,7 @@ class InstancesTest(common.HeatTestCase):
|
|||||||
error = self.assertRaises(exception.ResourceFailure, updater)
|
error = self.assertRaises(exception.ResourceFailure, updater)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Error: resources.ud_type_f: "
|
"Error: resources.ud_type_f: "
|
||||||
"Resizing to 'm1.small' failed, status 'ACTIVE'",
|
"Resizing to 'm1.small' failed, status 'ERROR'",
|
||||||
six.text_type(error))
|
six.text_type(error))
|
||||||
self.assertEqual((instance.UPDATE, instance.FAILED), instance.state)
|
self.assertEqual((instance.UPDATE, instance.FAILED), instance.state)
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
@ -1605,9 +1605,9 @@ class ServersTest(common.HeatTestCase):
|
|||||||
self.m.StubOutWithMock(self.fc.servers, 'get')
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
self.fc.servers.get('1234').AndReturn(return_server)
|
self.fc.servers.get('1234').AndReturn(return_server)
|
||||||
|
|
||||||
def activate_status(server):
|
def fail_status(server):
|
||||||
server.status = 'ACTIVE'
|
server.status = 'ERROR'
|
||||||
return_server.get = activate_status.__get__(return_server)
|
return_server.get = fail_status.__get__(return_server)
|
||||||
|
|
||||||
self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
|
self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
|
||||||
self.fc.client.post_servers_1234_action(
|
self.fc.client.post_servers_1234_action(
|
||||||
@ -1618,10 +1618,57 @@ class ServersTest(common.HeatTestCase):
|
|||||||
error = self.assertRaises(exception.ResourceFailure, updater)
|
error = self.assertRaises(exception.ResourceFailure, updater)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Error: resources.srv_update2: Resizing to 'm1.small' failed, "
|
"Error: resources.srv_update2: Resizing to 'm1.small' failed, "
|
||||||
"status 'ACTIVE'", six.text_type(error))
|
"status 'ERROR'", six.text_type(error))
|
||||||
self.assertEqual((server.UPDATE, server.FAILED), server.state)
|
self.assertEqual((server.UPDATE, server.FAILED), server.state)
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def test_server_update_flavor_resize_has_not_started(self):
|
||||||
|
"""Test update of server flavour if server resize has not started.
|
||||||
|
|
||||||
|
Server resize is asynchronous operation in nova. So when heat is
|
||||||
|
requesting resize and polling the server then the server may still be
|
||||||
|
in ACTIVE state. So we need to wait some amount of time till the server
|
||||||
|
status becomes RESIZE.
|
||||||
|
"""
|
||||||
|
# create the server for resizing
|
||||||
|
server = self.fc.servers.list()[1]
|
||||||
|
server.id = '1234'
|
||||||
|
server_resource = self._create_test_server(server,
|
||||||
|
'resize_server')
|
||||||
|
# prepare template with resized server
|
||||||
|
update_template = copy.deepcopy(server_resource.t)
|
||||||
|
update_template['Properties']['flavor'] = 'm1.small'
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get('1234').AndReturn(server)
|
||||||
|
|
||||||
|
# define status transition when server resize
|
||||||
|
# ACTIVE(initial) -> ACTIVE -> RESIZE -> VERIFY_RESIZE
|
||||||
|
|
||||||
|
def active_status(srv):
|
||||||
|
srv.status = 'ACTIVE'
|
||||||
|
server.get = active_status.__get__(server)
|
||||||
|
|
||||||
|
def resize_status(srv):
|
||||||
|
srv.status = 'RESIZE'
|
||||||
|
server.get = resize_status.__get__(server)
|
||||||
|
|
||||||
|
def verify_resize_status(srv):
|
||||||
|
srv.status = 'VERIFY_RESIZE'
|
||||||
|
server.get = verify_resize_status.__get__(server)
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
|
||||||
|
self.fc.client.post_servers_1234_action(
|
||||||
|
body={'resize': {'flavorRef': 2}}).AndReturn((202, None))
|
||||||
|
self.fc.client.post_servers_1234_action(
|
||||||
|
body={'confirmResize': None}).AndReturn((202, None))
|
||||||
|
self.m.ReplayAll()
|
||||||
|
# check that server resize has finished correctly
|
||||||
|
scheduler.TaskRunner(server_resource.update, update_template)()
|
||||||
|
self.assertEqual((server_resource.UPDATE, server_resource.COMPLETE),
|
||||||
|
server_resource.state)
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
def test_server_update_server_flavor_replace(self):
|
def test_server_update_server_flavor_replace(self):
|
||||||
stack_name = 'update_flvrep'
|
stack_name = 'update_flvrep'
|
||||||
(tmpl, stack) = self._setup_test_stack(stack_name)
|
(tmpl, stack) = self._setup_test_stack(stack_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user