def handle_update(self, json_snippet, tmpl_diff, prop_diff): checkers = [] if prop_diff: # Even though some combinations of changed properties # could be updated in UpdateReplace manner, # we still first detach the old resource so that # self.resource_id is not replaced prematurely volume_id = self.properties.get(self.VOLUME_ID) if self.VOLUME_ID in prop_diff: volume_id = prop_diff.get(self.VOLUME_ID) device = self.properties.get(self.DEVICE) if self.DEVICE in prop_diff: device = prop_diff.get(self.DEVICE) server_id = self._stored_properties_data.get(self.INSTANCE_ID) detach_task = vol_task.VolumeDetachTask(self.stack, server_id, self.resource_id) checkers.append(scheduler.TaskRunner(detach_task)) if self.INSTANCE_ID in prop_diff: server_id = prop_diff.get(self.INSTANCE_ID) attach_task = vol_task.VolumeAttachTask(self.stack, server_id, volume_id, device) checkers.append(scheduler.TaskRunner(attach_task)) if checkers: checkers[0].start() return checkers
def handle_delete(self): server_id = self.properties[self.INSTANCE_ID] detach_task = vol_task.VolumeDetachTask(self.stack, server_id, self.resource_id) detach_runner = scheduler.TaskRunner(detach_task) detach_runner.start() return detach_runner
def _detach_volumes_task(self): ''' Detach volumes from the instance ''' detach_tasks = (vol_task.VolumeDetachTask(self.stack, self.resource_id, volume_id) for volume_id, device in self.volumes()) return scheduler.PollingTaskGroup(detach_tasks)
def handle_update(self, json_snippet, tmpl_diff, prop_diff): vol = None checkers = [] cinder = self.cinder() # update the name and description for cinder volume if self.NAME in prop_diff or self.DESCRIPTION in prop_diff: vol = cinder.volumes.get(self.resource_id) update_name = (prop_diff.get(self.NAME) or self.properties.get(self.NAME)) update_description = (prop_diff.get(self.DESCRIPTION) or self.properties.get(self.DESCRIPTION)) kwargs = self._fetch_name_and_description( cinder.volume_api_version, update_name, update_description) cinder.volumes.update(vol, **kwargs) # update the metadata for cinder volume if self.METADATA in prop_diff: if not vol: vol = cinder.volumes.get(self.resource_id) metadata = prop_diff.get(self.METADATA) cinder.volumes.update_all_metadata(vol, metadata) # retype if self.VOLUME_TYPE in prop_diff: if self.cinder().volume_api_version == 1: LOG.info( _LI('Volume type update not supported ' 'by Cinder API V1.')) raise exception.NotSupported( feature=_('Using Cinder API V1, volume_type update')) else: if not vol: vol = cinder.volumes.get(self.resource_id) new_vol_type = prop_diff.get(self.VOLUME_TYPE) cinder.volumes.retype(vol, new_vol_type, 'never') # extend volume size if self.SIZE in prop_diff: if not vol: vol = cinder.volumes.get(self.resource_id) new_size = prop_diff[self.SIZE] if new_size < vol.size: raise exception.NotSupported(feature=_("Shrinking volume")) elif new_size > vol.size: if vol.attachments: # NOTE(pshchelo): # this relies on current behavior of cinder attachments, # i.e. volume attachments is a list with len<=1, # so the volume can be attached only to single instance, # and id of attachment is the same as id of the volume # it describes, so detach/attach the same volume # will not change volume attachment id. server_id = vol.attachments[0]['server_id'] device = vol.attachments[0]['device'] attachment_id = vol.attachments[0]['id'] detach_task = vol_task.VolumeDetachTask( self.stack, server_id, attachment_id) checkers.append(scheduler.TaskRunner(detach_task)) extend_task = vol_task.VolumeExtendTask( self.stack, vol.id, new_size) checkers.append(scheduler.TaskRunner(extend_task)) attach_task = vol_task.VolumeAttachTask( self.stack, server_id, vol.id, device) checkers.append(scheduler.TaskRunner(attach_task)) else: extend_task = vol_task.VolumeExtendTask( self.stack, vol.id, new_size) checkers.append(scheduler.TaskRunner(extend_task)) if checkers: checkers[0].start() return checkers