From: Zane Bitter Date: Fri, 24 May 2013 08:31:27 +0000 (+0200) Subject: Handle instance volume attachments with co-routines X-Git-Tag: 2014.1~557^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=0d00d02c1eaea087adc36e143f646c0af4acb2de;p=openstack-build%2Fheat-build.git Handle instance volume attachments with co-routines Don't sit in a loop when attaching volumes to instances, use a task that yields control and allows them to run in parallel - and, in future, in parallel with other resources being created. Change-Id: I4653baa87b09a9fb6c2c16b51218f4ea2f2ae6dd --- diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index 2f637a58..2dfc4c9b 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -345,23 +345,34 @@ class Instance(resource.Resource): if server is not None: self.resource_id_set(server.id) - return server - - def check_create_complete(self, server): - if server.status == 'ACTIVE': - return True - - server.get() - if server.status in self._deferred_server_statuses: - return False - if server.status == 'ACTIVE': - self._set_ipaddress(server.networks) - self.attach_volumes() - return True + 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) + + def check_create_complete(self, cookie): + server, volume_attach = cookie + + if not volume_attach.started(): + if server.status != 'ACTIVE': + server.get() + + if server.status in self._deferred_server_statuses: + return False + elif server.status == 'ACTIVE': + self._set_ipaddress(server.networks) + volume_attach.start() + return volume_attach.done() + else: + raise exception.Error('%s instance[%s] status[%s]' % + ('nova reported unexpected', + self.name, server.status)) else: - raise exception.Error('%s instance[%s] status[%s]' % - ('nova reported unexpected', - self.name, server.status)) + return volume_attach.step() def volumes(self): """ @@ -374,14 +385,6 @@ class Instance(resource.Resource): return ((vol['VolumeId'], vol['Device']) for vol in volumes) - def attach_volumes(self): - for volume_id, device in self.volumes(): - attach_task = volume.VolumeAttachTask(self.stack, - self.resource_id, - volume_id, - device) - scheduler.TaskRunner(attach_task)() - def detach_volumes(self): for volume_id, device in self.volumes(): detach_task = volume.VolumeDetachTask(self.stack,