if server is not None:
self.resource_id_set(server.id)
+ return server, scheduler.TaskRunner(self._attach_volumes_task())
+
+ def _attach_volumes_task(self):
attach_tasks = (volume.VolumeAttachTask(self.stack,
self.resource_id,
volume_id,
device)
for volume_id, device in self.volumes())
- attach_volumes_task = scheduler.PollingTaskGroup(attach_tasks)
-
- return server, scheduler.TaskRunner(attach_volumes_task)
+ return scheduler.PollingTaskGroup(attach_tasks)
def check_create_complete(self, cookie):
+ return self._check_active(cookie)
+
+ def _check_active(self, cookie):
server, volume_attach = cookie
if not volume_attach.started():
else:
return volumes_runner.step()
+ def handle_resume(self):
+ '''
+ Resume an instance - note we do not wait for the ACTIVE state,
+ this is polled for by check_resume_complete in a similar way to the
+ create logic so we can take advantage of coroutines
+ '''
+ if self.resource_id is None:
+ raise exception.Error(_('Cannot resume %s, resource_id not set') %
+ self.name)
+
+ try:
+ server = self.nova().servers.get(self.resource_id)
+ except clients.novaclient.exceptions.NotFound:
+ raise exception.NotFound(_('Failed to find instance %s') %
+ self.resource_id)
+ else:
+ logger.debug("resuming instance %s" % self.resource_id)
+ server.resume()
+ return server, scheduler.TaskRunner(self._attach_volumes_task())
+
+ def check_resume_complete(self, cookie):
+ return self._check_active(cookie)
+
def resource_mapping():
return {
self.m.VerifyAll()
+ def test_instance_status_resume_immediate(self):
+ return_server = self.fc.servers.list()[1]
+ instance = self._create_test_instance(return_server,
+ 'test_instance_resume')
+
+ instance.resource_id = 1234
+ self.m.ReplayAll()
+
+ # Override the get_servers_1234 handler status to SUSPENDED
+ d = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
+ d['server']['status'] = 'ACTIVE'
+ self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
+ get = self.fc.client.get_servers_1234
+ get().AndReturn((200, d))
+ mox.Replay(get)
+ instance.state_set(instance.SUSPEND, instance.COMPLETE)
+
+ scheduler.TaskRunner(instance.resume)()
+ self.assertEqual(instance.state, (instance.RESUME, instance.COMPLETE))
+
+ self.m.VerifyAll()
+
def test_instance_status_suspend_wait(self):
return_server = self.fc.servers.list()[1]
instance = self._create_test_instance(return_server,
self.m.VerifyAll()
+ def test_instance_status_resume_wait(self):
+ return_server = self.fc.servers.list()[1]
+ instance = self._create_test_instance(return_server,
+ 'test_instance_resume')
+
+ instance.resource_id = 1234
+ self.m.ReplayAll()
+
+ # Override the get_servers_1234 handler status to ACTIVE, but
+ # return the SUSPENDED state first (twice, so we sleep)
+ d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
+ d2 = copy.deepcopy(d1)
+ d1['server']['status'] = 'SUSPENDED'
+ d2['server']['status'] = 'ACTIVE'
+ self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
+ get = self.fc.client.get_servers_1234
+ get().AndReturn((200, d1))
+ get().AndReturn((200, d1))
+ self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep')
+ scheduler.TaskRunner._sleep(mox.IsA(int)).AndReturn(None)
+ get().AndReturn((200, d2))
+ self.m.ReplayAll()
+
+ instance.state_set(instance.SUSPEND, instance.COMPLETE)
+
+ scheduler.TaskRunner(instance.resume)()
+ self.assertEqual(instance.state, (instance.RESUME, instance.COMPLETE))
+
+ self.m.VerifyAll()
+
def test_instance_suspend_volumes_step(self):
return_server = self.fc.servers.list()[1]
instance = self._create_test_instance(return_server,
self.m.VerifyAll()
+ def test_instance_resume_volumes_step(self):
+ return_server = self.fc.servers.list()[1]
+ instance = self._create_test_instance(return_server,
+ 'test_instance_resume')
+
+ instance.resource_id = 1234
+ self.m.ReplayAll()
+
+ # Override the get_servers_1234 handler status to ACTIVE
+ d = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
+ d['server']['status'] = 'ACTIVE'
+
+ # Return a dummy PollingTaskGroup to make check_resume_complete step
+ def dummy_attach():
+ yield
+ dummy_tg = scheduler.PollingTaskGroup([dummy_attach, dummy_attach])
+ self.m.StubOutWithMock(instance, '_attach_volumes_task')
+ instance._attach_volumes_task().AndReturn(dummy_tg)
+
+ self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
+ get = self.fc.client.get_servers_1234
+ get().AndReturn((200, d))
+
+ self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep')
+ scheduler.TaskRunner._sleep(mox.IsA(int)).AndReturn(None)
+ self.m.ReplayAll()
+
+ instance.state_set(instance.SUSPEND, instance.COMPLETE)
+
+ scheduler.TaskRunner(instance.resume)()
+ self.assertEqual(instance.state, (instance.RESUME, instance.COMPLETE))
+
+ self.m.VerifyAll()
+
def test_instance_status_build_spawning(self):
self._test_instance_status_not_build_active('BUILD(SPAWNING)')