def auto_update_db(self, image, os_image): if not image: kind = _get_os_image_kind(os_image) if self.context.project_id == os_image.owner: image = ec2utils.get_db_item_by_os_id(self.context, kind, os_image.id, self.items_dict, os_image=os_image) else: image_id = ec2utils.os_id_to_ec2_id( self.context, kind, os_image.id, items_by_os_id=self.items_dict, ids_by_os_id=self.ids_dict) image = {'id': image_id, 'os_id': os_image.id} elif (self.context.project_id == os_image.owner and image.get('is_public') != os_image.is_public): image['is_public'] = os_image.is_public if image['id'] in self.local_images_os_ids: db_api.update_item(self.context, image) else: # TODO(ft): currently update_item can not update id mapping, # because its project_id is None. Instead of upgrade db_api, # we use add_item. But its execution leads to a needless # DB call. This should be reworked in the future. kind = ec2utils.get_ec2_id_kind(image['id']) db_api.add_item(self.context, kind, image) return image
def auto_update_db(self, image, os_image): if not image: kind = _get_os_image_kind(os_image) if self.context.project_id == os_image.owner: if os_image.properties.get('ec2_id') in self.pending_images: # NOTE(ft): the image is being creating, Glance had created # image, but creating thread doesn't yet update db item image = self.pending_images[os_image.properties['ec2_id']] image['os_id'] = os_image.id image['is_public'] = os_image.is_public db_api.update_item(self.context, image) else: image = ec2utils.get_db_item_by_os_id( self.context, kind, os_image.id, self.items_dict, os_image=os_image) else: image_id = ec2utils.os_id_to_ec2_id( self.context, kind, os_image.id, items_by_os_id=self.items_dict, ids_by_os_id=self.ids_dict) image = {'id': image_id, 'os_id': os_image.id} elif (self.context.project_id == os_image.owner and image.get('is_public') != os_image.is_public): image['is_public'] = os_image.is_public if image['id'] in self.local_images_os_ids: db_api.update_item(self.context, image) else: # TODO(ft): currently update_item can not update id mapping, # because its project_id is None. Instead of upgrade db_api, # we use add_item. But its execution leads to a needless # DB call. This should be reworked in the future. kind = ec2utils.get_ec2_id_kind(image['id']) db_api.add_item(self.context, kind, image) return image
def _format_volume(context, volume, os_volume, instances={}, os_instances={}, snapshots={}, snapshot_id=None): valid_ec2_api_volume_status_map = { 'reserved': 'in-use', 'attaching': 'in-use', 'detaching': 'in-use'} ec2_volume = { 'volumeId': volume['id'], 'status': valid_ec2_api_volume_status_map.get(os_volume.status, os_volume.status), 'size': os_volume.size, 'availabilityZone': os_volume.availability_zone, 'createTime': os_volume.created_at, 'volumeType': os_volume.volume_type, 'encrypted': os_volume.encrypted, } if ec2_volume['status'] == 'in-use': ec2_volume['attachmentSet'] = ( [_format_attachment(context, volume, os_volume, instances, os_instances)]) else: ec2_volume['attachmentSet'] = {} if snapshot_id is None and os_volume.snapshot_id: snapshot = ec2utils.get_db_item_by_os_id( context, 'snap', os_volume.snapshot_id, snapshots) snapshot_id = snapshot['id'] ec2_volume['snapshotId'] = snapshot_id return ec2_volume
def _format_attachment(context, volume, os_volume, instances={}, os_instances={}, instance_id=None): os_attachment = next(iter(os_volume.attachments), {}) os_instance_id = os_attachment.get('server_id') if not instance_id and os_instance_id: instance = ec2utils.get_db_item_by_os_id( context, 'i', os_instance_id, instances) instance_id = instance['id'] status = os_volume.status if status == 'reserved': status = 'attaching' ec2_attachment = { 'device': os_attachment.get('device'), 'instanceId': instance_id, 'status': (status if status in ('attaching', 'detaching') else 'attached' if os_attachment else 'detached'), 'volumeId': volume['id']} if os_instance_id in os_instances: os_instance = os_instances[os_instance_id] volumes_attached = getattr(os_instance, 'os-extended-volumes:volumes_attached', []) volume_attached = next((va for va in volumes_attached if va['id'] == volume['os_id']), None) if volume_attached and 'delete_on_termination' in volume_attached: ec2_attachment['deleteOnTermination'] = ( volume_attached['delete_on_termination']) return ec2_attachment
def _format_attachment(context, os_volume, instances={}, instance_id=None, delete_on_termination_flag=False): os_attachment = next(iter(os_volume.attachments), {}) os_instance_id = os_attachment.get('server_id') if not instance_id and os_instance_id: instance = ec2utils.get_db_item_by_os_id(context, 'i', os_instance_id, instances) instance_id = instance['id'] ec2_attachment = { 'device': os_attachment.get('device'), 'instanceId': instance_id, 'status': (os_volume.status if os_volume.status in ('attaching', 'detaching') else 'attached' if os_attachment else 'detached'), 'volumeId': os_volume.id, 'deleteOnTermination': delete_on_termination_flag } return ec2_attachment
def _format_volume(context, volume, os_volume, instances={}, os_instances={}, snapshots={}, snapshot_id=None): valid_ec2_api_volume_status_map = { 'reserved': 'in-use', 'attaching': 'in-use', 'detaching': 'in-use' } ec2_volume = { 'volumeId': volume['id'], 'status': valid_ec2_api_volume_status_map.get(os_volume.status, os_volume.status), 'size': os_volume.size, 'availabilityZone': os_volume.availability_zone, 'createTime': os_volume.created_at, 'volumeType': os_volume.volume_type, 'encrypted': os_volume.encrypted, } if ec2_volume['status'] == 'in-use': ec2_volume['attachmentSet'] = ([ _format_attachment(context, volume, os_volume, instances, os_instances) ]) else: ec2_volume['attachmentSet'] = {} if snapshot_id is None and os_volume.snapshot_id: snapshot = ec2utils.get_db_item_by_os_id(context, 'snap', os_volume.snapshot_id, snapshots) snapshot_id = snapshot['id'] ec2_volume['snapshotId'] = snapshot_id return ec2_volume
def _format_snapshot(context, snapshot, os_snapshot, volumes={}, volume_id=None): # NOTE(mikal): this is just a set of strings in cinder. If they # implement an enum, then we should move this code to use it. The # valid ec2 statuses are "pending", "completed", and "error". status_map = { 'new': 'pending', 'creating': 'pending', 'available': 'completed', 'active': 'completed', 'deleting': 'pending', 'deleted': None, 'error': 'error' } mapped_status = status_map.get(os_snapshot.status, os_snapshot.status) if not mapped_status: return None if not volume_id and os_snapshot.volume_id: volume = ec2utils.get_db_item_by_os_id(context, 'vol', os_snapshot.volume_id, volumes) volume_id = volume['id'] # NOTE(andrey-mp): ownerId and progress are empty in just created snapshot ownerId = os_snapshot.project_id if not ownerId: ownerId = context.project_id progress = os_snapshot.progress if not progress: progress = '0%' return { 'snapshotId': snapshot['id'], 'volumeId': volume_id, 'status': mapped_status, 'startTime': os_snapshot.created_at, 'progress': progress, 'ownerId': ownerId, 'volumeSize': os_snapshot.size, 'description': os_snapshot.display_description }
def _format_snapshot(context, snapshot, os_snapshot, volumes={}, volume_id=None): # NOTE(mikal): this is just a set of strings in cinder. If they # implement an enum, then we should move this code to use it. The # valid ec2 statuses are "pending", "completed", and "error". status_map = {'new': 'pending', 'creating': 'pending', 'available': 'completed', 'active': 'completed', 'deleting': 'pending', 'deleted': None, 'error': 'error'} mapped_status = status_map.get(os_snapshot.status, os_snapshot.status) if not mapped_status: return None if not volume_id and os_snapshot.volume_id: volume = ec2utils.get_db_item_by_os_id( context, 'vol', os_snapshot.volume_id, volumes) volume_id = volume['id'] # NOTE(andrey-mp): ownerId and progress are empty in just created snapshot ownerId = os_snapshot.project_id if not ownerId: ownerId = context.project_id progress = os_snapshot.progress if not progress: progress = '0%' description = (getattr(os_snapshot, 'description', None) or getattr(os_snapshot, 'display_description', None)) return {'snapshotId': snapshot['id'], 'volumeId': volume_id, 'status': mapped_status, 'startTime': os_snapshot.created_at, 'progress': progress, 'ownerId': ownerId, 'volumeSize': os_snapshot.size, 'description': description}
def auto_update_db(self, image, os_image): if not image: kind = _get_os_image_kind(os_image) if self.context.project_id == os_image.owner: if getattr(os_image, 'ec2_id', None) in self.pending_images: # NOTE(ft): the image is being creating, Glance had created # image, but creating thread doesn't yet update db item image = self.pending_images[os_image.ec2_id] image['os_id'] = os_image.id image['is_public'] = os_image.visibility == 'public' db_api.update_item(self.context, image) else: image = ec2utils.get_db_item_by_os_id(self.context, kind, os_image.id, self.items_dict, os_image=os_image) else: image_id = ec2utils.os_id_to_ec2_id( self.context, kind, os_image.id, items_by_os_id=self.items_dict, ids_by_os_id=self.ids_dict) image = {'id': image_id, 'os_id': os_image.id} elif (self.context.project_id == os_image.owner and image.get('is_public') != os_image.visibility == 'public'): image['is_public'] = os_image.visibility == 'public' if image['id'] in self.local_images_os_ids: db_api.update_item(self.context, image) else: # TODO(ft): currently update_item can not update id mapping, # because its project_id is None. Instead of upgrade db_api, # we use add_item. But its execution leads to a needless # DB call. This should be reworked in the future. kind = ec2utils.get_ec2_id_kind(image['id']) db_api.add_item(self.context, kind, image) return image
def _format_attachment(context, volume, os_volume, instances={}, os_instances={}, instance_id=None): os_attachment = next(iter(os_volume.attachments), {}) os_instance_id = os_attachment.get('server_id') if not instance_id and os_instance_id: instance = ec2utils.get_db_item_by_os_id(context, 'i', os_instance_id, instances) instance_id = instance['id'] status = os_volume.status if status == 'reserved': status = 'attaching' ec2_attachment = { 'device': os_attachment.get('device'), 'instanceId': instance_id, 'status': (status if status in ('attaching', 'detaching') else 'attached' if os_attachment else 'detached'), 'volumeId': volume['id'] } if os_instance_id in os_instances: os_instance = os_instances[os_instance_id] volumes_attached = getattr(os_instance, 'os-extended-volumes:volumes_attached', []) volume_attached = next( (va for va in volumes_attached if va['id'] == volume['os_id']), None) if volume_attached and 'delete_on_termination' in volume_attached: ec2_attachment['deleteOnTermination'] = ( volume_attached['delete_on_termination']) return ec2_attachment
def _get_instance_ec2_id_by_os_id(context, os_instance_id, db_instances_dict): db_item = ec2utils.get_db_item_by_os_id(context, 'i', os_instance_id, db_instances_dict) return db_item['id']